Example #1
0
		public override bool Resolve (BlockContext ec)
		{
			expr = expr.Resolve (ec);
			if (expr == null)
				return false;

			Report.Debug (64, "RESOLVE YIELD #1", this, ec, expr, expr.GetType (),
				      ec.CurrentAnonymousMethod, ec.CurrentIterator);

			if (!CheckContext (ec, loc))
				return false;

			iterator = ec.CurrentIterator;
			if (expr.Type != iterator.OriginalIteratorType) {
				expr = Convert.ImplicitConversionRequired (
					ec, expr, iterator.OriginalIteratorType, loc);
				if (expr == null)
					return false;
			}

			if (!ec.CurrentBranching.CurrentUsageVector.IsUnreachable)
				unwind_protect = ec.CurrentBranching.AddResumePoint (this, loc, out resume_pc);

			return true;
		}
Example #2
0
		public override void EmitForDispose (EmitContext ec, Iterator iterator, Label end, bool have_dispatcher)
		{
			if (emitted_dispose)
				return;

			emitted_dispose = true;

			Label end_of_try = ec.DefineLabel ();

			// Ensure that the only way we can get into this code is through a dispatcher
			if (have_dispatcher)
				ec.Emit (OpCodes.Br, end);

			ec.BeginExceptionBlock ();

			ec.MarkLabel (dispose_try_block);

			Label [] labels = null;
			for (int i = 0; i < resume_points.Count; ++i) {
				ResumableStatement s = (ResumableStatement) resume_points [i];
				Label ret = s.PrepareForDispose (ec, end_of_try);
				if (ret.Equals (end_of_try) && labels == null)
					continue;
				if (labels == null) {
					labels = new Label [resume_points.Count];
					for (int j = 0; j < i; ++j)
						labels [j] = end_of_try;
				}
				labels [i] = ret;
			}

			if (labels != null) {
				int j;
				for (j = 1; j < labels.Length; ++j)
					if (!labels [0].Equals (labels [j]))
						break;
				bool emit_dispatcher = j < labels.Length;

				if (emit_dispatcher) {
					//SymbolWriter.StartIteratorDispatcher (ec.ig);
					ec.Emit (OpCodes.Ldloc, iterator.CurrentPC);
					ec.EmitInt (first_resume_pc);
					ec.Emit (OpCodes.Sub);
					ec.Emit (OpCodes.Switch, labels);
					//SymbolWriter.EndIteratorDispatcher (ec.ig);
				}

				foreach (ResumableStatement s in resume_points)
					s.EmitForDispose (ec, iterator, end_of_try, emit_dispatcher);
			}

			ec.MarkLabel (end_of_try);

			ec.BeginFinallyBlock ();

			EmitFinallyBody (ec);

			ec.EndExceptionBlock ();
		}
Example #3
0
		public override bool Resolve (BlockContext ec)
		{
			// System.Reflection.Emit automatically emits a 'leave' at the end of a try clause
			// So, ensure there's some IL code after this statement.
			if (!code_follows && resume_points == null && ec.CurrentBranching.CurrentUsageVector.IsUnreachable)
				ec.NeedReturnLabel ();

			iter = ec.CurrentIterator;
			return true;
		}
Example #4
0
		public virtual void EmitForDispose (EmitContext ec, Iterator iterator, Label end, bool have_dispatcher)
		{
		}
Example #5
0
		public void WrapIntoIterator (IMethodData method, TypeContainer host, TypeSpec iterator_type, bool is_enumerable)
		{
			ParametersBlock pb = new ParametersBlock (this, ParametersCompiled.EmptyReadOnlyParameters, StartLocation);
			pb.EndLocation = EndLocation;
			pb.statements = statements;

			var iterator = new Iterator (pb, method, host, iterator_type, is_enumerable);
			am_storey = new IteratorStorey (iterator);

			statements = new List<Statement> (1);
			AddStatement (new Return (iterator, iterator.Location));
		}
Example #6
0
 public IteratorStorey(Iterator iterator)
     : base(iterator.Container.ParametersBlock, iterator.Host,
            iterator.OriginalMethod as MemberBase, iterator.OriginalMethod.CurrentTypeParameters, "Iterator", MemberKind.Class)
 {
     this.Iterator = iterator;
 }
Example #7
0
 public DisposeMethodStatement(Iterator iterator)
 {
     this.iterator = iterator;
     this.loc = iterator.Location;
 }
Example #8
0
 public IteratorStatement(Iterator iterator, Block original_block)
 {
     this.iterator = iterator;
     this.original_block = original_block;
     this.loc = iterator.Location;
 }
Example #9
0
		public IteratorStorey (Iterator iterator)
			: base (iterator.Container.ParametersBlock, iterator.Host,
			  iterator.OriginalMethod as MemberBase, iterator.GenericMethod == null ? null : iterator.GenericMethod.CurrentTypeParameters, "Iterator")
		{
			this.Iterator = iterator;
		}
		public static void CreateIterator (IMethodData method, TypeContainer parent, int modifiers, CompilerContext ctx)
		{
			bool is_enumerable;
			Type iterator_type;

			Type ret = method.ReturnType;
			if (ret == null)
				return;

			if (!CheckType (ret, out iterator_type, out is_enumerable)) {
				ctx.Report.Error (1624, method.Location,
					      "The body of `{0}' cannot be an iterator block " +
					      "because `{1}' is not an iterator interface type",
					      method.GetSignatureForError (),
					      TypeManager.CSharpName (ret));
				return;
			}

			ParametersCompiled parameters = method.ParameterInfo;
			for (int i = 0; i < parameters.Count; i++) {
				Parameter p = parameters [i];
				Parameter.Modifier mod = p.ModFlags;
				if ((mod & Parameter.Modifier.ISBYREF) != 0) {
					ctx.Report.Error (1623, p.Location,
						"Iterators cannot have ref or out parameters");
					return;
				}

				if (p is ArglistParameter) {
					ctx.Report.Error (1636, method.Location,
						"__arglist is not allowed in parameter list of iterators");
					return;
				}

				if (parameters.Types [i].IsPointer) {
					ctx.Report.Error (1637, p.Location,
							  "Iterators cannot have unsafe parameters or " +
							  "yield types");
					return;
				}
			}

			if ((modifiers & Modifiers.UNSAFE) != 0) {
				ctx.Report.Error (1629, method.Location, "Unsafe code may not appear in iterators");
				return;
			}

			Iterator iter = new Iterator (ctx, method, parent, iterator_type, is_enumerable);
			iter.Storey.DefineType ();
		}
Example #11
0
File: context.cs Project: ikvm/mono
		public FlowBranchingIterator StartFlowBranching (Iterator iterator)
		{
			FlowBranchingIterator branching = new FlowBranchingIterator (CurrentBranching, iterator);
			current_flow_branching = branching;
			return branching;
		}
 public MoveNextMethodStatement(Iterator iterator)
 {
     this.iterator = iterator;
     this.loc      = iterator.Location;
 }
 public IteratorStorey(Iterator iterator)
     : base(iterator.Container.ParametersBlock, iterator.Host,
            iterator.OriginalMethod as MemberBase, iterator.GenericMethod == null ? null : iterator.GenericMethod.CurrentTypeParameters, "Iterator")
 {
     this.Iterator = iterator;
 }
 public DisposeMethodStatement(Iterator iterator)
 {
     this.iterator = iterator;
     this.loc      = iterator.Location;
 }
 protected override bool DoResolve(BlockContext ec)
 {
     iterator = ec.CurrentIterator;
     return(Yield.CheckContext(ec, loc));
 }
Example #16
0
		public FlowBranchingIterator (FlowBranching parent, Iterator iterator)
			: base (parent, BranchingType.Iterator, SiblingType.Block, iterator.Block, iterator.Location)
		{
			this.iterator = iterator;
		}
Example #17
0
 protected override bool DoResolve(BlockContext ec)
 {
     iterator = ec.CurrentIterator;
     return Yield.CheckContext (ec, loc);
 }
Example #18
0
			public MoveNextMethodStatement (Iterator iterator)
			{
				this.iterator = iterator;
				this.loc = iterator.Location;
			}
Example #19
0
        public IteratorStorey(Iterator iterator)
            : base(iterator.Container.Toplevel, iterator.Host,
			  iterator.OriginalMethod as MemberBase, iterator.GenericMethod, "Iterator")
        {
            this.Iterator = iterator;
        }
Example #20
0
		//
		// Reformats this block to be top-level iterator block
		//
		public IteratorStorey ChangeToIterator (Iterator iterator, ToplevelBlock source)
		{
			IsIterator = true;

			// Creates block with original statements
			AddStatement (new IteratorStatement (iterator, new Block (this, source)));

			source.statements = new List<Statement> (1);
			source.AddStatement (new Return (iterator, iterator.Location));
			source.IsIterator = false;

			IteratorStorey iterator_storey = new IteratorStorey (iterator);
			source.am_storey = iterator_storey;
			return iterator_storey;
		}
Example #21
0
		public FlowBranchingIterator StartFlowBranching (Iterator iterator, FlowBranching parent)
		{
			FlowBranchingIterator branching = new FlowBranchingIterator (parent, iterator);
			current_flow_branching = branching;
			return branching;
		}
Example #22
0
 public TryFinallyBlockProxyStatement(Iterator iterator, TryFinallyBlock block)
 {
     this.iterator = iterator;
     this.block    = block;
 }