Files
2026-08-27 10:56:38 -06:00

485 lines
28 KiB
C#

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Emit.NoPia;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp;
internal class AsyncRewriter : StateMachineRewriter
{
private sealed class AsyncIteratorRewriter : AsyncRewriter
{
private FieldSymbol _promiseOfValueOrEndField;
private FieldSymbol _currentField;
private FieldSymbol _disposeModeField;
private FieldSymbol _combinedTokensField;
private readonly bool _isEnumerable;
protected override bool PreserveInitialParameterValuesAndThreadId => _isEnumerable;
internal AsyncIteratorRewriter(BoundStatement body, MethodSymbol method, int methodOrdinal, AsyncStateMachine stateMachineType, ArrayBuilder<StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
: base(body, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics)
{
_isEnumerable = method.IsAsyncReturningIAsyncEnumerable(method.DeclaringCompilation);
}
protected override void VerifyPresenceOfRequiredAPIs(BindingDiagnosticBag bag)
{
base.VerifyPresenceOfRequiredAPIs(bag);
if (_isEnumerable)
{
EnsureWellKnownMember((WellKnownMember)427, bag);
EnsureWellKnownMember((WellKnownMember)457, bag);
EnsureWellKnownMember((WellKnownMember)458, bag);
EnsureWellKnownMember((WellKnownMember)459, bag);
EnsureWellKnownMember((WellKnownMember)460, bag);
}
EnsureWellKnownMember((WellKnownMember)428, bag);
EnsureWellKnownMember((WellKnownMember)429, bag);
EnsureWellKnownMember((WellKnownMember)426, bag);
EnsureWellKnownMember((WellKnownMember)443, bag);
EnsureWellKnownMember((WellKnownMember)444, bag);
EnsureWellKnownMember((WellKnownMember)445, bag);
EnsureWellKnownMember((WellKnownMember)430, bag);
EnsureWellKnownMember((WellKnownMember)431, bag);
EnsureWellKnownMember((WellKnownMember)436, bag);
EnsureWellKnownMember((WellKnownMember)432, bag);
EnsureWellKnownMember((WellKnownMember)433, bag);
EnsureWellKnownMember((WellKnownMember)434, bag);
EnsureWellKnownMember((WellKnownMember)435, bag);
EnsureWellKnownMember((WellKnownMember)437, bag);
EnsureWellKnownMember((WellKnownMember)438, bag);
EnsureWellKnownMember((WellKnownMember)439, bag);
EnsureWellKnownMember((WellKnownMember)440, bag);
EnsureWellKnownMember((WellKnownMember)441, bag);
EnsureWellKnownMember((WellKnownMember)442, bag);
}
protected override void GenerateMethodImplementations()
{
base.GenerateMethodImplementations();
if (_isEnumerable)
{
GenerateIAsyncEnumerableImplementation_GetAsyncEnumerator();
}
GenerateIAsyncEnumeratorImplementation_MoveNextAsync();
GenerateIAsyncEnumeratorImplementation_Current();
GenerateIValueTaskSourceBoolImplementation_GetResult();
GenerateIValueTaskSourceBoolImplementation_GetStatus();
GenerateIValueTaskSourceBoolImplementation_OnCompleted();
GenerateIValueTaskSourceImplementation_GetResult();
GenerateIValueTaskSourceImplementation_GetStatus();
GenerateIValueTaskSourceImplementation_OnCompleted();
GenerateIAsyncDisposable_DisposeAsync();
}
protected override void GenerateControlFields()
{
base.GenerateControlFields();
NamedTypeSymbol namedTypeSymbol = F.SpecialType((SpecialType)7);
_promiseOfValueOrEndField = F.StateMachineField(F.WellKnownType((WellKnownType)290).Construct(namedTypeSymbol), GeneratedNames.MakeAsyncIteratorPromiseOfValueOrEndFieldName(), isPublic: true);
TypeSymbol iteratorElementType = ((AsyncStateMachine)stateMachineType).IteratorElementType;
_currentField = F.StateMachineField(iteratorElementType, GeneratedNames.MakeIteratorCurrentFieldName());
_disposeModeField = F.StateMachineField(namedTypeSymbol, GeneratedNames.MakeDisposeModeFieldName());
if (_isEnumerable && method.Parameters.Any((ParameterSymbol p) => p.IsSourceParameterWithEnumeratorCancellationAttribute()))
{
_combinedTokensField = F.StateMachineField(F.WellKnownType((WellKnownType)299), GeneratedNames.MakeAsyncIteratorCombinedTokensFieldName());
}
}
protected override void GenerateConstructor()
{
F.CurrentFunction = stateMachineType.Constructor;
ArrayBuilder<BoundStatement> instance = ArrayBuilder<BoundStatement>.GetInstance();
instance.Add(F.BaseInitialization());
instance.Add((BoundStatement)GenerateCreateAndAssignBuilder());
instance.Add((BoundStatement)F.Assignment(F.InstanceField(stateField), F.Parameter(F.CurrentFunction.Parameters[0])));
BoundExpression boundExpression = MakeCurrentThreadId();
if (boundExpression != null && (object)initialThreadIdField != null)
{
instance.Add((BoundStatement)F.Assignment(F.InstanceField(initialThreadIdField), boundExpression));
}
if ((object)instanceIdField != null)
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)361);
if ((object)methodSymbol != null)
{
instance.Add((BoundStatement)F.Assignment(F.InstanceField(instanceIdField), F.Call(null, methodSymbol)));
}
}
instance.Add((BoundStatement)F.Return());
F.CloseMethod(F.Block(instance.ToImmutableAndFree()));
}
private BoundExpressionStatement GenerateCreateAndAssignBuilder()
{
return F.Assignment(F.InstanceField(_builderField), F.StaticCall(null, _asyncMethodBuilderMemberCollection.CreateBuilder));
}
protected override void InitializeStateMachine(ArrayBuilder<BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
StateMachineState value = (StateMachineState)(_isEnumerable ? (-2) : (-3));
bodyBuilder.Add((BoundStatement)F.Assignment(F.Local(stateMachineLocal), F.New(stateMachineType.Constructor.AsMember(frameType), F.Literal(value))));
}
protected override BoundStatement InitializeParameterField(MethodSymbol getEnumeratorMethod, ParameterSymbol parameter, BoundExpression resultParameter, BoundExpression parameterProxy)
{
if ((object)_combinedTokensField != null && parameter.IsSourceParameterWithEnumeratorCancellationAttribute() && parameter.Type.Equals(F.Compilation.GetWellKnownType((WellKnownType)298), (TypeCompareKind)0))
{
BoundParameter boundParameter = F.Parameter(getEnumeratorMethod.Parameters[0]);
BoundFieldAccess boundFieldAccess = F.Field(F.This(), _combinedTokensField);
return F.If(F.Call(parameterProxy, (WellKnownMember)457, F.Default(parameterProxy.Type)), F.Assignment(resultParameter, boundParameter), F.If(F.LogicalOr(F.Call(boundParameter, (WellKnownMember)457, parameterProxy), F.Call(boundParameter, (WellKnownMember)457, F.Default(boundParameter.Type))), F.Assignment(resultParameter, parameterProxy), F.Block(F.Assignment(boundFieldAccess, F.StaticCall((WellKnownMember)458, parameterProxy, boundParameter)), F.Assignment(resultParameter, F.Property(boundFieldAccess, (WellKnownMember)459)))));
}
return F.Assignment(resultParameter, parameterProxy);
}
protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType, IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> proxies)
{
ArrayBuilder<BoundStatement> instance = ArrayBuilder<BoundStatement>.GetInstance();
instance.Add(GenerateParameterStorage(stateMachineVariable, proxies));
instance.Add((BoundStatement)F.Return(F.Local(stateMachineVariable)));
return F.Block(instance.ToImmutableAndFree());
}
private void GenerateIAsyncEnumeratorImplementation_MoveNextAsync()
{
NamedTypeSymbol newOwner = F.WellKnownType((WellKnownType)289).Construct(_currentField.Type);
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)428).AsMember(newOwner);
NamedTypeSymbol newOwner2 = (NamedTypeSymbol)_promiseOfValueOrEndField.Type;
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)431).AsMember(newOwner2);
MethodSymbol methodSymbol3 = F.WellKnownMethod((WellKnownMember)430).AsMember(newOwner2);
NamedTypeSymbol namedTypeSymbol = (NamedTypeSymbol)methodSymbol.ReturnType;
MethodSymbol ctor = F.WellKnownMethod((WellKnownMember)444).AsMember(namedTypeSymbol);
MethodSymbol ctor2 = F.WellKnownMethod((WellKnownMember)443).AsMember(namedTypeSymbol);
OpenMethodImplementation(methodSymbol);
GetPartsForStartingMachine(out var callReset, out var instSymbol, out var instAssignment, out var startCall, out var promise_get_Version);
BoundStatement boundStatement = F.If(F.IntEqual(F.InstanceField(stateField), F.Literal((StateMachineState)(-2))), F.Return(F.Default(namedTypeSymbol)));
LocalSymbol localSymbol = F.SynthesizedLocal(F.SpecialType((SpecialType)11), null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0, (SynthesizedLocalKind)(-2));
BoundLocal boundLocal = F.Local(localSymbol);
BoundExpressionStatement boundExpressionStatement = F.Assignment(boundLocal, F.Call(F.Field(F.This(), _promiseOfValueOrEndField), promise_get_Version));
BoundStatement boundStatement2 = F.If(F.IntEqual(F.Call(F.Field(F.This(), _promiseOfValueOrEndField), methodSymbol2, boundLocal), F.Literal(1)), F.Return(F.New(ctor, F.Call(F.Field(F.This(), _promiseOfValueOrEndField), methodSymbol3, boundLocal))));
BoundReturnStatement boundReturnStatement = F.Return(F.New(ctor2, F.This(), boundLocal));
F.CloseMethod(F.Block(ImmutableArray.Create(instSymbol, localSymbol), boundStatement, callReset, instAssignment, startCall, boundExpressionStatement, boundStatement2, boundReturnStatement));
}
private void GetPartsForStartingMachine(out BoundExpressionStatement callReset, out LocalSymbol instSymbol, out BoundStatement instAssignment, out BoundExpressionStatement startCall, out MethodSymbol promise_get_Version)
{
BoundFieldAccess receiver = F.InstanceField(_promiseOfValueOrEndField);
MethodSymbol methodSymbol = (MethodSymbol)F.WellKnownMethod((WellKnownMember)433, isOptional: true).SymbolAsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
callReset = F.ExpressionStatement(F.Call(receiver, methodSymbol));
MethodSymbol methodSymbol2 = _asyncMethodBuilderMemberCollection.Start.Construct(stateMachineType);
instSymbol = F.SynthesizedLocal(stateMachineType, null, isPinned: false, isKnownToReferToTempIfReferenceType: false, (RefKind)0, (SynthesizedLocalKind)(-2));
BoundLocal boundLocal = F.Local(instSymbol);
instAssignment = F.Assignment(boundLocal, F.This());
startCall = F.ExpressionStatement(F.Call(F.InstanceField(_builderField), methodSymbol2, ImmutableArray.Create((BoundExpression)boundLocal)));
promise_get_Version = F.WellKnownMethod((WellKnownMember)436).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
}
private void GenerateIAsyncDisposable_DisposeAsync()
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)426);
OpenMethodImplementation(methodSymbol);
TypeSymbol returnType = methodSymbol.ReturnType;
GetPartsForStartingMachine(out var callReset, out var instSymbol, out var instAssignment, out var startCall, out var promise_get_Version);
BoundStatement boundStatement = F.If(F.IntGreaterThanOrEqual(F.InstanceField(stateField), F.Literal((StateMachineState)(-1))), F.Throw(F.New(F.WellKnownType((WellKnownType)240))));
BoundStatement boundStatement2 = F.If(F.IntEqual(F.InstanceField(stateField), F.Literal((StateMachineState)(-2))), F.Return(F.Default(returnType)));
MethodSymbol ctor = F.WellKnownMethod((WellKnownMember)445).AsMember((NamedTypeSymbol)methodSymbol.ReturnType);
BoundReturnStatement boundReturnStatement = F.Return(F.New(ctor, F.This(), F.Call(F.InstanceField(_promiseOfValueOrEndField), promise_get_Version)));
F.CloseMethod(F.Block(ImmutableArray.Create(instSymbol), boundStatement, boundStatement2, F.Assignment(F.InstanceField(_disposeModeField), F.Literal(value: true)), callReset, instAssignment, startCall, boundReturnStatement));
}
private void GenerateIAsyncEnumeratorImplementation_Current()
{
NamedTypeSymbol newOwner = F.WellKnownType((WellKnownType)289).Construct(_currentField.Type);
MethodSymbol getterToImplement = F.WellKnownMethod((WellKnownMember)429).AsMember(newOwner);
OpenPropertyImplementation(getterToImplement);
F.CloseMethod(F.Block(F.Return(F.InstanceField(_currentField))));
}
private void GenerateIValueTaskSourceBoolImplementation_GetResult()
{
NamedTypeSymbol newOwner = F.WellKnownType((WellKnownType)293).Construct(F.SpecialType((SpecialType)7));
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)437).AsMember(newOwner);
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)430).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
OpenMethodImplementation(methodSymbol);
F.CloseMethod(F.Return(F.Call(F.InstanceField(_promiseOfValueOrEndField), methodSymbol2, F.Parameter(methodSymbol.Parameters[0]))));
}
private void GenerateIValueTaskSourceBoolImplementation_GetStatus()
{
NamedTypeSymbol newOwner = F.WellKnownType((WellKnownType)293).Construct(F.SpecialType((SpecialType)7));
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)438).AsMember(newOwner);
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)431).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
OpenMethodImplementation(methodSymbol);
F.CloseMethod(F.Return(F.Call(F.InstanceField(_promiseOfValueOrEndField), methodSymbol2, F.Parameter(methodSymbol.Parameters[0]))));
}
private void GenerateIValueTaskSourceBoolImplementation_OnCompleted()
{
NamedTypeSymbol newOwner = F.WellKnownType((WellKnownType)293).Construct(F.SpecialType((SpecialType)7));
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)439).AsMember(newOwner);
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)432).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
OpenMethodImplementation(methodSymbol);
F.CloseMethod(F.Block(F.ExpressionStatement(F.Call(F.InstanceField(_promiseOfValueOrEndField), methodSymbol2, F.Parameter(methodSymbol.Parameters[0]), F.Parameter(methodSymbol.Parameters[1]), F.Parameter(methodSymbol.Parameters[2]), F.Parameter(methodSymbol.Parameters[3]))), F.Return()));
}
private void GenerateIValueTaskSourceImplementation_GetResult()
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)440);
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)430).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
OpenMethodImplementation(methodSymbol);
F.CloseMethod(F.Block(F.ExpressionStatement(F.Call(F.InstanceField(_promiseOfValueOrEndField), methodSymbol2, F.Parameter(methodSymbol.Parameters[0]))), F.Return()));
}
private void GenerateIValueTaskSourceImplementation_GetStatus()
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)441);
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)431).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
OpenMethodImplementation(methodSymbol);
F.CloseMethod(F.Return(F.Call(F.InstanceField(_promiseOfValueOrEndField), methodSymbol2, F.Parameter(methodSymbol.Parameters[0]))));
}
private void GenerateIValueTaskSourceImplementation_OnCompleted()
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)442);
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)432).AsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
OpenMethodImplementation(methodSymbol);
F.CloseMethod(F.Block(F.ExpressionStatement(F.Call(F.InstanceField(_promiseOfValueOrEndField), methodSymbol2, F.Parameter(methodSymbol.Parameters[0]), F.Parameter(methodSymbol.Parameters[1]), F.Parameter(methodSymbol.Parameters[2]), F.Parameter(methodSymbol.Parameters[3]))), F.Return()));
}
private void GenerateIAsyncEnumerableImplementation_GetAsyncEnumerator()
{
NamedTypeSymbol newOwner = F.WellKnownType((WellKnownType)288).Construct(_currentField.Type);
MethodSymbol getEnumeratorMethod = F.WellKnownMethod((WellKnownMember)427).AsMember(newOwner);
BoundExpression managedThreadId = null;
GenerateIteratorGetEnumerator(getEnumeratorMethod, ref managedThreadId, (StateMachineState)(-3));
}
protected override void GenerateResetInstance(ArrayBuilder<BoundStatement> builder, StateMachineState initialState)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
builder.Add((BoundStatement)F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState)));
builder.Add((BoundStatement)GenerateCreateAndAssignBuilder());
builder.Add((BoundStatement)F.Assignment(F.InstanceField(_disposeModeField), F.Literal(value: false)));
}
protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)435, isOptional: true);
if ((object)methodSymbol != null)
{
methodSymbol = (MethodSymbol)methodSymbol.SymbolAsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
}
MethodSymbol methodSymbol2 = F.WellKnownMethod((WellKnownMember)434, isOptional: true);
if ((object)methodSymbol2 != null)
{
methodSymbol2 = (MethodSymbol)methodSymbol2.SymbolAsMember((NamedTypeSymbol)_promiseOfValueOrEndField.Type);
}
new AsyncIteratorMethodToStateMachineRewriter(method, _methodOrdinal, _asyncMethodBuilderMemberCollection, new AsyncIteratorInfo(_promiseOfValueOrEndField, _combinedTokensField, _currentField, _disposeModeField, methodSymbol, methodSymbol2), F, stateField, _builderField, instanceIdField, (IReadOnlySet<Symbol>)(object)hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics).GenerateMoveNext(body, moveNextMethod);
}
}
private class AwaitDetector : BoundTreeWalkerWithStackGuardWithoutRecursionOnTheLeftOfBinaryOperator
{
private bool _sawAwait;
public static bool ContainsAwait(BoundNode node)
{
AwaitDetector awaitDetector = new AwaitDetector();
awaitDetector.Visit(node);
return awaitDetector._sawAwait;
}
public override BoundNode VisitAwaitExpression(BoundAwaitExpression node)
{
_sawAwait = true;
return null;
}
}
private readonly AsyncMethodBuilderMemberCollection _asyncMethodBuilderMemberCollection;
private readonly bool _constructedSuccessfully;
private readonly int _methodOrdinal;
private FieldSymbol? _builderField;
protected override bool PreserveInitialParameterValuesAndThreadId => false;
private AsyncRewriter(BoundStatement body, MethodSymbol method, int methodOrdinal, AsyncStateMachine stateMachineType, ArrayBuilder<StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
: base(body, method, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics)
{
_constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, base.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection);
_methodOrdinal = methodOrdinal;
}
internal static BoundStatement Rewrite(BoundStatement bodyWithAwaitLifted, MethodSymbol method, int methodOrdinal, ArrayBuilder<StateMachineStateDebugInfo> stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, out AsyncStateMachine? stateMachineType)
{
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
if (!method.IsAsync)
{
stateMachineType = null;
return bodyWithAwaitLifted;
}
CSharpCompilation declaringCompilation = method.DeclaringCompilation;
bool flag = method.IsAsyncReturningIAsyncEnumerable(declaringCompilation) || method.IsAsyncReturningIAsyncEnumerator(declaringCompilation);
if (flag && !method.IsIterator)
{
bool flag2 = AwaitDetector.ContainsAwait(bodyWithAwaitLifted);
diagnostics.Add(flag2 ? ErrorCode.ERR_PossibleAsyncIteratorWithoutYield : ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait, method.GetFirstLocation());
stateMachineType = null;
return bodyWithAwaitLifted;
}
TypeKind typeKind = (TypeKind)((((CompilationOptions)compilationState.Compilation.Options).EnableEditAndContinue || method.IsIterator) ? 2 : 10);
stateMachineType = new AsyncStateMachine(slotAllocatorOpt, compilationState, method, methodOrdinal, typeKind);
((ModuleCompilationState<NamedTypeSymbol, MethodSymbol>)((PEModuleBuilder<CSharpCompilation, SourceModuleSymbol, AssemblySymbol, TypeSymbol, NamedTypeSymbol, MethodSymbol, SyntaxNode, EmbeddedTypesManager, ModuleCompilationState>)compilationState.ModuleBuilderOpt).CompilationState).SetStateMachineType(method, (NamedTypeSymbol)stateMachineType);
AsyncRewriter asyncRewriter = (flag ? new AsyncIteratorRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) : new AsyncRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics));
if (!asyncRewriter.VerifyPresenceOfRequiredAPIs())
{
return bodyWithAwaitLifted;
}
try
{
return asyncRewriter.Rewrite();
}
catch (SyntheticBoundNodeFactory.MissingPredefinedMember missingPredefinedMember)
{
((BindingDiagnosticBag)diagnostics).Add(missingPredefinedMember.Diagnostic);
return new BoundBadStatement(bodyWithAwaitLifted.Syntax, ImmutableArray.Create((BoundNode)bodyWithAwaitLifted), hasErrors: true);
}
}
protected bool VerifyPresenceOfRequiredAPIs()
{
BindingDiagnosticBag instance = BindingDiagnosticBag.GetInstance(withDiagnostics: true, ((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).AccumulatesDependencies);
VerifyPresenceOfRequiredAPIs(instance);
bool num = ((BindingDiagnosticBag)instance).HasAnyErrors();
if (!num)
{
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).AddDependencies((BindingDiagnosticBag<AssemblySymbol>)(object)instance, false);
}
else
{
((BindingDiagnosticBag<AssemblySymbol>)(object)diagnostics).AddRange((BindingDiagnosticBag<AssemblySymbol>)(object)instance, false);
}
((BindingDiagnosticBag<AssemblySymbol>)(object)instance).Free();
if (!num)
{
return _constructedSuccessfully;
}
return false;
}
protected virtual void VerifyPresenceOfRequiredAPIs(BindingDiagnosticBag bag)
{
EnsureWellKnownMember((WellKnownMember)268, bag);
EnsureWellKnownMember((WellKnownMember)269, bag);
}
private Symbol EnsureWellKnownMember(WellKnownMember member, BindingDiagnosticBag bag)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return Binder.GetWellKnownTypeMember(F.Compilation, member, bag, body.Syntax.Location);
}
protected override void GenerateControlFields()
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
stateField = F.StateMachineField(F.SpecialType((SpecialType)13), GeneratedNames.MakeStateMachineStateFieldName(), isPublic: true);
_builderField = F.StateMachineField(_asyncMethodBuilderMemberCollection.BuilderType, GeneratedNames.AsyncBuilderFieldName(), isPublic: true);
MethodInstrumentation methodBodyInstrumentations = F.ModuleBuilderOpt.GetMethodBodyInstrumentations(method);
if (((MethodInstrumentation)(ref methodBodyInstrumentations)).Kinds.Contains((InstrumentationKind)(-1)))
{
instanceIdField = F.StateMachineField(F.SpecialType((SpecialType)16), GeneratedNames.MakeStateMachineStateIdFieldName(), isPublic: true);
}
}
protected override void GenerateMethodImplementations()
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Invalid comparison between Unknown and I4
MethodSymbol methodToImplement = F.WellKnownMethod((WellKnownMember)268);
MethodSymbol methodToImplement2 = F.WellKnownMethod((WellKnownMember)269);
SynthesizedImplementationMethod moveNextMethod = OpenMoveNextMethodImplementation(methodToImplement);
GenerateMoveNext(moveNextMethod);
OpenMethodImplementation(methodToImplement2, "SetStateMachine");
if ((int)F.CurrentType.TypeKind == 2)
{
F.CloseMethod(F.Return());
}
else
{
F.CloseMethod(F.Block(F.ExpressionStatement(F.Call(F.Field(F.This(), _builderField), _asyncMethodBuilderMemberCollection.SetStateMachine, new BoundExpression[1] { F.Parameter(F.CurrentFunction.Parameters[0]) })), F.Return()));
}
GenerateConstructor();
}
protected virtual void GenerateConstructor()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
if ((int)stateMachineType.TypeKind == 2)
{
F.CurrentFunction = stateMachineType.Constructor;
F.CloseMethod(F.Block(ImmutableArray.Create(F.BaseInitialization(), F.Return())));
}
}
protected override void InitializeStateMachine(ArrayBuilder<BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)frameType.TypeKind == 2)
{
bodyBuilder.Add((BoundStatement)F.Assignment(F.Local(stateMachineLocal), F.New(frameType.InstanceConstructors[0])));
}
}
protected override BoundStatement GenerateStateMachineCreation(LocalSymbol stateMachineVariable, NamedTypeSymbol frameType, IReadOnlyDictionary<Symbol, CapturedSymbolReplacement> proxies)
{
if (!AsyncMethodBuilderMemberCollection.TryCreate(F, method, null, out var collection))
{
return new BoundBadStatement(F.Syntax, ImmutableArray<BoundNode>.Empty, hasErrors: true);
}
ArrayBuilder<BoundStatement> instance = ArrayBuilder<BoundStatement>.GetInstance();
instance.Add((BoundStatement)F.Assignment(F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)), F.StaticCall(null, collection.CreateBuilder)));
instance.Add(GenerateParameterStorage(stateMachineVariable, proxies));
instance.Add((BoundStatement)F.Assignment(F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)), F.Literal((StateMachineState)(-1))));
if ((object)instanceIdField != null)
{
MethodSymbol methodSymbol = F.WellKnownMethod((WellKnownMember)361);
if ((object)methodSymbol != null)
{
instance.Add((BoundStatement)F.Assignment(F.Field(F.Local(stateMachineVariable), instanceIdField.AsMember(frameType)), F.Call(null, methodSymbol)));
}
}
MethodSymbol methodSymbol2 = collection.Start.Construct(frameType);
if (collection.CheckGenericMethodConstraints)
{
methodSymbol2.CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(F.Compilation, F.Compilation.Conversions, includeNullability: false, F.Syntax.Location, diagnostics));
}
instance.Add((BoundStatement)F.ExpressionStatement(F.Call(F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)), methodSymbol2, ImmutableArray.Create((BoundExpression)F.Local(stateMachineVariable)))));
instance.Add((BoundStatement)(method.IsAsyncReturningVoid() ? F.Return() : F.Return(F.Property(F.Field(F.Local(stateMachineVariable), _builderField.AsMember(frameType)), collection.Task))));
return F.Block(instance.ToImmutableAndFree());
}
protected virtual void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
{
new AsyncMethodToStateMachineRewriter(method, _methodOrdinal, _asyncMethodBuilderMemberCollection, F, stateField, _builderField, instanceIdField, (IReadOnlySet<Symbol>)(object)hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics).GenerateMoveNext(body, moveNextMethod);
}
}