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);
     }
 }
Example #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 || _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);
        }