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); } }
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); }