/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override void Emit(CodeGenerator codeGenerator) { Statistics.AST.AddNode("Loop.While"); ILEmitter il = codeGenerator.IL; Label cond_label = il.DefineLabel(); Label exit_label = il.DefineLabel(); Label stat_label = il.DefineLabel(); codeGenerator.BranchingStack.BeginLoop(cond_label, exit_label, codeGenerator.ExceptionBlockNestingLevel); if (this.type == Type.While) { il.Emit(OpCodes.Br, cond_label); } // body: il.MarkLabel(stat_label); body.Emit(codeGenerator); // marks a sequence point containing condition: codeGenerator.MarkSequencePoint( condExpr.Position.FirstLine, condExpr.Position.FirstColumn, condExpr.Position.LastLine, condExpr.Position.LastColumn + 1); // condition: il.MarkLabel(cond_label); // bounded loop: if (condExpr != null) { // IF (<(bool) condition>) GOTO stat; codeGenerator.EmitConversion(condExpr, PhpTypeCode.Boolean); il.Emit(OpCodes.Brtrue, stat_label); } il.MarkLabel(exit_label); codeGenerator.BranchingStack.EndLoop(); il.ForgetLabel(cond_label); il.ForgetLabel(exit_label); il.ForgetLabel(stat_label); }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override void Emit(CodeGenerator codeGenerator) { Statistics.AST.AddNode("IfStmt"); Debug.Assert(conditions.Count > 0); // marks a sequence point containing whole condition: codeGenerator.MarkSequencePoint(conditions[0].Condition); // NOTE: (J) when emitting a statement, sequence point has to be marked. Normally it is done in Statement.Emit() ILEmitter il = codeGenerator.IL; Label exit_label = il.DefineLabel(); Label false_label = il.DefineLabel(); // IF codeGenerator.EmitConversion(conditions[0].Condition, PhpTypeCode.Boolean); il.Emit(OpCodes.Brfalse, false_label); conditions[0].Statement.Emit(codeGenerator); codeGenerator.MarkSequencePoint( // (J) Mark the end of condition body so debugger will jump off the block properly conditions[0].Statement.Position.LastLine, conditions[0].Statement.Position.LastColumn, conditions[0].Statement.Position.LastLine, conditions[0].Statement.Position.LastColumn + 1); il.Emit(OpCodes.Br, exit_label); // ELSEIF: for (int i = 1; i < conditions.Count && conditions[i].Condition != null; i++) { il.MarkLabel(false_label, true); false_label = il.DefineLabel(); // IF (!<(bool) condition>) codeGenerator.MarkSequencePoint(conditions[i].Condition); // marks a sequence point of the condition "statement" codeGenerator.EmitConversion(conditions[i].Condition, PhpTypeCode.Boolean); il.Emit(OpCodes.Brfalse, false_label); conditions[i].Statement.Emit(codeGenerator); il.Emit(OpCodes.Br, exit_label); } il.MarkLabel(false_label, true); // ELSE if (conditions[conditions.Count - 1].Condition == null) conditions[conditions.Count - 1].Statement.Emit(codeGenerator); il.MarkLabel(exit_label, true); }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override void Emit(CodeGenerator codeGenerator) { Statistics.AST.AddNode("Loop.For"); // Template: // we expand the for-statement // for (<expr1>; <expr2>; <expr3>) <loop body> // in the while form // { // <expr1>; // while (<expr2>) { // <loop body>; // <expr 3>; // } // } Label cond_label = codeGenerator.IL.DefineLabel(); Label iterate_label = codeGenerator.IL.DefineLabel(); Label exit_label = codeGenerator.IL.DefineLabel(); Label stat_label = codeGenerator.IL.DefineLabel(); codeGenerator.BranchingStack.BeginLoop(iterate_label, exit_label, codeGenerator.ExceptionBlockNestingLevel); // marks a sequence point containing initialization statements (if any): if (initExList.Count > 0) { codeGenerator.MarkSequencePoint( initExList[0].Position.FirstLine, initExList[0].Position.FirstColumn, initExList[initExList.Count - 1].Position.LastLine, initExList[initExList.Count - 1].Position.LastColumn + 1); } // Emit <expr1> foreach (Expression expr in initExList) expr.Emit(codeGenerator); // Branch unconditionally to the begin of condition evaluation codeGenerator.IL.Emit(OpCodes.Br, cond_label); // Emit loop body codeGenerator.IL.MarkLabel(stat_label); body.Emit(codeGenerator); codeGenerator.IL.MarkLabel(iterate_label); // marks a sequence point containing action statements (if any): if (actionExList.Count > 0) { codeGenerator.MarkSequencePoint( actionExList[0].Position.FirstLine, actionExList[0].Position.FirstColumn, actionExList[actionExList.Count - 1].Position.LastLine, actionExList[actionExList.Count - 1].Position.LastColumn + 1); } // Emit <expr3> foreach (Expression expr in actionExList) expr.Emit(codeGenerator); // marks a sequence point containing condition (if any): if (condExList.Count > 0) { codeGenerator.MarkSequencePoint( condExList[0].Position.FirstLine, condExList[0].Position.FirstColumn, condExList[condExList.Count - 1].Position.LastLine, condExList[condExList.Count - 1].Position.LastColumn + 1); } // Emit <expr2> codeGenerator.IL.MarkLabel(cond_label); if (condExList.Count > 0) { for (int i = 0; i < (condExList.Count - 1); i++) condExList[i].Emit(codeGenerator); // LOAD <(bool) condition> codeGenerator.EmitConversion(condExList[condExList.Count - 1], PhpTypeCode.Boolean); } else codeGenerator.IL.LdcI4(1); codeGenerator.IL.Emit(OpCodes.Brtrue, stat_label); codeGenerator.IL.MarkLabel(exit_label); codeGenerator.BranchingStack.EndLoop(); codeGenerator.IL.ForgetLabel(cond_label); codeGenerator.IL.ForgetLabel(iterate_label); codeGenerator.IL.ForgetLabel(exit_label); codeGenerator.IL.ForgetLabel(stat_label); }