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