⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statement.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
//// statement.cs: Statement representation for the IL tree.//// Author://   Miguel de Icaza (miguel@ximian.com)//   Martin Baulig (martin@ximian.com)//// (C) 2001, 2002, 2003 Ximian, Inc.// (C) 2003, 2004 Novell, Inc.//using System;using System.Text;using System.Reflection;using System.Reflection.Emit;using System.Diagnostics;using System.Collections;using System.Collections.Specialized;namespace Mono.CSharp {		public abstract class Statement {		public Location loc;				/// <summary>		///   Resolves the statement, true means that all sub-statements		///   did resolve ok.		//  </summary>		public virtual bool Resolve (EmitContext ec)		{			return true;		}		/// <summary>		///   We already know that the statement is unreachable, but we still		///   need to resolve it to catch errors.		/// </summary>		public virtual bool ResolveUnreachable (EmitContext ec, bool warn)		{			//			// This conflicts with csc's way of doing this, but IMHO it's			// the right thing to do.			//			// If something is unreachable, we still check whether it's			// correct.  This means that you cannot use unassigned variables			// in unreachable code, for instance.			//			if (warn && (RootContext.WarningLevel >= 2))				Report.Warning (162, loc, "Unreachable code detected");			ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);			bool ok = Resolve (ec);			ec.KillFlowBranching ();			return ok;		}						/// <summary>		///   Return value indicates whether all code paths emitted return.		/// </summary>		protected abstract void DoEmit (EmitContext ec);		/// <summary>		///   Utility wrapper routine for Error, just to beautify the code		/// </summary>		public void Error (int error, string format, params object[] args)		{			Error (error, String.Format (format, args));		}		public void Error (int error, string s)		{			if (!loc.IsNull)				Report.Error (error, loc, s);			else				Report.Error (error, s);		}		/// <summary>		///   Return value indicates whether all code paths emitted return.		/// </summary>		public virtual void Emit (EmitContext ec)		{			ec.Mark (loc, true);			DoEmit (ec);		}			}	public sealed class EmptyStatement : Statement {				private EmptyStatement () {}				public static readonly EmptyStatement Value = new EmptyStatement ();				public override bool Resolve (EmitContext ec)		{			return true;		}				protected override void DoEmit (EmitContext ec)		{		}	}		public class If : Statement {		Expression expr;		public Statement TrueStatement;		public Statement FalseStatement;		bool is_true_ret;				public If (Expression expr, Statement trueStatement, Location l)		{			this.expr = expr;			TrueStatement = trueStatement;			loc = l;		}		public If (Expression expr,			   Statement trueStatement,			   Statement falseStatement,			   Location l)		{			this.expr = expr;			TrueStatement = trueStatement;			FalseStatement = falseStatement;			loc = l;		}		public override bool Resolve (EmitContext ec)		{			bool ok = true;			Report.Debug (1, "START IF BLOCK", loc);			expr = Expression.ResolveBoolean (ec, expr, loc);			if (expr == null){				ok = false;				goto skip;			}			Assign ass = expr as Assign;			if (ass != null && ass.Source is Constant) {				Report.Warning (665, 3, loc, "Assignment in conditional expression is always constant; did you mean to use == instead of = ?");			}			//			// Dead code elimination			//			if (expr is BoolConstant){				bool take = ((BoolConstant) expr).Value;				if (take){					if (!TrueStatement.Resolve (ec))						return false;					if ((FalseStatement != null) &&					    !FalseStatement.ResolveUnreachable (ec, true))						return false;					FalseStatement = null;				} else {					if (!TrueStatement.ResolveUnreachable (ec, true))						return false;					TrueStatement = null;					if ((FalseStatement != null) &&					    !FalseStatement.Resolve (ec))						return false;				}				return true;			}		skip:			ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);						ok &= TrueStatement.Resolve (ec);			is_true_ret = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;			ec.CurrentBranching.CreateSibling ();			if (FalseStatement != null)				ok &= FalseStatement.Resolve (ec);								ec.EndFlowBranching ();			Report.Debug (1, "END IF BLOCK", loc);			return ok;		}				protected override void DoEmit (EmitContext ec)		{			ILGenerator ig = ec.ig;			Label false_target = ig.DefineLabel ();			Label end;			//			// If we're a boolean expression, Resolve() already			// eliminated dead code for us.			//			if (expr is BoolConstant){				bool take = ((BoolConstant) expr).Value;				if (take)					TrueStatement.Emit (ec);				else if (FalseStatement != null)					FalseStatement.Emit (ec);				return;			}						expr.EmitBranchable (ec, false_target, false);						TrueStatement.Emit (ec);			if (FalseStatement != null){				bool branch_emitted = false;								end = ig.DefineLabel ();				if (!is_true_ret){					ig.Emit (OpCodes.Br, end);					branch_emitted = true;				}				ig.MarkLabel (false_target);				FalseStatement.Emit (ec);				if (branch_emitted)					ig.MarkLabel (end);			} else {				ig.MarkLabel (false_target);			}		}	}	public class Do : Statement {		public Expression expr;		public readonly Statement  EmbeddedStatement;		bool infinite;				public Do (Statement statement, Expression boolExpr, Location l)		{			expr = boolExpr;			EmbeddedStatement = statement;			loc = l;		}		public override bool Resolve (EmitContext ec)		{			bool ok = true;			ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);			if (!EmbeddedStatement.Resolve (ec))				ok = false;			expr = Expression.ResolveBoolean (ec, expr, loc);			if (expr == null)				ok = false;			else if (expr is BoolConstant){				bool res = ((BoolConstant) expr).Value;				if (res)					infinite = true;			}			ec.CurrentBranching.Infinite = infinite;			ec.EndFlowBranching ();			return ok;		}				protected override void DoEmit (EmitContext ec)		{			ILGenerator ig = ec.ig;			Label loop = ig.DefineLabel ();			Label old_begin = ec.LoopBegin;			Label old_end = ec.LoopEnd;						ec.LoopBegin = ig.DefineLabel ();			ec.LoopEnd = ig.DefineLabel ();							ig.MarkLabel (loop);			EmbeddedStatement.Emit (ec);			ig.MarkLabel (ec.LoopBegin);			//			// Dead code elimination			//			if (expr is BoolConstant){				bool res = ((BoolConstant) expr).Value;				if (res)					ec.ig.Emit (OpCodes.Br, loop); 			} else				expr.EmitBranchable (ec, loop, true);						ig.MarkLabel (ec.LoopEnd);			ec.LoopBegin = old_begin;			ec.LoopEnd = old_end;		}	}	public class While : Statement {		public Expression expr;		public readonly Statement Statement;		bool infinite, empty;				public While (Expression boolExpr, Statement statement, Location l)		{			this.expr = boolExpr;			Statement = statement;			loc = l;		}		public override bool Resolve (EmitContext ec)		{			bool ok = true;			expr = Expression.ResolveBoolean (ec, expr, loc);			if (expr == null)				return false;			//			// Inform whether we are infinite or not			//			if (expr is BoolConstant){				BoolConstant bc = (BoolConstant) expr;				if (bc.Value == false){					if (!Statement.ResolveUnreachable (ec, true))						return false;					empty = true;					return true;				} else					infinite = true;			}			ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);			if (!infinite)				ec.CurrentBranching.CreateSibling ();			if (!Statement.Resolve (ec))				ok = false;			ec.CurrentBranching.Infinite = infinite;			ec.EndFlowBranching ();			return ok;		}				protected override void DoEmit (EmitContext ec)		{			if (empty)				return;			ILGenerator ig = ec.ig;			Label old_begin = ec.LoopBegin;			Label old_end = ec.LoopEnd;						ec.LoopBegin = ig.DefineLabel ();			ec.LoopEnd = ig.DefineLabel ();			//			// Inform whether we are infinite or not			//			if (expr is BoolConstant){				ig.MarkLabel (ec.LoopBegin);				Statement.Emit (ec);				ig.Emit (OpCodes.Br, ec.LoopBegin);									//				// Inform that we are infinite (ie, `we return'), only				// if we do not `break' inside the code.				//				ig.MarkLabel (ec.LoopEnd);			} else {				Label while_loop = ig.DefineLabel ();				ig.Emit (OpCodes.Br, ec.LoopBegin);				ig.MarkLabel (while_loop);				Statement.Emit (ec);							ig.MarkLabel (ec.LoopBegin);				expr.EmitBranchable (ec, while_loop, true);								ig.MarkLabel (ec.LoopEnd);			}				ec.LoopBegin = old_begin;			ec.LoopEnd = old_end;		}	}	public class For : Statement {		Expression Test;		readonly Statement InitStatement;		readonly Statement Increment;		public readonly Statement Statement;		bool infinite, empty;				public For (Statement initStatement,			    Expression test,			    Statement increment,			    Statement statement,			    Location l)		{			InitStatement = initStatement;			Test = test;			Increment = increment;			Statement = statement;			loc = l;		}		public override bool Resolve (EmitContext ec)		{			bool ok = true;			if (InitStatement != null){				if (!InitStatement.Resolve (ec))					ok = false;			}			if (Test != null){				Test = Expression.ResolveBoolean (ec, Test, loc);				if (Test == null)					ok = false;				else if (Test is BoolConstant){					BoolConstant bc = (BoolConstant) Test;					if (bc.Value == false){						if (!Statement.ResolveUnreachable (ec, true))							return false;						if ((Increment != null) &&						    !Increment.ResolveUnreachable (ec, false))							return false;						empty = true;						return true;					} else						infinite = true;				}			} else				infinite = true;			ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);			if (!infinite)				ec.CurrentBranching.CreateSibling ();			if (!Statement.Resolve (ec))				ok = false;			if (Increment != null){				if (!Increment.Resolve (ec))					ok = false;			}			ec.CurrentBranching.Infinite = infinite;			ec.EndFlowBranching ();			return ok;		}				protected override void DoEmit (EmitContext ec)		{			if (empty)				return;			ILGenerator ig = ec.ig;			Label old_begin = ec.LoopBegin;			Label old_end = ec.LoopEnd;			Label loop = ig.DefineLabel ();			Label test = ig.DefineLabel ();						if (InitStatement != null && InitStatement != EmptyStatement.Value)				InitStatement.Emit (ec);			ec.LoopBegin = ig.DefineLabel ();			ec.LoopEnd = ig.DefineLabel ();			ig.Emit (OpCodes.Br, test);			ig.MarkLabel (loop);			Statement.Emit (ec);			ig.MarkLabel (ec.LoopBegin);			if (Increment != EmptyStatement.Value)				Increment.Emit (ec);			ig.MarkLabel (test);			//			// If test is null, there is no test, and we are just			// an infinite loop			//			if (Test != null){				//				// The Resolve code already catches the case for				// Test == BoolConstant (false) so we know that				// this is true				//				if (Test is BoolConstant)					ig.Emit (OpCodes.Br, loop);				else					Test.EmitBranchable (ec, loop, true);							} else				ig.Emit (OpCodes.Br, loop);			ig.MarkLabel (ec.LoopEnd);			ec.LoopBegin = old_begin;			ec.LoopEnd = old_end;		}	}		public class StatementExpression : Statement {		ExpressionStatement expr;				public StatementExpression (ExpressionStatement expr)		{			this.expr = expr;			loc = expr.Location;		}		public override bool Resolve (EmitContext ec)		{			if (expr != null)				expr = expr.ResolveStatement (ec);			return expr != null;		}				protected override void DoEmit (EmitContext ec)		{			expr.EmitStatement (ec);		}		public override string ToString ()		{			return "StatementExpression (" + expr + ")";		}	}	/// <summary>	///   Implements the return statement	/// </summary>	public class Return : Statement {		public Expression Expr;		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -