コード例 #1
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);
        }
コード例 #2
0
        public override void Emit(InstructionWriter writer)
        {
            Debug.Assert(_firstLoopVarStack.Offset == _hiddenVariableStack.Offset + 3);

            _forBlock.EmitUpvalLists(writer);

            var exitLabel = new LabelStatementSyntaxNode();
            var loopLabel = new LabelStatementSyntaxNode();

            //Insert assignment and FORG instruction (call iterator function and check for exit condition).
            _assignment.Emit(writer);

            writer.MarkLabel(loopLabel);
            if (_hiddenVariableStack.Offset > 255 || _loopVarSig > 255)
            {
                throw new NotImplementedException();
            }
            writer.WriteUUS(Opcodes.FORG, _hiddenVariableStack.Offset, _loopVarSig, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUUSJump);

            //Emit inner block.
            _forBlock.EmitStatements(writer);

            //Jump back.
            writer.WriteUSx(Opcodes.JMP, 0, 0);
            writer.AddLabelFix(loopLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(exitLabel);
        }
コード例 #3
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);
 }
コード例 #4
0
 public override void EmitGet(InstructionWriter writer, IStackFragment sigBlock, int sigIndex, bool keepSig)
 {
     Debug.Assert(_isVararg);
     if (sigIndex > 255 || sigBlock.Offset > 255)
     {
         throw new NotImplementedException();
     }
     writer.WriteUUU(keepSig ? Opcodes.VARG : Opcodes.VARGC, sigIndex, sigBlock.Offset, 0);
 }
コード例 #5
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);
 }
コード例 #6
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);
 }
コード例 #7
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);
        }
コード例 #8
0
 public override void EmitPrep(InstructionWriter writer)
 {
     if (_tableStack.HasValue)
     {
         _table.EmitGet(writer, _tableStack.Value);
     }
     if (_keyStack.HasValue)
     {
         _key.EmitGet(writer, _keyStack.Value);
     }
 }
コード例 #9
0
        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);
        }
コード例 #10
0
        public override void Emit(InstructionWriter writer)
        {
            var restartLabel = new LabelStatementSyntaxNode();

            writer.MarkLabel(restartLabel);
            _cond.Emit(writer);

            _block.Emit(writer);

            writer.WriteUSx(OpCodes.JMP, 0, 0);
            writer.AddLabelFix(restartLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(_exitLabel);
        }
コード例 #11
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);
        }
コード例 #12
0
        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);
        }
コード例 #13
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);
 }
コード例 #14
0
 public override void EmitGet(InstructionWriter writer, IStackFragment sigBlock, StackSignature sigType,
                              int sigIndex, bool keepSig)
 {
     Debug.Assert(_isVararg);
     if (sigIndex > 255 || sigBlock.Offset > 255 | sigType.FixedSize > 127)
     {
         throw new NotImplementedException();
     }
     //Note that for VARG/VARGC, we are using a different version of R1-R3. See OpCodes doc for details.
     Debug.Assert(_funcVarargSig.FixedSize == 0);
     if (_funcVarargSig.IsCompatibleWith(sigType))
     {
         writer.WriteUUS(keepSig ? OpCodes.VARG : OpCodes.VARGC,
                         sigBlock.Offset, sigIndex, sigType.FixedSize);
     }
     else
     {
         writer.WriteUUS(keepSig ? OpCodes.VARG : OpCodes.VARGC,
                         sigBlock.Offset, sigIndex, -1);
     }
 }
コード例 #15
0
        public override void Emit(InstructionWriter writer)
        {
            Debug.Assert(_firstLoopVarStack.Offset == _hiddenVariableStack.Offset + 3);

            _forBlock.EmitUpvalLists(writer);

            var exitLabel = new LabelStatementSyntaxNode();
            var loopLabel = new LabelStatementSyntaxNode();

            //Insert assignment and FORG instruction (call iterator function and check for exit condition).
            _assignment.Emit(writer);

            writer.MarkLabel(loopLabel);
            if (_hiddenVariableStack.Offset > 255 || _loopVarSig > 255 || _loopVarSigType.FixedSize > 127)
            {
                throw new NotImplementedException();
            }

            writer.WriteUSx(OpCodes.FORG, _hiddenVariableStack.Offset, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUSxJump);
            //Adjust right parameter: assume EmptyV.
            if (_loopVarSigType.IsCompatibleWith(StackSignature.EmptyV))
            {
                writer.WriteUUS(OpCodes.FORG_CTN,
                                _loopVarSig, (int)WellKnownStackSignature.EmptyV, _loopVarSigType.FixedSize);
            }
            else
            {
                writer.WriteUUS(OpCodes.FORG_CTN, _loopVarSig, 0, 0);
            }

            //Emit inner block.
            _forBlock.EmitStatements(writer);

            //Jump back.
            writer.WriteUSx(OpCodes.JMP, 0, 0);
            writer.AddLabelFix(loopLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(exitLabel);
        }
コード例 #16
0
        public override void Emit(InstructionWriter writer)
        {
            var restartLabel = new LabelStatementSyntaxNode();
            var exitLabel    = new LabelStatementSyntaxNode();

            if (_e1Stack.Offset > 255 || _loopVar.Offset > 255)
            {
                throw new NotImplementedException();
            }

            //Calc expressions.
            _e1.EmitPrep(writer);
            _e1.EmitGet(writer, _e1Stack);
            _e2.EmitPrep(writer);
            _e2.EmitGet(writer, _e2Stack);
            _e3.EmitPrep(writer);
            _e3.EmitGet(writer, _e3Stack);

            //Init instruction (check type, check exit condition).
            writer.WriteUSx(_initOp, _e1Stack.Offset, 0);
            writer.AddLabelFix(exitLabel, InstructionWriter.FixUSxJump);

            //This is where we restart.
            writer.MarkLabel(restartLabel);

            //Start of the actual block (creates upvals).
            _forBlock.EmitUpvalLists(writer);
            //Copy hidden control variable to the visible loop var.
            writer.WriteUUU(Opcodes.MOV, _loopVar.Offset, _e1Stack.Offset, 0);

            //Emit inner aux block.
            _forBlock.EmitStatements(writer);

            //Loop instruction.
            writer.WriteUSx(_loopOp, _e1Stack.Offset, 0);
            writer.AddLabelFix(restartLabel, InstructionWriter.FixUSxJump);

            writer.MarkLabel(exitLabel);
        }
コード例 #17
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;
            }
        }
コード例 #18
0
 public override void Emit(InstructionWriter writer)
 {
     writer.WriteUUU(Opcodes.RET0, 0, 0, 0);
 }
コード例 #19
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;
            }
            }
        }
コード例 #20
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();
 }
コード例 #21
0
 //For expressions with side effects: perform the expression's side effect without saving the value.
 //EmitPrep will NOT be called before this.
 public virtual void EmitDiscard(InstructionWriter writer)
 {
     EmitPrep(writer);
     EmitGet(writer, _null);
 }
コード例 #22
0
 public override void EmitGet(InstructionWriter writer, AllocatedLocal dest)
 {
     throw new NotSupportedException();
 }
コード例 #23
0
 public override void Emit(InstructionWriter writer)
 {
     writer.WriteUSx(Opcodes.JMP, 0, 0);
     writer.AddLabelFix(_label, InstructionWriter.FixUSxJump);
 }
コード例 #24
0
 public override void Emit(InstructionWriter writer)
 {
     _expr.EmitPrep(writer);
     _expr.EmitDiscard(writer);
 }
コード例 #25
0
 //For vararg expr: calculate the value and write to stack at sigblock's location, with the given sig index.
 //The sigIndex is the index into proto's signature list. This should be the out signature of function calls.
 //sigType is the instance at sig index. It is needed by the new sig adjustment method.
 //EmitPrep will be called before this.
 public virtual void EmitGet(InstructionWriter writer, IStackFragment sigBlock, StackSignature sigType,
                             int sigIndex, bool keepSig)
 {
     throw new NotSupportedException();
 }
コード例 #26
0
 public override void Emit(InstructionWriter writer)
 {
     writer.MarkLabel(_label);
 }
コード例 #27
0
 public override void EmitDiscard(InstructionWriter writer)
 {
 }
コード例 #28
0
ファイル: StatementGenerator.cs プロジェクト: acaly/FastLua
 public abstract void Emit(InstructionWriter writer);
コード例 #29
0
 public override void Emit(InstructionWriter writer)
 {
     writer.MarkLabel(_repeatLabel);
     _block.Emit(writer);
     _cond.Emit(writer);
 }
コード例 #30
0
 public override void EmitDiscard(InstructionWriter writer)
 {
     throw new NotSupportedException();
 }