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