Ejemplo n.º 1
0
 public UpvalueExpressionGenerator(AllocatedLocal upvalList, int index, LocalVariableDefinitionSyntaxNode definition)
     : base(0)
 {
     _upvalList = upvalList;
     _index     = index;
     _type      = definition.Specialization.GetVMSpecializationType();
 }
Ejemplo n.º 2
0
        public ConditionGenerator(GeneratorFactory factory, BlockGenerator block,
                                  ExpressionSyntaxNode expr, LabelStatementSyntaxNode falseLabel, bool reverseCondition)
        {
            while (expr is UnaryExpressionSyntaxNode unary && unary.Operator == UnaryOperator.Not)
            {
                expr             = unary.Operand;
                reverseCondition = !reverseCondition;
            }

            if (expr is BinaryExpressionSyntaxNode bin && IsComparisonExpr(bin, out _opcode, out _exchangeComparison))
            {
                _isComparison = true;
                //Normally, reverse the cmp (jump to false label if condition is not met).
                if (!reverseCondition)
                {
                    ReverseComparisonResult(ref _opcode);
                }
                _expr1 = factory.CreateExpression(block, bin.Left);
                _expr2 = factory.CreateExpression(block, bin.Right);
                if (!_expr1.TryGetFromStack(out _))
                {
                    _expr1Stack = block.TempAllocator.Allocate(_expr1.GetSingleType());
                }
                if (!_expr2.TryGetFromStack(out _))
                {
                    _expr2Stack = block.TempAllocator.Allocate(_expr2.GetSingleType());
                }
            }
Ejemplo n.º 3
0
        public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
        {
            var leftStack  = _leftStack ?? dest;
            var rightStack = _rightStack ?? dest;

            if (_left.GetSingleType() != _type || _right.GetSingleType() != _type)
            {
                //Needs conversion in MOV and ISTC.
                throw new NotImplementedException();
            }
            if (leftStack.Offset > 255 || rightStack.Offset > 255 || dest.Offset > 255)
            {
                throw new NotImplementedException();
            }

            //  emit leftStack = _left
            //  ISFC/ISTC dest, leftStack, exitLabel
            //  emit rightStack = _right
            //  MOV dest, rightStack
            //exitLabel:

            var exitLabel = new LabelStatementSyntaxNode();

            _left.EmitPrep(writer);
            _left.EmitGet(writer, leftStack);
            writer.WriteUUS(_opcode, dest.Offset, leftStack.Offset, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUUSJump);
            _right.EmitPrep(writer);
            _right.EmitGet(writer, rightStack);
            //We already wrote to dest. No need to MOV.
            Debug.Assert(rightStack.Offset == dest.Offset);
            writer.MarkLabel(exitLabel);
        }
Ejemplo n.º 4
0
 public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
 {
     if (dest.Offset > 255 || _constIndex > 255)
     {
         throw new NotImplementedException();
     }
     writer.WriteUUU(OpCodes.K, dest.Offset, _constIndex, 0);
 }
Ejemplo n.º 5
0
 public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
 {
     Debug.Assert(!_isVararg);
     if (dest.Offset > 255)
     {
         throw new NotImplementedException();
     }
     writer.WriteUUU(OpCodes.VARG1, dest.Offset, 0, 0);
 }
Ejemplo n.º 6
0
 protected virtual void EmitInstruction(InstructionWriter writer, AllocatedLocal dest,
                                        AllocatedLocal leftStack, AllocatedLocal rightStack)
 {
     if (dest.Offset > 255 || leftStack.Offset > 255 || rightStack.Offset > 255)
     {
         throw new NotImplementedException();
     }
     writer.WriteUUU(_opcode, dest.Offset, leftStack.Offset, rightStack.Offset);
 }
        public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
        {
            var destIndex = dest.Offset;
            var offset    = _localInfo.Offset;

            if (offset > 255 || destIndex > 255)
            {
                throw new NotImplementedException();
            }
            writer.WriteUUU(Opcodes.MOV, destIndex, offset, 0);
        }
Ejemplo n.º 8
0
        public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
        {
            var destIndex  = dest.Offset;
            var listOffset = _upvalList.Offset;

            if (destIndex > 255 | listOffset > 255 | _index > 255)
            {
                throw new NotImplementedException();
            }
            writer.WriteUUU(OpCodes.UGET, destIndex, listOffset, _index);
        }
        public override void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type)
        {
            if (type != _type)
            {
                throw new NotImplementedException();
            }
            var srcIndex = src.Offset;
            var offset   = _localInfo.Offset;

            if (offset > 255 || srcIndex > 255)
            {
                throw new NotImplementedException();
            }
            writer.WriteUUU(Opcodes.MOV, offset, srcIndex, 0);
        }
Ejemplo n.º 10
0
        public override void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type)
        {
            if (type != _type)
            {
                throw new NotImplementedException();
            }
            var srcIndex   = src.Offset;
            var listOffset = _upvalList.Offset;

            if (srcIndex > 255 | listOffset > 255 | _index > 255)
            {
                throw new NotImplementedException();
            }
            writer.WriteUUU(OpCodes.USET, srcIndex, listOffset, _index);
        }
Ejemplo n.º 11
0
 public override void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type)
 {
     if (!_table.TryGetFromStack(out var tableStack))
     {
         tableStack = _tableStack.Value;
     }
     if (!_key.TryGetFromStack(out var keyStack))
     {
         keyStack = _keyStack.Value;
     }
     if (tableStack.Offset > 255 || keyStack.Offset > 255 || src.Offset > 255)
     {
         throw new NotImplementedException();
     }
     writer.WriteUUU(Opcodes.TSET, src.Offset, tableStack.Offset, keyStack.Offset);
 }
Ejemplo n.º 12
0
        public NumericForStatementGenerator(GeneratorFactory factory, BlockGenerator block, NumericForBlockSyntaxNode stat)
        {
            var stack = new GroupStackFragment();

            block.Stack.Add(stack);

            _e1 = factory.CreateExpression(block, stat.From);
            _e2 = factory.CreateExpression(block, stat.To);
            var stepExpr = stat.Step ?? new LiteralExpressionSyntaxNode()
            {
                DoubleValue = 1
            };

            _e3 = factory.CreateExpression(block, stepExpr);
            var e1t = _e1.GetSingleType();
            var e2t = _e2.GetSingleType();
            var e3t = _e3.GetSingleType();

            if (e1t == VMSpecializationType.Polymorphic &&
                e2t == VMSpecializationType.Polymorphic &&
                e3t == VMSpecializationType.Polymorphic)
            {
                _initOp = Opcodes.FORI;
                _loopOp = Opcodes.FORL;
            }
            else
            {
                throw new NotImplementedException();
            }

            var ctrlStack = new BlockStackFragment();

            stack.Add(ctrlStack);
            _e1Stack = ctrlStack.AddSpecializedType(e1t);
            _e2Stack = ctrlStack.AddSpecializedType(e2t);
            _e3Stack = ctrlStack.AddSpecializedType(e3t);

            //Use stack (so it's after control variables).
            //This will also handle the aux block for us.
            _forBlock = new BlockGenerator(factory, stack, stat);

            var loopVar        = factory.Function.Locals[stat.Variable];
            var loopVarOnStack = loopVar.TryGetFromStack(out _loopVar);

            Debug.Assert(loopVarOnStack);
        }
Ejemplo n.º 13
0
        public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
        {
            int operand;

            if (_tmpSlot.HasValue)
            {
                _operand.EmitGet(writer, _tmpSlot.Value);
                operand = _tmpSlot.Value.Offset;
            }
            else
            {
                var onStack = _operand.TryGetFromStack(out var s);
                Debug.Assert(onStack);
                operand = s.Offset;
            }
            var destIndex = dest.Offset;

            if (operand > 255 || destIndex > 255)
            {
                throw new NotImplementedException();
            }
            switch (_operator)
            {
            case UnaryOperator.Neg:
                writer.WriteUUU(OpCodes.NEG, destIndex, operand, 0);
                break;

            case UnaryOperator.Not:
                writer.WriteUUU(OpCodes.NOT, destIndex, operand, 0);
                break;

            case UnaryOperator.Num:
                writer.WriteUUU(OpCodes.LEN, destIndex, operand, 0);
                break;
            }
        }
Ejemplo n.º 14
0
 public override bool TryGetFromStack(out AllocatedLocal stackOffset)
 {
     stackOffset = default;
     return(false);
 }
Ejemplo n.º 15
0
 protected ExpressionGenerator(GeneratorFactory factory)
 {
     _null = factory.Function.NullSlot;
 }
Ejemplo n.º 16
0
 //For all expressions: get the single value and write to dest.
 //EmitPrep will be called before this.
 public abstract void EmitGet(InstructionWriter writer, AllocatedLocal dest);
Ejemplo n.º 17
0
        public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
        {
            //The two special cases.
            if (_mode == CalcMode.LeftToDest)
            {
                if (_right.TryGetFromStack(out var rightStack) && rightStack.Offset == dest.Offset)
                {
                    _left.EmitPrep(writer);
                    _left.EmitGet(writer, _rightTemp.Value);
                    EmitInstruction(writer, dest, _rightTemp.Value, rightStack);
                    return;
                }
            }
            else if (_mode == CalcMode.RightToDest)
            {
                if (_left.TryGetFromStack(out var leftStack) && leftStack.Offset == dest.Offset)
                {
                    _right.EmitPrep(writer);
                    _right.EmitGet(writer, _leftTemp.Value);
                    EmitInstruction(writer, dest, leftStack, _leftTemp.Value);
                    return;
                }
            }

            switch (_mode)
            {
            case CalcMode.LeftToDest:
            {
                _left.EmitPrep(writer);
                _left.EmitGet(writer, dest);
                if (!_right.TryGetFromStack(out var rightStack))
                {
                    rightStack = _rightTemp.Value;
                    _right.EmitPrep(writer);
                    _right.EmitGet(writer, rightStack);
                }
                EmitInstruction(writer, dest, dest, rightStack);
                break;
            }

            case CalcMode.RightToDest:
            {
                if (!_left.TryGetFromStack(out var leftStack))
                {
                    leftStack = _leftTemp.Value;
                    _left.EmitPrep(writer);
                    _left.EmitGet(writer, leftStack);
                }
                _right.EmitPrep(writer);
                _right.EmitGet(writer, dest);
                EmitInstruction(writer, dest, leftStack, dest);
                break;
            }

            case CalcMode.Normal:
            {
                if (!_left.TryGetFromStack(out var leftStack))
                {
                    leftStack = _leftTemp.Value;
                    _left.EmitPrep(writer);
                    _left.EmitGet(writer, leftStack);
                }
                if (!_right.TryGetFromStack(out var rightStack))
                {
                    rightStack = _rightTemp.Value;
                    _right.EmitPrep(writer);
                    _right.EmitGet(writer, rightStack);
                }
                EmitInstruction(writer, dest, leftStack, rightStack);
                break;
            }
            }
        }
Ejemplo n.º 18
0
 //For variables: set the value of the variable to the value at src.
 //EmitPrep will be called before this.
 public virtual void EmitSet(InstructionWriter writer, AllocatedLocal src, VMSpecializationType type)
 {
     throw new NotSupportedException();
 }
Ejemplo n.º 19
0
 public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
 {
     throw new NotSupportedException();
 }
Ejemplo n.º 20
0
 //For locals & arguments: provide the slot it occupies on stack.
 //This might be called before and during the emit stage.
 //EmitPrep will NOT be called before this.
 public abstract bool TryGetFromStack(out AllocatedLocal stackOffset);
 public override bool TryGetFromStack(out AllocatedLocal stackOffset)
 {
     stackOffset = _localInfo;
     return(true);
 }
 public LocalVariableExpressionGenerator(BlockStackFragment stack, LocalVariableDefinitionSyntaxNode definition)
     : base(0)
 {
     _type      = definition.Specialization.GetVMSpecializationType();
     _localInfo = stack.AddSpecializedType(_type);
 }