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; }
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; }
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())); }