Esempio n. 1
0
        public override void EmitStatement(EmitContext ec)
        {
            if (resolved == null)
            {
                return;
            }

            //
            // Emit sequence symbol info even if we are in compiler generated
            // block to allow debugging field initializers when constructor is
            // compiler generated
            //
            if (ec.HasSet(BuilderContext.Options.OmitDebugInfo) && ec.HasMethodSymbolBuilder)
            {
                using (ec.With(BuilderContext.Options.OmitDebugInfo, false)) {
                    ec.Mark(loc);
                }
            }

            if (resolved != this)
            {
                resolved.EmitStatement(ec);
            }
            else
            {
                base.EmitStatement(ec);
            }
        }
Esempio n. 2
0
        public override void Emit(EmitContext ec)
        {
            if (statement != null)
            {
                statement.EmitStatement(ec);
                ec.Emit(OpCodes.Ret);
                return;
            }

            base.Emit(ec);
        }
Esempio n. 3
0
        public override void EmitStatement(EmitContext ec)
        {
            if (resolved == null)
            {
                return;
            }

            if (resolved != this)
            {
                resolved.EmitStatement(ec);
            }
            else
            {
                base.EmitStatement(ec);
            }
        }
Esempio n. 4
0
        public override void Emit(EmitContext ec)
        {
            if (statement != null)
            {
                statement.EmitStatement(ec);
                if (unwind_protect)
                {
                    ec.Emit(OpCodes.Leave, ec.CreateReturnLabel());
                }
                else
                {
                    ec.Emit(OpCodes.Ret);
                }
                return;
            }

            base.Emit(ec);
        }
Esempio n. 5
0
        public void EmitPrologue(EmitContext ec)
        {
            var fe_awaiter = new FieldExpr(awaiter, loc);

            fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc);

            //
            // awaiter = expr.GetAwaiter ();
            //
            fe_awaiter.EmitAssign(ec, expr, false, false);

            Label skip_continuation = ec.DefineLabel();

            Expression completed_expr;

            if (IsDynamic)
            {
                var rc = new ResolveContext(ec.MemberContext);

                Arguments dargs = new Arguments(1);
                dargs.Add(new Argument(fe_awaiter));
                completed_expr = new DynamicMemberBinder("IsCompleted", dargs, loc).Resolve(rc);
            }
            else
            {
                var pe = PropertyExpr.CreatePredefined(is_completed, loc);
                pe.InstanceExpression = fe_awaiter;
                completed_expr        = pe;
            }

            completed_expr.EmitBranchable(ec, skip_continuation, true);

            base.DoEmit(ec);

            //
            // The stack has to be empty before calling await continuation. We handle this
            // by lifting values which would be left on stack into class fields. The process
            // is quite complicated and quite hard to test because any expression can possibly
            // leave a value on the stack.
            //
            // Following assert fails when some of expression called before is missing EmitToField
            // or parent expression fails to find await in children expressions
            //
            ec.AssertEmptyStack();

            var args    = new Arguments(1);
            var storey  = (AsyncTaskStorey)machine_initializer.Storey;
            var fe_cont = new FieldExpr(storey.Continuation, loc);

            fe_cont.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc);

            args.Add(new Argument(fe_cont));

            if (IsDynamic)
            {
                var rc      = new ResolveContext(ec.MemberContext);
                var mg_expr = new Invocation(new MemberAccess(fe_awaiter, "OnCompleted"), args).Resolve(rc);

                ExpressionStatement es = (ExpressionStatement)mg_expr;
                es.EmitStatement(ec);
            }
            else
            {
                var mg_completed = MethodGroupExpr.CreatePredefined(on_completed, fe_awaiter.Type, loc);
                mg_completed.InstanceExpression = fe_awaiter;

                //
                // awaiter.OnCompleted (continuation);
                //
                mg_completed.EmitCall(ec, args);
            }

            // Return ok
            machine_initializer.EmitLeave(ec, unwind_protect);

            ec.MarkLabel(resume_point);
            ec.MarkLabel(skip_continuation);
        }