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

📄 iterators.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
			if (!IsStatic)				list.Add (new Parameter (					new TypeExpression (container.TypeBuilder, Location),					"this", Parameter.Modifier.NONE,					null, Location));			list.Add (new Parameter (				TypeManager.system_boolean_expr, "initialized",				Parameter.Modifier.NONE, null, Location));			Parameter[] old_fixed = parameters.Parameters.FixedParameters;			if (old_fixed != null)				list.AddRange (old_fixed);			Parameter[] fixed_params = new Parameter [list.Count];			list.CopyTo (fixed_params);			ctor_params = new Parameters (				fixed_params, parameters.Parameters.ArrayParameter);			ctor = new Constructor (				this, Name, Modifiers.PUBLIC, ctor_params,				new GeneratedBaseInitializer (Location),				Location);			AddConstructor (ctor);			ctor.Block = new ToplevelBlock (block, parameters.Parameters, Location);			int first = IsStatic ? 2 : 3;			State initial = is_enumerable ? State.Uninitialized : State.Running;			ctor.Block.AddStatement (new SetState (this, initial, Location));			ctor.Block.AddStatement (new If (				new SimpleParameterReference (					TypeManager.bool_type, first - 1, Location),				new SetState (this, State.Running, Location),				Location));			ctor.Block.AddStatement (new InitScope (this, Location));		}		Statement Create_ThrowInvalidOperation ()		{			TypeExpr ex_type = new TypeExpression (				TypeManager.invalid_operation_exception_type, Location);			return new Throw (new New (ex_type, null, Location), Location);		}		Statement Create_ThrowNotSupported ()		{			TypeExpr ex_type = new TypeExpression (				TypeManager.not_supported_exception_type, Location);			return new Throw (new New (ex_type, null, Location), Location);		}		void Define_Current ()		{			ToplevelBlock get_block = new ToplevelBlock (				block, parameters.Parameters, Location);			MemberName left = new MemberName ("System.Collections.IEnumerator");			MemberName name = new MemberName (left, "Current", Location);			get_block.AddStatement (new If (				new Binary (					Binary.Operator.LessThanOrEqual,					new FieldExpression (this, pc_field),					new IntLiteral ((int) State.Running, pc_field.Location)),				Create_ThrowInvalidOperation (),				new Return (					new FieldExpression (this, current_field), Location),				Location));			Accessor getter = new Accessor (get_block, 0, null, Location);			Property current = new Property (				this, iterator_type_expr, 0,				false, name, null, getter, null);			AddProperty (current);		}		void Define_MoveNext ()		{			move_next_method = new MoveNextMethod (this, Location);			original_block.ReParent (block, move_next_method);			move_next_method.CreateMethod (ec);			AddMethod (move_next_method.method);		}		void Define_GetEnumerator ()		{			MemberName left = new MemberName ("System.Collections.IEnumerable");			MemberName name = new MemberName (left, "GetEnumerator", Location);			Method get_enumerator = new Method (				this,				new TypeExpression (TypeManager.ienumerator_type, Location),				0, false, name,				Parameters.EmptyReadOnlyParameters, null);			AddMethod (get_enumerator);			get_enumerator.Block = new ToplevelBlock (				block, parameters.Parameters, Location);			get_enumerator.Block.SetHaveAnonymousMethods (Location, move_next_method);			Expression ce = new MemberAccess (				new SimpleName ("System.Threading.Interlocked", Location),				"CompareExchange", Location);			Expression pc = new FieldExpression (this, pc_field);			Expression before = new IntLiteral ((int) State.Running, Location);			Expression uninitialized = new IntLiteral ((int) State.Uninitialized, Location);			ArrayList args = new ArrayList ();			args.Add (new Argument (pc, Argument.AType.Ref));			args.Add (new Argument (before, Argument.AType.Expression));			args.Add (new Argument (uninitialized, Argument.AType.Expression));			get_enumerator.Block.AddStatement (new If (				new Binary (					Binary.Operator.Equality,					new Invocation (ce, args),					uninitialized),				new Return (new ThisParameterReference (						    TypeManager.ienumerator_type, Location),					    Location),				Location));			args = new ArrayList ();			if (!IsStatic) {				args.Add (new Argument (new CapturedThisReference (this, Location)));			}			args.Add (new Argument (new BoolLiteral (true, Location)));			for (int i = 0; i < parameters.Count; i++) {				Expression cp = new CapturedParameterReference (					this, parameters.ParameterType (i),					parameters.ParameterName (i), Location);				args.Add (new Argument (cp));			}			Expression new_expr = new New (				new TypeExpression (TypeBuilder, Location), args, Location);			get_enumerator.Block.AddStatement (new Return (new_expr, Location));		}		protected class SimpleParameterReference : Expression		{			int idx;			public SimpleParameterReference (Type type, int idx, Location loc)			{				this.idx = idx;				this.loc = loc;				this.type = type;				eclass = ExprClass.Variable;			}			public override Expression DoResolve (EmitContext ec)			{				return this;			}			public override void Emit (EmitContext ec)			{				DoEmit (ec);			}			protected virtual void DoEmit (EmitContext ec)			{				ParameterReference.EmitLdArg (ec.ig, idx);			}		}		protected class ThisParameterReference : SimpleParameterReference, IMemoryLocation		{			public ThisParameterReference (Type type, Location loc)				: base (type, 0, loc)			{ }			protected override void DoEmit (EmitContext ec)			{				base.DoEmit (ec);				if (ec.TypeContainer is Struct)					ec.ig.Emit (OpCodes.Ldobj, type);			}			public void AddressOf (EmitContext ec, AddressOp mode)			{				if (ec.TypeContainer is Struct)					ec.ig.Emit (OpCodes.Ldarga, 0);				else					ec.ig.Emit (OpCodes.Ldarg, 0);			}		}		protected class CapturedParameterReference : Expression		{			Iterator iterator;			string name;			public CapturedParameterReference (Iterator iterator, Type type,							   string name, Location loc)			{				this.iterator = iterator;				this.loc = loc;				this.type = type;				this.name = name;				eclass = ExprClass.Variable;			}			public override Expression DoResolve (EmitContext ec)			{				return this;			}			public override void Emit (EmitContext ec)			{				ec.CurrentAnonymousMethod = iterator.move_next_method;				iterator.cc.EmitParameter (ec, name);			}		}		protected class CapturedThisReference : Expression		{			public CapturedThisReference (Iterator iterator, Location loc)			{				this.loc = loc;				this.type = iterator.this_type;				eclass = ExprClass.Variable;			}			public override Expression DoResolve (EmitContext ec)			{				return this;			}			public override void Emit (EmitContext ec)			{				ec.EmitThis ();			}		}		protected class FieldExpression : Expression		{			Iterator iterator;			Field field;			public FieldExpression (Iterator iterator, Field field)			{				this.iterator = iterator;				this.field = field;				this.loc = iterator.Location;			}			public override Expression DoResolveLValue (EmitContext ec, Expression right_side)			{				FieldExpr fexpr = new FieldExpr (field.FieldBuilder, loc);				fexpr.InstanceExpression = new ThisParameterReference (					iterator.this_type, loc);				return fexpr.ResolveLValue (ec, right_side, loc);			}			public override Expression DoResolve (EmitContext ec)			{				FieldExpr fexpr = new FieldExpr (field.FieldBuilder, loc);				fexpr.InstanceExpression = new ThisParameterReference (					iterator.this_type, loc);				return fexpr.Resolve (ec);			}			public override void Emit (EmitContext ec)			{				throw new InvalidOperationException ();			}		}		protected class MoveNextMethod : AnonymousContainer		{			Iterator iterator;			public MoveNextMethod (Iterator iterator, Location loc)				: base (iterator.parameters.Parameters, iterator.original_block, loc)			{				this.iterator = iterator;			}			protected override bool CreateMethodHost (EmitContext ec)			{				method = new Method (					iterator, TypeManager.system_boolean_expr,					Modifiers.PUBLIC, false, new MemberName ("MoveNext", loc),					Parameters.EmptyReadOnlyParameters, null);				method.Block = Block;				MoveNextStatement inline = new MoveNextStatement (iterator, loc);				Block.AddStatement (inline);				return true;			}			public bool CreateMethod (EmitContext ec)			{				return CreateMethodHost (ec);			}			public override bool IsIterator {				get { return true; }			}			public override void CreateScopeType (EmitContext ec, ScopeInfo scope)			{				scope.ScopeTypeBuilder = iterator.TypeBuilder;				scope.ScopeConstructor = iterator.ctor.ConstructorBuilder;			}			public override void Emit (EmitContext ec)			{				throw new InternalErrorException ();			}		}		protected class MoveNextStatement : Statement {			Iterator iterator;			public MoveNextStatement (Iterator iterator, Location loc)			{				this.loc = loc;				this.iterator = iterator;			}			public override bool Resolve (EmitContext ec)			{				return true;			}			protected override void DoEmit (EmitContext ec)			{				ec.CurrentIterator = iterator;				ec.CurrentAnonymousMethod = iterator.move_next_method;				ec.InIterator = true;				iterator.EmitMoveNext (ec);			}		}		protected class DisposeMethod : Statement {			Iterator iterator;			public DisposeMethod (Iterator iterator, Location loc)			{				this.loc = loc;				this.iterator = iterator;			}			public override bool Resolve (EmitContext ec)			{				return true;			}			protected override void DoEmit (EmitContext ec)			{				iterator.EmitDispose (ec);			}		}		protected class StatementList : Statement {			ArrayList statements;			public StatementList (Location loc)			{				this.loc = loc;				statements = new ArrayList ();			}			public void Add (Statement statement)			{				statements.Add (statement);			}			public override bool Resolve (EmitContext ec)			{				foreach (Statement stmt in statements) {					if (!stmt.Resolve (ec))						return false;				}				return true;			}			protected override void DoEmit (EmitContext ec)			{				foreach (Statement stmt in statements)					stmt.Emit (ec);			}		}		protected class SetState : Statement		{			Iterator iterator;			State state;			public SetState (Iterator iterator, State state, Location loc)			{				this.iterator = iterator;				this.state = state;				this.loc = loc;			}			public override bool Resolve (EmitContext ec)			{				return true;			}			protected override void DoEmit (EmitContext ec)			{				ec.ig.Emit (OpCodes.Ldarg_0);				IntConstant.EmitInt (ec.ig, (int) state);				ec.ig.Emit (OpCodes.Stfld, iterator.pc_field.FieldBuilder);			}		}		protected class InitScope : Statement		{			Iterator iterator;			public InitScope (Iterator iterator, Location loc)			{				this.iterator = iterator;				this.loc = loc;			}			public override bool Resolve (EmitContext ec)			{				return true;			}			protected override void DoEmit (EmitContext ec)			{				iterator.cc.EmitInitScope (ec);			}		}		void Define_Reset ()		{			Method reset = new Method (				this, TypeManager.system_void_expr, Modifiers.PUBLIC,				false, new MemberName ("Reset", Location),				Parameters.EmptyReadOnlyParameters, null);			AddMethod (reset);			reset.Block = new ToplevelBlock (Location);			reset.Block = new ToplevelBlock (block, parameters.Parameters, Location);			reset.Block.SetHaveAnonymousMethods (Location, move_next_method);			reset.Block.AddStatement (Create_ThrowNotSupported ());		}		void Define_Dispose ()		{			dispose = new Method (				this, TypeManager.system_void_expr, Modifiers.PUBLIC,				false, new MemberName ("Dispose", Location),				Parameters.EmptyReadOnlyParameters, null);			AddMethod (dispose);			dispose.Block = new ToplevelBlock (block, parameters.Parameters, Location);			dispose.Block.SetHaveAnonymousMethods (Location, move_next_method);			dispose.Block.AddStatement (new DisposeMethod (this, Location));		}		public Type IteratorType {			get { return iterator_type; }		}		//		// This return statement tricks return into not flagging an error for being		// used in a Yields method		//		class NoCheckReturn : Statement {			public Expression Expr;					public NoCheckReturn (Expression expr, Location l)			{				Expr = expr;				loc = l;			}			public override bool Resolve (EmitContext ec)			{				Expr = Expr.Resolve (ec);				if (Expr == null)					return false;				ec.CurrentBranching.CurrentUsageVector.Return ();				return true;			}			protected override void DoEmit (EmitContext ec)			{				Expr.Emit (ec);				ec.ig.Emit (OpCodes.Ret);			}		}		bool CheckType ()		{			Type ret = orig_method.ReturnType;			if (ret == TypeManager.ienumerable_type) {				iterator_type = TypeManager.object_type;				is_enumerable = true;				return true;			}			if (ret == TypeManager.ienumerator_type) {				iterator_type = TypeManager.object_type;				is_enumerable = false;				return true;			}			return false;		}	}}

⌨️ 快捷键说明

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