예제 #1
0
		/// <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);
		}
예제 #2
0
        /// <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);
		}
예제 #3
0
		/// <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);
		}