示例#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);
        }
 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);
     }
 }
示例#4
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);
        }