internal AsyncMethodToStateMachineRewriter( MethodSymbol method, int methodOrdinal, AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection, SyntheticBoundNodeFactory F, FieldSymbol state, FieldSymbol builder, IReadOnlySet <Symbol> hoistedVariables, IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, DiagnosticBag diagnostics) : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics, useFinalizerBookkeeping: false) { _method = method; _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection; _asyncMethodBuilderField = builder; _exprReturnLabel = F.GenerateLabel("exprReturn"); _exitLabel = F.GenerateLabel("exitLabel"); _exprRetValue = method.IsGenericTaskReturningAsync(F.Compilation) ? F.SynthesizedLocal(asyncMethodBuilderMemberCollection.ResultType, syntax: F.Syntax, kind: SynthesizedLocalKind.AsyncMethodReturnValue) : null; _awaiterFields = new Dictionary <TypeSymbol, FieldSymbol>(TypeSymbol.EqualsIgnoringDynamicTupleNamesAndNullabilityComparer); _nextAwaiterId = slotAllocatorOpt?.PreviousAwaiterSlotCount ?? 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; }
private static bool TryCreate( SyntheticBoundNodeFactory F, bool customBuilder, NamedTypeSymbol builderType, TypeSymbol resultType, MethodSymbol createBuilderMethod, PropertySymbol taskProperty, WellKnownMember?setException, WellKnownMember setResult, WellKnownMember awaitOnCompleted, WellKnownMember awaitUnsafeOnCompleted, WellKnownMember start, WellKnownMember?setStateMachine, out AsyncMethodBuilderMemberCollection collection) { MethodSymbol setExceptionMethod; MethodSymbol setResultMethod; MethodSymbol awaitOnCompletedMethod; MethodSymbol awaitUnsafeOnCompletedMethod; MethodSymbol startMethod; MethodSymbol setStateMachineMethod; if (TryGetBuilderMember(F, setException, builderType, customBuilder, out setExceptionMethod) && TryGetBuilderMember(F, setResult, builderType, customBuilder, out setResultMethod) && TryGetBuilderMember(F, awaitOnCompleted, builderType, customBuilder, out awaitOnCompletedMethod) && TryGetBuilderMember(F, awaitUnsafeOnCompleted, builderType, customBuilder, out awaitUnsafeOnCompletedMethod) && TryGetBuilderMember(F, start, builderType, customBuilder, out startMethod) && TryGetBuilderMember(F, setStateMachine, builderType, customBuilder, out setStateMachineMethod)) { collection = new AsyncMethodBuilderMemberCollection( builderType, resultType, createBuilderMethod, setExceptionMethod, setResultMethod, awaitOnCompletedMethod, awaitUnsafeOnCompletedMethod, startMethod, setStateMachineMethod, taskProperty, checkGenericMethodConstraints: customBuilder); return(true); } collection = default(AsyncMethodBuilderMemberCollection); return(false); }
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; }
private int _nextYieldReturnState = StateMachineStates.InitialAsyncIteratorStateMachine; // -3 internal AsyncIteratorMethodToStateMachineRewriter(MethodSymbol method, int methodOrdinal, AsyncMethodBuilderMemberCollection asyncMethodBuilderMemberCollection, AsyncIteratorInfo asyncIteratorInfo, SyntheticBoundNodeFactory F, FieldSymbol state, FieldSymbol builder, IReadOnlySet <Symbol> hoistedVariables, IReadOnlyDictionary <Symbol, CapturedSymbolReplacement> nonReusableLocalProxies, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, DiagnosticBag diagnostics) : base(method, methodOrdinal, asyncMethodBuilderMemberCollection, F, state, builder, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { Debug.Assert(asyncIteratorInfo != null); _asyncIteratorInfo = asyncIteratorInfo; _enclosingFinallyOrExitLabel = _exprReturnLabel; _exprReturnLabelTrue = F.GenerateLabel("yieldReturn"); }
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())); }
internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, TypeMap typeMap, out AsyncMethodBuilderMemberCollection collection) { if (method.IsIterator) { var builderType = F.WellKnownType(WellKnownType.core_runtime_compiler_AsyncIteratorMethodBuilder); Debug.Assert((object)builderType != null); TryGetBuilderMember <MethodSymbol>( F, WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Create, builderType, customBuilder: false, out MethodSymbol createBuilderMethod); if (createBuilderMethod is null) { collection = default; return(false); } return(TryCreate( F, customBuilder: false, builderType: builderType, resultType: F.SpecialType(SpecialType.System_Void), createBuilderMethod: createBuilderMethod, taskProperty: null, setException: null, // unused setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete, awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitOnCompleted, awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitUnsafeOnCompleted, start: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__MoveNext_T, setStateMachine: null, // unused collection: out collection)); } if (method.IsVoidReturningAsync()) { var builderType = F.WellKnownType(WellKnownType.core_runtime_compiler_AsyncVoidMethodBuilder); Debug.Assert((object)builderType != null); MethodSymbol createBuilderMethod; bool customBuilder = false; TryGetBuilderMember <MethodSymbol>( F, WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Create, builderType, customBuilder, out createBuilderMethod); if ((object)createBuilderMethod == null) { collection = default(AsyncMethodBuilderMemberCollection); return(false); } return(TryCreate( F, customBuilder: customBuilder, builderType: builderType, resultType: F.SpecialType(SpecialType.System_Void), createBuilderMethod: createBuilderMethod, taskProperty: null, setException: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetException, setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetResult, awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitOnCompleted, awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__AwaitUnsafeOnCompleted, start: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__Start_T, setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncVoidMethodBuilder__SetStateMachine, collection: out collection)); } if (method.IsTaskReturningAsync(F.Compilation)) { var returnType = (NamedTypeSymbol)method.ReturnType.TypeSymbol; NamedTypeSymbol builderType; MethodSymbol createBuilderMethod = null; PropertySymbol taskProperty = null; object builderArgument; bool customBuilder = returnType.IsCustomTaskType(out builderArgument); if (customBuilder) { builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric: false); if ((object)builderType != null) { taskProperty = GetCustomTaskProperty(F, builderType, returnType); createBuilderMethod = GetCustomCreateMethod(F, builderType); } } else { builderType = F.WellKnownType(WellKnownType.core_runtime_compiler_AsyncTaskMethodBuilder); Debug.Assert((object)builderType != null); TryGetBuilderMember <MethodSymbol>( F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Create, builderType, customBuilder, out createBuilderMethod); TryGetBuilderMember <PropertySymbol>( F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Task, builderType, customBuilder, out taskProperty); } if ((object)builderType == null || (object)createBuilderMethod == null || (object)taskProperty == null) { collection = default(AsyncMethodBuilderMemberCollection); return(false); } return(TryCreate( F, customBuilder: customBuilder, builderType: builderType, resultType: F.SpecialType(SpecialType.System_Void), createBuilderMethod: createBuilderMethod, taskProperty: taskProperty, setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetException, setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetResult, awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitOnCompleted, awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__AwaitUnsafeOnCompleted, start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__Start_T, setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder__SetStateMachine, collection: out collection)); } if (method.IsGenericTaskReturningAsync(F.Compilation)) { var returnType = (NamedTypeSymbol)method.ReturnType.TypeSymbol; var resultType = returnType.TypeArgumentsNoUseSiteDiagnostics.Single().TypeSymbol; if (resultType.IsDynamic()) { resultType = F.SpecialType(SpecialType.System_Object); } if (typeMap != null) { resultType = typeMap.SubstituteType(resultType).TypeSymbol; } returnType = returnType.ConstructedFrom.Construct(resultType); NamedTypeSymbol builderType; MethodSymbol createBuilderMethod = null; PropertySymbol taskProperty = null; object builderArgument; bool customBuilder = returnType.IsCustomTaskType(out builderArgument); if (customBuilder) { builderType = ValidateBuilderType(F, builderArgument, returnType.DeclaredAccessibility, isGeneric: true); if ((object)builderType != null) { builderType = builderType.ConstructedFrom.Construct(resultType); taskProperty = GetCustomTaskProperty(F, builderType, returnType); createBuilderMethod = GetCustomCreateMethod(F, builderType); } } else { builderType = F.WellKnownType(WellKnownType.core_runtime_compiler_AsyncTaskMethodBuilder_T); Debug.Assert((object)builderType != null); builderType = builderType.Construct(resultType); TryGetBuilderMember <MethodSymbol>( F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Create, builderType, customBuilder, out createBuilderMethod); TryGetBuilderMember <PropertySymbol>( F, WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Task, builderType, customBuilder, out taskProperty); } if ((object)builderType == null || (object)taskProperty == null || (object)createBuilderMethod == null) { collection = default(AsyncMethodBuilderMemberCollection); return(false); } return(TryCreate( F, customBuilder: customBuilder, builderType: builderType, resultType: resultType, createBuilderMethod: createBuilderMethod, taskProperty: taskProperty, setException: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetException, setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetResult, awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitOnCompleted, awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__AwaitUnsafeOnCompleted, start: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__Start_T, setStateMachine: WellKnownMember.System_Runtime_CompilerServices_AsyncTaskMethodBuilder_T__SetStateMachine, collection: out collection)); } throw ExceptionUtilities.UnexpectedValue(method); }