예제 #1
0
        public override void EmitStatement(EmitContext ec)
        {
            var storey = (AsyncTaskStorey)Storey;

            storey.Instance.Emit(ec);
            ec.Emit(OpCodes.Call, storey.StateMachineMethod.Spec);

            if (storey.Task != null)
            {
                //
                // async.$builder.Task;
                //
                var pe_task = new PropertyExpr(storey.Task, loc)
                {
                    InstanceExpression = new FieldExpr(storey.Builder, loc)
                    {
                        InstanceExpression = storey.Instance
                    },
                    Getter = storey.Task.Get
                };

                pe_task.Emit(ec);
            }

            ec.Emit(OpCodes.Ret);
        }
예제 #2
0
파일: async.cs 프로젝트: raj581/Marvin
        public override void EmitStatement(EmitContext ec)
        {
            var storey = (AsyncTaskStorey)Storey;

            storey.Instance.Emit(ec);

            var move_next_entry = storey.StateMachineMethod.Spec;

            if (storey.MemberName.Arity > 0)
            {
                move_next_entry = MemberCache.GetMember(storey.Instance.Type, move_next_entry);
            }

            ec.Emit(OpCodes.Call, move_next_entry);

            //
            // Emits return <async-storey-instance>.$builder.Task;
            //
            if (storey.Task != null)
            {
                var builder_field = storey.Builder.Spec;
                var task_get      = storey.Task.Get;

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

                var pe_task = new PropertyExpr(storey.Task, loc)
                {
                    InstanceExpression = new FieldExpr(builder_field, loc)
                    {
                        InstanceExpression = storey.Instance
                    },
                    Getter = task_get
                };

                pe_task.Emit(ec);
            }

            ec.Emit(OpCodes.Ret);
        }
예제 #3
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);
            }
        }