+ var pm = Module.PredefinedMembers;
+ PredefinedMember<MethodSpec> predefined;
+ bool has_task_return_type = false;
+ if (return_type.Kind == MemberKind.Void) {
+ predefined = unsafeVersion ? pm.AsyncVoidMethodBuilderOnCompletedUnsafe : pm.AsyncVoidMethodBuilderOnCompleted;
+ } else if (return_type == Module.PredefinedTypes.Task.TypeSpec) {
+ predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderOnCompletedUnsafe : pm.AsyncTaskMethodBuilderOnCompleted;
+ } else {
+ predefined = unsafeVersion ? pm.AsyncTaskMethodBuilderGenericOnCompletedUnsafe : pm.AsyncTaskMethodBuilderGenericOnCompleted;
+ has_task_return_type = true;
+ }
+
+ var on_completed = predefined.Resolve (Location);
+ if (on_completed == null)
+ return;
+
+ if (has_task_return_type)
+ on_completed = MemberCache.GetMember<MethodSpec> (set_result.DeclaringType, on_completed);
+
+ on_completed = on_completed.MakeGenericMethod (this, awaiter.Type, ec.CurrentType);
+
+ var mg = MethodGroupExpr.CreatePredefined (on_completed, on_completed.DeclaringType, Location);
+ mg.InstanceExpression = new FieldExpr (builder, Location) {
+ InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location)
+ };
+
+ var args = new Arguments (2);
+ args.Add (new Argument (awaiter, Argument.AType.Ref));
+ args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref));
+ mg.EmitCall (ec, args);
+ }
+
+ 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);
+ }