Exemplo n.º 1
0
        public void EmitInitializer(EmitContext ec)
        {
            //
            // Some predefined types are missing
            //
            if (builder == null)
            {
                return;
            }

            var instance      = (TemporaryVariableReference)Instance;
            var builder_field = builder.Spec;

            if (MemberName.Arity > 0)
            {
                builder_field = MemberCache.GetMember(instance.Type, builder_field);
            }

            //
            // Inflated factory method when task is of generic type
            //
            if (builder_factory.DeclaringType.IsGeneric)
            {
                var task_return_type = return_type.TypeArguments;
                var bt = builder_factory.DeclaringType.MakeGenericType(Module, task_return_type);
                builder_factory = MemberCache.GetMember(bt, builder_factory);
                builder_start   = MemberCache.GetMember(bt, builder_start);
            }

            //
            // stateMachine.$builder = AsyncTaskMethodBuilder<{task-type}>.Create();
            //
            instance.AddressOf(ec, AddressOp.Store);
            ec.Emit(OpCodes.Call, builder_factory);
            ec.Emit(OpCodes.Stfld, builder_field);

            //
            // stateMachine.$builder.Start<{storey-type}>(ref stateMachine);
            //
            instance.AddressOf(ec, AddressOp.Store);
            ec.Emit(OpCodes.Ldflda, builder_field);
            if (Task != null)
            {
                ec.Emit(OpCodes.Dup);
            }
            instance.AddressOf(ec, AddressOp.Store);
            ec.Emit(OpCodes.Call, builder_start.MakeGenericMethod(Module, instance.Type));

            //
            // Emits return stateMachine.$builder.Task;
            //
            if (Task != null)
            {
                var task_get = Task.Get;

                if (MemberName.Arity > 0)
                {
                    task_get = MemberCache.GetMember(builder_field.MemberType, task_get);
                }

                var pe_task = new PropertyExpr(Task, Location)
                {
                    InstanceExpression = EmptyExpression.Null,    // Comes from the dup above
                    Getter             = task_get
                };

                pe_task.Emit(ec);
            }
        }