diff --git a/docs/features/async-streams.md b/docs/features/async-streams.md index ae9e97062381fe8c9783fdb4e8965e26371645e1..94451737be0d60d08e00c49f3e7849eb8c0c09cb 100644 --- a/docs/features/async-streams.md +++ b/docs/features/async-streams.md @@ -176,6 +176,7 @@ IAsyncEnumerator GetAsyncEnumerator(CancellationToken token) if (initialThreadId == /*managedThreadId*/ && state == StateMachineStates.FinishedStateMachine) { state = InitialState; // -3 + builder = AsyncIteratorMethodBuilder.Create(); disposeMode = false; result = this; } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index f8f13ae79d6e48369b282bb21c87f6263f4a35d3..f524dbe4dec336c7d2439b5db53f1ead093679e7 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.CSharp.Symbols; @@ -71,6 +71,7 @@ protected override BoundStatement GenerateSetResultCall() // if (this.combinedTokens != null) { this.combinedTokens.Dispose(); this.combinedTokens = null; } // for enumerables only // this.promiseOfValueOrEnd.SetResult(false); + // this.builder.Complete(); // return; // _exprReturnLabelTrue: // this.promiseOfValueOrEnd.SetResult(true); @@ -86,6 +87,7 @@ protected override BoundStatement GenerateSetResultCall() builder.AddRange( // this.promiseOfValueOrEnd.SetResult(false); generateSetResultOnPromise(false), + GenerateCompleteOnBuilder(), F.Return(), F.Label(_exprReturnLabelTrue), // this.promiseOfValueOrEnd.SetResult(true); @@ -102,6 +104,17 @@ BoundExpressionStatement generateSetResultOnPromise(bool result) } } + private BoundExpressionStatement GenerateCompleteOnBuilder() + { + // Produce: + // this.builder.Complete(); + return F.ExpressionStatement( + F.Call( + F.Field(F.This(), _asyncMethodBuilderField), + _asyncMethodBuilderMemberCollection.SetResult, // AsyncIteratorMethodBuilder.Complete is the corresponding method to AsyncTaskMethodBuilder.SetResult + ImmutableArray.Empty)); + } + private void AddDisposeCombinedTokensIfNeeded(ArrayBuilder builder) { // if (this.combinedTokens != null) { this.combinedTokens.Dispose(); this.combinedTokens = null; } // for enumerables only @@ -131,6 +144,9 @@ protected override BoundStatement GenerateSetExceptionCall(LocalSymbol exception _asyncIteratorInfo.SetExceptionMethod, F.Local(exceptionLocal)))); + // this.builder.Complete(); + builder.Add(GenerateCompleteOnBuilder()); + return F.Block(builder.ToImmutableAndFree()); } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodBuilderMemberCollection.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodBuilderMemberCollection.cs index fba4638021cf32eb1f90c2cfb6bbf410df41fdfd..f6af19700ea8b013ed00a8384326e60b130c7f21 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodBuilderMemberCollection.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodBuilderMemberCollection.cs @@ -133,7 +133,7 @@ internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method, createBuilderMethod: createBuilderMethod, taskProperty: null, setException: null, // unused - setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete, + setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete, // AsyncIteratorMethodBuilder.Complete is the corresponding method to AsyncTaskMethodBuilder.SetResult awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitOnCompleted, awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitUnsafeOnCompleted, start: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__MoveNext_T, diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index c1b863d3ac1c36b75f13dfe75851d6e5367b09ab..eb102fdc02b519daf33c712975fa92cd55708fea 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -28,12 +28,12 @@ internal class AsyncMethodToStateMachineRewriter : MethodToStateMachineRewriter /// , , or depending on the /// return type of the async method. /// - private readonly FieldSymbol _asyncMethodBuilderField; + protected readonly FieldSymbol _asyncMethodBuilderField; /// /// A collection of well-known members for the current async method builder. /// - private readonly AsyncMethodBuilderMemberCollection _asyncMethodBuilderMemberCollection; + protected readonly AsyncMethodBuilderMemberCollection _asyncMethodBuilderMemberCollection; /// /// The exprReturnLabel is used to label the return handling code at the end of the async state-machine diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs index 31080de662c09e60733901a869356fcc45559e39..66fb7d807b846d99a5aca8d92ec384ea3f7b0669 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs @@ -148,7 +148,7 @@ protected override void GenerateConstructor() // { // this.state = state; // this.initialThreadId = {managedThreadId}; - // this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create(); + // this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create(); // } Debug.Assert(stateMachineType.Constructor is IteratorConstructor); @@ -164,23 +164,25 @@ protected override void GenerateConstructor() 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))); + // this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create(); + bodyBuilder.Add(GenerateCreateAndAssignBuilder()); bodyBuilder.Add(F.Return()); F.CloseMethod(F.Block(bodyBuilder.ToImmutableAndFree())); bodyBuilder = null; } + private BoundExpressionStatement GenerateCreateAndAssignBuilder() + { + // Produce: + // this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create(); + return F.Assignment( + F.InstanceField(_builderField), + F.StaticCall( + null, + _asyncMethodBuilderMemberCollection.CreateBuilder)); + } + protected override void InitializeStateMachine(ArrayBuilder bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal) { // var stateMachineLocal = new {StateMachineType}({initialState}) @@ -632,10 +634,23 @@ private void GenerateIAsyncEnumerableImplementation_GetAsyncEnumerator() GenerateIteratorGetEnumerator(IAsyncEnumerableOfElementType_GetEnumerator, ref managedThreadId, initialState: StateMachineStates.InitialAsyncIteratorStateMachine); } - protected override BoundStatement GetExtraResetForIteratorGetEnumerator() + protected override void GenerateResetInstance(ArrayBuilder builder, int initialState) { - // disposeMode = false; - return F.Assignment(F.InstanceField(_disposeModeField), F.Literal(false)); + // this.state = {initialState}; + // this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create(); + // this.disposeMode = false; + + builder.Add( + // this.state = {initialState}; + F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState))); + + builder.Add( + // this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create(); + GenerateCreateAndAssignBuilder()); + + builder.Add( + // disposeMode = false; + F.Assignment(F.InstanceField(_disposeModeField), F.Literal(false))); } protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod) diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs index 6d53fbd51267aa09854a3ec325e840e6fd0344d6..e88d08847c312848caf755192ee797c936394421 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs @@ -402,20 +402,12 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy managedThreadId = MakeCurrentThreadId(); var thenBuilder = ArrayBuilder.GetInstance(4); - thenBuilder.Add( - // this.state = {initialState}; - F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState))); + GenerateResetInstance(thenBuilder, initialState); thenBuilder.Add( // result = this; F.Assignment(F.Local(resultVariable), F.This())); - var extraReset = GetExtraResetForIteratorGetEnumerator(); - if (extraReset != null) - { - thenBuilder.Add(extraReset); - } - if (method.IsStatic || method.ThisParameter.Type.IsReferenceType) { // if this is a reference type, no need to copy it since it is not assignable @@ -473,6 +465,16 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy return getEnumerator; } + /// + /// Generate logic to reset the current instance (rather than creating a new instance) + /// + protected virtual void GenerateResetInstance(ArrayBuilder builder, int initialState) + { + builder.Add( + // this.state = {initialState}; + F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState))); + } + protected virtual BoundStatement InitializeParameterField(MethodSymbol getEnumeratorMethod, ParameterSymbol parameter, BoundExpression resultParameter, BoundExpression parameterProxy) { Debug.Assert(!method.IsIterator || !method.IsAsync); // an override handles async-iterators @@ -481,12 +483,6 @@ protected virtual BoundStatement InitializeParameterField(MethodSymbol getEnumer return F.Assignment(resultParameter, parameterProxy); } - /// - /// Async-iterator methods use a GetAsyncEnumerator method just like the GetEnumerator of iterator methods. - /// But they need to do a bit more work (to reset the dispose mode). - /// - protected virtual BoundStatement GetExtraResetForIteratorGetEnumerator() => null; - /// /// Returns true if either Thread.ManagedThreadId or Environment.CurrentManagedThreadId are available /// diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index e83fb5ac626d2b00e2e83fa6bad6b760eb4f5edf..7ae5dfe43188b5a308a9e1ea447dd68167e0deaf 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -163,7 +163,7 @@ public static async Task Main() var v = CompileAndVerify(comp, expectedOutput: "hello world"); v.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 226 (0xe2) + // Code size 250 (0xfa) .maxstack 3 .locals init (int V_0, System.Exception V_1) @@ -180,7 +180,7 @@ .maxstack 3 IL_0010: ldarg.0 IL_0011: ldfld ""bool C.d__1.<>w__disposeMode"" IL_0016: brfalse.s IL_001d - IL_0018: leave IL_00cb + IL_0018: leave IL_00d7 IL_001d: ldarg.0 IL_001e: ldc.i4.m1 IL_001f: dup @@ -252,11 +252,11 @@ .maxstack 3 IL_00a0: ldarg.0 IL_00a1: ldfld ""bool C.d__1.<>w__disposeMode"" IL_00a6: brfalse.s IL_00aa - IL_00a8: leave.s IL_00cb + IL_00a8: leave.s IL_00d7 IL_00aa: ldarg.0 IL_00ab: ldc.i4.1 IL_00ac: stfld ""bool C.d__1.<>w__disposeMode"" - IL_00b1: leave.s IL_00cb + IL_00b1: leave.s IL_00d7 } catch System.Exception { @@ -269,18 +269,26 @@ .maxstack 3 IL_00c2: ldloc.1 IL_00c3: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" IL_00c8: nop - IL_00c9: leave.s IL_00e1 + IL_00c9: ldarg.0 + IL_00ca: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" + IL_00cf: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00d4: nop + IL_00d5: leave.s IL_00f9 } - IL_00cb: ldarg.0 - IL_00cc: ldc.i4.s -2 - IL_00ce: stfld ""int C.d__1.<>1__state"" - IL_00d3: ldarg.0 - IL_00d4: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__1.<>v__promiseOfValueOrEnd"" - IL_00d9: ldc.i4.0 - IL_00da: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_00df: nop - IL_00e0: ret - IL_00e1: ret + IL_00d7: ldarg.0 + IL_00d8: ldc.i4.s -2 + IL_00da: stfld ""int C.d__1.<>1__state"" + IL_00df: ldarg.0 + IL_00e0: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__1.<>v__promiseOfValueOrEnd"" + IL_00e5: ldc.i4.0 + IL_00e6: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_00eb: nop + IL_00ec: ldarg.0 + IL_00ed: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" + IL_00f2: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00f7: nop + IL_00f8: ret + IL_00f9: ret }"); } @@ -326,7 +334,7 @@ public static async Task Main() var v = CompileAndVerify(comp, expectedOutput: "hello world!"); v.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 167 (0xa7) + // Code size 194 (0xc2) .maxstack 3 .locals init (int V_0, System.Exception V_1) @@ -342,89 +350,97 @@ .maxstack 3 IL_000e: br.s IL_0010 IL_0010: ldarg.0 IL_0011: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0016: brfalse.s IL_001a - IL_0018: leave.s IL_0090 - IL_001a: ldarg.0 - IL_001b: ldc.i4.m1 - IL_001c: dup - IL_001d: stloc.0 - IL_001e: stfld ""int C.d__0.<>1__state"" - IL_0023: nop + IL_0016: brfalse.s IL_001d + IL_0018: leave IL_009f + IL_001d: ldarg.0 + IL_001e: ldc.i4.m1 + IL_001f: dup + IL_0020: stloc.0 + IL_0021: stfld ""int C.d__0.<>1__state"" + IL_0026: nop .try { - IL_0024: nop - IL_0025: nop - IL_0026: leave.s IL_0065 + IL_0027: nop + IL_0028: nop + IL_0029: leave.s IL_0068 } finally { - IL_0028: ldloc.0 - IL_0029: ldc.i4.m1 - IL_002a: bne.un.s IL_0064 - IL_002c: nop + IL_002b: ldloc.0 + IL_002c: ldc.i4.m1 + IL_002d: bne.un.s IL_0067 + IL_002f: nop .try { - IL_002d: nop - IL_002e: ldstr ""hello "" - IL_0033: call ""void System.Console.Write(string)"" - IL_0038: nop - IL_0039: nop - IL_003a: leave.s IL_004e + IL_0030: nop + IL_0031: ldstr ""hello "" + IL_0036: call ""void System.Console.Write(string)"" + IL_003b: nop + IL_003c: nop + IL_003d: leave.s IL_0051 } finally { - IL_003c: ldloc.0 - IL_003d: ldc.i4.m1 - IL_003e: bne.un.s IL_004d - IL_0040: nop - IL_0041: ldstr ""world"" - IL_0046: call ""void System.Console.Write(string)"" - IL_004b: nop - IL_004c: nop - IL_004d: endfinally + IL_003f: ldloc.0 + IL_0040: ldc.i4.m1 + IL_0041: bne.un.s IL_0050 + IL_0043: nop + IL_0044: ldstr ""world"" + IL_0049: call ""void System.Console.Write(string)"" + IL_004e: nop + IL_004f: nop + IL_0050: endfinally } - IL_004e: ldarg.0 - IL_004f: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0054: brfalse.s IL_0058 - IL_0056: br.s IL_0064 - IL_0058: ldstr ""!"" - IL_005d: call ""void System.Console.Write(string)"" - IL_0062: nop - IL_0063: nop - IL_0064: endfinally + IL_0051: ldarg.0 + IL_0052: ldfld ""bool C.d__0.<>w__disposeMode"" + IL_0057: brfalse.s IL_005b + IL_0059: br.s IL_0067 + IL_005b: ldstr ""!"" + IL_0060: call ""void System.Console.Write(string)"" + IL_0065: nop + IL_0066: nop + IL_0067: endfinally } - IL_0065: ldarg.0 - IL_0066: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_006b: brfalse.s IL_006f - IL_006d: leave.s IL_0090 - IL_006f: ldarg.0 - IL_0070: ldc.i4.1 - IL_0071: stfld ""bool C.d__0.<>w__disposeMode"" - IL_0076: leave.s IL_0090 + IL_0068: ldarg.0 + IL_0069: ldfld ""bool C.d__0.<>w__disposeMode"" + IL_006e: brfalse.s IL_0072 + IL_0070: leave.s IL_009f + IL_0072: ldarg.0 + IL_0073: ldc.i4.1 + IL_0074: stfld ""bool C.d__0.<>w__disposeMode"" + IL_0079: leave.s IL_009f } catch System.Exception { - IL_0078: stloc.1 - IL_0079: ldarg.0 - IL_007a: ldc.i4.s -2 - IL_007c: stfld ""int C.d__0.<>1__state"" - IL_0081: ldarg.0 - IL_0082: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0087: ldloc.1 - IL_0088: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_008d: nop - IL_008e: leave.s IL_00a6 + IL_007b: stloc.1 + IL_007c: ldarg.0 + IL_007d: ldc.i4.s -2 + IL_007f: stfld ""int C.d__0.<>1__state"" + IL_0084: ldarg.0 + IL_0085: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_008a: ldloc.1 + IL_008b: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" + IL_0090: nop + IL_0091: ldarg.0 + IL_0092: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_0097: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_009c: nop + IL_009d: leave.s IL_00c1 } - IL_0090: ldarg.0 - IL_0091: ldc.i4.s -2 - IL_0093: stfld ""int C.d__0.<>1__state"" - IL_0098: ldarg.0 - IL_0099: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_009e: ldc.i4.0 - IL_009f: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_00a4: nop - IL_00a5: ret - IL_00a6: ret + IL_009f: ldarg.0 + IL_00a0: ldc.i4.s -2 + IL_00a2: stfld ""int C.d__0.<>1__state"" + IL_00a7: ldarg.0 + IL_00a8: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_00ad: ldc.i4.0 + IL_00ae: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_00b3: nop + IL_00b4: ldarg.0 + IL_00b5: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_00ba: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00bf: nop + IL_00c0: ret + IL_00c1: ret }"); } @@ -2473,31 +2489,34 @@ .maxstack 2 "); verifier.VerifyIL("C.d__0.System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)", @" { - // Code size 52 (0x34) + // Code size 63 (0x3f) .maxstack 2 .locals init (C.d__0 V_0) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__0.<>1__state"" IL_0006: ldc.i4.s -2 - IL_0008: bne.un.s IL_002a + IL_0008: bne.un.s IL_0035 IL_000a: ldarg.0 IL_000b: ldfld ""int C.d__0.<>l__initialThreadId"" IL_0010: call ""int System.Environment.CurrentManagedThreadId.get"" - IL_0015: bne.un.s IL_002a + IL_0015: bne.un.s IL_0035 IL_0017: ldarg.0 IL_0018: ldc.i4.s -3 IL_001a: stfld ""int C.d__0.<>1__state"" IL_001f: ldarg.0 - IL_0020: stloc.0 - IL_0021: ldarg.0 - IL_0022: ldc.i4.0 - IL_0023: stfld ""bool C.d__0.<>w__disposeMode"" - IL_0028: br.s IL_0032 - IL_002a: ldc.i4.s -3 - IL_002c: newobj ""C.d__0..ctor(int)"" - IL_0031: stloc.0 - IL_0032: ldloc.0 - IL_0033: ret + IL_0020: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()"" + IL_0025: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_002a: ldarg.0 + IL_002b: ldc.i4.0 + IL_002c: stfld ""bool C.d__0.<>w__disposeMode"" + IL_0031: ldarg.0 + IL_0032: stloc.0 + IL_0033: br.s IL_003d + IL_0035: ldc.i4.s -3 + IL_0037: newobj ""C.d__0..ctor(int)"" + IL_003c: stloc.0 + IL_003d: ldloc.0 + IL_003e: ret }"); verifier.VerifyIL("C.d__0.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(short)", @" { @@ -2542,7 +2561,7 @@ .maxstack 5 { verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"{ - // Code size 298 (0x12a) + // Code size 322 (0x142) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -2571,7 +2590,7 @@ .maxstack 3 IL_002f: ldarg.0 IL_0030: ldfld ""bool C.d__0.<>w__disposeMode"" IL_0035: brfalse.s IL_003c - IL_0037: leave IL_0106 + IL_0037: leave IL_0112 IL_003c: ldarg.0 IL_003d: ldc.i4.m1 IL_003e: dup @@ -2608,7 +2627,7 @@ .maxstack 3 IL_007f: ldloca.s V_2 IL_0081: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" IL_0086: nop - IL_0087: leave IL_0129 + IL_0087: leave IL_0141 // async: resume IL_008c: ldarg.0 IL_008d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" @@ -2637,7 +2656,7 @@ .maxstack 3 IL_00c5: dup IL_00c6: stloc.0 IL_00c7: stfld ""int C.d__0.<>1__state"" - IL_00cc: leave.s IL_011c + IL_00cc: leave.s IL_0134 // sequence point: IL_00ce: ldarg.0 IL_00cf: ldc.i4.m1 @@ -2647,12 +2666,12 @@ .maxstack 3 IL_00d7: ldarg.0 IL_00d8: ldfld ""bool C.d__0.<>w__disposeMode"" IL_00dd: brfalse.s IL_00e1 - IL_00df: leave.s IL_0106 + IL_00df: leave.s IL_0112 // sequence point: Write("" 4 ""); IL_00e1: ldstr "" 4 "" IL_00e6: call ""void System.Console.Write(string)"" IL_00eb: nop - IL_00ec: leave.s IL_0106 + IL_00ec: leave.s IL_0112 } catch System.Exception { @@ -2666,32 +2685,40 @@ .maxstack 3 IL_00fd: ldloc.3 IL_00fe: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" IL_0103: nop - IL_0104: leave.s IL_0129 + IL_0104: ldarg.0 + IL_0105: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_010a: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_010f: nop + IL_0110: leave.s IL_0141 } // sequence point: } - IL_0106: ldarg.0 - IL_0107: ldc.i4.s -2 - IL_0109: stfld ""int C.d__0.<>1__state"" + IL_0112: ldarg.0 + IL_0113: ldc.i4.s -2 + IL_0115: stfld ""int C.d__0.<>1__state"" // sequence point: - IL_010e: ldarg.0 - IL_010f: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0114: ldc.i4.0 - IL_0115: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_011a: nop - IL_011b: ret - IL_011c: ldarg.0 - IL_011d: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0122: ldc.i4.1 - IL_0123: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0128: nop - IL_0129: ret + IL_011a: ldarg.0 + IL_011b: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_0120: ldc.i4.0 + IL_0121: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0126: nop + IL_0127: ldarg.0 + IL_0128: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_012d: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_0132: nop + IL_0133: ret + IL_0134: ldarg.0 + IL_0135: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_013a: ldc.i4.1 + IL_013b: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0140: nop + IL_0141: ret }", sequencePoints: "C+d__0.MoveNext", source: source); } else { verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 278 (0x116) + // Code size 300 (0x12c) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -2716,7 +2743,7 @@ .maxstack 3 IL_0024: ldarg.0 IL_0025: ldfld ""bool C.d__0.<>w__disposeMode"" IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_00f4 + IL_002c: leave IL_00ff IL_0031: ldarg.0 IL_0032: ldc.i4.m1 IL_0033: dup @@ -2749,7 +2776,7 @@ .maxstack 3 IL_0070: ldloca.s V_1 IL_0072: ldloca.s V_2 IL_0074: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_0079: leave IL_0115 + IL_0079: leave IL_012b // async: resume IL_007e: ldarg.0 IL_007f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" @@ -2776,7 +2803,7 @@ .maxstack 3 IL_00b5: dup IL_00b6: stloc.0 IL_00b7: stfld ""int C.d__0.<>1__state"" - IL_00bc: leave.s IL_0109 + IL_00bc: leave.s IL_011f // sequence point: IL_00be: ldarg.0 IL_00bf: ldc.i4.m1 @@ -2786,11 +2813,11 @@ .maxstack 3 IL_00c7: ldarg.0 IL_00c8: ldfld ""bool C.d__0.<>w__disposeMode"" IL_00cd: brfalse.s IL_00d1 - IL_00cf: leave.s IL_00f4 + IL_00cf: leave.s IL_00ff // sequence point: Write("" 4 ""); IL_00d1: ldstr "" 4 "" IL_00d6: call ""void System.Console.Write(string)"" - IL_00db: leave.s IL_00f4 + IL_00db: leave.s IL_00ff } catch System.Exception { @@ -2803,23 +2830,29 @@ .maxstack 3 IL_00e7: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" IL_00ec: ldloc.3 IL_00ed: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_00f2: leave.s IL_0115 + IL_00f2: ldarg.0 + IL_00f3: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_00f8: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00fd: leave.s IL_012b } // sequence point: } - IL_00f4: ldarg.0 - IL_00f5: ldc.i4.s -2 - IL_00f7: stfld ""int C.d__0.<>1__state"" + IL_00ff: ldarg.0 + IL_0100: ldc.i4.s -2 + IL_0102: stfld ""int C.d__0.<>1__state"" // sequence point: - IL_00fc: ldarg.0 - IL_00fd: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0102: ldc.i4.0 - IL_0103: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0108: ret - IL_0109: ldarg.0 - IL_010a: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_010f: ldc.i4.1 - IL_0110: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0115: ret + IL_0107: ldarg.0 + IL_0108: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_010d: ldc.i4.0 + IL_010e: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0113: ldarg.0 + IL_0114: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_0119: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_011e: ret + IL_011f: ldarg.0 + IL_0120: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_0125: ldc.i4.1 + IL_0126: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_012b: ret }", sequencePoints: "C+d__0.MoveNext", source: source); } } @@ -2861,76 +2894,79 @@ static async System.Collections.Generic.IAsyncEnumerable M([EnumeratorCance // we generate initialization logic for the token parameter verifier.VerifyIL("C.d__0.System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)", @" { - // Code size 165 (0xa5) + // Code size 176 (0xb0) .maxstack 3 .locals init (C.d__0 V_0, System.Threading.CancellationToken V_1) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__0.<>1__state"" IL_0006: ldc.i4.s -2 - IL_0008: bne.un.s IL_002a + IL_0008: bne.un.s IL_0035 IL_000a: ldarg.0 IL_000b: ldfld ""int C.d__0.<>l__initialThreadId"" IL_0010: call ""int System.Environment.CurrentManagedThreadId.get"" - IL_0015: bne.un.s IL_002a + IL_0015: bne.un.s IL_0035 IL_0017: ldarg.0 IL_0018: ldc.i4.s -3 IL_001a: stfld ""int C.d__0.<>1__state"" IL_001f: ldarg.0 - IL_0020: stloc.0 - IL_0021: ldarg.0 - IL_0022: ldc.i4.0 - IL_0023: stfld ""bool C.d__0.<>w__disposeMode"" - IL_0028: br.s IL_0032 - IL_002a: ldc.i4.s -3 - IL_002c: newobj ""C.d__0..ctor(int)"" - IL_0031: stloc.0 - IL_0032: ldarg.0 - IL_0033: ldflda ""System.Threading.CancellationToken C.d__0.<>3__token"" - IL_0038: ldloca.s V_1 - IL_003a: initobj ""System.Threading.CancellationToken"" - IL_0040: ldloc.1 - IL_0041: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" - IL_0046: brfalse.s IL_0051 - IL_0048: ldloc.0 - IL_0049: ldarg.1 - IL_004a: stfld ""System.Threading.CancellationToken C.d__0.token"" - IL_004f: br.s IL_00a3 - IL_0051: ldarga.s V_1 - IL_0053: ldarg.0 - IL_0054: ldfld ""System.Threading.CancellationToken C.d__0.<>3__token"" - IL_0059: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" - IL_005e: brtrue.s IL_0072 - IL_0060: ldarga.s V_1 - IL_0062: ldloca.s V_1 - IL_0064: initobj ""System.Threading.CancellationToken"" - IL_006a: ldloc.1 - IL_006b: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" - IL_0070: brfalse.s IL_0080 - IL_0072: ldloc.0 - IL_0073: ldarg.0 - IL_0074: ldfld ""System.Threading.CancellationToken C.d__0.<>3__token"" - IL_0079: stfld ""System.Threading.CancellationToken C.d__0.token"" - IL_007e: br.s IL_00a3 - IL_0080: ldarg.0 - IL_0081: ldarg.0 - IL_0082: ldfld ""System.Threading.CancellationToken C.d__0.<>3__token"" - IL_0087: ldarg.1 - IL_0088: call ""System.Threading.CancellationTokenSource System.Threading.CancellationTokenSource.CreateLinkedTokenSource(System.Threading.CancellationToken, System.Threading.CancellationToken)"" - IL_008d: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_0092: ldloc.0 - IL_0093: ldarg.0 - IL_0094: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_0099: callvirt ""System.Threading.CancellationToken System.Threading.CancellationTokenSource.Token.get"" - IL_009e: stfld ""System.Threading.CancellationToken C.d__0.token"" - IL_00a3: ldloc.0 - IL_00a4: ret + IL_0020: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()"" + IL_0025: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_002a: ldarg.0 + IL_002b: ldc.i4.0 + IL_002c: stfld ""bool C.d__0.<>w__disposeMode"" + IL_0031: ldarg.0 + IL_0032: stloc.0 + IL_0033: br.s IL_003d + IL_0035: ldc.i4.s -3 + IL_0037: newobj ""C.d__0..ctor(int)"" + IL_003c: stloc.0 + IL_003d: ldarg.0 + IL_003e: ldflda ""System.Threading.CancellationToken C.d__0.<>3__token"" + IL_0043: ldloca.s V_1 + IL_0045: initobj ""System.Threading.CancellationToken"" + IL_004b: ldloc.1 + IL_004c: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" + IL_0051: brfalse.s IL_005c + IL_0053: ldloc.0 + IL_0054: ldarg.1 + IL_0055: stfld ""System.Threading.CancellationToken C.d__0.token"" + IL_005a: br.s IL_00ae + IL_005c: ldarga.s V_1 + IL_005e: ldarg.0 + IL_005f: ldfld ""System.Threading.CancellationToken C.d__0.<>3__token"" + IL_0064: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" + IL_0069: brtrue.s IL_007d + IL_006b: ldarga.s V_1 + IL_006d: ldloca.s V_1 + IL_006f: initobj ""System.Threading.CancellationToken"" + IL_0075: ldloc.1 + IL_0076: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" + IL_007b: brfalse.s IL_008b + IL_007d: ldloc.0 + IL_007e: ldarg.0 + IL_007f: ldfld ""System.Threading.CancellationToken C.d__0.<>3__token"" + IL_0084: stfld ""System.Threading.CancellationToken C.d__0.token"" + IL_0089: br.s IL_00ae + IL_008b: ldarg.0 + IL_008c: ldarg.0 + IL_008d: ldfld ""System.Threading.CancellationToken C.d__0.<>3__token"" + IL_0092: ldarg.1 + IL_0093: call ""System.Threading.CancellationTokenSource System.Threading.CancellationTokenSource.CreateLinkedTokenSource(System.Threading.CancellationToken, System.Threading.CancellationToken)"" + IL_0098: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_009d: ldloc.0 + IL_009e: ldarg.0 + IL_009f: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00a4: callvirt ""System.Threading.CancellationToken System.Threading.CancellationTokenSource.Token.get"" + IL_00a9: stfld ""System.Threading.CancellationToken C.d__0.token"" + IL_00ae: ldloc.0 + IL_00af: ret }"); // we generate disposal logic for the combinedTokens field verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 304 (0x130) + // Code size 329 (0x149) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -2947,7 +2983,7 @@ .maxstack 3 IL_0008: ldc.i4.s -4 IL_000a: sub IL_000b: switch ( - IL_00b1, + IL_00b4, IL_0024, IL_0024, IL_0024, @@ -2955,7 +2991,7 @@ .maxstack 3 IL_0024: ldarg.0 IL_0025: ldfld ""bool C.d__0.<>w__disposeMode"" IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_00f4 + IL_002c: leave IL_0102 IL_0031: ldarg.0 IL_0032: ldc.i4.m1 IL_0033: dup @@ -2989,7 +3025,7 @@ .maxstack 3 IL_006d: ldloca.s V_1 IL_006f: ldloca.s V_2 IL_0071: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_0076: leave IL_012f + IL_0076: leave IL_0148 // async: resume IL_007b: ldarg.0 IL_007c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" @@ -3013,65 +3049,71 @@ .maxstack 3 IL_00a8: dup IL_00a9: stloc.0 IL_00aa: stfld ""int C.d__0.<>1__state"" - IL_00af: leave.s IL_0123 + IL_00af: leave IL_013c // sequence point: - IL_00b1: ldarg.0 - IL_00b2: ldc.i4.m1 - IL_00b3: dup - IL_00b4: stloc.0 - IL_00b5: stfld ""int C.d__0.<>1__state"" - IL_00ba: ldarg.0 - IL_00bb: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_00c0: pop + IL_00b4: ldarg.0 + IL_00b5: ldc.i4.m1 + IL_00b6: dup + IL_00b7: stloc.0 + IL_00b8: stfld ""int C.d__0.<>1__state"" + IL_00bd: ldarg.0 + IL_00be: ldfld ""bool C.d__0.<>w__disposeMode"" + IL_00c3: pop // sequence point: - IL_00c1: leave.s IL_00f4 + IL_00c4: leave.s IL_0102 } catch System.Exception { // sequence point: - IL_00c3: stloc.3 - IL_00c4: ldarg.0 - IL_00c5: ldc.i4.s -2 - IL_00c7: stfld ""int C.d__0.<>1__state"" - IL_00cc: ldarg.0 - IL_00cd: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00d2: brfalse.s IL_00e6 - IL_00d4: ldarg.0 - IL_00d5: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00da: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" - IL_00df: ldarg.0 - IL_00e0: ldnull - IL_00e1: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00e6: ldarg.0 - IL_00e7: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_00ec: ldloc.3 - IL_00ed: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_00f2: leave.s IL_012f + IL_00c6: stloc.3 + IL_00c7: ldarg.0 + IL_00c8: ldc.i4.s -2 + IL_00ca: stfld ""int C.d__0.<>1__state"" + IL_00cf: ldarg.0 + IL_00d0: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00d5: brfalse.s IL_00e9 + IL_00d7: ldarg.0 + IL_00d8: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00dd: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" + IL_00e2: ldarg.0 + IL_00e3: ldnull + IL_00e4: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00e9: ldarg.0 + IL_00ea: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_00ef: ldloc.3 + IL_00f0: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" + IL_00f5: ldarg.0 + IL_00f6: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_00fb: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_0100: leave.s IL_0148 } // sequence point: } - IL_00f4: ldarg.0 - IL_00f5: ldc.i4.s -2 - IL_00f7: stfld ""int C.d__0.<>1__state"" + IL_0102: ldarg.0 + IL_0103: ldc.i4.s -2 + IL_0105: stfld ""int C.d__0.<>1__state"" // sequence point: - IL_00fc: ldarg.0 - IL_00fd: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_0102: brfalse.s IL_0116 - IL_0104: ldarg.0 - IL_0105: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_010a: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" - IL_010f: ldarg.0 - IL_0110: ldnull - IL_0111: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_0116: ldarg.0 - IL_0117: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_011c: ldc.i4.0 - IL_011d: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0122: ret - IL_0123: ldarg.0 - IL_0124: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0129: ldc.i4.1 - IL_012a: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_012f: ret + IL_010a: ldarg.0 + IL_010b: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_0110: brfalse.s IL_0124 + IL_0112: ldarg.0 + IL_0113: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_0118: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" + IL_011d: ldarg.0 + IL_011e: ldnull + IL_011f: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_0124: ldarg.0 + IL_0125: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_012a: ldc.i4.0 + IL_012b: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0130: ldarg.0 + IL_0131: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_0136: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_013b: ret + IL_013c: ldarg.0 + IL_013d: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_0142: ldc.i4.1 + IL_0143: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0148: ret }", sequencePoints: "C+d__0.MoveNext", source: source); } @@ -3108,37 +3150,40 @@ static async System.Collections.Generic.IAsyncEnumerable M([EnumeratorCance // we don't generate initialization logic verifier.VerifyIL("C.d__0.System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)", @" { - // Code size 52 (0x34) + // Code size 63 (0x3f) .maxstack 2 .locals init (C.d__0 V_0) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__0.<>1__state"" IL_0006: ldc.i4.s -2 - IL_0008: bne.un.s IL_002a + IL_0008: bne.un.s IL_0035 IL_000a: ldarg.0 IL_000b: ldfld ""int C.d__0.<>l__initialThreadId"" IL_0010: call ""int System.Environment.CurrentManagedThreadId.get"" - IL_0015: bne.un.s IL_002a + IL_0015: bne.un.s IL_0035 IL_0017: ldarg.0 IL_0018: ldc.i4.s -3 IL_001a: stfld ""int C.d__0.<>1__state"" IL_001f: ldarg.0 - IL_0020: stloc.0 - IL_0021: ldarg.0 - IL_0022: ldc.i4.0 - IL_0023: stfld ""bool C.d__0.<>w__disposeMode"" - IL_0028: br.s IL_0032 - IL_002a: ldc.i4.s -3 - IL_002c: newobj ""C.d__0..ctor(int)"" - IL_0031: stloc.0 - IL_0032: ldloc.0 - IL_0033: ret + IL_0020: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()"" + IL_0025: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_002a: ldarg.0 + IL_002b: ldc.i4.0 + IL_002c: stfld ""bool C.d__0.<>w__disposeMode"" + IL_0031: ldarg.0 + IL_0032: stloc.0 + IL_0033: br.s IL_003d + IL_0035: ldc.i4.s -3 + IL_0037: newobj ""C.d__0..ctor(int)"" + IL_003c: stloc.0 + IL_003d: ldloc.0 + IL_003e: ret }"); // we generate disposal logic for the combinedTokens field verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 297 (0x129) + // Code size 322 (0x142) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -3155,7 +3200,7 @@ .maxstack 3 IL_0008: ldc.i4.s -4 IL_000a: sub IL_000b: switch ( - IL_00aa, + IL_00ad, IL_0024, IL_0024, IL_0024, @@ -3163,7 +3208,7 @@ .maxstack 3 IL_0024: ldarg.0 IL_0025: ldfld ""bool C.d__0.<>w__disposeMode"" IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_00ed + IL_002c: leave IL_00fb IL_0031: ldarg.0 IL_0032: ldc.i4.m1 IL_0033: dup @@ -3193,7 +3238,7 @@ .maxstack 3 IL_0066: ldloca.s V_1 IL_0068: ldloca.s V_2 IL_006a: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_006f: leave IL_0128 + IL_006f: leave IL_0141 // async: resume IL_0074: ldarg.0 IL_0075: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" @@ -3217,65 +3262,71 @@ .maxstack 3 IL_00a1: dup IL_00a2: stloc.0 IL_00a3: stfld ""int C.d__0.<>1__state"" - IL_00a8: leave.s IL_011c + IL_00a8: leave IL_0135 // sequence point: - IL_00aa: ldarg.0 - IL_00ab: ldc.i4.m1 - IL_00ac: dup - IL_00ad: stloc.0 - IL_00ae: stfld ""int C.d__0.<>1__state"" - IL_00b3: ldarg.0 - IL_00b4: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_00b9: pop + IL_00ad: ldarg.0 + IL_00ae: ldc.i4.m1 + IL_00af: dup + IL_00b0: stloc.0 + IL_00b1: stfld ""int C.d__0.<>1__state"" + IL_00b6: ldarg.0 + IL_00b7: ldfld ""bool C.d__0.<>w__disposeMode"" + IL_00bc: pop // sequence point: - IL_00ba: leave.s IL_00ed + IL_00bd: leave.s IL_00fb } catch System.Exception { // sequence point: - IL_00bc: stloc.3 - IL_00bd: ldarg.0 - IL_00be: ldc.i4.s -2 - IL_00c0: stfld ""int C.d__0.<>1__state"" - IL_00c5: ldarg.0 - IL_00c6: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00cb: brfalse.s IL_00df - IL_00cd: ldarg.0 - IL_00ce: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00d3: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" - IL_00d8: ldarg.0 - IL_00d9: ldnull - IL_00da: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00df: ldarg.0 - IL_00e0: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_00e5: ldloc.3 - IL_00e6: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_00eb: leave.s IL_0128 + IL_00bf: stloc.3 + IL_00c0: ldarg.0 + IL_00c1: ldc.i4.s -2 + IL_00c3: stfld ""int C.d__0.<>1__state"" + IL_00c8: ldarg.0 + IL_00c9: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00ce: brfalse.s IL_00e2 + IL_00d0: ldarg.0 + IL_00d1: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00d6: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" + IL_00db: ldarg.0 + IL_00dc: ldnull + IL_00dd: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_00e2: ldarg.0 + IL_00e3: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_00e8: ldloc.3 + IL_00e9: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" + IL_00ee: ldarg.0 + IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_00f4: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00f9: leave.s IL_0141 } // sequence point: } - IL_00ed: ldarg.0 - IL_00ee: ldc.i4.s -2 - IL_00f0: stfld ""int C.d__0.<>1__state"" + IL_00fb: ldarg.0 + IL_00fc: ldc.i4.s -2 + IL_00fe: stfld ""int C.d__0.<>1__state"" // sequence point: - IL_00f5: ldarg.0 - IL_00f6: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_00fb: brfalse.s IL_010f - IL_00fd: ldarg.0 - IL_00fe: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_0103: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" - IL_0108: ldarg.0 - IL_0109: ldnull - IL_010a: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" - IL_010f: ldarg.0 - IL_0110: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0115: ldc.i4.0 - IL_0116: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_011b: ret - IL_011c: ldarg.0 - IL_011d: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0122: ldc.i4.1 - IL_0123: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0128: ret + IL_0103: ldarg.0 + IL_0104: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_0109: brfalse.s IL_011d + IL_010b: ldarg.0 + IL_010c: ldfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_0111: callvirt ""void System.Threading.CancellationTokenSource.Dispose()"" + IL_0116: ldarg.0 + IL_0117: ldnull + IL_0118: stfld ""System.Threading.CancellationTokenSource C.d__0.<>x__combinedTokens"" + IL_011d: ldarg.0 + IL_011e: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_0123: ldc.i4.0 + IL_0124: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0129: ldarg.0 + IL_012a: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" + IL_012f: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_0134: ret + IL_0135: ldarg.0 + IL_0136: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" + IL_013b: ldc.i4.1 + IL_013c: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0141: ret }", sequencePoints: "C+d__0.MoveNext", source: source); } @@ -3289,20 +3340,6 @@ private static void VerifyStateMachineFields(CSharpCompilation comp, string meth AssertEx.SetEqual(expectedFields, fields); } - private void ValidateStateMachineFields(ModuleSymbol module, string methodName, string[] expected) - { - var method = module.GlobalNamespace.GetMember(methodName); - AssertEx.SetEqual(new[] { "AsyncIteratorStateMachineAttribute" }, - GetAttributeNames(method.GetAttributes())); - - var attribute = method.GetAttributes().Single(); - var argument = attribute.ConstructorArguments.Single(); - var stateMachineType = (ITypeSymbol)argument.Value; - Assert.Equal("C.d__0", stateMachineType.ToTestDisplayString()); - - AssertEx.SetEqual(expected, stateMachineType.GetMembers().Where(m => m.Kind == SymbolKind.Field).Select(m => m.ToTestDisplayString())); - } - [Fact] public void AsyncIteratorWithGenericReturn() { @@ -6179,78 +6216,81 @@ static async System.Collections.Generic.IAsyncEnumerable Iter(int value, [E // GetAsyncEnumerator's token parameter is used directly, since the argument token is default verifier.VerifyIL("C.d__1.System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)", @" { - // Code size 189 (0xbd) + // Code size 200 (0xc8) .maxstack 3 .locals init (C.d__1 V_0, System.Threading.CancellationToken V_1) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__1.<>1__state"" IL_0006: ldc.i4.s -2 - IL_0008: bne.un.s IL_002a + IL_0008: bne.un.s IL_0035 IL_000a: ldarg.0 IL_000b: ldfld ""int C.d__1.<>l__initialThreadId"" IL_0010: call ""int System.Environment.CurrentManagedThreadId.get"" - IL_0015: bne.un.s IL_002a + IL_0015: bne.un.s IL_0035 IL_0017: ldarg.0 IL_0018: ldc.i4.s -3 IL_001a: stfld ""int C.d__1.<>1__state"" IL_001f: ldarg.0 - IL_0020: stloc.0 - IL_0021: ldarg.0 - IL_0022: ldc.i4.0 - IL_0023: stfld ""bool C.d__1.<>w__disposeMode"" - IL_0028: br.s IL_0032 - IL_002a: ldc.i4.s -3 - IL_002c: newobj ""C.d__1..ctor(int)"" - IL_0031: stloc.0 - IL_0032: ldloc.0 - IL_0033: ldarg.0 - IL_0034: ldfld ""int C.d__1.<>3__value"" - IL_0039: stfld ""int C.d__1.value"" + IL_0020: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()"" + IL_0025: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" + IL_002a: ldarg.0 + IL_002b: ldc.i4.0 + IL_002c: stfld ""bool C.d__1.<>w__disposeMode"" + IL_0031: ldarg.0 + IL_0032: stloc.0 + IL_0033: br.s IL_003d + IL_0035: ldc.i4.s -3 + IL_0037: newobj ""C.d__1..ctor(int)"" + IL_003c: stloc.0 + IL_003d: ldloc.0 IL_003e: ldarg.0 - IL_003f: ldflda ""System.Threading.CancellationToken C.d__1.<>3__token1"" - IL_0044: ldloca.s V_1 - IL_0046: initobj ""System.Threading.CancellationToken"" - IL_004c: ldloc.1 - IL_004d: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" - IL_0052: brfalse.s IL_005d - IL_0054: ldloc.0 - IL_0055: ldarg.1 - IL_0056: stfld ""System.Threading.CancellationToken C.d__1.token1"" - IL_005b: br.s IL_00af - IL_005d: ldarga.s V_1 - IL_005f: ldarg.0 - IL_0060: ldfld ""System.Threading.CancellationToken C.d__1.<>3__token1"" - IL_0065: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" - IL_006a: brtrue.s IL_007e - IL_006c: ldarga.s V_1 - IL_006e: ldloca.s V_1 - IL_0070: initobj ""System.Threading.CancellationToken"" - IL_0076: ldloc.1 - IL_0077: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" - IL_007c: brfalse.s IL_008c - IL_007e: ldloc.0 - IL_007f: ldarg.0 - IL_0080: ldfld ""System.Threading.CancellationToken C.d__1.<>3__token1"" - IL_0085: stfld ""System.Threading.CancellationToken C.d__1.token1"" - IL_008a: br.s IL_00af - IL_008c: ldarg.0 - IL_008d: ldarg.0 - IL_008e: ldfld ""System.Threading.CancellationToken C.d__1.<>3__token1"" - IL_0093: ldarg.1 - IL_0094: call ""System.Threading.CancellationTokenSource System.Threading.CancellationTokenSource.CreateLinkedTokenSource(System.Threading.CancellationToken, System.Threading.CancellationToken)"" - IL_0099: stfld ""System.Threading.CancellationTokenSource C.d__1.<>x__combinedTokens"" - IL_009e: ldloc.0 - IL_009f: ldarg.0 - IL_00a0: ldfld ""System.Threading.CancellationTokenSource C.d__1.<>x__combinedTokens"" - IL_00a5: callvirt ""System.Threading.CancellationToken System.Threading.CancellationTokenSource.Token.get"" - IL_00aa: stfld ""System.Threading.CancellationToken C.d__1.token1"" - IL_00af: ldloc.0 - IL_00b0: ldarg.0 - IL_00b1: ldfld ""System.Threading.CancellationToken C.d__1.<>3__origToken"" - IL_00b6: stfld ""System.Threading.CancellationToken C.d__1.origToken"" - IL_00bb: ldloc.0 - IL_00bc: ret + IL_003f: ldfld ""int C.d__1.<>3__value"" + IL_0044: stfld ""int C.d__1.value"" + IL_0049: ldarg.0 + IL_004a: ldflda ""System.Threading.CancellationToken C.d__1.<>3__token1"" + IL_004f: ldloca.s V_1 + IL_0051: initobj ""System.Threading.CancellationToken"" + IL_0057: ldloc.1 + IL_0058: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" + IL_005d: brfalse.s IL_0068 + IL_005f: ldloc.0 + IL_0060: ldarg.1 + IL_0061: stfld ""System.Threading.CancellationToken C.d__1.token1"" + IL_0066: br.s IL_00ba + IL_0068: ldarga.s V_1 + IL_006a: ldarg.0 + IL_006b: ldfld ""System.Threading.CancellationToken C.d__1.<>3__token1"" + IL_0070: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" + IL_0075: brtrue.s IL_0089 + IL_0077: ldarga.s V_1 + IL_0079: ldloca.s V_1 + IL_007b: initobj ""System.Threading.CancellationToken"" + IL_0081: ldloc.1 + IL_0082: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)"" + IL_0087: brfalse.s IL_0097 + IL_0089: ldloc.0 + IL_008a: ldarg.0 + IL_008b: ldfld ""System.Threading.CancellationToken C.d__1.<>3__token1"" + IL_0090: stfld ""System.Threading.CancellationToken C.d__1.token1"" + IL_0095: br.s IL_00ba + IL_0097: ldarg.0 + IL_0098: ldarg.0 + IL_0099: ldfld ""System.Threading.CancellationToken C.d__1.<>3__token1"" + IL_009e: ldarg.1 + IL_009f: call ""System.Threading.CancellationTokenSource System.Threading.CancellationTokenSource.CreateLinkedTokenSource(System.Threading.CancellationToken, System.Threading.CancellationToken)"" + IL_00a4: stfld ""System.Threading.CancellationTokenSource C.d__1.<>x__combinedTokens"" + IL_00a9: ldloc.0 + IL_00aa: ldarg.0 + IL_00ab: ldfld ""System.Threading.CancellationTokenSource C.d__1.<>x__combinedTokens"" + IL_00b0: callvirt ""System.Threading.CancellationToken System.Threading.CancellationTokenSource.Token.get"" + IL_00b5: stfld ""System.Threading.CancellationToken C.d__1.token1"" + IL_00ba: ldloc.0 + IL_00bb: ldarg.0 + IL_00bc: ldfld ""System.Threading.CancellationToken C.d__1.<>3__origToken"" + IL_00c1: stfld ""System.Threading.CancellationToken C.d__1.origToken"" + IL_00c6: ldloc.0 + IL_00c7: ret } "); }