Example #1
0
 private AsyncRewriter(
     BoundStatement body,
     MethodSymbol method,
     int methodOrdinal,
     AsyncStateMachine stateMachineType,
     VariableSlotAllocator slotAllocatorOpt,
     TypeCompilationState compilationState,
     DiagnosticBag diagnostics)
     : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics)
 {
     _constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection);
     _methodOrdinal           = methodOrdinal;
 }
Example #2
0
            protected override void GenerateConstructor()
            {
                // Produces:
                // .ctor(int state)
                // {
                //     this.state = state;
                //     this.initialThreadId = {managedThreadId};
                //     this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
                // }
                Debug.Assert(stateMachineType.Constructor is IteratorConstructor);

                F.CurrentFunction = stateMachineType.Constructor;
                var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                bodyBuilder.Add(F.BaseInitialization());
                bodyBuilder.Add(F.Assignment(F.InstanceField(stateField), F.Parameter(F.CurrentFunction.Parameters[0]))); // this.state = state;

                var managedThreadId = MakeCurrentThreadId();

                if (managedThreadId != null && (object)initialThreadIdField != null)
                {
                    // this.initialThreadId = {managedThreadId};
                    bodyBuilder.Add(F.Assignment(F.InstanceField(initialThreadIdField), managedThreadId));
                }

                // this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
                AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;
                bool found = AsyncMethodBuilderMemberCollection.TryCreate(F, method, typeMap: null, out methodScopeAsyncMethodBuilderMemberCollection);

                Debug.Assert(found);

                bodyBuilder.Add(
                    F.Assignment(
                        F.InstanceField(_builderField),
                        F.StaticCall(
                            null,
                            methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));

                bodyBuilder.Add(F.Return());
                F.CloseMethod(F.Block(bodyBuilder.ToImmutableAndFree()));
                bodyBuilder = null;
            }
Example #3
0
        protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType)
        {
            // If the async method's result type is a type parameter of the method, then the AsyncTaskMethodBuilder<T>
            // needs to use the method's type parameters inside the rewritten method body. All other methods generated
            // during async rewriting are members of the synthesized state machine struct, and use the type parameters
            // structs type parameters.
            AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;

            if (!AsyncMethodBuilderMemberCollection.TryCreate(F, method, null, out methodScopeAsyncMethodBuilderMemberCollection))
            {
                return(new BoundBadStatement(F.Syntax, ImmutableArray <BoundNode> .Empty, hasErrors: true));
            }

            var bodyBuilder = ArrayBuilder <BoundStatement> .GetInstance();

            var builderVariable = F.SynthesizedLocal(methodScopeAsyncMethodBuilderMemberCollection.BuilderType, null);

            // local.$builder = System.Runtime.CompilerServices.AsyncTaskMethodBuilder<typeArgs>.Create();
            bodyBuilder.Add(
                F.Assignment(
                    F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                    F.StaticCall(
                        null,
                        methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));

            // local.$stateField = NotStartedStateMachine
            bodyBuilder.Add(
                F.Assignment(
                    F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)),
                    F.Literal(StateMachineStates.NotStartedStateMachine)));

            bodyBuilder.Add(
                F.Assignment(
                    F.Local(builderVariable),
                    F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType))));

            // local.$builder.Start(ref local) -- binding to the method AsyncTaskMethodBuilder<typeArgs>.Start()
            var startMethod = methodScopeAsyncMethodBuilderMemberCollection.Start.Construct(frameType);

            if (methodScopeAsyncMethodBuilderMemberCollection.CheckGenericMethodConstraints)
            {
                startMethod.CheckConstraints(F.Compilation.Conversions, F.Syntax, F.Compilation, diagnostics);
            }
            bodyBuilder.Add(
                F.ExpressionStatement(
                    F.Call(
                        F.Local(builderVariable),
                        startMethod,
                        ImmutableArray.Create <BoundExpression>(F.Local(stateMachineVariable)))));

            bodyBuilder.Add(method.IsVoidReturningAsync()
                ? F.Return()
                : F.Return(
                                F.Property(
                                    F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)),
                                    methodScopeAsyncMethodBuilderMemberCollection.Task)));

            return(F.Block(
                       ImmutableArray.Create(builderVariable),
                       bodyBuilder.ToImmutableAndFree()));
        }