From accbe6c5d4cdd72a5ea89691c63650f39f48c628 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 8 Nov 2024 22:55:28 -0800 Subject: [PATCH 01/20] Add more tests for baseline --- .../MethodToStateMachineRewriter.cs | 5 - .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 1204 ++++++++++++++++- .../Test/Emit/CodeGen/CodeGenAsyncTests.cs | 129 +- .../Test/Emit/CodeGen/CodeGenIterators.cs | 1089 ++++++++++++++- 4 files changed, 2376 insertions(+), 51 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 1fe789a5a9a69..72423cff8f452 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -75,11 +75,6 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter /// private int _nextHoistedFieldId = 1; - /// - /// Used to enumerate the instance fields of a struct. - /// - private readonly EmptyStructTypeCache _emptyStructTypeCache = EmptyStructTypeCache.CreateNeverEmpty(); - /// /// The set of local variables and parameters that were hoisted and need a proxy. /// diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 890e20d8e09c2..00daa6d7d7cb5 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -9438,7 +9438,135 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("42"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("42"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 294 (0x126) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_00b7, + IL_0024, + IL_0024, + IL_0024, + IL_007c) + IL_0024: ldarg.0 + IL_0025: ldfld "bool C.d__0.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_00f2 + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldc.i4.s 42 + IL_003d: stfld "int C.d__0.5__2" + IL_0042: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0047: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_004c: stloc.1 + IL_004d: ldloca.s V_1 + IL_004f: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0054: brtrue.s IL_0098 + IL_0056: ldarg.0 + IL_0057: ldc.i4.0 + IL_0058: dup + IL_0059: stloc.0 + IL_005a: stfld "int C.d__0.<>1__state" + IL_005f: ldarg.0 + IL_0060: ldloc.1 + IL_0061: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0066: ldarg.0 + IL_0067: stloc.2 + IL_0068: ldarg.0 + IL_0069: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_006e: ldloca.s V_1 + IL_0070: ldloca.s V_2 + IL_0072: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_0077: leave IL_0125 + IL_007c: ldarg.0 + IL_007d: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0082: stloc.1 + IL_0083: ldarg.0 + IL_0084: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0089: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_008f: ldarg.0 + IL_0090: ldc.i4.m1 + IL_0091: dup + IL_0092: stloc.0 + IL_0093: stfld "int C.d__0.<>1__state" + IL_0098: ldloca.s V_1 + IL_009a: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_009f: ldarg.0 + IL_00a0: ldarg.0 + IL_00a1: ldfld "int C.d__0.5__2" + IL_00a6: stfld "int C.d__0.<>2__current" + IL_00ab: ldarg.0 + IL_00ac: ldc.i4.s -4 + IL_00ae: dup + IL_00af: stloc.0 + IL_00b0: stfld "int C.d__0.<>1__state" + IL_00b5: leave.s IL_0119 + IL_00b7: ldarg.0 + IL_00b8: ldc.i4.m1 + IL_00b9: dup + IL_00ba: stloc.0 + IL_00bb: stfld "int C.d__0.<>1__state" + IL_00c0: ldarg.0 + IL_00c1: ldfld "bool C.d__0.<>w__disposeMode" + IL_00c6: pop + IL_00c7: leave.s IL_00f2 + } + catch System.Exception + { + IL_00c9: stloc.3 + IL_00ca: ldarg.0 + IL_00cb: ldc.i4.s -2 + IL_00cd: stfld "int C.d__0.<>1__state" + IL_00d2: ldarg.0 + IL_00d3: ldc.i4.0 + IL_00d4: stfld "int C.d__0.<>2__current" + IL_00d9: ldarg.0 + IL_00da: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00df: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00e4: ldarg.0 + IL_00e5: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00ea: ldloc.3 + IL_00eb: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_00f0: leave.s IL_0125 + } + IL_00f2: ldarg.0 + IL_00f3: ldc.i4.s -2 + IL_00f5: stfld "int C.d__0.<>1__state" + IL_00fa: ldarg.0 + IL_00fb: ldc.i4.0 + IL_00fc: stfld "int C.d__0.<>2__current" + IL_0101: ldarg.0 + IL_0102: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0107: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_010c: ldarg.0 + IL_010d: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0112: ldc.i4.0 + IL_0113: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0118: ret + IL_0119: ldarg.0 + IL_011a: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_011f: ldc.i4.1 + IL_0120: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0125: ret +} +"""); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9463,7 +9591,450 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } """; // Note: hoisted top-level local does not get cleared when exiting normally - CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 306 (0x132) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_00b5, + IL_0024, + IL_0024, + IL_0024, + IL_007f) + IL_0024: ldarg.0 + IL_0025: ldfld "bool C.d__0.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_00fe + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldstr "value " + IL_0040: stfld "string C.d__0.5__2" + IL_0045: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_004a: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_004f: stloc.1 + IL_0050: ldloca.s V_1 + IL_0052: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0057: brtrue.s IL_009b + IL_0059: ldarg.0 + IL_005a: ldc.i4.0 + IL_005b: dup + IL_005c: stloc.0 + IL_005d: stfld "int C.d__0.<>1__state" + IL_0062: ldarg.0 + IL_0063: ldloc.1 + IL_0064: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0069: ldarg.0 + IL_006a: stloc.2 + IL_006b: ldarg.0 + IL_006c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0071: ldloca.s V_1 + IL_0073: ldloca.s V_2 + IL_0075: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_007a: leave IL_0131 + IL_007f: ldarg.0 + IL_0080: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0085: stloc.1 + IL_0086: ldarg.0 + IL_0087: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_008c: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0092: ldarg.0 + IL_0093: ldc.i4.m1 + IL_0094: dup + IL_0095: stloc.0 + IL_0096: stfld "int C.d__0.<>1__state" + IL_009b: ldloca.s V_1 + IL_009d: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00a2: ldarg.0 + IL_00a3: ldc.i4.1 + IL_00a4: stfld "int C.d__0.<>2__current" + IL_00a9: ldarg.0 + IL_00aa: ldc.i4.s -4 + IL_00ac: dup + IL_00ad: stloc.0 + IL_00ae: stfld "int C.d__0.<>1__state" + IL_00b3: leave.s IL_0125 + IL_00b5: ldarg.0 + IL_00b6: ldc.i4.m1 + IL_00b7: dup + IL_00b8: stloc.0 + IL_00b9: stfld "int C.d__0.<>1__state" + IL_00be: ldarg.0 + IL_00bf: ldfld "bool C.d__0.<>w__disposeMode" + IL_00c4: brfalse.s IL_00c8 + IL_00c6: leave.s IL_00fe + IL_00c8: ldarg.0 + IL_00c9: ldfld "string C.d__0.5__2" + IL_00ce: call "void System.Console.Write(string)" + IL_00d3: leave.s IL_00fe + } + catch System.Exception + { + IL_00d5: stloc.3 + IL_00d6: ldarg.0 + IL_00d7: ldc.i4.s -2 + IL_00d9: stfld "int C.d__0.<>1__state" + IL_00de: ldarg.0 + IL_00df: ldc.i4.0 + IL_00e0: stfld "int C.d__0.<>2__current" + IL_00e5: ldarg.0 + IL_00e6: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00eb: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00f0: ldarg.0 + IL_00f1: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00f6: ldloc.3 + IL_00f7: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_00fc: leave.s IL_0131 + } + IL_00fe: ldarg.0 + IL_00ff: ldc.i4.s -2 + IL_0101: stfld "int C.d__0.<>1__state" + IL_0106: ldarg.0 + IL_0107: ldc.i4.0 + IL_0108: stfld "int C.d__0.<>2__current" + IL_010d: ldarg.0 + IL_010e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0113: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0118: ldarg.0 + IL_0119: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_011e: ldc.i4.0 + IL_011f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0124: ret + IL_0125: ldarg.0 + IL_0126: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_012b: ldc.i4.1 + IL_012c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0131: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_YieldBreak() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +await foreach (int value in values) { } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + string values2 = "value "; + await System.Threading.Tasks.Task.CompletedTask; + System.Console.Write(values2); + if (b) yield break; + throw null; + } +} +"""; + // Note: hoisted top-level local does not get cleared when exiting with yield break + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 252 (0xfc) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -3 + IL_000a: beq.s IL_000f + IL_000c: ldloc.0 + IL_000d: brfalse.s IL_006a + IL_000f: ldarg.0 + IL_0010: ldfld "bool C.d__0.<>w__disposeMode" + IL_0015: brfalse.s IL_001c + IL_0017: leave IL_00d4 + IL_001c: ldarg.0 + IL_001d: ldc.i4.m1 + IL_001e: dup + IL_001f: stloc.0 + IL_0020: stfld "int C.d__0.<>1__state" + IL_0025: ldarg.0 + IL_0026: ldstr "value " + IL_002b: stfld "string C.d__0.5__2" + IL_0030: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0035: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_003a: stloc.1 + IL_003b: ldloca.s V_1 + IL_003d: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0042: brtrue.s IL_0086 + IL_0044: ldarg.0 + IL_0045: ldc.i4.0 + IL_0046: dup + IL_0047: stloc.0 + IL_0048: stfld "int C.d__0.<>1__state" + IL_004d: ldarg.0 + IL_004e: ldloc.1 + IL_004f: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0054: ldarg.0 + IL_0055: stloc.2 + IL_0056: ldarg.0 + IL_0057: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_005c: ldloca.s V_1 + IL_005e: ldloca.s V_2 + IL_0060: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_0065: leave IL_00fb + IL_006a: ldarg.0 + IL_006b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0070: stloc.1 + IL_0071: ldarg.0 + IL_0072: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0077: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_007d: ldarg.0 + IL_007e: ldc.i4.m1 + IL_007f: dup + IL_0080: stloc.0 + IL_0081: stfld "int C.d__0.<>1__state" + IL_0086: ldloca.s V_1 + IL_0088: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_008d: ldarg.0 + IL_008e: ldfld "string C.d__0.5__2" + IL_0093: call "void System.Console.Write(string)" + IL_0098: ldarg.0 + IL_0099: ldfld "bool C.d__0.b" + IL_009e: brfalse.s IL_00a9 + IL_00a0: ldarg.0 + IL_00a1: ldc.i4.1 + IL_00a2: stfld "bool C.d__0.<>w__disposeMode" + IL_00a7: leave.s IL_00d4 + IL_00a9: ldnull + IL_00aa: throw + } + catch System.Exception + { + IL_00ab: stloc.3 + IL_00ac: ldarg.0 + IL_00ad: ldc.i4.s -2 + IL_00af: stfld "int C.d__0.<>1__state" + IL_00b4: ldarg.0 + IL_00b5: ldc.i4.0 + IL_00b6: stfld "int C.d__0.<>2__current" + IL_00bb: ldarg.0 + IL_00bc: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00c1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00c6: ldarg.0 + IL_00c7: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00cc: ldloc.3 + IL_00cd: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_00d2: leave.s IL_00fb + } + IL_00d4: ldarg.0 + IL_00d5: ldc.i4.s -2 + IL_00d7: stfld "int C.d__0.<>1__state" + IL_00dc: ldarg.0 + IL_00dd: ldc.i4.0 + IL_00de: stfld "int C.d__0.<>2__current" + IL_00e3: ldarg.0 + IL_00e4: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00e9: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00ee: ldarg.0 + IL_00ef: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00f4: ldc.i4.0 + IL_00f5: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_00fa: ret + IL_00fb: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_ThrownException() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +try +{ + await foreach (int value in values) { } +} +catch (System.Exception e) +{ + System.Console.Write(e.Message); +} + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + string values2 = "value "; + await System.Threading.Tasks.Task.CompletedTask; + System.Console.Write(values2); + if (b) throw new System.Exception("exception "); + yield break; + } +} +"""; + // Note: hoisted top-level local does not get cleared when exiting from thrown exception + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 261 (0x105) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -3 + IL_000a: beq.s IL_000f + IL_000c: ldloc.0 + IL_000d: brfalse.s IL_006a + IL_000f: ldarg.0 + IL_0010: ldfld "bool C.d__0.<>w__disposeMode" + IL_0015: brfalse.s IL_001c + IL_0017: leave IL_00dd + IL_001c: ldarg.0 + IL_001d: ldc.i4.m1 + IL_001e: dup + IL_001f: stloc.0 + IL_0020: stfld "int C.d__0.<>1__state" + IL_0025: ldarg.0 + IL_0026: ldstr "value " + IL_002b: stfld "string C.d__0.5__2" + IL_0030: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0035: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_003a: stloc.1 + IL_003b: ldloca.s V_1 + IL_003d: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0042: brtrue.s IL_0086 + IL_0044: ldarg.0 + IL_0045: ldc.i4.0 + IL_0046: dup + IL_0047: stloc.0 + IL_0048: stfld "int C.d__0.<>1__state" + IL_004d: ldarg.0 + IL_004e: ldloc.1 + IL_004f: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0054: ldarg.0 + IL_0055: stloc.2 + IL_0056: ldarg.0 + IL_0057: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_005c: ldloca.s V_1 + IL_005e: ldloca.s V_2 + IL_0060: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_0065: leave IL_0104 + IL_006a: ldarg.0 + IL_006b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0070: stloc.1 + IL_0071: ldarg.0 + IL_0072: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0077: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_007d: ldarg.0 + IL_007e: ldc.i4.m1 + IL_007f: dup + IL_0080: stloc.0 + IL_0081: stfld "int C.d__0.<>1__state" + IL_0086: ldloca.s V_1 + IL_0088: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_008d: ldarg.0 + IL_008e: ldfld "string C.d__0.5__2" + IL_0093: call "void System.Console.Write(string)" + IL_0098: ldarg.0 + IL_0099: ldfld "bool C.d__0.b" + IL_009e: brfalse.s IL_00ab + IL_00a0: ldstr "exception " + IL_00a5: newobj "System.Exception..ctor(string)" + IL_00aa: throw + IL_00ab: ldarg.0 + IL_00ac: ldc.i4.1 + IL_00ad: stfld "bool C.d__0.<>w__disposeMode" + IL_00b2: leave.s IL_00dd + } + catch System.Exception + { + IL_00b4: stloc.3 + IL_00b5: ldarg.0 + IL_00b6: ldc.i4.s -2 + IL_00b8: stfld "int C.d__0.<>1__state" + IL_00bd: ldarg.0 + IL_00be: ldc.i4.0 + IL_00bf: stfld "int C.d__0.<>2__current" + IL_00c4: ldarg.0 + IL_00c5: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00ca: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00d5: ldloc.3 + IL_00d6: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_00db: leave.s IL_0104 + } + IL_00dd: ldarg.0 + IL_00de: ldc.i4.s -2 + IL_00e0: stfld "int C.d__0.<>1__state" + IL_00e5: ldarg.0 + IL_00e6: ldc.i4.0 + IL_00e7: stfld "int C.d__0.<>2__current" + IL_00ec: ldarg.0 + IL_00ed: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00f2: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00f7: ldarg.0 + IL_00f8: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00fd: ldc.i4.0 + IL_00fe: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0103: ret + IL_0104: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_EarlyIterationExit() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +await foreach (var value in values) { break; } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + string values2 = "value "; + await System.Threading.Tasks.Task.CompletedTask; + yield return 42; + System.Console.Write(values2); + } +} +"""; + // Note: hoisted top-level local does not get cleared when exiting loop early + CompileAndVerify(src, expectedOutput: ExpectedOutput("value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9506,7 +10077,592 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } """; // Note: hoisted nested local gets cleared when exiting nested scope normally - CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 424 (0x1a8) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -6 + IL_000a: sub + IL_000b: switch ( + IL_0139, + IL_00b2, + IL_0065, + IL_002c, + IL_002c, + IL_002c, + IL_0103) + IL_002c: ldarg.0 + IL_002d: ldfld "bool C.d__0.<>w__disposeMode" + IL_0032: brfalse.s IL_0039 + IL_0034: leave IL_0174 + IL_0039: ldarg.0 + IL_003a: ldc.i4.m1 + IL_003b: dup + IL_003c: stloc.0 + IL_003d: stfld "int C.d__0.<>1__state" + IL_0042: br.s IL_0094 + IL_0044: ldarg.0 + IL_0045: ldstr "value " + IL_004a: stfld "string C.d__0.5__2" + IL_004f: ldarg.0 + IL_0050: ldc.i4.1 + IL_0051: stfld "int C.d__0.<>2__current" + IL_0056: ldarg.0 + IL_0057: ldc.i4.s -4 + IL_0059: dup + IL_005a: stloc.0 + IL_005b: stfld "int C.d__0.<>1__state" + IL_0060: leave IL_019b + IL_0065: ldarg.0 + IL_0066: ldc.i4.m1 + IL_0067: dup + IL_0068: stloc.0 + IL_0069: stfld "int C.d__0.<>1__state" + IL_006e: ldarg.0 + IL_006f: ldfld "bool C.d__0.<>w__disposeMode" + IL_0074: brfalse.s IL_007b + IL_0076: leave IL_0174 + IL_007b: ldarg.0 + IL_007c: ldfld "string C.d__0.5__2" + IL_0081: call "void System.Console.Write(string)" + IL_0086: ldarg.0 + IL_0087: ldc.i4.0 + IL_0088: stfld "bool C.d__0.b" + IL_008d: ldarg.0 + IL_008e: ldnull + IL_008f: stfld "string C.d__0.5__2" + IL_0094: ldarg.0 + IL_0095: ldfld "bool C.d__0.b" + IL_009a: brtrue.s IL_0044 + IL_009c: ldarg.0 + IL_009d: ldc.i4.2 + IL_009e: stfld "int C.d__0.<>2__current" + IL_00a3: ldarg.0 + IL_00a4: ldc.i4.s -5 + IL_00a6: dup + IL_00a7: stloc.0 + IL_00a8: stfld "int C.d__0.<>1__state" + IL_00ad: leave IL_019b + IL_00b2: ldarg.0 + IL_00b3: ldc.i4.m1 + IL_00b4: dup + IL_00b5: stloc.0 + IL_00b6: stfld "int C.d__0.<>1__state" + IL_00bb: ldarg.0 + IL_00bc: ldfld "bool C.d__0.<>w__disposeMode" + IL_00c1: brfalse.s IL_00c8 + IL_00c3: leave IL_0174 + IL_00c8: ldarg.0 + IL_00c9: ldfld "System.Threading.Tasks.Task C.d__0.task" + IL_00ce: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_00d3: stloc.1 + IL_00d4: ldloca.s V_1 + IL_00d6: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_00db: brtrue.s IL_011f + IL_00dd: ldarg.0 + IL_00de: ldc.i4.0 + IL_00df: dup + IL_00e0: stloc.0 + IL_00e1: stfld "int C.d__0.<>1__state" + IL_00e6: ldarg.0 + IL_00e7: ldloc.1 + IL_00e8: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00ed: ldarg.0 + IL_00ee: stloc.2 + IL_00ef: ldarg.0 + IL_00f0: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00f5: ldloca.s V_1 + IL_00f7: ldloca.s V_2 + IL_00f9: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_00fe: leave IL_01a7 + IL_0103: ldarg.0 + IL_0104: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0109: stloc.1 + IL_010a: ldarg.0 + IL_010b: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0110: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0116: ldarg.0 + IL_0117: ldc.i4.m1 + IL_0118: dup + IL_0119: stloc.0 + IL_011a: stfld "int C.d__0.<>1__state" + IL_011f: ldloca.s V_1 + IL_0121: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0126: ldarg.0 + IL_0127: ldc.i4.3 + IL_0128: stfld "int C.d__0.<>2__current" + IL_012d: ldarg.0 + IL_012e: ldc.i4.s -6 + IL_0130: dup + IL_0131: stloc.0 + IL_0132: stfld "int C.d__0.<>1__state" + IL_0137: leave.s IL_019b + IL_0139: ldarg.0 + IL_013a: ldc.i4.m1 + IL_013b: dup + IL_013c: stloc.0 + IL_013d: stfld "int C.d__0.<>1__state" + IL_0142: ldarg.0 + IL_0143: ldfld "bool C.d__0.<>w__disposeMode" + IL_0148: pop + IL_0149: leave.s IL_0174 + } + catch System.Exception + { + IL_014b: stloc.3 + IL_014c: ldarg.0 + IL_014d: ldc.i4.s -2 + IL_014f: stfld "int C.d__0.<>1__state" + IL_0154: ldarg.0 + IL_0155: ldc.i4.0 + IL_0156: stfld "int C.d__0.<>2__current" + IL_015b: ldarg.0 + IL_015c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0161: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0166: ldarg.0 + IL_0167: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_016c: ldloc.3 + IL_016d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0172: leave.s IL_01a7 + } + IL_0174: ldarg.0 + IL_0175: ldc.i4.s -2 + IL_0177: stfld "int C.d__0.<>1__state" + IL_017c: ldarg.0 + IL_017d: ldc.i4.0 + IL_017e: stfld "int C.d__0.<>2__current" + IL_0183: ldarg.0 + IL_0184: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0189: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_018e: ldarg.0 + IL_018f: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0194: ldc.i4.0 + IL_0195: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_019a: ret + IL_019b: ldarg.0 + IL_019c: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_01a1: ldc.i4.1 + IL_01a2: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_01a7: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_YieldBreak() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +var enumerator = values.GetAsyncEnumerator(); +assert(await enumerator.MoveNextAsync()); +assert(enumerator.Current == 1); +assert(!(await enumerator.MoveNextAsync())); + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +void assert(bool b) +{ + if (!b) throw new System.Exception(); +} + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + while (b) + { + string values2 = "value "; + yield return 1; + System.Console.Write(values2); + await System.Threading.Tasks.Task.CompletedTask; + if (b) yield break; + } + throw null; + } +} +"""; + // Note: hoisted nested local does not get cleared when exiting nested scope with yield break + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 352 (0x160) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_0060, + IL_0024, + IL_0024, + IL_0024, + IL_00bb) + IL_0024: ldarg.0 + IL_0025: ldfld "bool C.d__0.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_012c + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: br IL_00f6 + IL_003f: ldarg.0 + IL_0040: ldstr "value " + IL_0045: stfld "string C.d__0.5__2" + IL_004a: ldarg.0 + IL_004b: ldc.i4.1 + IL_004c: stfld "int C.d__0.<>2__current" + IL_0051: ldarg.0 + IL_0052: ldc.i4.s -4 + IL_0054: dup + IL_0055: stloc.0 + IL_0056: stfld "int C.d__0.<>1__state" + IL_005b: leave IL_0153 + IL_0060: ldarg.0 + IL_0061: ldc.i4.m1 + IL_0062: dup + IL_0063: stloc.0 + IL_0064: stfld "int C.d__0.<>1__state" + IL_0069: ldarg.0 + IL_006a: ldfld "bool C.d__0.<>w__disposeMode" + IL_006f: brfalse.s IL_0076 + IL_0071: leave IL_012c + IL_0076: ldarg.0 + IL_0077: ldfld "string C.d__0.5__2" + IL_007c: call "void System.Console.Write(string)" + IL_0081: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0086: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_008b: stloc.1 + IL_008c: ldloca.s V_1 + IL_008e: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0093: brtrue.s IL_00d7 + IL_0095: ldarg.0 + IL_0096: ldc.i4.0 + IL_0097: dup + IL_0098: stloc.0 + IL_0099: stfld "int C.d__0.<>1__state" + IL_009e: ldarg.0 + IL_009f: ldloc.1 + IL_00a0: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00a5: ldarg.0 + IL_00a6: stloc.2 + IL_00a7: ldarg.0 + IL_00a8: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00ad: ldloca.s V_1 + IL_00af: ldloca.s V_2 + IL_00b1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_00b6: leave IL_015f + IL_00bb: ldarg.0 + IL_00bc: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00c1: stloc.1 + IL_00c2: ldarg.0 + IL_00c3: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00c8: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00ce: ldarg.0 + IL_00cf: ldc.i4.m1 + IL_00d0: dup + IL_00d1: stloc.0 + IL_00d2: stfld "int C.d__0.<>1__state" + IL_00d7: ldloca.s V_1 + IL_00d9: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00de: ldarg.0 + IL_00df: ldfld "bool C.d__0.b" + IL_00e4: brfalse.s IL_00ef + IL_00e6: ldarg.0 + IL_00e7: ldc.i4.1 + IL_00e8: stfld "bool C.d__0.<>w__disposeMode" + IL_00ed: leave.s IL_012c + IL_00ef: ldarg.0 + IL_00f0: ldnull + IL_00f1: stfld "string C.d__0.5__2" + IL_00f6: ldarg.0 + IL_00f7: ldfld "bool C.d__0.b" + IL_00fc: brtrue IL_003f + IL_0101: ldnull + IL_0102: throw + } + catch System.Exception + { + IL_0103: stloc.3 + IL_0104: ldarg.0 + IL_0105: ldc.i4.s -2 + IL_0107: stfld "int C.d__0.<>1__state" + IL_010c: ldarg.0 + IL_010d: ldc.i4.0 + IL_010e: stfld "int C.d__0.<>2__current" + 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: ldarg.0 + IL_011f: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0124: ldloc.3 + IL_0125: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_012a: leave.s IL_015f + } + IL_012c: ldarg.0 + IL_012d: ldc.i4.s -2 + IL_012f: stfld "int C.d__0.<>1__state" + IL_0134: ldarg.0 + IL_0135: ldc.i4.0 + IL_0136: stfld "int C.d__0.<>2__current" + IL_013b: ldarg.0 + IL_013c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0141: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0146: ldarg.0 + IL_0147: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_014c: ldc.i4.0 + IL_014d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0152: ret + IL_0153: ldarg.0 + IL_0154: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0159: ldc.i4.1 + IL_015a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_015f: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_ThrownException() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +var enumerator = values.GetAsyncEnumerator(); +assert(await enumerator.MoveNextAsync()); +assert(enumerator.Current == 1); +try +{ + assert(!(await enumerator.MoveNextAsync())); +} +catch (System.Exception e) +{ + System.Console.Write(e.Message); +} + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +void assert(bool b) +{ + if (!b) throw new System.Exception(); +} + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + while (b) + { + string values2 = "value "; + yield return 1; + System.Console.Write(values2); + await System.Threading.Tasks.Task.CompletedTask; + if (b) throw new System.Exception("exception "); + } + throw null; + } +} +"""; + // Note: hoisted nested local does not get cleared when exiting nested scope with thrown exception + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 354 (0x162) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_0060, + IL_0024, + IL_0024, + IL_0024, + IL_00bb) + IL_0024: ldarg.0 + IL_0025: ldfld "bool C.d__0.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_012e + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: br IL_00f8 + IL_003f: ldarg.0 + IL_0040: ldstr "value " + IL_0045: stfld "string C.d__0.5__2" + IL_004a: ldarg.0 + IL_004b: ldc.i4.1 + IL_004c: stfld "int C.d__0.<>2__current" + IL_0051: ldarg.0 + IL_0052: ldc.i4.s -4 + IL_0054: dup + IL_0055: stloc.0 + IL_0056: stfld "int C.d__0.<>1__state" + IL_005b: leave IL_0155 + IL_0060: ldarg.0 + IL_0061: ldc.i4.m1 + IL_0062: dup + IL_0063: stloc.0 + IL_0064: stfld "int C.d__0.<>1__state" + IL_0069: ldarg.0 + IL_006a: ldfld "bool C.d__0.<>w__disposeMode" + IL_006f: brfalse.s IL_0076 + IL_0071: leave IL_012e + IL_0076: ldarg.0 + IL_0077: ldfld "string C.d__0.5__2" + IL_007c: call "void System.Console.Write(string)" + IL_0081: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0086: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_008b: stloc.1 + IL_008c: ldloca.s V_1 + IL_008e: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0093: brtrue.s IL_00d7 + IL_0095: ldarg.0 + IL_0096: ldc.i4.0 + IL_0097: dup + IL_0098: stloc.0 + IL_0099: stfld "int C.d__0.<>1__state" + IL_009e: ldarg.0 + IL_009f: ldloc.1 + IL_00a0: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00a5: ldarg.0 + IL_00a6: stloc.2 + IL_00a7: ldarg.0 + IL_00a8: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00ad: ldloca.s V_1 + IL_00af: ldloca.s V_2 + IL_00b1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_00b6: leave IL_0161 + IL_00bb: ldarg.0 + IL_00bc: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00c1: stloc.1 + IL_00c2: ldarg.0 + IL_00c3: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00c8: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00ce: ldarg.0 + IL_00cf: ldc.i4.m1 + IL_00d0: dup + IL_00d1: stloc.0 + IL_00d2: stfld "int C.d__0.<>1__state" + IL_00d7: ldloca.s V_1 + IL_00d9: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00de: ldarg.0 + IL_00df: ldfld "bool C.d__0.b" + IL_00e4: brfalse.s IL_00f1 + IL_00e6: ldstr "exception " + IL_00eb: newobj "System.Exception..ctor(string)" + IL_00f0: throw + IL_00f1: ldarg.0 + IL_00f2: ldnull + IL_00f3: stfld "string C.d__0.5__2" + IL_00f8: ldarg.0 + IL_00f9: ldfld "bool C.d__0.b" + IL_00fe: brtrue IL_003f + IL_0103: ldnull + IL_0104: throw + } + catch System.Exception + { + IL_0105: stloc.3 + IL_0106: ldarg.0 + IL_0107: ldc.i4.s -2 + IL_0109: stfld "int C.d__0.<>1__state" + IL_010e: ldarg.0 + IL_010f: ldc.i4.0 + IL_0110: stfld "int C.d__0.<>2__current" + IL_0115: ldarg.0 + IL_0116: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_011b: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0120: ldarg.0 + IL_0121: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0126: ldloc.3 + IL_0127: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_012c: leave.s IL_0161 + } + IL_012e: ldarg.0 + IL_012f: ldc.i4.s -2 + IL_0131: stfld "int C.d__0.<>1__state" + IL_0136: ldarg.0 + IL_0137: ldc.i4.0 + IL_0138: stfld "int C.d__0.<>2__current" + IL_013d: ldarg.0 + IL_013e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0143: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0148: ldarg.0 + IL_0149: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_014e: ldc.i4.0 + IL_014f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0154: ret + IL_0155: ldarg.0 + IL_0156: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_015b: ldc.i4.1 + IL_015c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0161: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_EarlyIterationExit() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +await foreach (var value in values) { break; } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + while (b) + { + string values2 = "value "; + yield return 1; + System.Console.Write(values2); + await System.Threading.Tasks.Task.CompletedTask; + throw null; + } + throw null; + } +} +"""; + // Note: hoisted nested local does not get cleared when exiting nested scope with early exit + CompileAndVerify(src, expectedOutput: ExpectedOutput("value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9743,5 +10899,47 @@ .locals init (int V_0, } """); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow_EarlyIterationExit() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); +try +{ + await foreach (var value in values) { break; } // we interrupt the iteration early +} +catch (System.Exception e) +{ + System.Console.Write(e.Message); +} + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) + { + try + { + string values2 = "value "; + await System.Threading.Tasks.Task.CompletedTask; + yield return 42; + values2.ToString(); + throw null; + } + finally + { + throw new System.Exception("exception "); + } + } +} +"""; + // Note: hoisted nested local does not get cleared when exiting loop early + CompileAndVerify(src, expectedOutput: ExpectedOutput("exception value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + } + // TODO2 test that variables aren't clear too soon } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 89482c2907c11..4ec5f8c76ffea 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -6090,7 +6090,134 @@ public static async System.Threading.Tasks.Task ProduceAsync(bool b, System } """; // Note: nested hoisted local gets cleared when exiting nested scope normally - CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), targetFramework: TargetFramework.Net90, verify: Verification.Skipped).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), targetFramework: TargetFramework.Net90, verify: Verification.Skipped).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 293 (0x125) + .maxstack 3 + .locals init (int V_0, + int V_1, + System.Runtime.CompilerServices.TaskAwaiter V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0055 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_00d1 + IL_0011: br.s IL_0091 + IL_0013: ldarg.0 + IL_0014: ldstr "value " + IL_0019: stfld "string C.d__0.5__2" + IL_001e: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0023: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0028: stloc.2 + IL_0029: ldloca.s V_2 + IL_002b: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0030: brtrue.s IL_0071 + IL_0032: ldarg.0 + IL_0033: ldc.i4.0 + IL_0034: dup + IL_0035: stloc.0 + IL_0036: stfld "int C.d__0.<>1__state" + IL_003b: ldarg.0 + IL_003c: ldloc.2 + IL_003d: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0042: ldarg.0 + IL_0043: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" + IL_0048: ldloca.s V_2 + IL_004a: ldarg.0 + IL_004b: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_0050: leave IL_0124 + IL_0055: ldarg.0 + IL_0056: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_005b: stloc.2 + IL_005c: ldarg.0 + IL_005d: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0062: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0068: ldarg.0 + IL_0069: ldc.i4.m1 + IL_006a: dup + IL_006b: stloc.0 + IL_006c: stfld "int C.d__0.<>1__state" + IL_0071: ldloca.s V_2 + IL_0073: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0078: ldarg.0 + IL_0079: ldfld "string C.d__0.5__2" + IL_007e: call "void System.Console.Write(string)" + IL_0083: ldarg.0 + IL_0084: ldc.i4.0 + IL_0085: stfld "bool C.d__0.b" + IL_008a: ldarg.0 + IL_008b: ldnull + IL_008c: stfld "string C.d__0.5__2" + IL_0091: ldarg.0 + IL_0092: ldfld "bool C.d__0.b" + IL_0097: brtrue IL_0013 + IL_009c: ldarg.0 + IL_009d: ldfld "System.Threading.Tasks.Task C.d__0.task" + IL_00a2: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_00a7: stloc.2 + IL_00a8: ldloca.s V_2 + IL_00aa: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_00af: brtrue.s IL_00ed + IL_00b1: ldarg.0 + IL_00b2: ldc.i4.1 + IL_00b3: dup + IL_00b4: stloc.0 + IL_00b5: stfld "int C.d__0.<>1__state" + IL_00ba: ldarg.0 + IL_00bb: ldloc.2 + IL_00bc: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00c1: ldarg.0 + IL_00c2: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" + IL_00c7: ldloca.s V_2 + IL_00c9: ldarg.0 + IL_00ca: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_00cf: leave.s IL_0124 + IL_00d1: ldarg.0 + IL_00d2: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00d7: stloc.2 + IL_00d8: ldarg.0 + IL_00d9: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_00de: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00e4: ldarg.0 + IL_00e5: ldc.i4.m1 + IL_00e6: dup + IL_00e7: stloc.0 + IL_00e8: stfld "int C.d__0.<>1__state" + IL_00ed: ldloca.s V_2 + IL_00ef: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00f4: ldc.i4.s 42 + IL_00f6: stloc.1 + IL_00f7: leave.s IL_0110 + } + catch System.Exception + { + IL_00f9: stloc.3 + IL_00fa: ldarg.0 + IL_00fb: ldc.i4.s -2 + IL_00fd: stfld "int C.d__0.<>1__state" + IL_0102: ldarg.0 + IL_0103: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" + IL_0108: ldloc.3 + IL_0109: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_010e: leave.s IL_0124 + } + IL_0110: ldarg.0 + IL_0111: ldc.i4.s -2 + IL_0113: stfld "int C.d__0.<>1__state" + IL_0118: ldarg.0 + IL_0119: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" + IL_011e: ldloc.1 + IL_011f: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)" + IL_0124: ret +} +"""); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index f4ad723ea8864..dd9166ef1d4fa 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3022,100 +3022,1076 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - CompileAndVerify(src, expectedOutput: "42 42").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "42 42").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 87 (0x57) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0034 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldc.i4.s 42 + IL_001a: stfld "int C.d__0.5__2" + IL_001f: ldarg.0 + IL_0020: ldarg.0 + IL_0021: ldfld "int C.d__0.5__2" + IL_0026: stfld "int C.d__0.<>2__current" + IL_002b: ldarg.0 + IL_002c: ldc.i4.1 + IL_002d: stfld "int C.d__0.<>1__state" + IL_0032: ldc.i4.1 + IL_0033: ret + IL_0034: ldarg.0 + IL_0035: ldc.i4.m1 + IL_0036: stfld "int C.d__0.<>1__state" + IL_003b: ldstr "{0} " + IL_0040: ldarg.0 + IL_0041: ldfld "int C.d__0.5__2" + IL_0046: box "int" + IL_004b: call "string string.Format(string, object)" + IL_0050: call "void System.Console.Write(string)" + IL_0055: ldc.i4.0 + IL_0056: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +foreach (int value in values) { } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + string values2 = "ran"; + yield return 42; + System.Console.Write($"{values2} "); + } +} +"""; + // Note: top-level hoisted local does not get cleared when exiting normally + var verifier = CompileAndVerify(src, expectedOutput: "ran ran").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 81 (0x51) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0033 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldstr "ran" + IL_001d: stfld "string C.d__0.5__2" + IL_0022: ldarg.0 + IL_0023: ldc.i4.s 42 + IL_0025: stfld "int C.d__0.<>2__current" + IL_002a: ldarg.0 + IL_002b: ldc.i4.1 + IL_002c: stfld "int C.d__0.<>1__state" + IL_0031: ldc.i4.1 + IL_0032: ret + IL_0033: ldarg.0 + IL_0034: ldc.i4.m1 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldfld "string C.d__0.5__2" + IL_0040: ldstr " " + IL_0045: call "string string.Concat(string, string)" + IL_004a: call "void System.Console.Write(string)" + IL_004f: ldc.i4.0 + IL_0050: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_YieldBreak() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +foreach (int value in values) { } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + string values2 = "ran"; + yield return 42; + System.Console.Write($"{values2} "); + yield break; + } +} +"""; + // Note: top-level hoisted local does not get cleared when exiting with yield break + var verifier = CompileAndVerify(src, expectedOutput: "ran ran").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 81 (0x51) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0033 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldstr "ran" + IL_001d: stfld "string C.d__0.5__2" + IL_0022: ldarg.0 + IL_0023: ldc.i4.s 42 + IL_0025: stfld "int C.d__0.<>2__current" + IL_002a: ldarg.0 + IL_002b: ldc.i4.1 + IL_002c: stfld "int C.d__0.<>1__state" + IL_0031: ldc.i4.1 + IL_0032: ret + IL_0033: ldarg.0 + IL_0034: ldc.i4.m1 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldfld "string C.d__0.5__2" + IL_0040: ldstr " " + IL_0045: call "string string.Concat(string, string)" + IL_004a: call "void System.Console.Write(string)" + IL_004f: ldc.i4.0 + IL_0050: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_IntArrayLocalAndForeachLocals() + { + string source = """ +using System.Linq; +using System.Reflection; + +var values = C.Produce(); +foreach (int value in values) { } +System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)).Length); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + int[] values2 = Enumerable.Range(0, 100).ToArray(); + yield return 42; + System.Console.Write($"{values2.Length} "); + } +} +"""; + // Note: top-level hoisted local does not get cleared when exiting normally + var comp = CreateCompilation(source); + var verifier = CompileAndVerify(comp, expectedOutput: "100 100").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 96 (0x60) + .maxstack 3 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_003b + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldc.i4.0 + IL_0019: ldc.i4.s 100 + IL_001b: call "System.Collections.Generic.IEnumerable System.Linq.Enumerable.Range(int, int)" + IL_0020: call "int[] System.Linq.Enumerable.ToArray(System.Collections.Generic.IEnumerable)" + IL_0025: stfld "int[] C.d__0.5__2" + IL_002a: ldarg.0 + IL_002b: ldc.i4.s 42 + IL_002d: stfld "int C.d__0.<>2__current" + IL_0032: ldarg.0 + IL_0033: ldc.i4.1 + IL_0034: stfld "int C.d__0.<>1__state" + IL_0039: ldc.i4.1 + IL_003a: ret + IL_003b: ldarg.0 + IL_003c: ldc.i4.m1 + IL_003d: stfld "int C.d__0.<>1__state" + IL_0042: ldstr "{0} " + IL_0047: ldarg.0 + IL_0048: ldfld "int[] C.d__0.5__2" + IL_004d: ldlen + IL_004e: conv.i4 + IL_004f: box "int" + IL_0054: call "string string.Format(string, object)" + IL_0059: call "void System.Console.Write(string)" + IL_005e: ldc.i4.0 + IL_005f: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal() + { + var src = """ +using System.Reflection; + +var enumerable = C.M(true); +var enumerator = enumerable.GetEnumerator(); +try +{ + assert(enumerator.MoveNext()); + System.Console.Write($"{enumerator.Current} "); + assert(!enumerator.MoveNext()); + System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator)) is null); +} +finally +{ + enumerator.Dispose(); +} + +void assert(bool b) +{ + if (!b) throw new System.Exception(); +} + +public class C +{ + public static System.Collections.Generic.IEnumerable M(bool b) + { + while (b) + { + string s = "value "; + yield return 42; + b = false; + System.Console.Write(s); + } + } +} +"""; + // Note: nested hoisted local gets cleared when exiting normally + var verifier = CompileAndVerify(src, expectedOutput: "42 value True").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 95 (0x5f) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0035 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: br.s IL_0055 + IL_0019: ldarg.0 + IL_001a: ldstr "value " + IL_001f: stfld "string C.d__0.5__2" + IL_0024: ldarg.0 + IL_0025: ldc.i4.s 42 + IL_0027: stfld "int C.d__0.<>2__current" + IL_002c: ldarg.0 + IL_002d: ldc.i4.1 + IL_002e: stfld "int C.d__0.<>1__state" + IL_0033: ldc.i4.1 + IL_0034: ret + IL_0035: ldarg.0 + IL_0036: ldc.i4.m1 + IL_0037: stfld "int C.d__0.<>1__state" + IL_003c: ldarg.0 + IL_003d: ldc.i4.0 + IL_003e: stfld "bool C.d__0.b" + IL_0043: ldarg.0 + IL_0044: ldfld "string C.d__0.5__2" + IL_0049: call "void System.Console.Write(string)" + IL_004e: ldarg.0 + IL_004f: ldnull + IL_0050: stfld "string C.d__0.5__2" + IL_0055: ldarg.0 + IL_0056: ldfld "bool C.d__0.b" + IL_005b: brtrue.s IL_0019 + IL_005d: ldc.i4.0 + IL_005e: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_YieldBreak() + { + var src = """ +using System.Reflection; + +var enumerable = C.M(true); +var enumerator = enumerable.GetEnumerator(); +try +{ + assert(enumerator.MoveNext()); + System.Console.Write($"{enumerator.Current} "); + assert(!enumerator.MoveNext()); + System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator))); +} +finally +{ + enumerator.Dispose(); +} +System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator))); + +void assert(bool b) +{ + if (!b) throw new System.Exception(); +} + +public class C +{ + public static System.Collections.Generic.IEnumerable M(bool b) + { + while (b) + { + string s = "value "; + yield return 42; + System.Console.Write(s); + yield break; + } + } +} +"""; + // Note: nested hoisted local does not get cleared when exiting with yield break + var verifier = CompileAndVerify(src, expectedOutput: "42 value value value").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 83 (0x53) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0035 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: br.s IL_0049 + IL_0019: ldarg.0 + IL_001a: ldstr "value " + IL_001f: stfld "string C.d__0.5__2" + IL_0024: ldarg.0 + IL_0025: ldc.i4.s 42 + IL_0027: stfld "int C.d__0.<>2__current" + IL_002c: ldarg.0 + IL_002d: ldc.i4.1 + IL_002e: stfld "int C.d__0.<>1__state" + IL_0033: ldc.i4.1 + IL_0034: ret + IL_0035: ldarg.0 + IL_0036: ldc.i4.m1 + IL_0037: stfld "int C.d__0.<>1__state" + IL_003c: ldarg.0 + IL_003d: ldfld "string C.d__0.5__2" + IL_0042: call "void System.Console.Write(string)" + IL_0047: ldc.i4.0 + IL_0048: ret + IL_0049: ldarg.0 + IL_004a: ldfld "bool C.d__0.b" + IL_004f: brtrue.s IL_0019 + IL_0051: ldc.i4.0 + IL_0052: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_ThrownException() + { + var src = """ +using System.Reflection; + +var enumerable = C.M(true); +var enumerator = enumerable.GetEnumerator(); +try +{ + assert(enumerator.MoveNext()); + System.Console.Write($"{enumerator.Current} "); +} +finally +{ + enumerator.Dispose(); +} +System.Console.Write(((string)enumerable.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerable))); + +void assert(bool b) +{ + if (!b) throw new System.Exception(); +} + +public class C +{ + public static System.Collections.Generic.IEnumerable M(bool b) + { + while (b) + { + string s = "value "; + yield return 42; + System.Console.Write(s); + throw new System.Exception(); + } + } +} +"""; + // Note: nested hoisted local does not get cleared when exiting with thrown exception + CompileAndVerify(src, expectedOutput: "42 value").VerifyDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_IntParameter() + { + string src = """ +using System.Reflection; + +var values = C.Produce(42); +foreach (int value in values) { } +System.Console.Write(((int)values.GetType().GetField("values2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((int)values.GetType().GetField("<>3__values2", BindingFlags.Public | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce(int values2) + { + yield return 0; + System.Console.Write($"{values2} "); + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "42 4242").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 74 (0x4a) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0027 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldc.i4.0 + IL_0019: stfld "int C.d__0.<>2__current" + IL_001e: ldarg.0 + IL_001f: ldc.i4.1 + IL_0020: stfld "int C.d__0.<>1__state" + IL_0025: ldc.i4.1 + IL_0026: ret + IL_0027: ldarg.0 + IL_0028: ldc.i4.m1 + IL_0029: stfld "int C.d__0.<>1__state" + IL_002e: ldstr "{0} " + IL_0033: ldarg.0 + IL_0034: ldfld "int C.d__0.values2" + IL_0039: box "int" + IL_003e: call "string string.Format(string, object)" + IL_0043: call "void System.Console.Write(string)" + IL_0048: ldc.i4.0 + IL_0049: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_ClosureOverLocal() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +foreach (int value in values) { } +var closure = values.GetType().GetField("<>8__1", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values); +System.Console.Write((int)(closure.GetType().GetField("values2", BindingFlags.Public | BindingFlags.Instance).GetValue(closure))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + int values2 = 41; + local(); + yield return 0; + System.Console.Write($"{values2} "); + + void local() + { + values2++; + } + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "42 42").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 103 (0x67) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_003f + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int C.d__0.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldflda "C.<>c__DisplayClass0_0 C.d__0.<>8__1" + IL_001d: ldc.i4.s 41 + IL_001f: stfld "int C.<>c__DisplayClass0_0.values2" + IL_0024: ldarg.0 + IL_0025: ldflda "C.<>c__DisplayClass0_0 C.d__0.<>8__1" + IL_002a: call "void C.g__local|0_0(ref C.<>c__DisplayClass0_0)" + IL_002f: ldarg.0 + IL_0030: ldc.i4.0 + IL_0031: stfld "int C.d__0.<>2__current" + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld "int C.d__0.<>1__state" + IL_003d: ldc.i4.1 + IL_003e: ret + IL_003f: ldarg.0 + IL_0040: ldc.i4.m1 + IL_0041: stfld "int C.d__0.<>1__state" + IL_0046: ldstr "{0} " + IL_004b: ldarg.0 + IL_004c: ldflda "C.<>c__DisplayClass0_0 C.d__0.<>8__1" + IL_0051: ldfld "int C.<>c__DisplayClass0_0.values2" + IL_0056: box "int" + IL_005b: call "string string.Format(string, object)" + IL_0060: call "void System.Console.Write(string)" + IL_0065: ldc.i4.0 + IL_0066: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] - public void AddVariableCleanup_StringLocal() + public void AddVariableCleanup_ClosureOverThis() + { + string src = """ +using System.Reflection; + +class C +{ + int field = 41; + public static void Main() + { + var values = new C().Produce(); + foreach (int value in values) { } + System.Console.Write(((C)values.GetType().GetField("<>4__this", BindingFlags.Public | BindingFlags.Instance).GetValue(values)).field); + } + + private System.Collections.Generic.IEnumerable Produce() + { + local(); + yield return this.field; + + void local() + { + this.field++; + } + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "42").VerifyDiagnostics(); + verifier.VerifyIL("C.d__2.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 66 (0x42) + .maxstack 2 + .locals init (int V_0, + C V_1) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__2.<>1__state" + IL_0006: stloc.0 + IL_0007: ldarg.0 + IL_0008: ldfld "C C.d__2.<>4__this" + IL_000d: stloc.1 + IL_000e: ldloc.0 + IL_000f: brfalse.s IL_0017 + IL_0011: ldloc.0 + IL_0012: ldc.i4.1 + IL_0013: beq.s IL_0039 + IL_0015: ldc.i4.0 + IL_0016: ret + IL_0017: ldarg.0 + IL_0018: ldc.i4.m1 + IL_0019: stfld "int C.d__2.<>1__state" + IL_001e: ldloc.1 + IL_001f: call "void C.g__local|2_0()" + IL_0024: ldarg.0 + IL_0025: ldloc.1 + IL_0026: ldfld "int C.field" + IL_002b: stfld "int C.d__2.<>2__current" + IL_0030: ldarg.0 + IL_0031: ldc.i4.1 + IL_0032: stfld "int C.d__2.<>1__state" + IL_0037: ldc.i4.1 + IL_0038: ret + IL_0039: ldarg.0 + IL_003a: ldc.i4.m1 + IL_003b: stfld "int C.d__2.<>1__state" + IL_0040: ldc.i4.0 + IL_0041: ret +} +"""); + verifier.VerifyIL("C.d__2.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_InTryFinally() { string src = """ using System.Reflection; var values = C.Produce(); foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - string values2 = "ran"; - yield return 42; - System.Console.Write($"{values2} "); + try + { + var values2 = "value "; + yield return 0; + System.Console.Write(values2); + } + finally + { + System.Console.Write("ran "); + } } } """; - // Note: top-level hoisted local does not get cleared when exiting normally - CompileAndVerify(src, expectedOutput: "ran ran").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "value ran True").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 107 (0x6b) + .maxstack 2 + .locals init (bool V_0, + int V_1) + .try + { + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: brfalse.s IL_0012 + IL_000a: ldloc.1 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_003e + IL_000e: ldc.i4.0 + IL_000f: stloc.0 + IL_0010: leave.s IL_0069 + IL_0012: ldarg.0 + IL_0013: ldc.i4.m1 + IL_0014: stfld "int C.d__0.<>1__state" + IL_0019: ldarg.0 + IL_001a: ldc.i4.s -3 + IL_001c: stfld "int C.d__0.<>1__state" + IL_0021: ldarg.0 + IL_0022: ldstr "value " + IL_0027: stfld "string C.d__0.5__2" + IL_002c: ldarg.0 + IL_002d: ldc.i4.0 + IL_002e: stfld "int C.d__0.<>2__current" + IL_0033: ldarg.0 + IL_0034: ldc.i4.1 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldc.i4.1 + IL_003b: stloc.0 + IL_003c: leave.s IL_0069 + IL_003e: ldarg.0 + IL_003f: ldc.i4.s -3 + IL_0041: stfld "int C.d__0.<>1__state" + IL_0046: ldarg.0 + IL_0047: ldfld "string C.d__0.5__2" + IL_004c: call "void System.Console.Write(string)" + IL_0051: ldarg.0 + IL_0052: ldnull + IL_0053: stfld "string C.d__0.5__2" + IL_0058: ldarg.0 + IL_0059: call "void C.d__0.<>m__Finally1()" + IL_005e: ldc.i4.0 + IL_005f: stloc.0 + IL_0060: leave.s IL_0069 + } + fault + { + IL_0062: ldarg.0 + IL_0063: call "void C.d__0.Dispose()" + IL_0068: endfinally + } + IL_0069: ldloc.0 + IL_006a: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 27 (0x1b) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -3 + IL_000a: beq.s IL_0010 + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: bne.un.s IL_001a + IL_0010: nop + .try + { + IL_0011: leave.s IL_001a + } + finally + { + IL_0013: ldarg.0 + IL_0014: call "void C.d__0.<>m__Finally1()" + IL_0019: endfinally + } + IL_001a: ret +} +"""); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] - public void AddVariableCleanup_IntArrayLocalAndForeachLocals() + public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow() { - string source = """ -using System.Linq; + string src = """ using System.Reflection; var values = C.Produce(); -foreach (int value in values) { } -System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)).Length); + +try +{ + foreach (int value in values) { } +} +catch (System.Exception e) +{ + System.Console.Write(e.Message); +} + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - int[] values2 = Enumerable.Range(0, 100).ToArray(); - yield return 42; - System.Console.Write($"{values2.Length} "); + try + { + string values2 = "value "; + yield return 0; + System.Console.Write(values2); + } + finally + { + throw new System.Exception("exception "); + } } } """; - // Note: top-level hoisted local does not get cleared when exiting normally - var comp = CreateCompilation(source); - CompileAndVerify(comp, expectedOutput: "100 100").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "value exception True").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 113 (0x71) + .maxstack 2 + .locals init (bool V_0, + int V_1) + .try + { + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.1 + IL_0007: ldloc.1 + IL_0008: brfalse.s IL_0012 + IL_000a: ldloc.1 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_003e + IL_000e: ldc.i4.0 + IL_000f: stloc.0 + IL_0010: leave.s IL_006f + IL_0012: ldarg.0 + IL_0013: ldc.i4.m1 + IL_0014: stfld "int C.d__0.<>1__state" + IL_0019: ldarg.0 + IL_001a: ldc.i4.s -3 + IL_001c: stfld "int C.d__0.<>1__state" + IL_0021: ldarg.0 + IL_0022: ldstr "value " + IL_0027: stfld "string C.d__0.5__2" + IL_002c: ldarg.0 + IL_002d: ldc.i4.0 + IL_002e: stfld "int C.d__0.<>2__current" + IL_0033: ldarg.0 + IL_0034: ldc.i4.1 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldc.i4.1 + IL_003b: stloc.0 + IL_003c: leave.s IL_006f + IL_003e: ldarg.0 + IL_003f: ldc.i4.s -3 + IL_0041: stfld "int C.d__0.<>1__state" + IL_0046: ldarg.0 + IL_0047: ldfld "string C.d__0.5__2" + IL_004c: call "void System.Console.Write(string)" + IL_0051: ldarg.0 + IL_0052: ldnull + IL_0053: stfld "string C.d__0.5__2" + IL_0058: ldarg.0 + IL_0059: call "void C.d__0.<>m__Finally1()" + IL_005e: leave.s IL_0067 + } + fault + { + IL_0060: ldarg.0 + IL_0061: call "void C.d__0.Dispose()" + IL_0066: endfinally + } + IL_0067: ldarg.0 + IL_0068: call "void C.d__0.Dispose()" + IL_006d: ldc.i4.1 + IL_006e: stloc.0 + IL_006f: ldloc.0 + IL_0070: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 27 (0x1b) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -3 + IL_000a: beq.s IL_0010 + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: bne.un.s IL_001a + IL_0010: nop + .try + { + IL_0011: leave.s IL_001a + } + finally + { + IL_0013: ldarg.0 + IL_0014: call "void C.d__0.<>m__Finally1()" + IL_0019: endfinally + } + IL_001a: ret +} +"""); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] - public void AddVariableCleanup_NestedStringLocal() + public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow_EarlyIterationExit() { - var src = """ + string src = """ using System.Reflection; -var enumerable = C.M(true); -var enumerator = enumerable.GetEnumerator(); +var values = C.Produce(); + try { - assert(enumerator.MoveNext()); - System.Console.Write($"{enumerator.Current} "); - assert(!enumerator.MoveNext()); - System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator)) is null); + foreach (int value in values) { break; } // we interrupt the iteration early } -finally +catch (System.Exception e) { - enumerator.Dispose(); + System.Console.Write(e.Message); } -void assert(bool b) -{ - if (!b) throw new System.Exception(); -} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); -public class C +class C { - public static System.Collections.Generic.IEnumerable M(bool b) + public static System.Collections.Generic.IEnumerable Produce() { - while (b) + try { - string s = "value "; - yield return 42; - b = false; - System.Console.Write(s); + string values2 = "value"; + yield return 0; + values2.ToString(); + throw null; + } + finally + { + throw new System.Exception("exception "); } } } """; - // Note: nested hoisted local gets cleared when exiting normally - CompileAndVerify(src, expectedOutput: "42 value True").VerifyDiagnostics(); + // Note: nested hoisted local does not get cleared when exiting loop early + CompileAndVerify(src, expectedOutput: "exception value").VerifyDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_WithThrownException() + { + string src = """ +using System.Reflection; + +var values = C.Produce(true); + +try +{ + foreach (int value in values) { } +} +catch (System.Exception e) +{ + System.Console.Write(e.Message); +} + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce(bool b) + { + string values2 = "value "; + if (b) throw new System.Exception("exception "); + yield return 0; + System.Console.Write(values2); + } +} +"""; + // Note: top-level hoisted local does not get cleared when exiting with a thrown exception + CompileAndVerify(src, expectedOutput: "exception value").VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -3370,5 +4346,34 @@ public static System.Collections.Generic.IEnumerable M(bool b, T t) wher """; CompileAndVerify(src, expectedOutput: "42 4242").VerifyDiagnostics(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_EarlyIterationExit() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); + +foreach (int value in values) { break; } // we interrupt the iteration early + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + string values2 = "value"; + yield return 0; + values2.ToString(); + throw null; + } +} +"""; + // Note: top-level hoisted local does not get cleared when exiting loop early + CompileAndVerify(src, expectedOutput: "value").VerifyDiagnostics(); + } + + // TODO2 test that variables aren't clear too soon } } From 04902e162b3b90128833fab19fb3fe54b0c5a30b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 11 Nov 2024 18:20:26 -0800 Subject: [PATCH 02/20] Change for iterators and async-iterators --- ...yncIteratorMethodToStateMachineRewriter.cs | 11 + .../AsyncMethodToStateMachineRewriter.cs | 3 +- .../IteratorMethodToStateMachineRewriter.cs | 7 +- .../MethodToStateMachineRewriter.cs | 46 +- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 1121 +++++++++++++---- .../Test/Emit/CodeGen/CodeGenIterators.cs | 475 ++++++- 6 files changed, 1372 insertions(+), 291 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 51cd9ae093a78..d13f2ce0d8c9e 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -88,11 +88,22 @@ internal AsyncIteratorMethodToStateMachineRewriter( return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; } + + protected override BoundStatement GenerateHoistedLocalsCleanup(ImmutableArray hoistedLocals) + { + // We need to clean nested hoisted local variables too (not just top-level ones) + // as they are not cleaned when exiting a block if we exit using a `yield break` + // or if the caller interrupts the enumeration after we reached a `yield return`. + // So we clean both top-level and nested hoisted local variables + return GenerateAllHoistedLocalsCleanup(); + } #nullable disable + protected override BoundStatement GenerateSetResultCall() { // ... _exprReturnLabel: ... // ... this.state = FinishedState; ... + // ... hoisted locals cleanup ... // if (this.combinedTokens != null) { this.combinedTokens.Dispose(); this.combinedTokens = null; } // for enumerables only // _current = default; diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index 43993b7fe05da..01a73a4bcd364 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -258,7 +259,7 @@ protected BoundCatchBlock GenerateExceptionHandling(LocalSymbol exceptionLocal, isSynthesizedAsyncCatchAll: true); } - protected BoundStatement GenerateHoistedLocalsCleanup(ImmutableArray hoistedLocals) + protected virtual BoundStatement GenerateHoistedLocalsCleanup(ImmutableArray hoistedLocals) { var builder = ArrayBuilder.GetInstance(); diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs index 606cde97b5066..bf4c244ea2d67 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs @@ -160,7 +160,11 @@ internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImpleme if (rootFrame.knownStates == null) { // nothing to finalize - F.CloseMethod(F.Return()); + var disposeBody = F.Block( + GenerateAllHoistedLocalsCleanup(), + F.Return()); + + F.CloseMethod(disposeBody); } else { @@ -171,6 +175,7 @@ internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImpleme ImmutableArray.Create(stateLocal), F.Assignment(F.Local(stateLocal), F.Field(F.This(), stateField)), EmitFinallyFrame(rootFrame, state), + GenerateAllHoistedLocalsCleanup(), F.Return()); F.CloseMethod(disposeBody); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 72423cff8f452..fb1be68b0618a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -61,7 +61,7 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter /// Note that there is a dispatch occurring at every try-finally statement, so this /// variable takes on a new set of values inside each try block. /// - private Dictionary> _dispatches = new(); + private Dictionary> _dispatches = new Dictionary>(); /// /// A pool of fields used to hoist locals. They appear in this set when not in scope, @@ -429,6 +429,50 @@ private void AddVariableCleanup(ArrayBuilder cleanup, FieldSymb } } +#nullable enable + protected BoundBlock GenerateAllHoistedLocalsCleanup() + { + var variableCleanup = ArrayBuilder.GetInstance(); + var alreadyCleaned = PooledHashSet.GetInstance(); + foreach (var symbol in HoistedVariables) + { + if (symbol is LocalSymbol + && proxies.TryGetValue(symbol, out CapturedSymbolReplacement? replacement)) + { + Debug.Assert(replacement is CapturedToStateMachineFieldReplacement or CapturedToExpressionSymbolReplacement); + + if (replacement is CapturedToStateMachineFieldReplacement fieldReplacement) + { + addVariableCleanupOnce(variableCleanup, fieldReplacement.HoistedField, alreadyCleaned); + } + else if (replacement is CapturedToExpressionSymbolReplacement expressionReplacement) + { + foreach (var field in expressionReplacement.HoistedFields) + { + addVariableCleanupOnce(variableCleanup, field, alreadyCleaned); + } + } + } + } + + var result = F.Block(variableCleanup.SelectAsArray((e, f) => (BoundStatement)f.ExpressionStatement(e), F)); + + variableCleanup.Free(); + alreadyCleaned.Free(); + + return result; + + void addVariableCleanupOnce(ArrayBuilder variableCleanup, FieldSymbol field, PooledHashSet alreadyCleaned) + { + // Hoisted fields may be re-used, so we can skip those that were cleaed already + if (alreadyCleaned.Add(field.Name)) + { + AddVariableCleanup(variableCleanup, field); + } + } + } +#nullable disable + private StateMachineFieldSymbol GetOrAllocateReusableHoistedField(TypeSymbol type, out bool reused, LocalSymbol local = null) { ArrayBuilder fields; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 00daa6d7d7cb5..bab70b808ac17 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -182,7 +182,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 254 (0xfe) + // Code size 268 (0x10c) .maxstack 3 .locals init (int V_0, System.Exception V_1) @@ -199,7 +199,7 @@ .locals init (int V_0, IL_0010: ldarg.0 IL_0011: ldfld ""bool C.d__1.<>w__disposeMode"" IL_0016: brfalse.s IL_001d - IL_0018: leave IL_00d4 + IL_0018: leave IL_00db IL_001d: ldarg.0 IL_001e: ldc.i4.m1 IL_001f: dup @@ -267,11 +267,11 @@ .locals init (int V_0, IL_0096: ldarg.0 IL_0097: ldfld ""bool C.d__1.<>w__disposeMode"" IL_009c: brfalse.s IL_00a0 - IL_009e: leave.s IL_00d4 + IL_009e: leave.s IL_00db IL_00a0: ldarg.0 IL_00a1: ldc.i4.1 IL_00a2: stfld ""bool C.d__1.<>w__disposeMode"" - IL_00a7: leave.s IL_00d4 + IL_00a7: leave.s IL_00db } catch System.Exception { @@ -281,35 +281,41 @@ .locals init (int V_0, IL_00ad: stfld ""int C.d__1.<>1__state"" IL_00b2: ldarg.0 IL_00b3: ldnull - IL_00b4: stfld ""string C.d__1.<>2__current"" + IL_00b4: stfld ""object C.d__1.<>s__1"" IL_00b9: ldarg.0 - IL_00ba: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" - IL_00bf: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_00c4: nop - IL_00c5: ldarg.0 - IL_00c6: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__1.<>v__promiseOfValueOrEnd"" - IL_00cb: ldloc.1 - IL_00cc: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_00d1: nop - IL_00d2: leave.s IL_00fd + IL_00ba: ldnull + IL_00bb: stfld ""string C.d__1.<>2__current"" + IL_00c0: ldarg.0 + IL_00c1: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" + IL_00c6: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00cb: nop + IL_00cc: ldarg.0 + IL_00cd: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__1.<>v__promiseOfValueOrEnd"" + IL_00d2: ldloc.1 + IL_00d3: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" + IL_00d8: nop + IL_00d9: leave.s IL_010b } - IL_00d4: ldarg.0 - IL_00d5: ldc.i4.s -2 - IL_00d7: stfld ""int C.d__1.<>1__state"" - IL_00dc: ldarg.0 - IL_00dd: ldnull - IL_00de: stfld ""string C.d__1.<>2__current"" + IL_00db: ldarg.0 + IL_00dc: ldc.i4.s -2 + IL_00de: stfld ""int C.d__1.<>1__state"" IL_00e3: ldarg.0 - IL_00e4: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" - IL_00e9: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_00ee: nop - IL_00ef: ldarg.0 - IL_00f0: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__1.<>v__promiseOfValueOrEnd"" - IL_00f5: ldc.i4.0 - IL_00f6: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_00fb: nop - IL_00fc: ret - IL_00fd: ret + IL_00e4: ldnull + IL_00e5: stfld ""object C.d__1.<>s__1"" + IL_00ea: ldarg.0 + IL_00eb: ldnull + IL_00ec: stfld ""string C.d__1.<>2__current"" + IL_00f1: ldarg.0 + IL_00f2: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__1.<>t__builder"" + IL_00f7: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" + IL_00fc: nop + IL_00fd: ldarg.0 + IL_00fe: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__1.<>v__promiseOfValueOrEnd"" + IL_0103: ldc.i4.0 + IL_0104: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" + IL_0109: nop + IL_010a: ret + IL_010b: ret }"); } @@ -9577,7 +9583,7 @@ public void AddVariableCleanup_StringLocal() var values = C.Produce(); await foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -9590,11 +9596,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } } """; - // Note: hoisted top-level local does not get cleared when exiting normally - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 306 (0x132) + // Code size 320 (0x140) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -9617,7 +9622,7 @@ .locals init (int V_0, IL_0024: ldarg.0 IL_0025: ldfld "bool C.d__0.<>w__disposeMode" IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_00fe + IL_002c: leave IL_0105 IL_0031: ldarg.0 IL_0032: ldc.i4.m1 IL_0033: dup @@ -9647,7 +9652,7 @@ .locals init (int V_0, IL_0071: ldloca.s V_1 IL_0073: ldloca.s V_2 IL_0075: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_007a: leave IL_0131 + IL_007a: leave IL_013f IL_007f: ldarg.0 IL_0080: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" IL_0085: stloc.1 @@ -9669,7 +9674,7 @@ .locals init (int V_0, IL_00ac: dup IL_00ad: stloc.0 IL_00ae: stfld "int C.d__0.<>1__state" - IL_00b3: leave.s IL_0125 + IL_00b3: leave.s IL_0133 IL_00b5: ldarg.0 IL_00b6: ldc.i4.m1 IL_00b7: dup @@ -9678,11 +9683,11 @@ .locals init (int V_0, IL_00be: ldarg.0 IL_00bf: ldfld "bool C.d__0.<>w__disposeMode" IL_00c4: brfalse.s IL_00c8 - IL_00c6: leave.s IL_00fe + IL_00c6: leave.s IL_0105 IL_00c8: ldarg.0 IL_00c9: ldfld "string C.d__0.5__2" IL_00ce: call "void System.Console.Write(string)" - IL_00d3: leave.s IL_00fe + IL_00d3: leave.s IL_0105 } catch System.Exception { @@ -9691,36 +9696,42 @@ .locals init (int V_0, IL_00d7: ldc.i4.s -2 IL_00d9: stfld "int C.d__0.<>1__state" IL_00de: ldarg.0 - IL_00df: ldc.i4.0 - IL_00e0: stfld "int C.d__0.<>2__current" + IL_00df: ldnull + IL_00e0: stfld "string C.d__0.5__2" IL_00e5: ldarg.0 - IL_00e6: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00eb: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00f0: ldarg.0 - IL_00f1: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00f6: ldloc.3 - IL_00f7: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_00fc: leave.s IL_0131 + IL_00e6: ldc.i4.0 + IL_00e7: stfld "int C.d__0.<>2__current" + IL_00ec: ldarg.0 + IL_00ed: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00f2: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00f7: ldarg.0 + IL_00f8: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00fd: ldloc.3 + IL_00fe: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0103: leave.s IL_013f } - IL_00fe: ldarg.0 - IL_00ff: ldc.i4.s -2 - IL_0101: stfld "int C.d__0.<>1__state" - IL_0106: ldarg.0 - IL_0107: ldc.i4.0 - IL_0108: stfld "int C.d__0.<>2__current" + IL_0105: ldarg.0 + IL_0106: ldc.i4.s -2 + IL_0108: stfld "int C.d__0.<>1__state" IL_010d: ldarg.0 - IL_010e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0113: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0118: ldarg.0 - IL_0119: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_011e: ldc.i4.0 - IL_011f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0124: ret - IL_0125: ldarg.0 - IL_0126: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_012b: ldc.i4.1 - IL_012c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0131: ret + IL_010e: ldnull + IL_010f: stfld "string C.d__0.5__2" + IL_0114: ldarg.0 + IL_0115: ldc.i4.0 + IL_0116: stfld "int C.d__0.<>2__current" + IL_011b: ldarg.0 + IL_011c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0121: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0126: ldarg.0 + IL_0127: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_012c: ldc.i4.0 + IL_012d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0132: ret + IL_0133: ldarg.0 + IL_0134: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0139: ldc.i4.1 + IL_013a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_013f: ret } """); } @@ -9733,7 +9744,7 @@ public void AddVariableCleanup_StringLocal_YieldBreak() var values = C.Produce(true); await foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -9747,11 +9758,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted top-level local does not get cleared when exiting with yield break - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 252 (0xfc) + // Code size 266 (0x10a) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -9770,7 +9780,7 @@ .locals init (int V_0, IL_000f: ldarg.0 IL_0010: ldfld "bool C.d__0.<>w__disposeMode" IL_0015: brfalse.s IL_001c - IL_0017: leave IL_00d4 + IL_0017: leave IL_00db IL_001c: ldarg.0 IL_001d: ldc.i4.m1 IL_001e: dup @@ -9800,7 +9810,7 @@ .locals init (int V_0, IL_005c: ldloca.s V_1 IL_005e: ldloca.s V_2 IL_0060: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_0065: leave IL_00fb + IL_0065: leave IL_0109 IL_006a: ldarg.0 IL_006b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" IL_0070: stloc.1 @@ -9823,7 +9833,7 @@ .locals init (int V_0, IL_00a0: ldarg.0 IL_00a1: ldc.i4.1 IL_00a2: stfld "bool C.d__0.<>w__disposeMode" - IL_00a7: leave.s IL_00d4 + IL_00a7: leave.s IL_00db IL_00a9: ldnull IL_00aa: throw } @@ -9834,32 +9844,38 @@ .locals init (int V_0, IL_00ad: ldc.i4.s -2 IL_00af: stfld "int C.d__0.<>1__state" IL_00b4: ldarg.0 - IL_00b5: ldc.i4.0 - IL_00b6: stfld "int C.d__0.<>2__current" + IL_00b5: ldnull + IL_00b6: stfld "string C.d__0.5__2" IL_00bb: ldarg.0 - IL_00bc: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00c1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00c6: ldarg.0 - IL_00c7: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00cc: ldloc.3 - IL_00cd: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_00d2: leave.s IL_00fb + IL_00bc: ldc.i4.0 + IL_00bd: stfld "int C.d__0.<>2__current" + IL_00c2: ldarg.0 + IL_00c3: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00c8: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00cd: ldarg.0 + IL_00ce: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00d3: ldloc.3 + IL_00d4: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_00d9: leave.s IL_0109 } - IL_00d4: ldarg.0 - IL_00d5: ldc.i4.s -2 - IL_00d7: stfld "int C.d__0.<>1__state" - IL_00dc: ldarg.0 - IL_00dd: ldc.i4.0 - IL_00de: stfld "int C.d__0.<>2__current" + IL_00db: ldarg.0 + IL_00dc: ldc.i4.s -2 + IL_00de: stfld "int C.d__0.<>1__state" IL_00e3: ldarg.0 - IL_00e4: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00e9: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00ee: ldarg.0 - IL_00ef: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00f4: ldc.i4.0 - IL_00f5: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_00fa: ret - IL_00fb: ret + IL_00e4: ldnull + IL_00e5: stfld "string C.d__0.5__2" + IL_00ea: ldarg.0 + IL_00eb: ldc.i4.0 + IL_00ec: stfld "int C.d__0.<>2__current" + IL_00f1: ldarg.0 + IL_00f2: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00f7: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + 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: ret } """); } @@ -9880,7 +9896,7 @@ public void AddVariableCleanup_StringLocal_ThrownException() System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -9894,11 +9910,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted top-level local does not get cleared when exiting from thrown exception - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 261 (0x105) + // Code size 275 (0x113) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -9917,7 +9932,7 @@ .locals init (int V_0, IL_000f: ldarg.0 IL_0010: ldfld "bool C.d__0.<>w__disposeMode" IL_0015: brfalse.s IL_001c - IL_0017: leave IL_00dd + IL_0017: leave IL_00e4 IL_001c: ldarg.0 IL_001d: ldc.i4.m1 IL_001e: dup @@ -9947,7 +9962,7 @@ .locals init (int V_0, IL_005c: ldloca.s V_1 IL_005e: ldloca.s V_2 IL_0060: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_0065: leave IL_0104 + IL_0065: leave IL_0112 IL_006a: ldarg.0 IL_006b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" IL_0070: stloc.1 @@ -9973,7 +9988,7 @@ .locals init (int V_0, IL_00ab: ldarg.0 IL_00ac: ldc.i4.1 IL_00ad: stfld "bool C.d__0.<>w__disposeMode" - IL_00b2: leave.s IL_00dd + IL_00b2: leave.s IL_00e4 } catch System.Exception { @@ -9982,32 +9997,38 @@ .locals init (int V_0, IL_00b6: ldc.i4.s -2 IL_00b8: stfld "int C.d__0.<>1__state" IL_00bd: ldarg.0 - IL_00be: ldc.i4.0 - IL_00bf: stfld "int C.d__0.<>2__current" + IL_00be: ldnull + IL_00bf: stfld "string C.d__0.5__2" IL_00c4: ldarg.0 - IL_00c5: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00ca: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00cf: ldarg.0 - IL_00d0: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00d5: ldloc.3 - IL_00d6: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_00db: leave.s IL_0104 + IL_00c5: ldc.i4.0 + IL_00c6: stfld "int C.d__0.<>2__current" + IL_00cb: ldarg.0 + IL_00cc: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00d1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00d6: ldarg.0 + IL_00d7: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00dc: ldloc.3 + IL_00dd: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_00e2: leave.s IL_0112 } - IL_00dd: ldarg.0 - IL_00de: ldc.i4.s -2 - IL_00e0: stfld "int C.d__0.<>1__state" - IL_00e5: ldarg.0 - IL_00e6: ldc.i4.0 - IL_00e7: stfld "int C.d__0.<>2__current" + IL_00e4: ldarg.0 + IL_00e5: ldc.i4.s -2 + IL_00e7: stfld "int C.d__0.<>1__state" IL_00ec: ldarg.0 - IL_00ed: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00f2: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00f7: ldarg.0 - IL_00f8: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00fd: ldc.i4.0 - IL_00fe: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0103: ret - IL_0104: ret + IL_00ed: ldnull + IL_00ee: stfld "string C.d__0.5__2" + IL_00f3: ldarg.0 + IL_00f4: ldc.i4.0 + IL_00f5: stfld "int C.d__0.<>2__current" + IL_00fa: ldarg.0 + IL_00fb: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0100: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0105: ldarg.0 + IL_0106: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_010b: ldc.i4.0 + IL_010c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0111: ret + IL_0112: ret } """); } @@ -10020,7 +10041,7 @@ public void AddVariableCleanup_StringLocal_EarlyIterationExit() var values = C.Produce(true); await foreach (var value in values) { break; } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -10029,12 +10050,11 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo string values2 = "value "; await System.Threading.Tasks.Task.CompletedTask; yield return 42; - System.Console.Write(values2); + _ = values2.ToString(); } } """; - // Note: hoisted top-level local does not get cleared when exiting loop early - CompileAndVerify(src, expectedOutput: ExpectedOutput("value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10076,11 +10096,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted nested local gets cleared when exiting nested scope normally var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 424 (0x1a8) + // Code size 438 (0x1b6) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -10105,7 +10124,7 @@ .locals init (int V_0, IL_002c: ldarg.0 IL_002d: ldfld "bool C.d__0.<>w__disposeMode" IL_0032: brfalse.s IL_0039 - IL_0034: leave IL_0174 + IL_0034: leave IL_017b IL_0039: ldarg.0 IL_003a: ldc.i4.m1 IL_003b: dup @@ -10123,7 +10142,7 @@ .locals init (int V_0, IL_0059: dup IL_005a: stloc.0 IL_005b: stfld "int C.d__0.<>1__state" - IL_0060: leave IL_019b + IL_0060: leave IL_01a9 IL_0065: ldarg.0 IL_0066: ldc.i4.m1 IL_0067: dup @@ -10132,7 +10151,7 @@ .locals init (int V_0, IL_006e: ldarg.0 IL_006f: ldfld "bool C.d__0.<>w__disposeMode" IL_0074: brfalse.s IL_007b - IL_0076: leave IL_0174 + IL_0076: leave IL_017b IL_007b: ldarg.0 IL_007c: ldfld "string C.d__0.5__2" IL_0081: call "void System.Console.Write(string)" @@ -10153,7 +10172,7 @@ .locals init (int V_0, IL_00a6: dup IL_00a7: stloc.0 IL_00a8: stfld "int C.d__0.<>1__state" - IL_00ad: leave IL_019b + IL_00ad: leave IL_01a9 IL_00b2: ldarg.0 IL_00b3: ldc.i4.m1 IL_00b4: dup @@ -10162,7 +10181,7 @@ .locals init (int V_0, IL_00bb: ldarg.0 IL_00bc: ldfld "bool C.d__0.<>w__disposeMode" IL_00c1: brfalse.s IL_00c8 - IL_00c3: leave IL_0174 + IL_00c3: leave IL_017b IL_00c8: ldarg.0 IL_00c9: ldfld "System.Threading.Tasks.Task C.d__0.task" IL_00ce: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" @@ -10185,7 +10204,7 @@ .locals init (int V_0, IL_00f5: ldloca.s V_1 IL_00f7: ldloca.s V_2 IL_00f9: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00fe: leave IL_01a7 + IL_00fe: leave IL_01b5 IL_0103: ldarg.0 IL_0104: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" IL_0109: stloc.1 @@ -10207,7 +10226,7 @@ .locals init (int V_0, IL_0130: dup IL_0131: stloc.0 IL_0132: stfld "int C.d__0.<>1__state" - IL_0137: leave.s IL_019b + IL_0137: leave.s IL_01a9 IL_0139: ldarg.0 IL_013a: ldc.i4.m1 IL_013b: dup @@ -10216,7 +10235,7 @@ .locals init (int V_0, IL_0142: ldarg.0 IL_0143: ldfld "bool C.d__0.<>w__disposeMode" IL_0148: pop - IL_0149: leave.s IL_0174 + IL_0149: leave.s IL_017b } catch System.Exception { @@ -10225,36 +10244,42 @@ .locals init (int V_0, IL_014d: ldc.i4.s -2 IL_014f: stfld "int C.d__0.<>1__state" IL_0154: ldarg.0 - IL_0155: ldc.i4.0 - IL_0156: stfld "int C.d__0.<>2__current" + IL_0155: ldnull + IL_0156: stfld "string C.d__0.5__2" IL_015b: ldarg.0 - IL_015c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0161: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0166: ldarg.0 - IL_0167: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_016c: ldloc.3 - IL_016d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0172: leave.s IL_01a7 + IL_015c: ldc.i4.0 + IL_015d: stfld "int C.d__0.<>2__current" + IL_0162: ldarg.0 + IL_0163: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0168: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_016d: ldarg.0 + IL_016e: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0173: ldloc.3 + IL_0174: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0179: leave.s IL_01b5 } - IL_0174: ldarg.0 - IL_0175: ldc.i4.s -2 - IL_0177: stfld "int C.d__0.<>1__state" - IL_017c: ldarg.0 - IL_017d: ldc.i4.0 - IL_017e: stfld "int C.d__0.<>2__current" + IL_017b: ldarg.0 + IL_017c: ldc.i4.s -2 + IL_017e: stfld "int C.d__0.<>1__state" IL_0183: ldarg.0 - IL_0184: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0189: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_018e: ldarg.0 - IL_018f: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0194: ldc.i4.0 - IL_0195: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_019a: ret - IL_019b: ldarg.0 - IL_019c: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_01a1: ldc.i4.1 - IL_01a2: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_01a7: ret + IL_0184: ldnull + IL_0185: stfld "string C.d__0.5__2" + IL_018a: ldarg.0 + IL_018b: ldc.i4.0 + IL_018c: stfld "int C.d__0.<>2__current" + IL_0191: ldarg.0 + IL_0192: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0197: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_019c: ldarg.0 + IL_019d: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_01a2: ldc.i4.0 + IL_01a3: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_01a8: ret + IL_01a9: ldarg.0 + IL_01aa: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_01af: ldc.i4.1 + IL_01b0: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_01b5: ret } """); } @@ -10271,7 +10296,7 @@ public void AddVariableCleanup_NestedStringLocal_YieldBreak() assert(enumerator.Current == 1); assert(!(await enumerator.MoveNextAsync())); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); void assert(bool b) { @@ -10294,11 +10319,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted nested local does not get cleared when exiting nested scope with yield break - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 352 (0x160) + // Code size 366 (0x16e) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -10321,7 +10345,7 @@ .locals init (int V_0, IL_0024: ldarg.0 IL_0025: ldfld "bool C.d__0.<>w__disposeMode" IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_012c + IL_002c: leave IL_0133 IL_0031: ldarg.0 IL_0032: ldc.i4.m1 IL_0033: dup @@ -10339,7 +10363,7 @@ .locals init (int V_0, IL_0054: dup IL_0055: stloc.0 IL_0056: stfld "int C.d__0.<>1__state" - IL_005b: leave IL_0153 + IL_005b: leave IL_0161 IL_0060: ldarg.0 IL_0061: ldc.i4.m1 IL_0062: dup @@ -10348,7 +10372,7 @@ .locals init (int V_0, IL_0069: ldarg.0 IL_006a: ldfld "bool C.d__0.<>w__disposeMode" IL_006f: brfalse.s IL_0076 - IL_0071: leave IL_012c + IL_0071: leave IL_0133 IL_0076: ldarg.0 IL_0077: ldfld "string C.d__0.5__2" IL_007c: call "void System.Console.Write(string)" @@ -10373,7 +10397,7 @@ .locals init (int V_0, IL_00ad: ldloca.s V_1 IL_00af: ldloca.s V_2 IL_00b1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00b6: leave IL_015f + IL_00b6: leave IL_016d IL_00bb: ldarg.0 IL_00bc: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" IL_00c1: stloc.1 @@ -10393,7 +10417,7 @@ .locals init (int V_0, IL_00e6: ldarg.0 IL_00e7: ldc.i4.1 IL_00e8: stfld "bool C.d__0.<>w__disposeMode" - IL_00ed: leave.s IL_012c + IL_00ed: leave.s IL_0133 IL_00ef: ldarg.0 IL_00f0: ldnull IL_00f1: stfld "string C.d__0.5__2" @@ -10410,36 +10434,42 @@ .locals init (int V_0, IL_0105: ldc.i4.s -2 IL_0107: stfld "int C.d__0.<>1__state" IL_010c: ldarg.0 - IL_010d: ldc.i4.0 - IL_010e: stfld "int C.d__0.<>2__current" + IL_010d: ldnull + IL_010e: stfld "string C.d__0.5__2" 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: ldarg.0 - IL_011f: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0124: ldloc.3 - IL_0125: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_012a: leave.s IL_015f + IL_0114: ldc.i4.0 + IL_0115: stfld "int C.d__0.<>2__current" + IL_011a: ldarg.0 + IL_011b: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0120: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0125: ldarg.0 + IL_0126: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_012b: ldloc.3 + IL_012c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0131: leave.s IL_016d } - IL_012c: ldarg.0 - IL_012d: ldc.i4.s -2 - IL_012f: stfld "int C.d__0.<>1__state" - IL_0134: ldarg.0 - IL_0135: ldc.i4.0 - IL_0136: stfld "int C.d__0.<>2__current" + IL_0133: ldarg.0 + IL_0134: ldc.i4.s -2 + IL_0136: stfld "int C.d__0.<>1__state" IL_013b: ldarg.0 - IL_013c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0141: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0146: ldarg.0 - IL_0147: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_014c: ldc.i4.0 - IL_014d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0152: ret - IL_0153: ldarg.0 - IL_0154: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0159: ldc.i4.1 - IL_015a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_015f: ret + IL_013c: ldnull + IL_013d: stfld "string C.d__0.5__2" + IL_0142: ldarg.0 + IL_0143: ldc.i4.0 + IL_0144: stfld "int C.d__0.<>2__current" + IL_0149: ldarg.0 + IL_014a: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_014f: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0154: ldarg.0 + IL_0155: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_015a: ldc.i4.0 + IL_015b: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0160: ret + IL_0161: ldarg.0 + IL_0162: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0167: ldc.i4.1 + IL_0168: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_016d: ret } """); } @@ -10462,8 +10492,9 @@ public void AddVariableCleanup_NestedStringLocal_ThrownException() { System.Console.Write(e.Message); } +await enumerator.DisposeAsync(); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); void assert(bool b) { @@ -10486,11 +10517,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted nested local does not get cleared when exiting nested scope with thrown exception - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { - // Code size 354 (0x162) + // Code size 368 (0x170) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -10513,7 +10543,7 @@ .locals init (int V_0, IL_0024: ldarg.0 IL_0025: ldfld "bool C.d__0.<>w__disposeMode" IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_012e + IL_002c: leave IL_0135 IL_0031: ldarg.0 IL_0032: ldc.i4.m1 IL_0033: dup @@ -10531,7 +10561,7 @@ .locals init (int V_0, IL_0054: dup IL_0055: stloc.0 IL_0056: stfld "int C.d__0.<>1__state" - IL_005b: leave IL_0155 + IL_005b: leave IL_0163 IL_0060: ldarg.0 IL_0061: ldc.i4.m1 IL_0062: dup @@ -10540,7 +10570,7 @@ .locals init (int V_0, IL_0069: ldarg.0 IL_006a: ldfld "bool C.d__0.<>w__disposeMode" IL_006f: brfalse.s IL_0076 - IL_0071: leave IL_012e + IL_0071: leave IL_0135 IL_0076: ldarg.0 IL_0077: ldfld "string C.d__0.5__2" IL_007c: call "void System.Console.Write(string)" @@ -10565,7 +10595,7 @@ .locals init (int V_0, IL_00ad: ldloca.s V_1 IL_00af: ldloca.s V_2 IL_00b1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00b6: leave IL_0161 + IL_00b6: leave IL_016f IL_00bb: ldarg.0 IL_00bc: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" IL_00c1: stloc.1 @@ -10601,36 +10631,42 @@ .locals init (int V_0, IL_0107: ldc.i4.s -2 IL_0109: stfld "int C.d__0.<>1__state" IL_010e: ldarg.0 - IL_010f: ldc.i4.0 - IL_0110: stfld "int C.d__0.<>2__current" + IL_010f: ldnull + IL_0110: stfld "string C.d__0.5__2" IL_0115: ldarg.0 - IL_0116: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_011b: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0120: ldarg.0 - IL_0121: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0126: ldloc.3 - IL_0127: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_012c: leave.s IL_0161 + IL_0116: ldc.i4.0 + IL_0117: stfld "int C.d__0.<>2__current" + IL_011c: ldarg.0 + IL_011d: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0122: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0127: ldarg.0 + IL_0128: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_012d: ldloc.3 + IL_012e: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0133: leave.s IL_016f } - IL_012e: ldarg.0 - IL_012f: ldc.i4.s -2 - IL_0131: stfld "int C.d__0.<>1__state" - IL_0136: ldarg.0 - IL_0137: ldc.i4.0 - IL_0138: stfld "int C.d__0.<>2__current" + IL_0135: ldarg.0 + IL_0136: ldc.i4.s -2 + IL_0138: stfld "int C.d__0.<>1__state" IL_013d: ldarg.0 - IL_013e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0143: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0148: ldarg.0 - IL_0149: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_014e: ldc.i4.0 - IL_014f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0154: ret - IL_0155: ldarg.0 - IL_0156: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_015b: ldc.i4.1 - IL_015c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0161: ret + IL_013e: ldnull + IL_013f: stfld "string C.d__0.5__2" + IL_0144: ldarg.0 + IL_0145: ldc.i4.0 + IL_0146: stfld "int C.d__0.<>2__current" + IL_014b: ldarg.0 + IL_014c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0151: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0156: ldarg.0 + IL_0157: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_015c: ldc.i4.0 + IL_015d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0162: ret + IL_0163: ldarg.0 + IL_0164: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0169: ldc.i4.1 + IL_016a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_016f: ret } """); } @@ -10643,7 +10679,7 @@ public void AddVariableCleanup_NestedStringLocal_EarlyIterationExit() var values = C.Produce(true); await foreach (var value in values) { break; } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -10661,8 +10697,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted nested local does not get cleared when exiting nested scope with early exit - CompileAndVerify(src, expectedOutput: ExpectedOutput("value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10916,7 +10951,7 @@ public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow_EarlyIte System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -10937,9 +10972,605 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - // Note: hoisted nested local does not get cleared when exiting loop early - CompileAndVerify(src, expectedOutput: ExpectedOutput("exception value"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_IAsyncEnumerator() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +assert(await values.MoveNextAsync()); +assert(values.Current == 1); +assert(!(await values.MoveNextAsync())); +await values.DisposeAsync(); + +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +static void assert(bool b) { if (!b) throw new System.Exception(); } + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerator Produce() + { + string values2 = "value "; + await System.Threading.Tasks.Task.CompletedTask; + yield return 1; + System.Console.Write(values2); + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 320 (0x140) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_00b5, + IL_0024, + IL_0024, + IL_0024, + IL_007f) + IL_0024: ldarg.0 + IL_0025: ldfld "bool C.d__0.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_0105 + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldstr "value " + IL_0040: stfld "string C.d__0.5__2" + IL_0045: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_004a: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_004f: stloc.1 + IL_0050: ldloca.s V_1 + IL_0052: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0057: brtrue.s IL_009b + IL_0059: ldarg.0 + IL_005a: ldc.i4.0 + IL_005b: dup + IL_005c: stloc.0 + IL_005d: stfld "int C.d__0.<>1__state" + IL_0062: ldarg.0 + IL_0063: ldloc.1 + IL_0064: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0069: ldarg.0 + IL_006a: stloc.2 + IL_006b: ldarg.0 + IL_006c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0071: ldloca.s V_1 + IL_0073: ldloca.s V_2 + IL_0075: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_007a: leave IL_013f + IL_007f: ldarg.0 + IL_0080: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0085: stloc.1 + IL_0086: ldarg.0 + IL_0087: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_008c: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0092: ldarg.0 + IL_0093: ldc.i4.m1 + IL_0094: dup + IL_0095: stloc.0 + IL_0096: stfld "int C.d__0.<>1__state" + IL_009b: ldloca.s V_1 + IL_009d: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00a2: ldarg.0 + IL_00a3: ldc.i4.1 + IL_00a4: stfld "int C.d__0.<>2__current" + IL_00a9: ldarg.0 + IL_00aa: ldc.i4.s -4 + IL_00ac: dup + IL_00ad: stloc.0 + IL_00ae: stfld "int C.d__0.<>1__state" + IL_00b3: leave.s IL_0133 + IL_00b5: ldarg.0 + IL_00b6: ldc.i4.m1 + IL_00b7: dup + IL_00b8: stloc.0 + IL_00b9: stfld "int C.d__0.<>1__state" + IL_00be: ldarg.0 + IL_00bf: ldfld "bool C.d__0.<>w__disposeMode" + IL_00c4: brfalse.s IL_00c8 + IL_00c6: leave.s IL_0105 + IL_00c8: ldarg.0 + IL_00c9: ldfld "string C.d__0.5__2" + IL_00ce: call "void System.Console.Write(string)" + IL_00d3: leave.s IL_0105 + } + catch System.Exception + { + IL_00d5: stloc.3 + IL_00d6: ldarg.0 + IL_00d7: ldc.i4.s -2 + IL_00d9: stfld "int C.d__0.<>1__state" + IL_00de: ldarg.0 + IL_00df: ldnull + IL_00e0: stfld "string C.d__0.5__2" + IL_00e5: ldarg.0 + IL_00e6: ldc.i4.0 + IL_00e7: stfld "int C.d__0.<>2__current" + IL_00ec: ldarg.0 + IL_00ed: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_00f2: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_00f7: ldarg.0 + IL_00f8: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_00fd: ldloc.3 + IL_00fe: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0103: leave.s IL_013f + } + IL_0105: ldarg.0 + IL_0106: ldc.i4.s -2 + IL_0108: stfld "int C.d__0.<>1__state" + IL_010d: ldarg.0 + IL_010e: ldnull + IL_010f: stfld "string C.d__0.5__2" + IL_0114: ldarg.0 + IL_0115: ldc.i4.0 + IL_0116: stfld "int C.d__0.<>2__current" + IL_011b: ldarg.0 + IL_011c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0121: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0126: ldarg.0 + IL_0127: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_012c: ldc.i4.0 + IL_012d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0132: ret + IL_0133: ldarg.0 + IL_0134: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_0139: ldc.i4.1 + IL_013a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_013f: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NotCleanedTooSoon() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +await foreach (int i in values) { break; } +System.Console.Write((values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce() + { + try + { + string values2 = "value "; + try + { + await System.Threading.Tasks.Task.CompletedTask; + yield return 42; + } + finally + { + System.Console.Write(values2); + } + } + finally + { + System.Console.Write("outer "); + } + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value outer True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 385 (0x181) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + C.d__0 V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_003a, + IL_0024, + IL_0024, + IL_0024, + IL_003a) + IL_0024: ldarg.0 + IL_0025: ldfld "bool C.d__0.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_0146 + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.d__0.<>1__state" + IL_003a: nop + .try + { + IL_003b: ldloc.0 + IL_003c: ldc.i4.s -4 + IL_003e: beq.s IL_004e + IL_0040: ldloc.0 + IL_0041: brfalse.s IL_004e + IL_0043: ldarg.0 + IL_0044: ldstr "value " + IL_0049: stfld "string C.d__0.5__2" + IL_004e: nop + .try + { + IL_004f: ldloc.0 + IL_0050: ldc.i4.s -4 + IL_0052: beq.s IL_00cb + IL_0054: ldloc.0 + IL_0055: brfalse.s IL_0091 + IL_0057: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_005c: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0061: stloc.1 + IL_0062: ldloca.s V_1 + IL_0064: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0069: brtrue.s IL_00ad + IL_006b: ldarg.0 + IL_006c: ldc.i4.0 + IL_006d: dup + IL_006e: stloc.0 + IL_006f: stfld "int C.d__0.<>1__state" + IL_0074: ldarg.0 + IL_0075: ldloc.1 + IL_0076: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_007b: ldarg.0 + IL_007c: stloc.2 + IL_007d: ldarg.0 + IL_007e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0083: ldloca.s V_1 + IL_0085: ldloca.s V_2 + IL_0087: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" + IL_008c: leave IL_0180 + IL_0091: ldarg.0 + IL_0092: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_0097: stloc.1 + IL_0098: ldarg.0 + IL_0099: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" + IL_009e: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00a4: ldarg.0 + IL_00a5: ldc.i4.m1 + IL_00a6: dup + IL_00a7: stloc.0 + IL_00a8: stfld "int C.d__0.<>1__state" + IL_00ad: ldloca.s V_1 + IL_00af: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00b4: ldarg.0 + IL_00b5: ldc.i4.s 42 + IL_00b7: stfld "int C.d__0.<>2__current" + IL_00bc: ldarg.0 + IL_00bd: ldc.i4.s -4 + IL_00bf: dup + IL_00c0: stloc.0 + IL_00c1: stfld "int C.d__0.<>1__state" + IL_00c6: leave IL_0174 + IL_00cb: ldarg.0 + IL_00cc: ldc.i4.m1 + IL_00cd: dup + IL_00ce: stloc.0 + IL_00cf: stfld "int C.d__0.<>1__state" + IL_00d4: ldarg.0 + IL_00d5: ldfld "bool C.d__0.<>w__disposeMode" + IL_00da: pop + IL_00db: leave.s IL_00ed + } + finally + { + IL_00dd: ldloc.0 + IL_00de: ldc.i4.m1 + IL_00df: bne.un.s IL_00ec + IL_00e1: ldarg.0 + IL_00e2: ldfld "string C.d__0.5__2" + IL_00e7: call "void System.Console.Write(string)" + IL_00ec: endfinally + } + IL_00ed: ldarg.0 + IL_00ee: ldfld "bool C.d__0.<>w__disposeMode" + IL_00f3: brtrue.s IL_00fc + IL_00f5: ldarg.0 + IL_00f6: ldnull + IL_00f7: stfld "string C.d__0.5__2" + IL_00fc: leave.s IL_010d + } + finally + { + IL_00fe: ldloc.0 + IL_00ff: ldc.i4.m1 + IL_0100: bne.un.s IL_010c + IL_0102: ldstr "outer " + IL_0107: call "void System.Console.Write(string)" + IL_010c: endfinally + } + IL_010d: ldarg.0 + IL_010e: ldfld "bool C.d__0.<>w__disposeMode" + IL_0113: pop + IL_0114: leave.s IL_0146 + } + catch System.Exception + { + IL_0116: stloc.3 + IL_0117: ldarg.0 + IL_0118: ldc.i4.s -2 + IL_011a: stfld "int C.d__0.<>1__state" + IL_011f: ldarg.0 + IL_0120: ldnull + IL_0121: stfld "string C.d__0.5__2" + IL_0126: ldarg.0 + IL_0127: ldc.i4.0 + IL_0128: stfld "int C.d__0.<>2__current" + IL_012d: ldarg.0 + IL_012e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0133: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0138: ldarg.0 + IL_0139: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_013e: ldloc.3 + IL_013f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0144: leave.s IL_0180 + } + IL_0146: ldarg.0 + IL_0147: ldc.i4.s -2 + IL_0149: stfld "int C.d__0.<>1__state" + IL_014e: ldarg.0 + IL_014f: ldnull + IL_0150: stfld "string C.d__0.5__2" + IL_0155: ldarg.0 + IL_0156: ldc.i4.0 + IL_0157: stfld "int C.d__0.<>2__current" + IL_015c: ldarg.0 + IL_015d: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" + IL_0162: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0167: ldarg.0 + IL_0168: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_016d: ldc.i4.0 + IL_016e: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0173: ret + IL_0174: ldarg.0 + IL_0175: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" + IL_017a: ldc.i4.1 + IL_017b: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0180: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_HoistedFromRefExpression() + { + string src = """ +using System.Reflection; + +var c = new C(); +var values = Program.Produce(c); +await foreach (int i in values) { System.Console.Write(i); } +System.Console.Write((values.GetType().GetField("<>7__wrap3", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +partial class Program +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(C x) + { + int i = 0; + foreach (var y in x.F) + { + await System.Threading.Tasks.Task.CompletedTask; + yield return i++; + } + } +} + +class C +{ + public Buffer4 F = default; +} + +[System.Runtime.CompilerServices.InlineArray(4)] +public struct Buffer4 +{ + private T _element0; +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("0123True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + verifier.VerifyIL("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 418 (0x1a2) + .maxstack 4 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + Program.d__1 V_2, + int V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.d__1.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_00ff, + IL_0024, + IL_0024, + IL_0024, + IL_00b6) + IL_0024: ldarg.0 + IL_0025: ldfld "bool Program.d__1.<>w__disposeMode" + IL_002a: brfalse.s IL_0031 + IL_002c: leave IL_0167 + IL_0031: ldarg.0 + IL_0032: ldc.i4.m1 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int Program.d__1.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldc.i4.0 + IL_003c: stfld "int Program.d__1.5__2" + IL_0041: ldarg.0 + IL_0042: ldarg.0 + IL_0043: ldfld "C Program.d__1.x" + IL_0048: stfld "C Program.d__1.<>7__wrap3" + IL_004d: ldarg.0 + IL_004e: ldfld "C Program.d__1.<>7__wrap3" + IL_0053: ldfld "Buffer4 C.F" + IL_0058: pop + IL_0059: ldarg.0 + IL_005a: ldc.i4.0 + IL_005b: stfld "int Program.d__1.<>7__wrap2" + IL_0060: br IL_0120 + IL_0065: ldarg.0 + IL_0066: ldfld "C Program.d__1.<>7__wrap3" + IL_006b: ldflda "Buffer4 C.F" + IL_0070: ldarg.0 + IL_0071: ldfld "int Program.d__1.<>7__wrap2" + IL_0076: call "ref int .InlineArrayElementRef, int>(ref Buffer4, int)" + IL_007b: pop + IL_007c: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0081: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0086: stloc.1 + IL_0087: ldloca.s V_1 + IL_0089: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_008e: brtrue.s IL_00d2 + IL_0090: ldarg.0 + IL_0091: ldc.i4.0 + IL_0092: dup + IL_0093: stloc.0 + IL_0094: stfld "int Program.d__1.<>1__state" + IL_0099: ldarg.0 + IL_009a: ldloc.1 + IL_009b: stfld "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" + IL_00a0: ldarg.0 + IL_00a1: stloc.2 + IL_00a2: ldarg.0 + IL_00a3: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_00a8: ldloca.s V_1 + IL_00aa: ldloca.s V_2 + IL_00ac: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__1)" + IL_00b1: leave IL_01a1 + IL_00b6: ldarg.0 + IL_00b7: ldfld "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" + IL_00bc: stloc.1 + IL_00bd: ldarg.0 + IL_00be: ldflda "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" + IL_00c3: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00c9: ldarg.0 + IL_00ca: ldc.i4.m1 + IL_00cb: dup + IL_00cc: stloc.0 + IL_00cd: stfld "int Program.d__1.<>1__state" + IL_00d2: ldloca.s V_1 + IL_00d4: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00d9: ldarg.0 + IL_00da: ldarg.0 + IL_00db: ldfld "int Program.d__1.5__2" + IL_00e0: stloc.3 + IL_00e1: ldarg.0 + IL_00e2: ldloc.3 + IL_00e3: ldc.i4.1 + IL_00e4: add + IL_00e5: stfld "int Program.d__1.5__2" + IL_00ea: ldloc.3 + IL_00eb: stfld "int Program.d__1.<>2__current" + IL_00f0: ldarg.0 + IL_00f1: ldc.i4.s -4 + IL_00f3: dup + IL_00f4: stloc.0 + IL_00f5: stfld "int Program.d__1.<>1__state" + IL_00fa: leave IL_0195 + IL_00ff: ldarg.0 + IL_0100: ldc.i4.m1 + IL_0101: dup + IL_0102: stloc.0 + IL_0103: stfld "int Program.d__1.<>1__state" + IL_0108: ldarg.0 + IL_0109: ldfld "bool Program.d__1.<>w__disposeMode" + IL_010e: brfalse.s IL_0112 + IL_0110: leave.s IL_0167 + IL_0112: ldarg.0 + IL_0113: ldarg.0 + IL_0114: ldfld "int Program.d__1.<>7__wrap2" + IL_0119: ldc.i4.1 + IL_011a: add + IL_011b: stfld "int Program.d__1.<>7__wrap2" + IL_0120: ldarg.0 + IL_0121: ldfld "int Program.d__1.<>7__wrap2" + IL_0126: ldc.i4.4 + IL_0127: blt IL_0065 + IL_012c: ldarg.0 + IL_012d: ldnull + IL_012e: stfld "C Program.d__1.<>7__wrap3" + IL_0133: leave.s IL_0167 + } + catch System.Exception + { + IL_0135: stloc.s V_4 + IL_0137: ldarg.0 + IL_0138: ldc.i4.s -2 + IL_013a: stfld "int Program.d__1.<>1__state" + IL_013f: ldarg.0 + IL_0140: ldnull + IL_0141: stfld "C Program.d__1.<>7__wrap3" + IL_0146: ldarg.0 + IL_0147: ldc.i4.0 + IL_0148: stfld "int Program.d__1.<>2__current" + IL_014d: ldarg.0 + IL_014e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_0153: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0158: ldarg.0 + IL_0159: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_015e: ldloc.s V_4 + IL_0160: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0165: leave.s IL_01a1 + } + IL_0167: ldarg.0 + IL_0168: ldc.i4.s -2 + IL_016a: stfld "int Program.d__1.<>1__state" + IL_016f: ldarg.0 + IL_0170: ldnull + IL_0171: stfld "C Program.d__1.<>7__wrap3" + IL_0176: ldarg.0 + IL_0177: ldc.i4.0 + IL_0178: stfld "int Program.d__1.<>2__current" + IL_017d: ldarg.0 + IL_017e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_0183: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0188: ldarg.0 + IL_0189: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_018e: ldc.i4.0 + IL_018f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0194: ret + IL_0195: ldarg.0 + IL_0196: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_019b: ldc.i4.1 + IL_019c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_01a1: ret +} +"""); } - // TODO2 test that variables aren't clear too soon } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index dd9166ef1d4fa..eb6aca017b56d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3083,7 +3083,7 @@ public void AddVariableCleanup_StringLocal() var values = C.Produce(); foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -3095,8 +3095,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - // Note: top-level hoisted local does not get cleared when exiting normally - var verifier = CompileAndVerify(src, expectedOutput: "ran ran").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "ran True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ { // Code size 81 (0x51) @@ -3140,9 +3139,12 @@ .locals init (int V_0) """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 1 (0x1) - .maxstack 0 - IL_0000: ret + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "string C.d__0.5__2" + IL_0007: ret } """); } @@ -3155,7 +3157,7 @@ public void AddVariableCleanup_StringLocal_YieldBreak() var values = C.Produce(); foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -3168,8 +3170,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - // Note: top-level hoisted local does not get cleared when exiting with yield break - var verifier = CompileAndVerify(src, expectedOutput: "ran ran").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "ran True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ { // Code size 81 (0x51) @@ -3213,9 +3214,12 @@ .locals init (int V_0) """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 1 (0x1) - .maxstack 0 - IL_0000: ret + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "string C.d__0.5__2" + IL_0007: ret } """); } @@ -3229,7 +3233,7 @@ public void AddVariableCleanup_IntArrayLocalAndForeachLocals() var values = C.Produce(); foreach (int value in values) { } -System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)).Length); +System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -3241,9 +3245,8 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - // Note: top-level hoisted local does not get cleared when exiting normally var comp = CreateCompilation(source); - var verifier = CompileAndVerify(comp, expectedOutput: "100 100").VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, expectedOutput: "100 True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ { // Code size 96 (0x60) @@ -3293,9 +3296,12 @@ .locals init (int V_0) """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 1 (0x1) - .maxstack 0 - IL_0000: ret + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "int[] C.d__0.5__2" + IL_0007: ret } """); } @@ -3339,7 +3345,6 @@ public static System.Collections.Generic.IEnumerable M(bool b) } } """; - // Note: nested hoisted local gets cleared when exiting normally var verifier = CompileAndVerify(src, expectedOutput: "42 value True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ { @@ -3392,9 +3397,12 @@ .locals init (int V_0) """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 1 (0x1) - .maxstack 0 - IL_0000: ret + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "string C.d__0.5__2" + IL_0007: ret } """); } @@ -3418,7 +3426,7 @@ public void AddVariableCleanup_NestedStringLocal_YieldBreak() { enumerator.Dispose(); } -System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator))); +System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator)) is null); void assert(bool b) { @@ -3439,8 +3447,7 @@ public static System.Collections.Generic.IEnumerable M(bool b) } } """; - // Note: nested hoisted local does not get cleared when exiting with yield break - var verifier = CompileAndVerify(src, expectedOutput: "42 value value value").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "42 value value True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ { // Code size 83 (0x53) @@ -3488,9 +3495,12 @@ .locals init (int V_0) """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 1 (0x1) - .maxstack 0 - IL_0000: ret + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "string C.d__0.5__2" + IL_0007: ret } """); } @@ -3512,7 +3522,7 @@ public void AddVariableCleanup_NestedStringLocal_ThrownException() { enumerator.Dispose(); } -System.Console.Write(((string)enumerable.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerable))); +System.Console.Write(((string)enumerable.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerable)) is null); void assert(bool b) { @@ -3533,8 +3543,7 @@ public static System.Collections.Generic.IEnumerable M(bool b) } } """; - // Note: nested hoisted local does not get cleared when exiting with thrown exception - CompileAndVerify(src, expectedOutput: "42 value").VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: "42 True").VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -3860,7 +3869,7 @@ .locals init (bool V_0, """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 27 (0x1b) + // Code size 34 (0x22) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.0 @@ -3883,7 +3892,10 @@ .locals init (int V_0) IL_0014: call "void C.d__0.<>m__Finally1()" IL_0019: endfinally } - IL_001a: ret + IL_001a: ldarg.0 + IL_001b: ldnull + IL_001c: stfld "string C.d__0.5__2" + IL_0021: ret } """); } @@ -3991,7 +4003,7 @@ .locals init (bool V_0, """); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { - // Code size 27 (0x1b) + // Code size 34 (0x22) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.0 @@ -4014,7 +4026,10 @@ .locals init (int V_0) IL_0014: call "void C.d__0.<>m__Finally1()" IL_0019: endfinally } - IL_001a: ret + IL_001a: ldarg.0 + IL_001b: ldnull + IL_001c: stfld "string C.d__0.5__2" + IL_0021: ret } """); } @@ -4056,7 +4071,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - // Note: nested hoisted local does not get cleared when exiting loop early + // Note: nested hoisted local does not get cleared when an exception is thrown during disposal CompileAndVerify(src, expectedOutput: "exception value").VerifyDiagnostics(); } @@ -4077,7 +4092,7 @@ public void AddVariableCleanup_StringLocal_WithThrownException() System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -4090,8 +4105,7 @@ public static System.Collections.Generic.IEnumerable Produce(bool b) } } """; - // Note: top-level hoisted local does not get cleared when exiting with a thrown exception - CompileAndVerify(src, expectedOutput: "exception value").VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: "exception True").VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -4357,7 +4371,7 @@ public void AddVariableCleanup_StringLocal_EarlyIterationExit() foreach (int value in values) { break; } // we interrupt the iteration early -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -4370,10 +4384,385 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - // Note: top-level hoisted local does not get cleared when exiting loop early - CompileAndVerify(src, expectedOutput: "value").VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: "True").VerifyDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NestedStringLocal_Reused() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +foreach (int value in values) { } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + { + string values2 = "values2 "; + yield return 42; + System.Console.Write(values2); + } + { + string values3 = "values3 "; + yield return 43; + System.Console.Write(values3); + } + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "values2 values3 True").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ +{ + // Code size 142 (0x8e) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: switch ( + IL_001b, + IL_003e, + IL_0073) + IL_0019: ldc.i4.0 + IL_001a: ret + IL_001b: ldarg.0 + IL_001c: ldc.i4.m1 + IL_001d: stfld "int C.d__0.<>1__state" + IL_0022: ldarg.0 + IL_0023: ldstr "values2 " + IL_0028: stfld "string C.d__0.5__2" + IL_002d: ldarg.0 + IL_002e: ldc.i4.s 42 + IL_0030: stfld "int C.d__0.<>2__current" + IL_0035: ldarg.0 + IL_0036: ldc.i4.1 + IL_0037: stfld "int C.d__0.<>1__state" + IL_003c: ldc.i4.1 + IL_003d: ret + IL_003e: ldarg.0 + IL_003f: ldc.i4.m1 + IL_0040: stfld "int C.d__0.<>1__state" + IL_0045: ldarg.0 + IL_0046: ldfld "string C.d__0.5__2" + IL_004b: call "void System.Console.Write(string)" + IL_0050: ldarg.0 + IL_0051: ldnull + IL_0052: stfld "string C.d__0.5__2" + IL_0057: ldarg.0 + IL_0058: ldstr "values3 " + IL_005d: stfld "string C.d__0.5__2" + IL_0062: ldarg.0 + IL_0063: ldc.i4.s 43 + IL_0065: stfld "int C.d__0.<>2__current" + IL_006a: ldarg.0 + IL_006b: ldc.i4.2 + IL_006c: stfld "int C.d__0.<>1__state" + IL_0071: ldc.i4.1 + IL_0072: ret + IL_0073: ldarg.0 + IL_0074: ldc.i4.m1 + IL_0075: stfld "int C.d__0.<>1__state" + IL_007a: ldarg.0 + IL_007b: ldfld "string C.d__0.5__2" + IL_0080: call "void System.Console.Write(string)" + IL_0085: ldarg.0 + IL_0086: ldnull + IL_0087: stfld "string C.d__0.5__2" + IL_008c: ldc.i4.0 + IL_008d: ret +} +"""); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "string C.d__0.5__2" + IL_0007: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_Parameters() + { + string src = """ +string s = "ran "; +var values = C.Produce(s); +foreach (int value in values) { } +foreach (int value in values) { } + +class C +{ + public static System.Collections.Generic.IEnumerable Produce(string s) + { + yield return 42; + System.Console.Write(s); + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "ran ran").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); } - // TODO2 test that variables aren't clear too soon + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_NotCleanedTooSoon() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +foreach (int value in values) { break; } +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce() + { + try + { + string values2 = "value "; + try + { + yield return 42; + } + finally + { + System.Console.Write(values2); + } + } + finally + { + System.Console.Write("outer "); + } + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "value outer True").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 55 (0x37) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.d__0.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: ldc.i4.1 + IL_000c: ble.un.s IL_0012 + IL_000e: ldloc.0 + IL_000f: ldc.i4.1 + IL_0010: bne.un.s IL_002f + IL_0012: nop + .try + { + IL_0013: ldloc.0 + IL_0014: ldc.i4.s -4 + IL_0016: beq.s IL_001e + IL_0018: ldloc.0 + IL_0019: ldc.i4.1 + IL_001a: beq.s IL_001e + IL_001c: leave.s IL_002f + IL_001e: nop + .try + { + IL_001f: leave.s IL_002f + } + finally + { + IL_0021: ldarg.0 + IL_0022: call "void C.d__0.<>m__Finally2()" + IL_0027: endfinally + } + } + finally + { + IL_0028: ldarg.0 + IL_0029: call "void C.d__0.<>m__Finally1()" + IL_002e: endfinally + } + IL_002f: ldarg.0 + IL_0030: ldnull + IL_0031: stfld "string C.d__0.5__2" + IL_0036: ret +} +"""); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void AddVariableCleanup_HoistedFromRefExpression() + { + var src = """ +using System.Reflection; + +C c = new C(); +var coll = Test(c); +var enumerator = coll.GetEnumerator(); +try +{ + enumerator.MoveNext(); + System.Console.Write(((C)coll.GetType().GetField("<>7__wrap2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(coll)) is null); +} +finally +{ + enumerator.Dispose(); +} + +System.Console.Write(((C)coll.GetType().GetField("<>7__wrap2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(coll)) is null); + +class C +{ + public Buffer4 F = default; +} + +partial class Program +{ + static System.Collections.Generic.IEnumerable Test(C x) + { + foreach (var y in x.F) + { + yield return -1; + } + } +} + +[System.Runtime.CompilerServices.InlineArray(4)] +public struct Buffer4 +{ + private T _element0; +} +"""; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + var verifier = CompileAndVerify(comp, expectedOutput: "FalseTrue", verify: Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Program.d__1.System.Collections.IEnumerator.MoveNext", """ +{ + // Code size 134 (0x86) + .maxstack 3 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.d__1.<>1__state" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_005f + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld "int Program.d__1.<>1__state" + IL_0017: ldarg.0 + IL_0018: ldarg.0 + IL_0019: ldfld "C Program.d__1.x" + IL_001e: stfld "C Program.d__1.<>7__wrap2" + IL_0023: ldarg.0 + IL_0024: ldfld "C Program.d__1.<>7__wrap2" + IL_0029: ldfld "Buffer4 C.F" + IL_002e: pop + IL_002f: ldarg.0 + IL_0030: ldc.i4.0 + IL_0031: stfld "int Program.d__1.<>7__wrap1" + IL_0036: br.s IL_0074 + IL_0038: ldarg.0 + IL_0039: ldfld "C Program.d__1.<>7__wrap2" + IL_003e: ldflda "Buffer4 C.F" + IL_0043: ldarg.0 + IL_0044: ldfld "int Program.d__1.<>7__wrap1" + IL_0049: call "ref int .InlineArrayElementRef, int>(ref Buffer4, int)" + IL_004e: pop + IL_004f: ldarg.0 + IL_0050: ldc.i4.m1 + IL_0051: stfld "int Program.d__1.<>2__current" + IL_0056: ldarg.0 + IL_0057: ldc.i4.1 + IL_0058: stfld "int Program.d__1.<>1__state" + IL_005d: ldc.i4.1 + IL_005e: ret + IL_005f: ldarg.0 + IL_0060: ldc.i4.m1 + IL_0061: stfld "int Program.d__1.<>1__state" + IL_0066: ldarg.0 + IL_0067: ldarg.0 + IL_0068: ldfld "int Program.d__1.<>7__wrap1" + IL_006d: ldc.i4.1 + IL_006e: add + IL_006f: stfld "int Program.d__1.<>7__wrap1" + IL_0074: ldarg.0 + IL_0075: ldfld "int Program.d__1.<>7__wrap1" + IL_007a: ldc.i4.4 + IL_007b: blt.s IL_0038 + IL_007d: ldarg.0 + IL_007e: ldnull + IL_007f: stfld "C Program.d__1.<>7__wrap2" + IL_0084: ldc.i4.0 + IL_0085: ret +} +"""); + verifier.VerifyIL("Program.d__1.System.IDisposable.Dispose()", """ +{ + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "C Program.d__1.<>7__wrap2" + IL_0007: ret +} +"""); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal_IEnumerator() + { + string src = """ +using System.Reflection; + +var values = C.Produce(); +assert(values.MoveNext()); +assert(values.Current == 42); +assert(!values.MoveNext()); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +values.Dispose(); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +static void assert(bool b) { if (!b) throw new System.Exception(); } + +class C +{ + public static System.Collections.Generic.IEnumerator Produce() + { + string values2 = "ran "; + yield return 42; + System.Console.Write(values2); + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "ran ran True").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 8 (0x8) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld "string C.d__0.5__2" + IL_0007: ret +} +"""); + } } } From 61ca29507e5d777ba3aff069964ef65fc09d1d0e Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 13 Nov 2024 17:34:44 -0800 Subject: [PATCH 03/20] Remove VerifyIL --- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 1374 +---------------- .../Test/Emit/CodeGen/CodeGenAsyncTests.cs | 129 +- .../Test/Emit/CodeGen/CodeGenIterators.cs | 743 --------- 3 files changed, 14 insertions(+), 2232 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index bab70b808ac17..690bb19e2550e 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -9444,135 +9444,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("42"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 294 (0x126) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -4 - IL_000a: sub - IL_000b: switch ( - IL_00b7, - IL_0024, - IL_0024, - IL_0024, - IL_007c) - IL_0024: ldarg.0 - IL_0025: ldfld "bool C.d__0.<>w__disposeMode" - IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_00f2 - IL_0031: ldarg.0 - IL_0032: ldc.i4.m1 - IL_0033: dup - IL_0034: stloc.0 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: ldarg.0 - IL_003b: ldc.i4.s 42 - IL_003d: stfld "int C.d__0.5__2" - IL_0042: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0047: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_004c: stloc.1 - IL_004d: ldloca.s V_1 - IL_004f: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0054: brtrue.s IL_0098 - IL_0056: ldarg.0 - IL_0057: ldc.i4.0 - IL_0058: dup - IL_0059: stloc.0 - IL_005a: stfld "int C.d__0.<>1__state" - IL_005f: ldarg.0 - IL_0060: ldloc.1 - IL_0061: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0066: ldarg.0 - IL_0067: stloc.2 - IL_0068: ldarg.0 - IL_0069: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_006e: ldloca.s V_1 - IL_0070: ldloca.s V_2 - IL_0072: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_0077: leave IL_0125 - IL_007c: ldarg.0 - IL_007d: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0082: stloc.1 - IL_0083: ldarg.0 - IL_0084: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0089: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_008f: ldarg.0 - IL_0090: ldc.i4.m1 - IL_0091: dup - IL_0092: stloc.0 - IL_0093: stfld "int C.d__0.<>1__state" - IL_0098: ldloca.s V_1 - IL_009a: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_009f: ldarg.0 - IL_00a0: ldarg.0 - IL_00a1: ldfld "int C.d__0.5__2" - IL_00a6: stfld "int C.d__0.<>2__current" - IL_00ab: ldarg.0 - IL_00ac: ldc.i4.s -4 - IL_00ae: dup - IL_00af: stloc.0 - IL_00b0: stfld "int C.d__0.<>1__state" - IL_00b5: leave.s IL_0119 - IL_00b7: ldarg.0 - IL_00b8: ldc.i4.m1 - IL_00b9: dup - IL_00ba: stloc.0 - IL_00bb: stfld "int C.d__0.<>1__state" - IL_00c0: ldarg.0 - IL_00c1: ldfld "bool C.d__0.<>w__disposeMode" - IL_00c6: pop - IL_00c7: leave.s IL_00f2 - } - catch System.Exception - { - IL_00c9: stloc.3 - IL_00ca: ldarg.0 - IL_00cb: ldc.i4.s -2 - IL_00cd: stfld "int C.d__0.<>1__state" - IL_00d2: ldarg.0 - IL_00d3: ldc.i4.0 - IL_00d4: stfld "int C.d__0.<>2__current" - IL_00d9: ldarg.0 - IL_00da: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00df: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00e4: ldarg.0 - IL_00e5: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00ea: ldloc.3 - IL_00eb: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_00f0: leave.s IL_0125 - } - IL_00f2: ldarg.0 - IL_00f3: ldc.i4.s -2 - IL_00f5: stfld "int C.d__0.<>1__state" - IL_00fa: ldarg.0 - IL_00fb: ldc.i4.0 - IL_00fc: stfld "int C.d__0.<>2__current" - IL_0101: ldarg.0 - IL_0102: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0107: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_010c: ldarg.0 - IL_010d: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0112: ldc.i4.0 - IL_0113: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0118: ret - IL_0119: ldarg.0 - IL_011a: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_011f: ldc.i4.1 - IL_0120: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0125: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("42"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9758,126 +9630,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 266 (0x10a) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -3 - IL_000a: beq.s IL_000f - IL_000c: ldloc.0 - IL_000d: brfalse.s IL_006a - IL_000f: ldarg.0 - IL_0010: ldfld "bool C.d__0.<>w__disposeMode" - IL_0015: brfalse.s IL_001c - IL_0017: leave IL_00db - IL_001c: ldarg.0 - IL_001d: ldc.i4.m1 - IL_001e: dup - IL_001f: stloc.0 - IL_0020: stfld "int C.d__0.<>1__state" - IL_0025: ldarg.0 - IL_0026: ldstr "value " - IL_002b: stfld "string C.d__0.5__2" - IL_0030: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0035: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_003a: stloc.1 - IL_003b: ldloca.s V_1 - IL_003d: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0042: brtrue.s IL_0086 - IL_0044: ldarg.0 - IL_0045: ldc.i4.0 - IL_0046: dup - IL_0047: stloc.0 - IL_0048: stfld "int C.d__0.<>1__state" - IL_004d: ldarg.0 - IL_004e: ldloc.1 - IL_004f: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0054: ldarg.0 - IL_0055: stloc.2 - IL_0056: ldarg.0 - IL_0057: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_005c: ldloca.s V_1 - IL_005e: ldloca.s V_2 - IL_0060: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_0065: leave IL_0109 - IL_006a: ldarg.0 - IL_006b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0070: stloc.1 - IL_0071: ldarg.0 - IL_0072: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0077: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_007d: ldarg.0 - IL_007e: ldc.i4.m1 - IL_007f: dup - IL_0080: stloc.0 - IL_0081: stfld "int C.d__0.<>1__state" - IL_0086: ldloca.s V_1 - IL_0088: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_008d: ldarg.0 - IL_008e: ldfld "string C.d__0.5__2" - IL_0093: call "void System.Console.Write(string)" - IL_0098: ldarg.0 - IL_0099: ldfld "bool C.d__0.b" - IL_009e: brfalse.s IL_00a9 - IL_00a0: ldarg.0 - IL_00a1: ldc.i4.1 - IL_00a2: stfld "bool C.d__0.<>w__disposeMode" - IL_00a7: leave.s IL_00db - IL_00a9: ldnull - IL_00aa: throw - } - catch System.Exception - { - IL_00ab: stloc.3 - IL_00ac: ldarg.0 - IL_00ad: ldc.i4.s -2 - IL_00af: stfld "int C.d__0.<>1__state" - IL_00b4: ldarg.0 - IL_00b5: ldnull - IL_00b6: stfld "string C.d__0.5__2" - IL_00bb: ldarg.0 - IL_00bc: ldc.i4.0 - IL_00bd: stfld "int C.d__0.<>2__current" - IL_00c2: ldarg.0 - IL_00c3: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00c8: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00cd: ldarg.0 - IL_00ce: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00d3: ldloc.3 - IL_00d4: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_00d9: leave.s IL_0109 - } - IL_00db: ldarg.0 - IL_00dc: ldc.i4.s -2 - IL_00de: stfld "int C.d__0.<>1__state" - IL_00e3: ldarg.0 - IL_00e4: ldnull - IL_00e5: stfld "string C.d__0.5__2" - IL_00ea: ldarg.0 - IL_00eb: ldc.i4.0 - IL_00ec: stfld "int C.d__0.<>2__current" - IL_00f1: ldarg.0 - IL_00f2: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00f7: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - 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: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9910,127 +9663,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 275 (0x113) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -3 - IL_000a: beq.s IL_000f - IL_000c: ldloc.0 - IL_000d: brfalse.s IL_006a - IL_000f: ldarg.0 - IL_0010: ldfld "bool C.d__0.<>w__disposeMode" - IL_0015: brfalse.s IL_001c - IL_0017: leave IL_00e4 - IL_001c: ldarg.0 - IL_001d: ldc.i4.m1 - IL_001e: dup - IL_001f: stloc.0 - IL_0020: stfld "int C.d__0.<>1__state" - IL_0025: ldarg.0 - IL_0026: ldstr "value " - IL_002b: stfld "string C.d__0.5__2" - IL_0030: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0035: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_003a: stloc.1 - IL_003b: ldloca.s V_1 - IL_003d: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0042: brtrue.s IL_0086 - IL_0044: ldarg.0 - IL_0045: ldc.i4.0 - IL_0046: dup - IL_0047: stloc.0 - IL_0048: stfld "int C.d__0.<>1__state" - IL_004d: ldarg.0 - IL_004e: ldloc.1 - IL_004f: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0054: ldarg.0 - IL_0055: stloc.2 - IL_0056: ldarg.0 - IL_0057: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_005c: ldloca.s V_1 - IL_005e: ldloca.s V_2 - IL_0060: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_0065: leave IL_0112 - IL_006a: ldarg.0 - IL_006b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0070: stloc.1 - IL_0071: ldarg.0 - IL_0072: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0077: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_007d: ldarg.0 - IL_007e: ldc.i4.m1 - IL_007f: dup - IL_0080: stloc.0 - IL_0081: stfld "int C.d__0.<>1__state" - IL_0086: ldloca.s V_1 - IL_0088: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_008d: ldarg.0 - IL_008e: ldfld "string C.d__0.5__2" - IL_0093: call "void System.Console.Write(string)" - IL_0098: ldarg.0 - IL_0099: ldfld "bool C.d__0.b" - IL_009e: brfalse.s IL_00ab - IL_00a0: ldstr "exception " - IL_00a5: newobj "System.Exception..ctor(string)" - IL_00aa: throw - IL_00ab: ldarg.0 - IL_00ac: ldc.i4.1 - IL_00ad: stfld "bool C.d__0.<>w__disposeMode" - IL_00b2: leave.s IL_00e4 - } - catch System.Exception - { - IL_00b4: stloc.3 - IL_00b5: ldarg.0 - IL_00b6: ldc.i4.s -2 - IL_00b8: stfld "int C.d__0.<>1__state" - IL_00bd: ldarg.0 - IL_00be: ldnull - IL_00bf: stfld "string C.d__0.5__2" - IL_00c4: ldarg.0 - IL_00c5: ldc.i4.0 - IL_00c6: stfld "int C.d__0.<>2__current" - IL_00cb: ldarg.0 - IL_00cc: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00d1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00d6: ldarg.0 - IL_00d7: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00dc: ldloc.3 - IL_00dd: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_00e2: leave.s IL_0112 - } - IL_00e4: ldarg.0 - IL_00e5: ldc.i4.s -2 - IL_00e7: stfld "int C.d__0.<>1__state" - IL_00ec: ldarg.0 - IL_00ed: ldnull - IL_00ee: stfld "string C.d__0.5__2" - IL_00f3: ldarg.0 - IL_00f4: ldc.i4.0 - IL_00f5: stfld "int C.d__0.<>2__current" - IL_00fa: ldarg.0 - IL_00fb: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0100: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0105: ldarg.0 - IL_0106: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_010b: ldc.i4.0 - IL_010c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0111: ret - IL_0112: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10096,192 +9729,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 438 (0x1b6) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -6 - IL_000a: sub - IL_000b: switch ( - IL_0139, - IL_00b2, - IL_0065, - IL_002c, - IL_002c, - IL_002c, - IL_0103) - IL_002c: ldarg.0 - IL_002d: ldfld "bool C.d__0.<>w__disposeMode" - IL_0032: brfalse.s IL_0039 - IL_0034: leave IL_017b - IL_0039: ldarg.0 - IL_003a: ldc.i4.m1 - IL_003b: dup - IL_003c: stloc.0 - IL_003d: stfld "int C.d__0.<>1__state" - IL_0042: br.s IL_0094 - IL_0044: ldarg.0 - IL_0045: ldstr "value " - IL_004a: stfld "string C.d__0.5__2" - IL_004f: ldarg.0 - IL_0050: ldc.i4.1 - IL_0051: stfld "int C.d__0.<>2__current" - IL_0056: ldarg.0 - IL_0057: ldc.i4.s -4 - IL_0059: dup - IL_005a: stloc.0 - IL_005b: stfld "int C.d__0.<>1__state" - IL_0060: leave IL_01a9 - IL_0065: ldarg.0 - IL_0066: ldc.i4.m1 - IL_0067: dup - IL_0068: stloc.0 - IL_0069: stfld "int C.d__0.<>1__state" - IL_006e: ldarg.0 - IL_006f: ldfld "bool C.d__0.<>w__disposeMode" - IL_0074: brfalse.s IL_007b - IL_0076: leave IL_017b - IL_007b: ldarg.0 - IL_007c: ldfld "string C.d__0.5__2" - IL_0081: call "void System.Console.Write(string)" - IL_0086: ldarg.0 - IL_0087: ldc.i4.0 - IL_0088: stfld "bool C.d__0.b" - IL_008d: ldarg.0 - IL_008e: ldnull - IL_008f: stfld "string C.d__0.5__2" - IL_0094: ldarg.0 - IL_0095: ldfld "bool C.d__0.b" - IL_009a: brtrue.s IL_0044 - IL_009c: ldarg.0 - IL_009d: ldc.i4.2 - IL_009e: stfld "int C.d__0.<>2__current" - IL_00a3: ldarg.0 - IL_00a4: ldc.i4.s -5 - IL_00a6: dup - IL_00a7: stloc.0 - IL_00a8: stfld "int C.d__0.<>1__state" - IL_00ad: leave IL_01a9 - IL_00b2: ldarg.0 - IL_00b3: ldc.i4.m1 - IL_00b4: dup - IL_00b5: stloc.0 - IL_00b6: stfld "int C.d__0.<>1__state" - IL_00bb: ldarg.0 - IL_00bc: ldfld "bool C.d__0.<>w__disposeMode" - IL_00c1: brfalse.s IL_00c8 - IL_00c3: leave IL_017b - IL_00c8: ldarg.0 - IL_00c9: ldfld "System.Threading.Tasks.Task C.d__0.task" - IL_00ce: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_00d3: stloc.1 - IL_00d4: ldloca.s V_1 - IL_00d6: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_00db: brtrue.s IL_011f - IL_00dd: ldarg.0 - IL_00de: ldc.i4.0 - IL_00df: dup - IL_00e0: stloc.0 - IL_00e1: stfld "int C.d__0.<>1__state" - IL_00e6: ldarg.0 - IL_00e7: ldloc.1 - IL_00e8: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00ed: ldarg.0 - IL_00ee: stloc.2 - IL_00ef: ldarg.0 - IL_00f0: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00f5: ldloca.s V_1 - IL_00f7: ldloca.s V_2 - IL_00f9: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00fe: leave IL_01b5 - IL_0103: ldarg.0 - IL_0104: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0109: stloc.1 - IL_010a: ldarg.0 - IL_010b: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0110: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0116: ldarg.0 - IL_0117: ldc.i4.m1 - IL_0118: dup - IL_0119: stloc.0 - IL_011a: stfld "int C.d__0.<>1__state" - IL_011f: ldloca.s V_1 - IL_0121: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_0126: ldarg.0 - IL_0127: ldc.i4.3 - IL_0128: stfld "int C.d__0.<>2__current" - IL_012d: ldarg.0 - IL_012e: ldc.i4.s -6 - IL_0130: dup - IL_0131: stloc.0 - IL_0132: stfld "int C.d__0.<>1__state" - IL_0137: leave.s IL_01a9 - IL_0139: ldarg.0 - IL_013a: ldc.i4.m1 - IL_013b: dup - IL_013c: stloc.0 - IL_013d: stfld "int C.d__0.<>1__state" - IL_0142: ldarg.0 - IL_0143: ldfld "bool C.d__0.<>w__disposeMode" - IL_0148: pop - IL_0149: leave.s IL_017b - } - catch System.Exception - { - IL_014b: stloc.3 - IL_014c: ldarg.0 - IL_014d: ldc.i4.s -2 - IL_014f: stfld "int C.d__0.<>1__state" - IL_0154: ldarg.0 - IL_0155: ldnull - IL_0156: stfld "string C.d__0.5__2" - IL_015b: ldarg.0 - IL_015c: ldc.i4.0 - IL_015d: stfld "int C.d__0.<>2__current" - IL_0162: ldarg.0 - IL_0163: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0168: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_016d: ldarg.0 - IL_016e: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0173: ldloc.3 - IL_0174: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0179: leave.s IL_01b5 - } - IL_017b: ldarg.0 - IL_017c: ldc.i4.s -2 - IL_017e: stfld "int C.d__0.<>1__state" - IL_0183: ldarg.0 - IL_0184: ldnull - IL_0185: stfld "string C.d__0.5__2" - IL_018a: ldarg.0 - IL_018b: ldc.i4.0 - IL_018c: stfld "int C.d__0.<>2__current" - IL_0191: ldarg.0 - IL_0192: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0197: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_019c: ldarg.0 - IL_019d: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_01a2: ldc.i4.0 - IL_01a3: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_01a8: ret - IL_01a9: ldarg.0 - IL_01aa: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_01af: ldc.i4.1 - IL_01b0: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_01b5: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10319,159 +9767,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 366 (0x16e) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -4 - IL_000a: sub - IL_000b: switch ( - IL_0060, - IL_0024, - IL_0024, - IL_0024, - IL_00bb) - IL_0024: ldarg.0 - IL_0025: ldfld "bool C.d__0.<>w__disposeMode" - IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_0133 - IL_0031: ldarg.0 - IL_0032: ldc.i4.m1 - IL_0033: dup - IL_0034: stloc.0 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: br IL_00f6 - IL_003f: ldarg.0 - IL_0040: ldstr "value " - IL_0045: stfld "string C.d__0.5__2" - IL_004a: ldarg.0 - IL_004b: ldc.i4.1 - IL_004c: stfld "int C.d__0.<>2__current" - IL_0051: ldarg.0 - IL_0052: ldc.i4.s -4 - IL_0054: dup - IL_0055: stloc.0 - IL_0056: stfld "int C.d__0.<>1__state" - IL_005b: leave IL_0161 - IL_0060: ldarg.0 - IL_0061: ldc.i4.m1 - IL_0062: dup - IL_0063: stloc.0 - IL_0064: stfld "int C.d__0.<>1__state" - IL_0069: ldarg.0 - IL_006a: ldfld "bool C.d__0.<>w__disposeMode" - IL_006f: brfalse.s IL_0076 - IL_0071: leave IL_0133 - IL_0076: ldarg.0 - IL_0077: ldfld "string C.d__0.5__2" - IL_007c: call "void System.Console.Write(string)" - IL_0081: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0086: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_008b: stloc.1 - IL_008c: ldloca.s V_1 - IL_008e: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0093: brtrue.s IL_00d7 - IL_0095: ldarg.0 - IL_0096: ldc.i4.0 - IL_0097: dup - IL_0098: stloc.0 - IL_0099: stfld "int C.d__0.<>1__state" - IL_009e: ldarg.0 - IL_009f: ldloc.1 - IL_00a0: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00a5: ldarg.0 - IL_00a6: stloc.2 - IL_00a7: ldarg.0 - IL_00a8: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00ad: ldloca.s V_1 - IL_00af: ldloca.s V_2 - IL_00b1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00b6: leave IL_016d - IL_00bb: ldarg.0 - IL_00bc: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00c1: stloc.1 - IL_00c2: ldarg.0 - IL_00c3: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00c8: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_00ce: ldarg.0 - IL_00cf: ldc.i4.m1 - IL_00d0: dup - IL_00d1: stloc.0 - IL_00d2: stfld "int C.d__0.<>1__state" - IL_00d7: ldloca.s V_1 - IL_00d9: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_00de: ldarg.0 - IL_00df: ldfld "bool C.d__0.b" - IL_00e4: brfalse.s IL_00ef - IL_00e6: ldarg.0 - IL_00e7: ldc.i4.1 - IL_00e8: stfld "bool C.d__0.<>w__disposeMode" - IL_00ed: leave.s IL_0133 - IL_00ef: ldarg.0 - IL_00f0: ldnull - IL_00f1: stfld "string C.d__0.5__2" - IL_00f6: ldarg.0 - IL_00f7: ldfld "bool C.d__0.b" - IL_00fc: brtrue IL_003f - IL_0101: ldnull - IL_0102: throw - } - catch System.Exception - { - IL_0103: stloc.3 - IL_0104: ldarg.0 - IL_0105: ldc.i4.s -2 - IL_0107: stfld "int C.d__0.<>1__state" - IL_010c: ldarg.0 - IL_010d: ldnull - IL_010e: stfld "string C.d__0.5__2" - IL_0113: ldarg.0 - IL_0114: ldc.i4.0 - IL_0115: stfld "int C.d__0.<>2__current" - IL_011a: ldarg.0 - IL_011b: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0120: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0125: ldarg.0 - IL_0126: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_012b: ldloc.3 - IL_012c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0131: leave.s IL_016d - } - IL_0133: ldarg.0 - IL_0134: ldc.i4.s -2 - IL_0136: stfld "int C.d__0.<>1__state" - IL_013b: ldarg.0 - IL_013c: ldnull - IL_013d: stfld "string C.d__0.5__2" - IL_0142: ldarg.0 - IL_0143: ldc.i4.0 - IL_0144: stfld "int C.d__0.<>2__current" - IL_0149: ldarg.0 - IL_014a: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_014f: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0154: ldarg.0 - IL_0155: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_015a: ldc.i4.0 - IL_015b: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0160: ret - IL_0161: ldarg.0 - IL_0162: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0167: ldc.i4.1 - IL_0168: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_016d: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10512,163 +9808,12 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo System.Console.Write(values2); await System.Threading.Tasks.Task.CompletedTask; if (b) throw new System.Exception("exception "); - } - throw null; - } -} -"""; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 368 (0x170) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -4 - IL_000a: sub - IL_000b: switch ( - IL_0060, - IL_0024, - IL_0024, - IL_0024, - IL_00bb) - IL_0024: ldarg.0 - IL_0025: ldfld "bool C.d__0.<>w__disposeMode" - IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_0135 - IL_0031: ldarg.0 - IL_0032: ldc.i4.m1 - IL_0033: dup - IL_0034: stloc.0 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: br IL_00f8 - IL_003f: ldarg.0 - IL_0040: ldstr "value " - IL_0045: stfld "string C.d__0.5__2" - IL_004a: ldarg.0 - IL_004b: ldc.i4.1 - IL_004c: stfld "int C.d__0.<>2__current" - IL_0051: ldarg.0 - IL_0052: ldc.i4.s -4 - IL_0054: dup - IL_0055: stloc.0 - IL_0056: stfld "int C.d__0.<>1__state" - IL_005b: leave IL_0163 - IL_0060: ldarg.0 - IL_0061: ldc.i4.m1 - IL_0062: dup - IL_0063: stloc.0 - IL_0064: stfld "int C.d__0.<>1__state" - IL_0069: ldarg.0 - IL_006a: ldfld "bool C.d__0.<>w__disposeMode" - IL_006f: brfalse.s IL_0076 - IL_0071: leave IL_0135 - IL_0076: ldarg.0 - IL_0077: ldfld "string C.d__0.5__2" - IL_007c: call "void System.Console.Write(string)" - IL_0081: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0086: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_008b: stloc.1 - IL_008c: ldloca.s V_1 - IL_008e: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0093: brtrue.s IL_00d7 - IL_0095: ldarg.0 - IL_0096: ldc.i4.0 - IL_0097: dup - IL_0098: stloc.0 - IL_0099: stfld "int C.d__0.<>1__state" - IL_009e: ldarg.0 - IL_009f: ldloc.1 - IL_00a0: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00a5: ldarg.0 - IL_00a6: stloc.2 - IL_00a7: ldarg.0 - IL_00a8: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00ad: ldloca.s V_1 - IL_00af: ldloca.s V_2 - IL_00b1: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00b6: leave IL_016f - IL_00bb: ldarg.0 - IL_00bc: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00c1: stloc.1 - IL_00c2: ldarg.0 - IL_00c3: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00c8: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_00ce: ldarg.0 - IL_00cf: ldc.i4.m1 - IL_00d0: dup - IL_00d1: stloc.0 - IL_00d2: stfld "int C.d__0.<>1__state" - IL_00d7: ldloca.s V_1 - IL_00d9: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_00de: ldarg.0 - IL_00df: ldfld "bool C.d__0.b" - IL_00e4: brfalse.s IL_00f1 - IL_00e6: ldstr "exception " - IL_00eb: newobj "System.Exception..ctor(string)" - IL_00f0: throw - IL_00f1: ldarg.0 - IL_00f2: ldnull - IL_00f3: stfld "string C.d__0.5__2" - IL_00f8: ldarg.0 - IL_00f9: ldfld "bool C.d__0.b" - IL_00fe: brtrue IL_003f - IL_0103: ldnull - IL_0104: throw - } - catch System.Exception - { - IL_0105: stloc.3 - IL_0106: ldarg.0 - IL_0107: ldc.i4.s -2 - IL_0109: stfld "int C.d__0.<>1__state" - IL_010e: ldarg.0 - IL_010f: ldnull - IL_0110: stfld "string C.d__0.5__2" - IL_0115: ldarg.0 - IL_0116: ldc.i4.0 - IL_0117: stfld "int C.d__0.<>2__current" - IL_011c: ldarg.0 - IL_011d: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0122: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0127: ldarg.0 - IL_0128: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_012d: ldloc.3 - IL_012e: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0133: leave.s IL_016f - } - IL_0135: ldarg.0 - IL_0136: ldc.i4.s -2 - IL_0138: stfld "int C.d__0.<>1__state" - IL_013d: ldarg.0 - IL_013e: ldnull - IL_013f: stfld "string C.d__0.5__2" - IL_0144: ldarg.0 - IL_0145: ldc.i4.0 - IL_0146: stfld "int C.d__0.<>2__current" - IL_014b: ldarg.0 - IL_014c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0151: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0156: ldarg.0 - IL_0157: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_015c: ldc.i4.0 - IL_015d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0162: ret - IL_0163: ldarg.0 - IL_0164: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0169: ldc.i4.1 - IL_016a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_016f: ret + } + throw null; + } } -"""); +"""; + CompileAndVerify(src, expectedOutput: ExpectedOutput("value exception True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -11002,144 +10147,7 @@ public static async System.Collections.Generic.IAsyncEnumerator Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 320 (0x140) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -4 - IL_000a: sub - IL_000b: switch ( - IL_00b5, - IL_0024, - IL_0024, - IL_0024, - IL_007f) - IL_0024: ldarg.0 - IL_0025: ldfld "bool C.d__0.<>w__disposeMode" - IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_0105 - IL_0031: ldarg.0 - IL_0032: ldc.i4.m1 - IL_0033: dup - IL_0034: stloc.0 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: ldarg.0 - IL_003b: ldstr "value " - IL_0040: stfld "string C.d__0.5__2" - IL_0045: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_004a: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_004f: stloc.1 - IL_0050: ldloca.s V_1 - IL_0052: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0057: brtrue.s IL_009b - IL_0059: ldarg.0 - IL_005a: ldc.i4.0 - IL_005b: dup - IL_005c: stloc.0 - IL_005d: stfld "int C.d__0.<>1__state" - IL_0062: ldarg.0 - IL_0063: ldloc.1 - IL_0064: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0069: ldarg.0 - IL_006a: stloc.2 - IL_006b: ldarg.0 - IL_006c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0071: ldloca.s V_1 - IL_0073: ldloca.s V_2 - IL_0075: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_007a: leave IL_013f - IL_007f: ldarg.0 - IL_0080: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0085: stloc.1 - IL_0086: ldarg.0 - IL_0087: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_008c: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0092: ldarg.0 - IL_0093: ldc.i4.m1 - IL_0094: dup - IL_0095: stloc.0 - IL_0096: stfld "int C.d__0.<>1__state" - IL_009b: ldloca.s V_1 - IL_009d: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_00a2: ldarg.0 - IL_00a3: ldc.i4.1 - IL_00a4: stfld "int C.d__0.<>2__current" - IL_00a9: ldarg.0 - IL_00aa: ldc.i4.s -4 - IL_00ac: dup - IL_00ad: stloc.0 - IL_00ae: stfld "int C.d__0.<>1__state" - IL_00b3: leave.s IL_0133 - IL_00b5: ldarg.0 - IL_00b6: ldc.i4.m1 - IL_00b7: dup - IL_00b8: stloc.0 - IL_00b9: stfld "int C.d__0.<>1__state" - IL_00be: ldarg.0 - IL_00bf: ldfld "bool C.d__0.<>w__disposeMode" - IL_00c4: brfalse.s IL_00c8 - IL_00c6: leave.s IL_0105 - IL_00c8: ldarg.0 - IL_00c9: ldfld "string C.d__0.5__2" - IL_00ce: call "void System.Console.Write(string)" - IL_00d3: leave.s IL_0105 - } - catch System.Exception - { - IL_00d5: stloc.3 - IL_00d6: ldarg.0 - IL_00d7: ldc.i4.s -2 - IL_00d9: stfld "int C.d__0.<>1__state" - IL_00de: ldarg.0 - IL_00df: ldnull - IL_00e0: stfld "string C.d__0.5__2" - IL_00e5: ldarg.0 - IL_00e6: ldc.i4.0 - IL_00e7: stfld "int C.d__0.<>2__current" - IL_00ec: ldarg.0 - IL_00ed: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_00f2: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_00f7: ldarg.0 - IL_00f8: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_00fd: ldloc.3 - IL_00fe: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0103: leave.s IL_013f - } - IL_0105: ldarg.0 - IL_0106: ldc.i4.s -2 - IL_0108: stfld "int C.d__0.<>1__state" - IL_010d: ldarg.0 - IL_010e: ldnull - IL_010f: stfld "string C.d__0.5__2" - IL_0114: ldarg.0 - IL_0115: ldc.i4.0 - IL_0116: stfld "int C.d__0.<>2__current" - IL_011b: ldarg.0 - IL_011c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0121: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0126: ldarg.0 - IL_0127: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_012c: ldc.i4.0 - IL_012d: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0132: ret - IL_0133: ldarg.0 - IL_0134: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_0139: ldc.i4.1 - IL_013a: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_013f: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -11176,188 +10184,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value outer True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 385 (0x181) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -4 - IL_000a: sub - IL_000b: switch ( - IL_003a, - IL_0024, - IL_0024, - IL_0024, - IL_003a) - IL_0024: ldarg.0 - IL_0025: ldfld "bool C.d__0.<>w__disposeMode" - IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_0146 - IL_0031: ldarg.0 - IL_0032: ldc.i4.m1 - IL_0033: dup - IL_0034: stloc.0 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: nop - .try - { - IL_003b: ldloc.0 - IL_003c: ldc.i4.s -4 - IL_003e: beq.s IL_004e - IL_0040: ldloc.0 - IL_0041: brfalse.s IL_004e - IL_0043: ldarg.0 - IL_0044: ldstr "value " - IL_0049: stfld "string C.d__0.5__2" - IL_004e: nop - .try - { - IL_004f: ldloc.0 - IL_0050: ldc.i4.s -4 - IL_0052: beq.s IL_00cb - IL_0054: ldloc.0 - IL_0055: brfalse.s IL_0091 - IL_0057: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_005c: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_0061: stloc.1 - IL_0062: ldloca.s V_1 - IL_0064: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0069: brtrue.s IL_00ad - IL_006b: ldarg.0 - IL_006c: ldc.i4.0 - IL_006d: dup - IL_006e: stloc.0 - IL_006f: stfld "int C.d__0.<>1__state" - IL_0074: ldarg.0 - IL_0075: ldloc.1 - IL_0076: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_007b: ldarg.0 - IL_007c: stloc.2 - IL_007d: ldarg.0 - IL_007e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0083: ldloca.s V_1 - IL_0085: ldloca.s V_2 - IL_0087: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_008c: leave IL_0180 - IL_0091: ldarg.0 - IL_0092: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0097: stloc.1 - IL_0098: ldarg.0 - IL_0099: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_009e: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_00a4: ldarg.0 - IL_00a5: ldc.i4.m1 - IL_00a6: dup - IL_00a7: stloc.0 - IL_00a8: stfld "int C.d__0.<>1__state" - IL_00ad: ldloca.s V_1 - IL_00af: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_00b4: ldarg.0 - IL_00b5: ldc.i4.s 42 - IL_00b7: stfld "int C.d__0.<>2__current" - IL_00bc: ldarg.0 - IL_00bd: ldc.i4.s -4 - IL_00bf: dup - IL_00c0: stloc.0 - IL_00c1: stfld "int C.d__0.<>1__state" - IL_00c6: leave IL_0174 - IL_00cb: ldarg.0 - IL_00cc: ldc.i4.m1 - IL_00cd: dup - IL_00ce: stloc.0 - IL_00cf: stfld "int C.d__0.<>1__state" - IL_00d4: ldarg.0 - IL_00d5: ldfld "bool C.d__0.<>w__disposeMode" - IL_00da: pop - IL_00db: leave.s IL_00ed - } - finally - { - IL_00dd: ldloc.0 - IL_00de: ldc.i4.m1 - IL_00df: bne.un.s IL_00ec - IL_00e1: ldarg.0 - IL_00e2: ldfld "string C.d__0.5__2" - IL_00e7: call "void System.Console.Write(string)" - IL_00ec: endfinally - } - IL_00ed: ldarg.0 - IL_00ee: ldfld "bool C.d__0.<>w__disposeMode" - IL_00f3: brtrue.s IL_00fc - IL_00f5: ldarg.0 - IL_00f6: ldnull - IL_00f7: stfld "string C.d__0.5__2" - IL_00fc: leave.s IL_010d - } - finally - { - IL_00fe: ldloc.0 - IL_00ff: ldc.i4.m1 - IL_0100: bne.un.s IL_010c - IL_0102: ldstr "outer " - IL_0107: call "void System.Console.Write(string)" - IL_010c: endfinally - } - IL_010d: ldarg.0 - IL_010e: ldfld "bool C.d__0.<>w__disposeMode" - IL_0113: pop - IL_0114: leave.s IL_0146 - } - catch System.Exception - { - IL_0116: stloc.3 - IL_0117: ldarg.0 - IL_0118: ldc.i4.s -2 - IL_011a: stfld "int C.d__0.<>1__state" - IL_011f: ldarg.0 - IL_0120: ldnull - IL_0121: stfld "string C.d__0.5__2" - IL_0126: ldarg.0 - IL_0127: ldc.i4.0 - IL_0128: stfld "int C.d__0.<>2__current" - IL_012d: ldarg.0 - IL_012e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0133: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0138: ldarg.0 - IL_0139: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_013e: ldloc.3 - IL_013f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0144: leave.s IL_0180 - } - IL_0146: ldarg.0 - IL_0147: ldc.i4.s -2 - IL_0149: stfld "int C.d__0.<>1__state" - IL_014e: ldarg.0 - IL_014f: ldnull - IL_0150: stfld "string C.d__0.5__2" - IL_0155: ldarg.0 - IL_0156: ldc.i4.0 - IL_0157: stfld "int C.d__0.<>2__current" - IL_015c: ldarg.0 - IL_015d: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder" - IL_0162: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0167: ldarg.0 - IL_0168: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_016d: ldc.i4.0 - IL_016e: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0173: ret - IL_0174: ldarg.0 - IL_0175: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd" - IL_017a: ldc.i4.1 - IL_017b: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0180: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value outer True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -11395,182 +10222,7 @@ public struct Buffer4 private T _element0; } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("0123True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); - verifier.VerifyIL("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 418 (0x1a2) - .maxstack 4 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - Program.d__1 V_2, - int V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld "int Program.d__1.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -4 - IL_000a: sub - IL_000b: switch ( - IL_00ff, - IL_0024, - IL_0024, - IL_0024, - IL_00b6) - IL_0024: ldarg.0 - IL_0025: ldfld "bool Program.d__1.<>w__disposeMode" - IL_002a: brfalse.s IL_0031 - IL_002c: leave IL_0167 - IL_0031: ldarg.0 - IL_0032: ldc.i4.m1 - IL_0033: dup - IL_0034: stloc.0 - IL_0035: stfld "int Program.d__1.<>1__state" - IL_003a: ldarg.0 - IL_003b: ldc.i4.0 - IL_003c: stfld "int Program.d__1.5__2" - IL_0041: ldarg.0 - IL_0042: ldarg.0 - IL_0043: ldfld "C Program.d__1.x" - IL_0048: stfld "C Program.d__1.<>7__wrap3" - IL_004d: ldarg.0 - IL_004e: ldfld "C Program.d__1.<>7__wrap3" - IL_0053: ldfld "Buffer4 C.F" - IL_0058: pop - IL_0059: ldarg.0 - IL_005a: ldc.i4.0 - IL_005b: stfld "int Program.d__1.<>7__wrap2" - IL_0060: br IL_0120 - IL_0065: ldarg.0 - IL_0066: ldfld "C Program.d__1.<>7__wrap3" - IL_006b: ldflda "Buffer4 C.F" - IL_0070: ldarg.0 - IL_0071: ldfld "int Program.d__1.<>7__wrap2" - IL_0076: call "ref int .InlineArrayElementRef, int>(ref Buffer4, int)" - IL_007b: pop - IL_007c: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0081: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_0086: stloc.1 - IL_0087: ldloca.s V_1 - IL_0089: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_008e: brtrue.s IL_00d2 - IL_0090: ldarg.0 - IL_0091: ldc.i4.0 - IL_0092: dup - IL_0093: stloc.0 - IL_0094: stfld "int Program.d__1.<>1__state" - IL_0099: ldarg.0 - IL_009a: ldloc.1 - IL_009b: stfld "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" - IL_00a0: ldarg.0 - IL_00a1: stloc.2 - IL_00a2: ldarg.0 - IL_00a3: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" - IL_00a8: ldloca.s V_1 - IL_00aa: ldloca.s V_2 - IL_00ac: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__1)" - IL_00b1: leave IL_01a1 - IL_00b6: ldarg.0 - IL_00b7: ldfld "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" - IL_00bc: stloc.1 - IL_00bd: ldarg.0 - IL_00be: ldflda "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" - IL_00c3: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_00c9: ldarg.0 - IL_00ca: ldc.i4.m1 - IL_00cb: dup - IL_00cc: stloc.0 - IL_00cd: stfld "int Program.d__1.<>1__state" - IL_00d2: ldloca.s V_1 - IL_00d4: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_00d9: ldarg.0 - IL_00da: ldarg.0 - IL_00db: ldfld "int Program.d__1.5__2" - IL_00e0: stloc.3 - IL_00e1: ldarg.0 - IL_00e2: ldloc.3 - IL_00e3: ldc.i4.1 - IL_00e4: add - IL_00e5: stfld "int Program.d__1.5__2" - IL_00ea: ldloc.3 - IL_00eb: stfld "int Program.d__1.<>2__current" - IL_00f0: ldarg.0 - IL_00f1: ldc.i4.s -4 - IL_00f3: dup - IL_00f4: stloc.0 - IL_00f5: stfld "int Program.d__1.<>1__state" - IL_00fa: leave IL_0195 - IL_00ff: ldarg.0 - IL_0100: ldc.i4.m1 - IL_0101: dup - IL_0102: stloc.0 - IL_0103: stfld "int Program.d__1.<>1__state" - IL_0108: ldarg.0 - IL_0109: ldfld "bool Program.d__1.<>w__disposeMode" - IL_010e: brfalse.s IL_0112 - IL_0110: leave.s IL_0167 - IL_0112: ldarg.0 - IL_0113: ldarg.0 - IL_0114: ldfld "int Program.d__1.<>7__wrap2" - IL_0119: ldc.i4.1 - IL_011a: add - IL_011b: stfld "int Program.d__1.<>7__wrap2" - IL_0120: ldarg.0 - IL_0121: ldfld "int Program.d__1.<>7__wrap2" - IL_0126: ldc.i4.4 - IL_0127: blt IL_0065 - IL_012c: ldarg.0 - IL_012d: ldnull - IL_012e: stfld "C Program.d__1.<>7__wrap3" - IL_0133: leave.s IL_0167 - } - catch System.Exception - { - IL_0135: stloc.s V_4 - IL_0137: ldarg.0 - IL_0138: ldc.i4.s -2 - IL_013a: stfld "int Program.d__1.<>1__state" - IL_013f: ldarg.0 - IL_0140: ldnull - IL_0141: stfld "C Program.d__1.<>7__wrap3" - IL_0146: ldarg.0 - IL_0147: ldc.i4.0 - IL_0148: stfld "int Program.d__1.<>2__current" - IL_014d: ldarg.0 - IL_014e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" - IL_0153: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0158: ldarg.0 - IL_0159: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" - IL_015e: ldloc.s V_4 - IL_0160: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" - IL_0165: leave.s IL_01a1 - } - IL_0167: ldarg.0 - IL_0168: ldc.i4.s -2 - IL_016a: stfld "int Program.d__1.<>1__state" - IL_016f: ldarg.0 - IL_0170: ldnull - IL_0171: stfld "C Program.d__1.<>7__wrap3" - IL_0176: ldarg.0 - IL_0177: ldc.i4.0 - IL_0178: stfld "int Program.d__1.<>2__current" - IL_017d: ldarg.0 - IL_017e: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" - IL_0183: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" - IL_0188: ldarg.0 - IL_0189: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" - IL_018e: ldc.i4.0 - IL_018f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_0194: ret - IL_0195: ldarg.0 - IL_0196: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" - IL_019b: ldc.i4.1 - IL_019c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" - IL_01a1: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("0123True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 4ec5f8c76ffea..89482c2907c11 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -6090,134 +6090,7 @@ public static async System.Threading.Tasks.Task ProduceAsync(bool b, System } """; // Note: nested hoisted local gets cleared when exiting nested scope normally - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), targetFramework: TargetFramework.Net90, verify: Verification.Skipped).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 293 (0x125) - .maxstack 3 - .locals init (int V_0, - int V_1, - System.Runtime.CompilerServices.TaskAwaiter V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0055 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq IL_00d1 - IL_0011: br.s IL_0091 - IL_0013: ldarg.0 - IL_0014: ldstr "value " - IL_0019: stfld "string C.d__0.5__2" - IL_001e: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" - IL_0023: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_0028: stloc.2 - IL_0029: ldloca.s V_2 - IL_002b: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0030: brtrue.s IL_0071 - IL_0032: ldarg.0 - IL_0033: ldc.i4.0 - IL_0034: dup - IL_0035: stloc.0 - IL_0036: stfld "int C.d__0.<>1__state" - IL_003b: ldarg.0 - IL_003c: ldloc.2 - IL_003d: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0042: ldarg.0 - IL_0043: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" - IL_0048: ldloca.s V_2 - IL_004a: ldarg.0 - IL_004b: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_0050: leave IL_0124 - IL_0055: ldarg.0 - IL_0056: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_005b: stloc.2 - IL_005c: ldarg.0 - IL_005d: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_0062: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0068: ldarg.0 - IL_0069: ldc.i4.m1 - IL_006a: dup - IL_006b: stloc.0 - IL_006c: stfld "int C.d__0.<>1__state" - IL_0071: ldloca.s V_2 - IL_0073: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_0078: ldarg.0 - IL_0079: ldfld "string C.d__0.5__2" - IL_007e: call "void System.Console.Write(string)" - IL_0083: ldarg.0 - IL_0084: ldc.i4.0 - IL_0085: stfld "bool C.d__0.b" - IL_008a: ldarg.0 - IL_008b: ldnull - IL_008c: stfld "string C.d__0.5__2" - IL_0091: ldarg.0 - IL_0092: ldfld "bool C.d__0.b" - IL_0097: brtrue IL_0013 - IL_009c: ldarg.0 - IL_009d: ldfld "System.Threading.Tasks.Task C.d__0.task" - IL_00a2: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_00a7: stloc.2 - IL_00a8: ldloca.s V_2 - IL_00aa: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_00af: brtrue.s IL_00ed - IL_00b1: ldarg.0 - IL_00b2: ldc.i4.1 - IL_00b3: dup - IL_00b4: stloc.0 - IL_00b5: stfld "int C.d__0.<>1__state" - IL_00ba: ldarg.0 - IL_00bb: ldloc.2 - IL_00bc: stfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00c1: ldarg.0 - IL_00c2: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" - IL_00c7: ldloca.s V_2 - IL_00c9: ldarg.0 - IL_00ca: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)" - IL_00cf: leave.s IL_0124 - IL_00d1: ldarg.0 - IL_00d2: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00d7: stloc.2 - IL_00d8: ldarg.0 - IL_00d9: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1" - IL_00de: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_00e4: ldarg.0 - IL_00e5: ldc.i4.m1 - IL_00e6: dup - IL_00e7: stloc.0 - IL_00e8: stfld "int C.d__0.<>1__state" - IL_00ed: ldloca.s V_2 - IL_00ef: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_00f4: ldc.i4.s 42 - IL_00f6: stloc.1 - IL_00f7: leave.s IL_0110 - } - catch System.Exception - { - IL_00f9: stloc.3 - IL_00fa: ldarg.0 - IL_00fb: ldc.i4.s -2 - IL_00fd: stfld "int C.d__0.<>1__state" - IL_0102: ldarg.0 - IL_0103: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" - IL_0108: ldloc.3 - IL_0109: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" - IL_010e: leave.s IL_0124 - } - IL_0110: ldarg.0 - IL_0111: ldc.i4.s -2 - IL_0113: stfld "int C.d__0.<>1__state" - IL_0118: ldarg.0 - IL_0119: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder" - IL_011e: ldloc.1 - IL_011f: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)" - IL_0124: ret -} -"""); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), targetFramework: TargetFramework.Net90, verify: Verification.Skipped).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index eb6aca017b56d..51b76429652d4 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3023,49 +3023,6 @@ public static System.Collections.Generic.IEnumerable Produce() } """; var verifier = CompileAndVerify(src, expectedOutput: "42 42").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 87 (0x57) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0034 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldc.i4.s 42 - IL_001a: stfld "int C.d__0.5__2" - IL_001f: ldarg.0 - IL_0020: ldarg.0 - IL_0021: ldfld "int C.d__0.5__2" - IL_0026: stfld "int C.d__0.<>2__current" - IL_002b: ldarg.0 - IL_002c: ldc.i4.1 - IL_002d: stfld "int C.d__0.<>1__state" - IL_0032: ldc.i4.1 - IL_0033: ret - IL_0034: ldarg.0 - IL_0035: ldc.i4.m1 - IL_0036: stfld "int C.d__0.<>1__state" - IL_003b: ldstr "{0} " - IL_0040: ldarg.0 - IL_0041: ldfld "int C.d__0.5__2" - IL_0046: box "int" - IL_004b: call "string string.Format(string, object)" - IL_0050: call "void System.Console.Write(string)" - IL_0055: ldc.i4.0 - IL_0056: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 1 (0x1) @@ -3096,47 +3053,6 @@ public static System.Collections.Generic.IEnumerable Produce() } """; var verifier = CompileAndVerify(src, expectedOutput: "ran True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 81 (0x51) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0033 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldstr "ran" - IL_001d: stfld "string C.d__0.5__2" - IL_0022: ldarg.0 - IL_0023: ldc.i4.s 42 - IL_0025: stfld "int C.d__0.<>2__current" - IL_002a: ldarg.0 - IL_002b: ldc.i4.1 - IL_002c: stfld "int C.d__0.<>1__state" - IL_0031: ldc.i4.1 - IL_0032: ret - IL_0033: ldarg.0 - IL_0034: ldc.i4.m1 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: ldarg.0 - IL_003b: ldfld "string C.d__0.5__2" - IL_0040: ldstr " " - IL_0045: call "string string.Concat(string, string)" - IL_004a: call "void System.Console.Write(string)" - IL_004f: ldc.i4.0 - IL_0050: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3171,47 +3087,6 @@ public static System.Collections.Generic.IEnumerable Produce() } """; var verifier = CompileAndVerify(src, expectedOutput: "ran True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 81 (0x51) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0033 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldstr "ran" - IL_001d: stfld "string C.d__0.5__2" - IL_0022: ldarg.0 - IL_0023: ldc.i4.s 42 - IL_0025: stfld "int C.d__0.<>2__current" - IL_002a: ldarg.0 - IL_002b: ldc.i4.1 - IL_002c: stfld "int C.d__0.<>1__state" - IL_0031: ldc.i4.1 - IL_0032: ret - IL_0033: ldarg.0 - IL_0034: ldc.i4.m1 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: ldarg.0 - IL_003b: ldfld "string C.d__0.5__2" - IL_0040: ldstr " " - IL_0045: call "string string.Concat(string, string)" - IL_004a: call "void System.Console.Write(string)" - IL_004f: ldc.i4.0 - IL_0050: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3247,53 +3122,6 @@ public static System.Collections.Generic.IEnumerable Produce() """; var comp = CreateCompilation(source); var verifier = CompileAndVerify(comp, expectedOutput: "100 True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 96 (0x60) - .maxstack 3 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_003b - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldc.i4.0 - IL_0019: ldc.i4.s 100 - IL_001b: call "System.Collections.Generic.IEnumerable System.Linq.Enumerable.Range(int, int)" - IL_0020: call "int[] System.Linq.Enumerable.ToArray(System.Collections.Generic.IEnumerable)" - IL_0025: stfld "int[] C.d__0.5__2" - IL_002a: ldarg.0 - IL_002b: ldc.i4.s 42 - IL_002d: stfld "int C.d__0.<>2__current" - IL_0032: ldarg.0 - IL_0033: ldc.i4.1 - IL_0034: stfld "int C.d__0.<>1__state" - IL_0039: ldc.i4.1 - IL_003a: ret - IL_003b: ldarg.0 - IL_003c: ldc.i4.m1 - IL_003d: stfld "int C.d__0.<>1__state" - IL_0042: ldstr "{0} " - IL_0047: ldarg.0 - IL_0048: ldfld "int[] C.d__0.5__2" - IL_004d: ldlen - IL_004e: conv.i4 - IL_004f: box "int" - IL_0054: call "string string.Format(string, object)" - IL_0059: call "void System.Console.Write(string)" - IL_005e: ldc.i4.0 - IL_005f: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3346,55 +3174,6 @@ public static System.Collections.Generic.IEnumerable M(bool b) } """; var verifier = CompileAndVerify(src, expectedOutput: "42 value True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 95 (0x5f) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0035 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: br.s IL_0055 - IL_0019: ldarg.0 - IL_001a: ldstr "value " - IL_001f: stfld "string C.d__0.5__2" - IL_0024: ldarg.0 - IL_0025: ldc.i4.s 42 - IL_0027: stfld "int C.d__0.<>2__current" - IL_002c: ldarg.0 - IL_002d: ldc.i4.1 - IL_002e: stfld "int C.d__0.<>1__state" - IL_0033: ldc.i4.1 - IL_0034: ret - IL_0035: ldarg.0 - IL_0036: ldc.i4.m1 - IL_0037: stfld "int C.d__0.<>1__state" - IL_003c: ldarg.0 - IL_003d: ldc.i4.0 - IL_003e: stfld "bool C.d__0.b" - IL_0043: ldarg.0 - IL_0044: ldfld "string C.d__0.5__2" - IL_0049: call "void System.Console.Write(string)" - IL_004e: ldarg.0 - IL_004f: ldnull - IL_0050: stfld "string C.d__0.5__2" - IL_0055: ldarg.0 - IL_0056: ldfld "bool C.d__0.b" - IL_005b: brtrue.s IL_0019 - IL_005d: ldc.i4.0 - IL_005e: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3448,51 +3227,6 @@ public static System.Collections.Generic.IEnumerable M(bool b) } """; var verifier = CompileAndVerify(src, expectedOutput: "42 value value True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 83 (0x53) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0035 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: br.s IL_0049 - IL_0019: ldarg.0 - IL_001a: ldstr "value " - IL_001f: stfld "string C.d__0.5__2" - IL_0024: ldarg.0 - IL_0025: ldc.i4.s 42 - IL_0027: stfld "int C.d__0.<>2__current" - IL_002c: ldarg.0 - IL_002d: ldc.i4.1 - IL_002e: stfld "int C.d__0.<>1__state" - IL_0033: ldc.i4.1 - IL_0034: ret - IL_0035: ldarg.0 - IL_0036: ldc.i4.m1 - IL_0037: stfld "int C.d__0.<>1__state" - IL_003c: ldarg.0 - IL_003d: ldfld "string C.d__0.5__2" - IL_0042: call "void System.Console.Write(string)" - IL_0047: ldc.i4.0 - IL_0048: ret - IL_0049: ldarg.0 - IL_004a: ldfld "bool C.d__0.b" - IL_004f: brtrue.s IL_0019 - IL_0051: ldc.i4.0 - IL_0052: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3567,45 +3301,6 @@ public static System.Collections.Generic.IEnumerable Produce(int values2) } """; var verifier = CompileAndVerify(src, expectedOutput: "42 4242").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 74 (0x4a) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0027 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldc.i4.0 - IL_0019: stfld "int C.d__0.<>2__current" - IL_001e: ldarg.0 - IL_001f: ldc.i4.1 - IL_0020: stfld "int C.d__0.<>1__state" - IL_0025: ldc.i4.1 - IL_0026: ret - IL_0027: ldarg.0 - IL_0028: ldc.i4.m1 - IL_0029: stfld "int C.d__0.<>1__state" - IL_002e: ldstr "{0} " - IL_0033: ldarg.0 - IL_0034: ldfld "int C.d__0.values2" - IL_0039: box "int" - IL_003e: call "string string.Format(string, object)" - IL_0043: call "void System.Console.Write(string)" - IL_0048: ldc.i4.0 - IL_0049: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 1 (0x1) @@ -3643,53 +3338,6 @@ void local() } """; var verifier = CompileAndVerify(src, expectedOutput: "42 42").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 103 (0x67) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_003f - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldflda "C.<>c__DisplayClass0_0 C.d__0.<>8__1" - IL_001d: ldc.i4.s 41 - IL_001f: stfld "int C.<>c__DisplayClass0_0.values2" - IL_0024: ldarg.0 - IL_0025: ldflda "C.<>c__DisplayClass0_0 C.d__0.<>8__1" - IL_002a: call "void C.g__local|0_0(ref C.<>c__DisplayClass0_0)" - IL_002f: ldarg.0 - IL_0030: ldc.i4.0 - IL_0031: stfld "int C.d__0.<>2__current" - IL_0036: ldarg.0 - IL_0037: ldc.i4.1 - IL_0038: stfld "int C.d__0.<>1__state" - IL_003d: ldc.i4.1 - IL_003e: ret - IL_003f: ldarg.0 - IL_0040: ldc.i4.m1 - IL_0041: stfld "int C.d__0.<>1__state" - IL_0046: ldstr "{0} " - IL_004b: ldarg.0 - IL_004c: ldflda "C.<>c__DisplayClass0_0 C.d__0.<>8__1" - IL_0051: ldfld "int C.<>c__DisplayClass0_0.values2" - IL_0056: box "int" - IL_005b: call "string string.Format(string, object)" - IL_0060: call "void System.Console.Write(string)" - IL_0065: ldc.i4.0 - IL_0066: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 1 (0x1) @@ -3728,46 +3376,6 @@ void local() } """; var verifier = CompileAndVerify(src, expectedOutput: "42").VerifyDiagnostics(); - verifier.VerifyIL("C.d__2.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 66 (0x42) - .maxstack 2 - .locals init (int V_0, - C V_1) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__2.<>1__state" - IL_0006: stloc.0 - IL_0007: ldarg.0 - IL_0008: ldfld "C C.d__2.<>4__this" - IL_000d: stloc.1 - IL_000e: ldloc.0 - IL_000f: brfalse.s IL_0017 - IL_0011: ldloc.0 - IL_0012: ldc.i4.1 - IL_0013: beq.s IL_0039 - IL_0015: ldc.i4.0 - IL_0016: ret - IL_0017: ldarg.0 - IL_0018: ldc.i4.m1 - IL_0019: stfld "int C.d__2.<>1__state" - IL_001e: ldloc.1 - IL_001f: call "void C.g__local|2_0()" - IL_0024: ldarg.0 - IL_0025: ldloc.1 - IL_0026: ldfld "int C.field" - IL_002b: stfld "int C.d__2.<>2__current" - IL_0030: ldarg.0 - IL_0031: ldc.i4.1 - IL_0032: stfld "int C.d__2.<>1__state" - IL_0037: ldc.i4.1 - IL_0038: ret - IL_0039: ldarg.0 - IL_003a: ldc.i4.m1 - IL_003b: stfld "int C.d__2.<>1__state" - IL_0040: ldc.i4.0 - IL_0041: ret -} -"""); verifier.VerifyIL("C.d__2.System.IDisposable.Dispose()", """ { // Code size 1 (0x1) @@ -3805,68 +3413,6 @@ public static System.Collections.Generic.IEnumerable Produce() } """; var verifier = CompileAndVerify(src, expectedOutput: "value ran True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 107 (0x6b) - .maxstack 2 - .locals init (bool V_0, - int V_1) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: brfalse.s IL_0012 - IL_000a: ldloc.1 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_003e - IL_000e: ldc.i4.0 - IL_000f: stloc.0 - IL_0010: leave.s IL_0069 - IL_0012: ldarg.0 - IL_0013: ldc.i4.m1 - IL_0014: stfld "int C.d__0.<>1__state" - IL_0019: ldarg.0 - IL_001a: ldc.i4.s -3 - IL_001c: stfld "int C.d__0.<>1__state" - IL_0021: ldarg.0 - IL_0022: ldstr "value " - IL_0027: stfld "string C.d__0.5__2" - IL_002c: ldarg.0 - IL_002d: ldc.i4.0 - IL_002e: stfld "int C.d__0.<>2__current" - IL_0033: ldarg.0 - IL_0034: ldc.i4.1 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: ldc.i4.1 - IL_003b: stloc.0 - IL_003c: leave.s IL_0069 - IL_003e: ldarg.0 - IL_003f: ldc.i4.s -3 - IL_0041: stfld "int C.d__0.<>1__state" - IL_0046: ldarg.0 - IL_0047: ldfld "string C.d__0.5__2" - IL_004c: call "void System.Console.Write(string)" - IL_0051: ldarg.0 - IL_0052: ldnull - IL_0053: stfld "string C.d__0.5__2" - IL_0058: ldarg.0 - IL_0059: call "void C.d__0.<>m__Finally1()" - IL_005e: ldc.i4.0 - IL_005f: stloc.0 - IL_0060: leave.s IL_0069 - } - fault - { - IL_0062: ldarg.0 - IL_0063: call "void C.d__0.Dispose()" - IL_0068: endfinally - } - IL_0069: ldloc.0 - IL_006a: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 34 (0x22) @@ -3937,70 +3483,6 @@ public static System.Collections.Generic.IEnumerable Produce() } """; var verifier = CompileAndVerify(src, expectedOutput: "value exception True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 113 (0x71) - .maxstack 2 - .locals init (bool V_0, - int V_1) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: brfalse.s IL_0012 - IL_000a: ldloc.1 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_003e - IL_000e: ldc.i4.0 - IL_000f: stloc.0 - IL_0010: leave.s IL_006f - IL_0012: ldarg.0 - IL_0013: ldc.i4.m1 - IL_0014: stfld "int C.d__0.<>1__state" - IL_0019: ldarg.0 - IL_001a: ldc.i4.s -3 - IL_001c: stfld "int C.d__0.<>1__state" - IL_0021: ldarg.0 - IL_0022: ldstr "value " - IL_0027: stfld "string C.d__0.5__2" - IL_002c: ldarg.0 - IL_002d: ldc.i4.0 - IL_002e: stfld "int C.d__0.<>2__current" - IL_0033: ldarg.0 - IL_0034: ldc.i4.1 - IL_0035: stfld "int C.d__0.<>1__state" - IL_003a: ldc.i4.1 - IL_003b: stloc.0 - IL_003c: leave.s IL_006f - IL_003e: ldarg.0 - IL_003f: ldc.i4.s -3 - IL_0041: stfld "int C.d__0.<>1__state" - IL_0046: ldarg.0 - IL_0047: ldfld "string C.d__0.5__2" - IL_004c: call "void System.Console.Write(string)" - IL_0051: ldarg.0 - IL_0052: ldnull - IL_0053: stfld "string C.d__0.5__2" - IL_0058: ldarg.0 - IL_0059: call "void C.d__0.<>m__Finally1()" - IL_005e: leave.s IL_0067 - } - fault - { - IL_0060: ldarg.0 - IL_0061: call "void C.d__0.Dispose()" - IL_0066: endfinally - } - IL_0067: ldarg.0 - IL_0068: call "void C.d__0.Dispose()" - IL_006d: ldc.i4.1 - IL_006e: stloc.0 - IL_006f: ldloc.0 - IL_0070: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 34 (0x22) @@ -4149,54 +3631,6 @@ public static System.Collections.Generic.IEnumerable M(bool b, T t) wher } """; var verifier = CompileAndVerify(src, expectedOutput: "10 42 42").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 94 (0x5e) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0036 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: br.s IL_0054 - IL_0019: ldarg.0 - IL_001a: ldarg.0 - IL_001b: ldfld "T C.d__0.t" - IL_0020: stfld "T C.d__0.5__2" - IL_0025: ldarg.0 - IL_0026: ldc.i4.s 10 - IL_0028: stfld "int C.d__0.<>2__current" - IL_002d: ldarg.0 - IL_002e: ldc.i4.1 - IL_002f: stfld "int C.d__0.<>1__state" - IL_0034: ldc.i4.1 - IL_0035: ret - IL_0036: ldarg.0 - IL_0037: ldc.i4.m1 - IL_0038: stfld "int C.d__0.<>1__state" - IL_003d: ldarg.0 - IL_003e: ldc.i4.0 - IL_003f: stfld "bool C.d__0.b" - IL_0044: ldarg.0 - IL_0045: ldfld "T C.d__0.5__2" - IL_004a: box "T" - IL_004f: call "void System.Console.Write(object)" - IL_0054: ldarg.0 - IL_0055: ldfld "bool C.d__0.b" - IL_005a: brtrue.s IL_0019 - IL_005c: ldc.i4.0 - IL_005d: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 1 (0x1) @@ -4256,55 +3690,6 @@ public static System.Collections.Generic.IEnumerable M(bool b, S s) """; var verifier = CompileAndVerify(src, expectedOutput: "10 42 42", references: [libComp.EmitToImageReference()]).VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 100 (0x64) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0036 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int C.d__0.<>1__state" - IL_0017: br.s IL_005a - IL_0019: ldarg.0 - IL_001a: ldarg.0 - IL_001b: ldfld "S C.d__0.s" - IL_0020: stfld "S C.d__0.5__2" - IL_0025: ldarg.0 - IL_0026: ldc.i4.s 10 - IL_0028: stfld "int C.d__0.<>2__current" - IL_002d: ldarg.0 - IL_002e: ldc.i4.1 - IL_002f: stfld "int C.d__0.<>1__state" - IL_0034: ldc.i4.1 - IL_0035: ret - IL_0036: ldarg.0 - IL_0037: ldc.i4.m1 - IL_0038: stfld "int C.d__0.<>1__state" - IL_003d: ldarg.0 - IL_003e: ldc.i4.0 - IL_003f: stfld "bool C.d__0.b" - IL_0044: ldarg.0 - IL_0045: ldflda "S C.d__0.5__2" - IL_004a: constrained. "S" - IL_0050: callvirt "string object.ToString()" - IL_0055: call "void System.Console.Write(string)" - IL_005a: ldarg.0 - IL_005b: ldfld "bool C.d__0.b" - IL_0060: brtrue.s IL_0019 - IL_0062: ldc.i4.0 - IL_0063: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 1 (0x1) @@ -4415,68 +3800,6 @@ public static System.Collections.Generic.IEnumerable Produce() } """; var verifier = CompileAndVerify(src, expectedOutput: "values2 values3 True").VerifyDiagnostics(); - verifier.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext()", """ -{ - // Code size 142 (0x8e) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int C.d__0.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001b, - IL_003e, - IL_0073) - IL_0019: ldc.i4.0 - IL_001a: ret - IL_001b: ldarg.0 - IL_001c: ldc.i4.m1 - IL_001d: stfld "int C.d__0.<>1__state" - IL_0022: ldarg.0 - IL_0023: ldstr "values2 " - IL_0028: stfld "string C.d__0.5__2" - IL_002d: ldarg.0 - IL_002e: ldc.i4.s 42 - IL_0030: stfld "int C.d__0.<>2__current" - IL_0035: ldarg.0 - IL_0036: ldc.i4.1 - IL_0037: stfld "int C.d__0.<>1__state" - IL_003c: ldc.i4.1 - IL_003d: ret - IL_003e: ldarg.0 - IL_003f: ldc.i4.m1 - IL_0040: stfld "int C.d__0.<>1__state" - IL_0045: ldarg.0 - IL_0046: ldfld "string C.d__0.5__2" - IL_004b: call "void System.Console.Write(string)" - IL_0050: ldarg.0 - IL_0051: ldnull - IL_0052: stfld "string C.d__0.5__2" - IL_0057: ldarg.0 - IL_0058: ldstr "values3 " - IL_005d: stfld "string C.d__0.5__2" - IL_0062: ldarg.0 - IL_0063: ldc.i4.s 43 - IL_0065: stfld "int C.d__0.<>2__current" - IL_006a: ldarg.0 - IL_006b: ldc.i4.2 - IL_006c: stfld "int C.d__0.<>1__state" - IL_0071: ldc.i4.1 - IL_0072: ret - IL_0073: ldarg.0 - IL_0074: ldc.i4.m1 - IL_0075: stfld "int C.d__0.<>1__state" - IL_007a: ldarg.0 - IL_007b: ldfld "string C.d__0.5__2" - IL_0080: call "void System.Console.Write(string)" - IL_0085: ldarg.0 - IL_0086: ldnull - IL_0087: stfld "string C.d__0.5__2" - IL_008c: ldc.i4.0 - IL_008d: ret -} -"""); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -4648,72 +3971,6 @@ public struct Buffer4 """; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); var verifier = CompileAndVerify(comp, expectedOutput: "FalseTrue", verify: Verification.Skipped).VerifyDiagnostics(); - - verifier.VerifyIL("Program.d__1.System.Collections.IEnumerator.MoveNext", """ -{ - // Code size 134 (0x86) - .maxstack 3 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld "int Program.d__1.<>1__state" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_005f - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld "int Program.d__1.<>1__state" - IL_0017: ldarg.0 - IL_0018: ldarg.0 - IL_0019: ldfld "C Program.d__1.x" - IL_001e: stfld "C Program.d__1.<>7__wrap2" - IL_0023: ldarg.0 - IL_0024: ldfld "C Program.d__1.<>7__wrap2" - IL_0029: ldfld "Buffer4 C.F" - IL_002e: pop - IL_002f: ldarg.0 - IL_0030: ldc.i4.0 - IL_0031: stfld "int Program.d__1.<>7__wrap1" - IL_0036: br.s IL_0074 - IL_0038: ldarg.0 - IL_0039: ldfld "C Program.d__1.<>7__wrap2" - IL_003e: ldflda "Buffer4 C.F" - IL_0043: ldarg.0 - IL_0044: ldfld "int Program.d__1.<>7__wrap1" - IL_0049: call "ref int .InlineArrayElementRef, int>(ref Buffer4, int)" - IL_004e: pop - IL_004f: ldarg.0 - IL_0050: ldc.i4.m1 - IL_0051: stfld "int Program.d__1.<>2__current" - IL_0056: ldarg.0 - IL_0057: ldc.i4.1 - IL_0058: stfld "int Program.d__1.<>1__state" - IL_005d: ldc.i4.1 - IL_005e: ret - IL_005f: ldarg.0 - IL_0060: ldc.i4.m1 - IL_0061: stfld "int Program.d__1.<>1__state" - IL_0066: ldarg.0 - IL_0067: ldarg.0 - IL_0068: ldfld "int Program.d__1.<>7__wrap1" - IL_006d: ldc.i4.1 - IL_006e: add - IL_006f: stfld "int Program.d__1.<>7__wrap1" - IL_0074: ldarg.0 - IL_0075: ldfld "int Program.d__1.<>7__wrap1" - IL_007a: ldc.i4.4 - IL_007b: blt.s IL_0038 - IL_007d: ldarg.0 - IL_007e: ldnull - IL_007f: stfld "C Program.d__1.<>7__wrap2" - IL_0084: ldc.i4.0 - IL_0085: ret -} -"""); verifier.VerifyIL("Program.d__1.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) From e19d7abb6f635d7e7d0a8107cbc267931dccb4b9 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 13 Nov 2024 19:06:01 -0800 Subject: [PATCH 04/20] Refine tests --- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 153 ++++++++------ .../Test/Emit/CodeGen/CodeGenAsyncTests.cs | 20 +- .../CodeGenDisplayClassOptimisationTests.cs | 25 ++- .../Test/Emit/CodeGen/CodeGenIterators.cs | 188 ++++++++++++------ .../EditAndContinueStateMachineTests.cs | 14 +- 5 files changed, 250 insertions(+), 150 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 690bb19e2550e..8dfc944d5a3a8 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -9432,15 +9432,15 @@ public void AddVariableCleanup_IntLocal() var values = C.Produce(); await foreach (int value in values) { } -System.Console.Write(((int)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((int)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce() { - int values2 = 42; + int s = 42; await System.Threading.Tasks.Task.CompletedTask; - yield return values2; + yield return s; } } """; @@ -9454,21 +9454,24 @@ public void AddVariableCleanup_StringLocal() using System.Reflection; var values = C.Produce(); -await foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +await foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce() { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); } } """; - var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("value value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ { // Code size 320 (0x140) @@ -9502,7 +9505,7 @@ .locals init (int V_0, IL_0035: stfld "int C.d__0.<>1__state" IL_003a: ldarg.0 IL_003b: ldstr "value " - IL_0040: stfld "string C.d__0.5__2" + IL_0040: stfld "string C.d__0.5__2" IL_0045: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" IL_004a: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" IL_004f: stloc.1 @@ -9557,7 +9560,7 @@ .locals init (int V_0, IL_00c4: brfalse.s IL_00c8 IL_00c6: leave.s IL_0105 IL_00c8: ldarg.0 - IL_00c9: ldfld "string C.d__0.5__2" + IL_00c9: ldfld "string C.d__0.5__2" IL_00ce: call "void System.Console.Write(string)" IL_00d3: leave.s IL_0105 } @@ -9569,7 +9572,7 @@ .locals init (int V_0, IL_00d9: stfld "int C.d__0.<>1__state" IL_00de: ldarg.0 IL_00df: ldnull - IL_00e0: stfld "string C.d__0.5__2" + IL_00e0: stfld "string C.d__0.5__2" IL_00e5: ldarg.0 IL_00e6: ldc.i4.0 IL_00e7: stfld "int C.d__0.<>2__current" @@ -9587,7 +9590,7 @@ .locals init (int V_0, IL_0108: stfld "int C.d__0.<>1__state" IL_010d: ldarg.0 IL_010e: ldnull - IL_010f: stfld "string C.d__0.5__2" + IL_010f: stfld "string C.d__0.5__2" IL_0114: ldarg.0 IL_0115: ldc.i4.0 IL_0116: stfld "int C.d__0.<>2__current" @@ -9615,22 +9618,26 @@ public void AddVariableCleanup_StringLocal_YieldBreak() using System.Reflection; var values = C.Produce(true); -await foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +await foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; - System.Console.Write(values2); + yield return 42; + System.Console.Write(s); if (b) yield break; throw null; } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9649,15 +9656,15 @@ public void AddVariableCleanup_StringLocal_ThrownException() System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; - System.Console.Write(values2); + System.Console.Write(s); if (b) throw new System.Exception("exception "); yield break; } @@ -9673,21 +9680,25 @@ public void AddVariableCleanup_StringLocal_EarlyIterationExit() using System.Reflection; var values = C.Produce(true); -await foreach (var value in values) { break; } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +await foreach (var value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + break; +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce(bool b) { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; yield return 42; - _ = values2.ToString(); + _ = s.ToString(); } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9701,11 +9712,13 @@ public void AddVariableCleanup_NestedStringLocal() var enumerator = values.GetAsyncEnumerator(); assert(await enumerator.MoveNextAsync()); assert(enumerator.Current == 1); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + assert(await enumerator.MoveNextAsync()); assert(enumerator.Current == 2); _ = enumerator.MoveNextAsync(); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); void assert(bool b) { @@ -9718,9 +9731,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - string values2 = "value "; + string s = "value "; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); b = false; } yield return 2; @@ -9729,7 +9742,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9742,9 +9755,10 @@ public void AddVariableCleanup_NestedStringLocal_YieldBreak() var enumerator = values.GetAsyncEnumerator(); assert(await enumerator.MoveNextAsync()); assert(enumerator.Current == 1); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); assert(!(await enumerator.MoveNextAsync())); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); void assert(bool b) { @@ -9757,9 +9771,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - string values2 = "value "; + string s = "value "; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); await System.Threading.Tasks.Task.CompletedTask; if (b) yield break; } @@ -9767,7 +9781,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9790,7 +9804,7 @@ public void AddVariableCleanup_NestedStringLocal_ThrownException() } await enumerator.DisposeAsync(); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); void assert(bool b) { @@ -9803,9 +9817,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - string values2 = "value "; + string s = "value "; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); await System.Threading.Tasks.Task.CompletedTask; if (b) throw new System.Exception("exception "); } @@ -9823,8 +9837,12 @@ public void AddVariableCleanup_NestedStringLocal_EarlyIterationExit() using System.Reflection; var values = C.Produce(true); -await foreach (var value in values) { break; } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +await foreach (var value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + break; +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -9832,9 +9850,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - string values2 = "value "; + string s = "value "; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); await System.Threading.Tasks.Task.CompletedTask; throw null; } @@ -9842,7 +9860,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -9868,7 +9886,7 @@ public struct S assert(enumerator.Current == 2); _ = enumerator.MoveNextAsync(); -System.Console.Write(((S)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((S)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); void assert(bool b) { @@ -9881,9 +9899,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - S values2 = new S { field = 42 }; + S s = new S { field = 42 }; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); b = false; } yield return 2; @@ -9937,7 +9955,7 @@ .locals init (int V_0, IL_004f: ldc.i4.s 42 IL_0051: stfld "int S.field" IL_0056: ldloc.1 - IL_0057: stfld "S C.d__0.5__2" + IL_0057: stfld "S C.d__0.5__2" IL_005c: ldarg.0 IL_005d: ldc.i4.1 IL_005e: stfld "int C.d__0.<>2__current" @@ -9957,7 +9975,7 @@ .locals init (int V_0, IL_0081: brfalse.s IL_0088 IL_0083: leave IL_0181 IL_0088: ldarg.0 - IL_0089: ldfld "S C.d__0.5__2" + IL_0089: ldfld "S C.d__0.5__2" IL_008e: box "S" IL_0093: call "void System.Console.Write(object)" IL_0098: ldarg.0 @@ -10096,7 +10114,7 @@ public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow_EarlyIte System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -10104,10 +10122,10 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { try { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; yield return 42; - values2.ToString(); + s.ToString(); throw null; } finally @@ -10129,10 +10147,11 @@ public void AddVariableCleanup_StringLocal_IAsyncEnumerator() var values = C.Produce(); assert(await values.MoveNextAsync()); assert(values.Current == 1); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); assert(!(await values.MoveNextAsync())); await values.DisposeAsync(); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); static void assert(bool b) { if (!b) throw new System.Exception(); } @@ -10140,14 +10159,14 @@ class C { public static async System.Collections.Generic.IAsyncEnumerator Produce() { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; yield return 1; - System.Console.Write(values2); + System.Console.Write(s); } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value value True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10157,8 +10176,12 @@ public void AddVariableCleanup_NotCleanedTooSoon() using System.Reflection; var values = C.Produce(); -await foreach (int i in values) { break; } -System.Console.Write((values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +await foreach (int i in values) +{ + System.Console.Write((values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + break; +} +System.Console.Write((values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -10166,7 +10189,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() { try { - string values2 = "value "; + string s = "value "; try { await System.Threading.Tasks.Task.CompletedTask; @@ -10174,7 +10197,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } finally { - System.Console.Write(values2); + System.Console.Write(s); } } finally @@ -10184,7 +10207,7 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce() } } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("value outer True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("value value outer True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -10195,7 +10218,11 @@ public void AddVariableCleanup_HoistedFromRefExpression() var c = new C(); var values = Program.Produce(c); -await foreach (int i in values) { System.Console.Write(i); } +await foreach (int i in values) +{ + System.Console.Write((values.GetType().GetField("<>7__wrap3", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + System.Console.Write($" {i} "); +} System.Console.Write((values.GetType().GetField("<>7__wrap3", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); partial class Program @@ -10213,16 +10240,16 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(C x class C { - public Buffer4 F = default; + public Buffer2 F = default; } -[System.Runtime.CompilerServices.InlineArray(4)] -public struct Buffer4 +[System.Runtime.CompilerServices.InlineArray(2)] +public struct Buffer2 { private T _element0; } """; - CompileAndVerify(src, expectedOutput: ExpectedOutput("0123True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: ExpectedOutput("False 0 False 1 True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 89482c2907c11..297059bfb94c8 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -6071,7 +6071,7 @@ public void AddVariableCleanup_NestedStringLocal() object stateMachineBox = callback.Target; object stateMachine = stateMachineBox.GetType().GetField("StateMachine", BindingFlags.Public | BindingFlags.Instance).GetValue(stateMachineBox); -System.Console.Write((string)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine) is null); +System.Console.Write((string)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine) is null); class C { @@ -6079,12 +6079,12 @@ public static async System.Threading.Tasks.Task ProduceAsync(bool b, System { while (b) { - string values2 = "value "; + string s = "value "; await System.Threading.Tasks.Task.CompletedTask; - System.Console.Write(values2); + System.Console.Write(s); b = false; } - await task; // block execution here to check what's in the field for "values2" + await task; // block execution here to check what's in the field for "s" return 42; } } @@ -6114,7 +6114,7 @@ public struct S object stateMachineBox = callback.Target; object stateMachine = stateMachineBox.GetType().GetField("StateMachine", BindingFlags.Public | BindingFlags.Instance).GetValue(stateMachineBox); -System.Console.Write((S)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine)); +System.Console.Write((S)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine)); class C { @@ -6122,12 +6122,12 @@ public static async System.Threading.Tasks.Task ProduceAsync(bool b, System { while (b) { - S values2 = new S { field = 42 }; + S s = new S { field = 42 }; await System.Threading.Tasks.Task.CompletedTask; - System.Console.Write(values2); + System.Console.Write(s); b = false; } - await task; // block execution here to check what's in the field for "values2" + await task; // block execution here to check what's in the field for "s" return 10; } } @@ -6162,7 +6162,7 @@ .locals init (int V_0, IL_0021: ldc.i4.s 42 IL_0023: stfld "int S.field" IL_0028: ldloc.2 - IL_0029: stfld "S C.d__0.5__2" + IL_0029: stfld "S C.d__0.5__2" IL_002e: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" IL_0033: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" IL_0038: stloc.3 @@ -6197,7 +6197,7 @@ .locals init (int V_0, IL_0081: ldloca.s V_3 IL_0083: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" IL_0088: ldarg.0 - IL_0089: ldfld "S C.d__0.5__2" + IL_0089: ldfld "S C.d__0.5__2" IL_008e: box "S" IL_0093: call "void System.Console.Write(object)" IL_0098: ldarg.0 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDisplayClassOptimisationTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDisplayClassOptimisationTests.cs index 03941adc0d1c2..9de4494e5794c 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDisplayClassOptimisationTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDisplayClassOptimisationTests.cs @@ -7742,15 +7742,24 @@ 01 00 00 00 ) .override method instance void [mscorlib]System.IDisposable::Dispose() // Method begins at RVA 0x20b1 - // Code size 1 (0x1) + // Code size 22 (0x16) .maxstack 8 - IL_0000: ret + IL_0000: ldarg.0 + IL_0001: ldnull + IL_0002: stfld class C/'<>c__DisplayClass0_0' C/'d__0'::'<>8__1' + IL_0007: ldarg.0 + IL_0008: ldnull + IL_0009: stfld class C/'<>c__DisplayClass0_1' C/'d__0'::'<>8__2' + IL_000e: ldarg.0 + IL_000f: ldnull + IL_0010: stfld class C/'<>c__DisplayClass0_2' C/'d__0'::'<>8__3' + IL_0015: ret } // end of method 'd__0'::System.IDisposable.Dispose .method private final hidebysig newslot virtual instance bool MoveNext () cil managed { .override method instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() - // Method begins at RVA 0x20b4 + // Method begins at RVA 0x20c8 // Code size 342 (0x156) .maxstack 2 .locals init ( @@ -7889,7 +7898,7 @@ .method private final hidebysig specialname newslot virtual 01 00 00 00 ) .override method instance !0 class [mscorlib]System.Collections.Generic.IEnumerator`1::get_Current() - // Method begins at RVA 0x2216 + // Method begins at RVA 0x222a // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 @@ -7903,7 +7912,7 @@ instance void System.Collections.IEnumerator.Reset () cil managed 01 00 00 00 ) .override method instance void [mscorlib]System.Collections.IEnumerator::Reset() - // Method begins at RVA 0x221e + // Method begins at RVA 0x2232 // Code size 6 (0x6) .maxstack 8 IL_0000: newobj instance void [mscorlib]System.NotSupportedException::.ctor() @@ -7916,7 +7925,7 @@ instance object System.Collections.IEnumerator.get_Current () cil managed 01 00 00 00 ) .override method instance object [mscorlib]System.Collections.IEnumerator::get_Current() - // Method begins at RVA 0x2225 + // Method begins at RVA 0x2239 // Code size 12 (0xc) .maxstack 8 IL_0000: ldarg.0 @@ -7931,7 +7940,7 @@ .method private final hidebysig newslot virtual 01 00 00 00 ) .override method instance class [mscorlib]System.Collections.Generic.IEnumerator`1 class [mscorlib]System.Collections.Generic.IEnumerable`1::GetEnumerator() - // Method begins at RVA 0x2234 + // Method begins at RVA 0x2248 // Code size 43 (0x2b) .maxstack 2 .locals init ( @@ -7964,7 +7973,7 @@ instance class [mscorlib]System.Collections.IEnumerator System.Collections.IEnum 01 00 00 00 ) .override method instance class [mscorlib]System.Collections.IEnumerator [mscorlib]System.Collections.IEnumerable::GetEnumerator() - // Method begins at RVA 0x226b + // Method begins at RVA 0x227f // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index 51b76429652d4..5f3be7001f73f 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3039,27 +3039,30 @@ public void AddVariableCleanup_StringLocal() using System.Reflection; var values = C.Produce(); -foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - string values2 = "ran"; + string s = "ran "; yield return 42; - System.Console.Write($"{values2} "); + System.Console.Write(s); } } """; - var verifier = CompileAndVerify(src, expectedOutput: "ran True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "ran ran True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "string C.d__0.5__2" + IL_0002: stfld "string C.d__0.5__2" IL_0007: ret } """); @@ -3072,63 +3075,69 @@ public void AddVariableCleanup_StringLocal_YieldBreak() using System.Reflection; var values = C.Produce(); -foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - string values2 = "ran"; + string s = "ran "; yield return 42; - System.Console.Write($"{values2} "); + System.Console.Write(s); yield break; } } """; - var verifier = CompileAndVerify(src, expectedOutput: "ran True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "ran ran True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "string C.d__0.5__2" + IL_0002: stfld "string C.d__0.5__2" IL_0007: ret } """); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] - public void AddVariableCleanup_IntArrayLocalAndForeachLocals() + public void AddVariableCleanup_IntArrayLocal() { string source = """ using System.Linq; using System.Reflection; var values = C.Produce(); -foreach (int value in values) { } -System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +foreach (int value in values) +{ + System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)).Length); +} +System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - int[] values2 = Enumerable.Range(0, 100).ToArray(); + int[] s = Enumerable.Range(0, 100).ToArray(); yield return 42; - System.Console.Write($"{values2.Length} "); + System.Console.Write($" {s.Length} "); } } """; var comp = CreateCompilation(source); - var verifier = CompileAndVerify(comp, expectedOutput: "100 True").VerifyDiagnostics(); + var verifier = CompileAndVerify(comp, expectedOutput: "100 100 True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "int[] C.d__0.5__2" + IL_0002: stfld "int[] C.d__0.5__2" IL_0007: ret } """); @@ -3146,6 +3155,7 @@ public void AddVariableCleanup_NestedStringLocal() { assert(enumerator.MoveNext()); System.Console.Write($"{enumerator.Current} "); + System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator))); assert(!enumerator.MoveNext()); System.Console.Write(((string)enumerator.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerator)) is null); } @@ -3173,7 +3183,7 @@ public static System.Collections.Generic.IEnumerable M(bool b) } } """; - var verifier = CompileAndVerify(src, expectedOutput: "42 value True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "42 value value True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3254,6 +3264,7 @@ public void AddVariableCleanup_NestedStringLocal_ThrownException() } finally { + System.Console.Write(((string)enumerable.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerable))); enumerator.Dispose(); } System.Console.Write(((string)enumerable.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(enumerable)) is null); @@ -3277,7 +3288,7 @@ public static System.Collections.Generic.IEnumerable M(bool b) } } """; - CompileAndVerify(src, expectedOutput: "42 True").VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: "42 value True").VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -3288,15 +3299,15 @@ public void AddVariableCleanup_IntParameter() var values = C.Produce(42); foreach (int value in values) { } -System.Console.Write(((int)values.GetType().GetField("values2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); -System.Console.Write(((int)values.GetType().GetField("<>3__values2", BindingFlags.Public | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((int)values.GetType().GetField("s", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((int)values.GetType().GetField("<>3__s", BindingFlags.Public | BindingFlags.Instance).GetValue(values))); class C { - public static System.Collections.Generic.IEnumerable Produce(int values2) + public static System.Collections.Generic.IEnumerable Produce(int s) { yield return 0; - System.Console.Write($"{values2} "); + System.Console.Write($"{s} "); } } """; @@ -3310,6 +3321,36 @@ .maxstack 0 """); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringParameter() + { + string src = """ +using System.Reflection; + +var values = C.Produce("value "); +foreach (int value in values) { } +System.Console.Write(((string)values.GetType().GetField("s", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("<>3__s", BindingFlags.Public | BindingFlags.Instance).GetValue(values))); + +class C +{ + public static System.Collections.Generic.IEnumerable Produce(string s) + { + yield return 0; + System.Console.Write(s); + } +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: "value value value").VerifyDiagnostics(); + verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ +{ + // Code size 1 (0x1) + .maxstack 0 + IL_0000: ret +} +"""); + } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] public void AddVariableCleanup_ClosureOverLocal() { @@ -3319,20 +3360,20 @@ public void AddVariableCleanup_ClosureOverLocal() var values = C.Produce(); foreach (int value in values) { } var closure = values.GetType().GetField("<>8__1", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values); -System.Console.Write((int)(closure.GetType().GetField("values2", BindingFlags.Public | BindingFlags.Instance).GetValue(closure))); +System.Console.Write((int)(closure.GetType().GetField("s", BindingFlags.Public | BindingFlags.Instance).GetValue(closure))); class C { public static System.Collections.Generic.IEnumerable Produce() { - int values2 = 41; + int s = 41; local(); yield return 0; - System.Console.Write($"{values2} "); + System.Console.Write($"{s} "); void local() { - values2++; + s++; } } } @@ -3392,8 +3433,11 @@ public void AddVariableCleanup_NestedStringLocal_InTryFinally() using System.Reflection; var values = C.Produce(); -foreach (int value in values) { } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -3401,9 +3445,9 @@ public static System.Collections.Generic.IEnumerable Produce() { try { - var values2 = "value "; + var s = "value "; yield return 0; - System.Console.Write(values2); + System.Console.Write(s); } finally { @@ -3412,7 +3456,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: "value ran True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "value value ran True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 34 (0x22) @@ -3440,7 +3484,7 @@ .locals init (int V_0) } IL_001a: ldarg.0 IL_001b: ldnull - IL_001c: stfld "string C.d__0.5__2" + IL_001c: stfld "string C.d__0.5__2" IL_0021: ret } """); @@ -3456,14 +3500,17 @@ public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow() try { - foreach (int value in values) { } + foreach (int value in values) + { + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + } } catch (System.Exception e) { System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -3471,9 +3518,9 @@ public static System.Collections.Generic.IEnumerable Produce() { try { - string values2 = "value "; + string s = "value "; yield return 0; - System.Console.Write(values2); + System.Console.Write(s); } finally { @@ -3482,7 +3529,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: "value exception True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "value value exception True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 34 (0x22) @@ -3510,7 +3557,7 @@ .locals init (int V_0) } IL_001a: ldarg.0 IL_001b: ldnull - IL_001c: stfld "string C.d__0.5__2" + IL_001c: stfld "string C.d__0.5__2" IL_0021: ret } """); @@ -3533,7 +3580,7 @@ public void AddVariableCleanup_NestedStringLocal_InTryFinally_WithThrow_EarlyIte System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); class C { @@ -3541,9 +3588,9 @@ public static System.Collections.Generic.IEnumerable Produce() { try { - string values2 = "value"; + string s = "value"; yield return 0; - values2.ToString(); + s.ToString(); throw null; } finally @@ -3574,16 +3621,16 @@ public void AddVariableCleanup_StringLocal_WithThrownException() System.Console.Write(e.Message); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce(bool b) { - string values2 = "value "; + string s = "value "; if (b) throw new System.Exception("exception "); yield return 0; - System.Console.Write(values2); + System.Console.Write(s); } } """; @@ -3754,22 +3801,26 @@ public void AddVariableCleanup_StringLocal_EarlyIterationExit() var values = C.Produce(); -foreach (int value in values) { break; } // we interrupt the iteration early +foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + break; +} -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - string values2 = "value"; + string s = "value "; yield return 0; - values2.ToString(); + s.ToString(); throw null; } } """; - CompileAndVerify(src, expectedOutput: "True").VerifyDiagnostics(); + CompileAndVerify(src, expectedOutput: "value True").VerifyDiagnostics(); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] @@ -3779,7 +3830,10 @@ public void AddVariableCleanup_NestedStringLocal_Reused() using System.Reflection; var values = C.Produce(); -foreach (int value in values) { } +foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +} System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C @@ -3799,7 +3853,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: "values2 values3 True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "values2 values2 values3 values3 True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 8 (0x8) @@ -3847,8 +3901,12 @@ public void AddVariableCleanup_NotCleanedTooSoon() using System.Reflection; var values = C.Produce(); -foreach (int value in values) { break; } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +foreach (int value in values) +{ + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + break; +} +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { @@ -3856,14 +3914,14 @@ public static System.Collections.Generic.IEnumerable Produce() { try { - string values2 = "value "; + string s = "value "; try { yield return 42; } finally { - System.Console.Write(values2); + System.Console.Write(s); } } finally @@ -3873,7 +3931,7 @@ public static System.Collections.Generic.IEnumerable Produce() } } """; - var verifier = CompileAndVerify(src, expectedOutput: "value outer True").VerifyDiagnostics(); + var verifier = CompileAndVerify(src, expectedOutput: "value value outer True").VerifyDiagnostics(); verifier.VerifyIL("C.d__0.System.IDisposable.Dispose()", """ { // Code size 55 (0x37) @@ -3920,7 +3978,7 @@ .locals init (int V_0) } IL_002f: ldarg.0 IL_0030: ldnull - IL_0031: stfld "string C.d__0.5__2" + IL_0031: stfld "string C.d__0.5__2" IL_0036: ret } """); @@ -3993,9 +4051,9 @@ public void AddVariableCleanup_StringLocal_IEnumerator() assert(values.MoveNext()); assert(values.Current == 42); assert(!values.MoveNext()); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); values.Dispose(); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); static void assert(bool b) { if (!b) throw new System.Exception(); } @@ -4003,9 +4061,9 @@ class C { public static System.Collections.Generic.IEnumerator Produce() { - string values2 = "ran "; + string s = "ran "; yield return 42; - System.Console.Write(values2); + System.Console.Write(s); } } """; @@ -4016,7 +4074,7 @@ public static System.Collections.Generic.IEnumerator Produce() .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "string C.d__0.5__2" + IL_0002: stfld "string C.d__0.5__2" IL_0007: ret } """); diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs index f814e6204c9b2..41169ac72a8ff 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs @@ -5176,7 +5176,7 @@ .maxstack 2 v0.VerifyIL("C.d__0.System.IDisposable.Dispose", @" { - // Code size 33 (0x21) + // Code size 40 (0x28) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.0 @@ -5202,12 +5202,15 @@ .locals init (int V_0) IL_001d: endfinally } IL_001e: br.s IL_0020 - IL_0020: ret + IL_0020: ldarg.0 + IL_0021: ldnull + IL_0022: stfld ""System.IDisposable C.d__0.5__1"" + IL_0027: ret } "); diff1.VerifyIL("C.d__0.System.IDisposable.Dispose", @" { - // Code size 35 (0x23) + // Code size 42 (0x2a) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.0 @@ -5235,7 +5238,10 @@ .locals init (int V_0) IL_001f: endfinally } IL_0020: br.s IL_0022 - IL_0022: ret + IL_0022: ldarg.0 + IL_0023: ldnull + IL_0024: stfld ""System.IDisposable C.d__0.5__1"" + IL_0029: ret } "); From 386a0561f3183b5dea065a59a325714f3a539261 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 14 Nov 2024 14:02:18 -0800 Subject: [PATCH 05/20] typo --- .../StateMachineRewriter/MethodToStateMachineRewriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index fb1be68b0618a..83ccb02811418 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -464,7 +464,7 @@ protected BoundBlock GenerateAllHoistedLocalsCleanup() void addVariableCleanupOnce(ArrayBuilder variableCleanup, FieldSymbol field, PooledHashSet alreadyCleaned) { - // Hoisted fields may be re-used, so we can skip those that were cleaed already + // Hoisted fields may be re-used, so we can skip those that were cleared already if (alreadyCleaned.Add(field.Name)) { AddVariableCleanup(variableCleanup, field); From cdcadd007ee5b329ea2fc8c619c6bb64e5f17e4b Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 13:18:54 -0800 Subject: [PATCH 06/20] Add test baseline --- .../Emit/CodeGen/CodeGenAsyncLocalsTests.cs | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs index caaf685ab21be..c097674c5be4d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs @@ -1151,6 +1151,7 @@ public static async void M() var actual = GetFieldLoadsAndStores(c, "Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"); + // TODO2 // make sure we are reusing synthesized iterator locals and that the locals are nulled: AssertEx.AssertEqualToleratingWhitespaceDifferences(@" IL_0000: ldarg.0 @@ -1212,6 +1213,190 @@ public static async void M() IL_0188: ldarg.0 IL_0189: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" ", actual); + + c.VerifyIL("Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ +{ + // Code size 404 (0x194) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int Test.d__3.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0021 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_00cd + IL_0011: ldarg.0 + IL_0012: call "System.Collections.Generic.IEnumerable Test.GetDynamicEnum()" + IL_0017: callvirt "System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()" + IL_001c: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0021: nop + .try + { + IL_0022: ldloc.0 + IL_0023: brfalse.s IL_006b + IL_0025: br.s IL_008f + IL_0027: ldarg.0 + IL_0028: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_002d: callvirt "dynamic System.Collections.Generic.IEnumerator.Current.get" + IL_0032: pop + IL_0033: ldc.i4.1 + IL_0034: call "System.Threading.Tasks.Task Test.F(int)" + IL_0039: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_003e: stloc.1 + IL_003f: ldloca.s V_1 + IL_0041: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0046: brtrue.s IL_0087 + IL_0048: ldarg.0 + IL_0049: ldc.i4.0 + IL_004a: dup + IL_004b: stloc.0 + IL_004c: stfld "int Test.d__3.<>1__state" + IL_0051: ldarg.0 + IL_0052: ldloc.1 + IL_0053: stfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0058: ldarg.0 + IL_0059: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_005e: ldloca.s V_1 + IL_0060: ldarg.0 + IL_0061: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" + IL_0066: leave IL_0193 + IL_006b: ldarg.0 + IL_006c: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0071: stloc.1 + IL_0072: ldarg.0 + IL_0073: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0078: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_007e: ldarg.0 + IL_007f: ldc.i4.m1 + IL_0080: dup + IL_0081: stloc.0 + IL_0082: stfld "int Test.d__3.<>1__state" + IL_0087: ldloca.s V_1 + IL_0089: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_008e: pop + IL_008f: ldarg.0 + IL_0090: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0095: callvirt "bool System.Collections.IEnumerator.MoveNext()" + IL_009a: brtrue.s IL_0027 + IL_009c: leave.s IL_00b6 + } + finally + { + IL_009e: ldloc.0 + IL_009f: ldc.i4.0 + IL_00a0: bge.s IL_00b5 + IL_00a2: ldarg.0 + IL_00a3: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_00a8: brfalse.s IL_00b5 + IL_00aa: ldarg.0 + IL_00ab: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_00b0: callvirt "void System.IDisposable.Dispose()" + IL_00b5: endfinally + } + IL_00b6: ldarg.0 + IL_00b7: ldnull + IL_00b8: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_00bd: ldarg.0 + IL_00be: call "System.Collections.Generic.IEnumerable Test.GetObjectEnum()" + IL_00c3: callvirt "System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()" + IL_00c8: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_00cd: nop + .try + { + IL_00ce: ldloc.0 + IL_00cf: ldc.i4.1 + IL_00d0: beq.s IL_0115 + IL_00d2: br.s IL_0139 + IL_00d4: ldarg.0 + IL_00d5: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_00da: callvirt "object System.Collections.Generic.IEnumerator.Current.get" + IL_00df: pop + IL_00e0: ldc.i4.2 + IL_00e1: call "System.Threading.Tasks.Task Test.F(int)" + IL_00e6: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_00eb: stloc.1 + IL_00ec: ldloca.s V_1 + IL_00ee: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_00f3: brtrue.s IL_0131 + IL_00f5: ldarg.0 + IL_00f6: ldc.i4.1 + IL_00f7: dup + IL_00f8: stloc.0 + IL_00f9: stfld "int Test.d__3.<>1__state" + IL_00fe: ldarg.0 + IL_00ff: ldloc.1 + IL_0100: stfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0105: ldarg.0 + IL_0106: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_010b: ldloca.s V_1 + IL_010d: ldarg.0 + IL_010e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" + IL_0113: leave.s IL_0193 + IL_0115: ldarg.0 + IL_0116: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_011b: stloc.1 + IL_011c: ldarg.0 + IL_011d: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0122: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0128: ldarg.0 + IL_0129: ldc.i4.m1 + IL_012a: dup + IL_012b: stloc.0 + IL_012c: stfld "int Test.d__3.<>1__state" + IL_0131: ldloca.s V_1 + IL_0133: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0138: pop + IL_0139: ldarg.0 + IL_013a: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_013f: callvirt "bool System.Collections.IEnumerator.MoveNext()" + IL_0144: brtrue.s IL_00d4 + IL_0146: leave.s IL_0160 + } + finally + { + IL_0148: ldloc.0 + IL_0149: ldc.i4.0 + IL_014a: bge.s IL_015f + IL_014c: ldarg.0 + IL_014d: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0152: brfalse.s IL_015f + IL_0154: ldarg.0 + IL_0155: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_015a: callvirt "void System.IDisposable.Dispose()" + IL_015f: endfinally + } + IL_0160: ldarg.0 + IL_0161: ldnull + IL_0162: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0167: leave.s IL_0180 + } + catch System.Exception + { + IL_0169: stloc.2 + IL_016a: ldarg.0 + IL_016b: ldc.i4.s -2 + IL_016d: stfld "int Test.d__3.<>1__state" + IL_0172: ldarg.0 + IL_0173: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_0178: ldloc.2 + IL_0179: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" + IL_017e: leave.s IL_0193 + } + IL_0180: ldarg.0 + IL_0181: ldc.i4.s -2 + IL_0183: stfld "int Test.d__3.<>1__state" + IL_0188: ldarg.0 + IL_0189: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_018e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" + IL_0193: ret +} +"""); } [Fact] From e170504bc65e7e549dfe1ec09605561629df2aa4 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 13:56:49 -0800 Subject: [PATCH 07/20] Clear all hoisted locals in async too --- ...yncIteratorMethodToStateMachineRewriter.cs | 9 - .../AsyncMethodToStateMachineRewriter.cs | 31 +- .../Test/Emit/CodeGen/CodeGenAsyncEHTests.cs | 152 ++-- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 38 +- .../Emit/CodeGen/CodeGenAsyncLocalsTests.cs | 221 +++--- .../Emit/CodeGen/CodeGenAsyncMainTests.cs | 84 +- .../Emit/CodeGen/CodeGenAsyncSpillTests.cs | 732 ++++++++++-------- .../Test/Emit/CodeGen/CodeGenAsyncTests.cs | 48 +- .../Emit/CodeGen/CodeGenAwaitForeachTests.cs | 46 +- .../Emit/CodeGen/CodeGenAwaitUsingTests.cs | 264 ++++--- .../CodeGenRefConditionalOperatorTests.cs | 150 ++-- 11 files changed, 1003 insertions(+), 772 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index d13f2ce0d8c9e..360919ddc8d28 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -88,15 +88,6 @@ internal AsyncIteratorMethodToStateMachineRewriter( return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; } - - protected override BoundStatement GenerateHoistedLocalsCleanup(ImmutableArray hoistedLocals) - { - // We need to clean nested hoisted local variables too (not just top-level ones) - // as they are not cleaned when exiting a block if we exit using a `yield break` - // or if the caller interrupts the enumeration after we reached a `yield return`. - // So we clean both top-level and nested hoisted local variables - return GenerateAllHoistedLocalsCleanup(); - } #nullable disable protected override BoundStatement GenerateSetResultCall() diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index 01a73a4bcd364..dd72b1e49ec13 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -156,7 +156,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) // [body] rewrittenBody ), - F.CatchBlocks(GenerateExceptionHandling(exceptionLocal, rootScopeHoistedLocals))) + F.CatchBlocks(GenerateExceptionHandling(exceptionLocal))) ); // ReturnLabel (for the rewritten return expressions in the user's method body) @@ -177,7 +177,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) // The remaining code is hidden to hide the fact that it can run concurrently with the task's continuation } - bodyBuilder.Add(GenerateHoistedLocalsCleanup(rootScopeHoistedLocals)); + bodyBuilder.Add(GenerateAllHoistedLocalsCleanup()); bodyBuilder.Add(GenerateSetResultCall()); @@ -224,7 +224,8 @@ protected virtual BoundStatement GenerateSetResultCall() : ImmutableArray.Empty)); } - protected BoundCatchBlock GenerateExceptionHandling(LocalSymbol exceptionLocal, ImmutableArray hoistedLocals) + // TODO2 move to local function + protected BoundCatchBlock GenerateExceptionHandling(LocalSymbol exceptionLocal) { // catch (Exception ex) // { @@ -253,34 +254,12 @@ protected BoundCatchBlock GenerateExceptionHandling(LocalSymbol exceptionLocal, exceptionFilterOpt: null, body: F.Block( assignFinishedState, // _state = finishedState; - GenerateHoistedLocalsCleanup(hoistedLocals), + GenerateAllHoistedLocalsCleanup(), callSetException, // builder.SetException(ex); OR _promiseOfValueOrEnd.SetException(ex); GenerateReturn(false)), // return; isSynthesizedAsyncCatchAll: true); } - protected virtual BoundStatement GenerateHoistedLocalsCleanup(ImmutableArray hoistedLocals) - { - var builder = ArrayBuilder.GetInstance(); - - // Cleanup all hoisted local variables - // so that they can be collected by GC if needed - foreach (var hoistedLocal in hoistedLocals) - { - var useSiteInfo = new CompoundUseSiteInfo(F.Diagnostics, F.Compilation.Assembly); - var isManagedType = hoistedLocal.Type.IsManagedType(ref useSiteInfo); - F.Diagnostics.Add(hoistedLocal.GetFirstLocationOrNone(), useSiteInfo); - if (!isManagedType) - { - continue; - } - - builder.Add(F.Assignment(F.Field(F.This(), hoistedLocal), F.NullOrDefault(hoistedLocal.Type))); - } - - return F.Block(builder.ToImmutableAndFree()); - } - protected virtual BoundStatement GenerateSetExceptionCall(LocalSymbol exceptionLocal) { Debug.Assert(!CurrentMethod.IsIterator); // an override handles async-iterators diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs index 3078e2a20345e..d334ecedab136 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs @@ -733,7 +733,7 @@ public static void Main() CompileAndVerify(source, expectedOutput: expected). VerifyIL("Test.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 210 (0xd2) + // Code size 227 (0xe3) .maxstack 3 .locals init (int V_0, int V_1, @@ -746,7 +746,7 @@ .locals init (int V_0, .try { IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0058 + IL_0008: brfalse.s IL_005b IL_000a: ldarg.0 IL_000b: ldnull IL_000c: stfld ""object Test.d__1.<>7__wrap1"" @@ -770,7 +770,7 @@ .locals init (int V_0, IL_002e: stloc.3 IL_002f: ldloca.s V_3 IL_0031: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0036: brtrue.s IL_0074 + IL_0036: brtrue.s IL_0077 IL_0038: ldarg.0 IL_0039: ldc.i4.0 IL_003a: dup @@ -784,59 +784,65 @@ .locals init (int V_0, IL_004e: ldloca.s V_3 IL_0050: ldarg.0 IL_0051: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__1)"" - IL_0056: leave.s IL_00d1 - IL_0058: ldarg.0 - IL_0059: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" - IL_005e: stloc.3 - IL_005f: ldarg.0 - IL_0060: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" - IL_0065: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_006b: ldarg.0 - IL_006c: ldc.i4.m1 - IL_006d: dup - IL_006e: stloc.0 - IL_006f: stfld ""int Test.d__1.<>1__state"" - IL_0074: ldloca.s V_3 - IL_0076: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_007b: ldarg.0 - IL_007c: ldfld ""object Test.d__1.<>7__wrap1"" - IL_0081: stloc.2 - IL_0082: ldloc.2 - IL_0083: brfalse.s IL_009a + IL_0056: leave IL_00e2 + IL_005b: ldarg.0 + IL_005c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" + IL_0061: stloc.3 + IL_0062: ldarg.0 + IL_0063: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" + IL_0068: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_006e: ldarg.0 + IL_006f: ldc.i4.m1 + IL_0070: dup + IL_0071: stloc.0 + IL_0072: stfld ""int Test.d__1.<>1__state"" + IL_0077: ldloca.s V_3 + IL_0079: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_007e: ldarg.0 + IL_007f: ldfld ""object Test.d__1.<>7__wrap1"" + IL_0084: stloc.2 IL_0085: ldloc.2 - IL_0086: isinst ""System.Exception"" - IL_008b: dup - IL_008c: brtrue.s IL_0090 - IL_008e: ldloc.2 - IL_008f: throw - IL_0090: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" - IL_0095: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" - IL_009a: ldarg.0 - IL_009b: ldnull - IL_009c: stfld ""object Test.d__1.<>7__wrap1"" - IL_00a1: stloc.1 - IL_00a2: leave.s IL_00bd + IL_0086: brfalse.s IL_009d + IL_0088: ldloc.2 + IL_0089: isinst ""System.Exception"" + IL_008e: dup + IL_008f: brtrue.s IL_0093 + IL_0091: ldloc.2 + IL_0092: throw + IL_0093: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0098: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_009d: ldarg.0 + IL_009e: ldnull + IL_009f: stfld ""object Test.d__1.<>7__wrap1"" + IL_00a4: stloc.1 + IL_00a5: leave.s IL_00c7 } catch System.Exception { - IL_00a4: stloc.s V_4 - IL_00a6: ldarg.0 - IL_00a7: ldc.i4.s -2 - IL_00a9: stfld ""int Test.d__1.<>1__state"" - IL_00ae: ldarg.0 - IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_00b4: ldloc.s V_4 - IL_00b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00bb: leave.s IL_00d1 + IL_00a7: stloc.s V_4 + IL_00a9: ldarg.0 + IL_00aa: ldc.i4.s -2 + IL_00ac: stfld ""int Test.d__1.<>1__state"" + IL_00b1: ldarg.0 + IL_00b2: ldnull + IL_00b3: stfld ""object Test.d__1.<>7__wrap1"" + IL_00b8: ldarg.0 + IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_00be: ldloc.s V_4 + IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00c5: leave.s IL_00e2 } - IL_00bd: ldarg.0 - IL_00be: ldc.i4.s -2 - IL_00c0: stfld ""int Test.d__1.<>1__state"" - IL_00c5: ldarg.0 - IL_00c6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_00cb: ldloc.1 - IL_00cc: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_00d1: ret + IL_00c7: ldarg.0 + IL_00c8: ldc.i4.s -2 + IL_00ca: stfld ""int Test.d__1.<>1__state"" + IL_00cf: ldarg.0 + IL_00d0: ldnull + IL_00d1: stfld ""object Test.d__1.<>7__wrap1"" + IL_00d6: ldarg.0 + IL_00d7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_00dc: ldloc.1 + IL_00dd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_00e2: ret } "); } @@ -985,7 +991,7 @@ public static void Main() v.VerifyIL("Test.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @"{ - // Code size 461 (0x1cd) + // Code size 475 (0x1db) .maxstack 3 .locals init (int V_0, int V_1, @@ -1049,7 +1055,7 @@ .locals init (int V_0, IL_0066: ldloca.s V_3 IL_0068: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__1)"" IL_006d: nop - IL_006e: leave IL_01cc + IL_006e: leave IL_01da >IL_0073: ldarg.0 IL_0074: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" IL_0079: stloc.2 @@ -1114,7 +1120,7 @@ .locals init (int V_0, IL_0108: ldloca.s V_3 IL_010a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__1)"" IL_010f: nop - IL_0110: leave IL_01cc + IL_0110: leave IL_01da >IL_0115: ldarg.0 IL_0116: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" IL_011b: stloc.s V_5 @@ -1164,11 +1170,11 @@ .locals init (int V_0, IL_018b: ldarg.0 IL_018c: ldfld ""int Test.d__1.<>s__4"" IL_0191: stloc.1 - IL_0192: leave.s IL_01b7 + IL_0192: leave.s IL_01be IL_0194: ldarg.0 IL_0195: ldnull IL_0196: stfld ""object Test.d__1.<>s__2"" - IL_019b: leave.s IL_01b7 + IL_019b: leave.s IL_01be } catch System.Exception { @@ -1177,21 +1183,27 @@ .locals init (int V_0, IL_01a0: ldc.i4.s -2 IL_01a2: stfld ""int Test.d__1.<>1__state"" IL_01a7: ldarg.0 - IL_01a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_01ad: ldloc.s V_6 - IL_01af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01b4: nop - IL_01b5: leave.s IL_01cc + IL_01a8: ldnull + IL_01a9: stfld ""object Test.d__1.<>s__2"" + IL_01ae: ldarg.0 + IL_01af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_01b4: ldloc.s V_6 + IL_01b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01bb: nop + IL_01bc: leave.s IL_01da } - -IL_01b7: ldarg.0 - IL_01b8: ldc.i4.s -2 - IL_01ba: stfld ""int Test.d__1.<>1__state"" - ~IL_01bf: ldarg.0 - IL_01c0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_01c5: ldloc.1 - IL_01c6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_01cb: nop - IL_01cc: ret + -IL_01be: ldarg.0 + IL_01bf: ldc.i4.s -2 + IL_01c1: stfld ""int Test.d__1.<>1__state"" + ~IL_01c6: ldarg.0 + IL_01c7: ldnull + IL_01c8: stfld ""object Test.d__1.<>s__2"" + IL_01cd: ldarg.0 + IL_01ce: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_01d3: ldloc.1 + IL_01d4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_01d9: nop + IL_01da: ret }", sequencePoints: "Test+d__1.MoveNext"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 8dfc944d5a3a8..6950456ddee54 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -720,7 +720,7 @@ ref struct S verifier.VerifyDiagnostics(); verifier.VerifyIL("C.
d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ { - // Code size 238 (0xee) + // Code size 252 (0xfc) .maxstack 3 .locals init (int V_0, S V_1, //s @@ -782,7 +782,7 @@ .locals init (int V_0, IL_0078: ldloca.s V_3 IL_007a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__1)" IL_007f: nop - IL_0080: leave.s IL_00ed + IL_0080: leave.s IL_00fb IL_0082: ldarg.0 IL_0083: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__1.<>u__1" IL_0088: stloc.2 @@ -804,7 +804,7 @@ .locals init (int V_0, IL_00b6: ldarg.0 IL_00b7: ldnull IL_00b8: stfld "E C.
d__1.<>s__1" - IL_00bd: leave.s IL_00d9 + IL_00bd: leave.s IL_00e0 } catch System.Exception { @@ -813,20 +813,26 @@ .locals init (int V_0, IL_00c2: ldc.i4.s -2 IL_00c4: stfld "int C.
d__1.<>1__state" IL_00c9: ldarg.0 - IL_00ca: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" - IL_00cf: ldloc.s V_4 - IL_00d1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" - IL_00d6: nop - IL_00d7: leave.s IL_00ed + IL_00ca: ldnull + IL_00cb: stfld "E C.
d__1.<>s__1" + IL_00d0: ldarg.0 + IL_00d1: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_00d6: ldloc.s V_4 + IL_00d8: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_00dd: nop + IL_00de: leave.s IL_00fb } - IL_00d9: ldarg.0 - IL_00da: ldc.i4.s -2 - IL_00dc: stfld "int C.
d__1.<>1__state" - IL_00e1: ldarg.0 - IL_00e2: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" - IL_00e7: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" - IL_00ec: nop - IL_00ed: ret + IL_00e0: ldarg.0 + IL_00e1: ldc.i4.s -2 + IL_00e3: stfld "int C.
d__1.<>1__state" + IL_00e8: ldarg.0 + IL_00e9: ldnull + IL_00ea: stfld "E C.
d__1.<>s__1" + IL_00ef: ldarg.0 + IL_00f0: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_00f5: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_00fa: nop + IL_00fb: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs index c097674c5be4d..db85c729f2910 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs @@ -1103,28 +1103,40 @@ public static async void M() IL_0317: stfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" IL_031c: ldarg.0 IL_031d: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" -IL_032c: ldarg.0 -IL_032d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" -IL_0333: ldarg.0 -IL_0334: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" -IL_0342: stloc.0 -IL_0343: stfld ""int Test.d__2.<>1__state"" -IL_0350: ldarg.0 -IL_0351: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_0363: ldarg.0 -IL_0364: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_036b: ldarg.0 -IL_036c: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_0378: ldnull -IL_0379: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_0382: ldc.i4.s -2 -IL_0384: stfld ""int Test.d__2.<>1__state"" -IL_0389: ldarg.0 -IL_038a: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" -IL_0398: ldc.i4.s -2 -IL_039a: stfld ""int Test.d__2.<>1__state"" -IL_039f: ldarg.0 -IL_03a0: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" +IL_032f: ldarg.0 +IL_0330: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" +IL_0336: ldarg.0 +IL_0337: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" +IL_0345: stloc.0 +IL_0346: stfld ""int Test.d__2.<>1__state"" +IL_0353: ldarg.0 +IL_0354: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_0366: ldarg.0 +IL_0367: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_036e: ldarg.0 +IL_036f: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_037b: ldnull +IL_037c: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_0385: ldc.i4.s -2 +IL_0387: stfld ""int Test.d__2.<>1__state"" +IL_038d: ldnull +IL_038e: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap1"" +IL_0394: ldnull +IL_0395: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap2"" +IL_039b: ldnull +IL_039c: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_03a1: ldarg.0 +IL_03a2: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" +IL_03b0: ldc.i4.s -2 +IL_03b2: stfld ""int Test.d__2.<>1__state"" +IL_03b8: ldnull +IL_03b9: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap1"" +IL_03bf: ldnull +IL_03c0: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap2"" +IL_03c6: ldnull +IL_03c7: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_03cc: ldarg.0 +IL_03cd: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" ", actual); } @@ -1151,7 +1163,6 @@ public static async void M() var actual = GetFieldLoadsAndStores(c, "Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"); - // TODO2 // make sure we are reusing synthesized iterator locals and that the locals are nulled: AssertEx.AssertEqualToleratingWhitespaceDifferences(@" IL_0000: ldarg.0 @@ -1190,33 +1201,37 @@ public static async void M() IL_0100: stfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" IL_0105: ldarg.0 IL_0106: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" -IL_0115: ldarg.0 -IL_0116: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" -IL_011c: ldarg.0 -IL_011d: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" -IL_012b: stloc.0 -IL_012c: stfld ""int Test.d__3.<>1__state"" -IL_0139: ldarg.0 -IL_013a: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_014c: ldarg.0 -IL_014d: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_0154: ldarg.0 -IL_0155: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_0161: ldnull -IL_0162: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_016b: ldc.i4.s -2 -IL_016d: stfld ""int Test.d__3.<>1__state"" -IL_0172: ldarg.0 -IL_0173: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" -IL_0181: ldc.i4.s -2 -IL_0183: stfld ""int Test.d__3.<>1__state"" -IL_0188: ldarg.0 -IL_0189: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" +IL_0118: ldarg.0 +IL_0119: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" +IL_011f: ldarg.0 +IL_0120: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" +IL_012e: stloc.0 +IL_012f: stfld ""int Test.d__3.<>1__state"" +IL_013c: ldarg.0 +IL_013d: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_014f: ldarg.0 +IL_0150: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_0157: ldarg.0 +IL_0158: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_0164: ldnull +IL_0165: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_016e: ldc.i4.s -2 +IL_0170: stfld ""int Test.d__3.<>1__state"" +IL_0176: ldnull +IL_0177: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_017c: ldarg.0 +IL_017d: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" +IL_018b: ldc.i4.s -2 +IL_018d: stfld ""int Test.d__3.<>1__state"" +IL_0193: ldnull +IL_0194: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_0199: ldarg.0 +IL_019a: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" ", actual); c.VerifyIL("Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ { - // Code size 404 (0x194) + // Code size 421 (0x1a5) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -1265,7 +1280,7 @@ .locals init (int V_0, IL_005e: ldloca.s V_1 IL_0060: ldarg.0 IL_0061: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" - IL_0066: leave IL_0193 + IL_0066: leave IL_01a4 IL_006b: ldarg.0 IL_006c: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" IL_0071: stloc.1 @@ -1311,8 +1326,8 @@ .locals init (int V_0, { IL_00ce: ldloc.0 IL_00cf: ldc.i4.1 - IL_00d0: beq.s IL_0115 - IL_00d2: br.s IL_0139 + IL_00d0: beq.s IL_0118 + IL_00d2: br.s IL_013c IL_00d4: ldarg.0 IL_00d5: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" IL_00da: callvirt "object System.Collections.Generic.IEnumerator.Current.get" @@ -1323,7 +1338,7 @@ .locals init (int V_0, IL_00eb: stloc.1 IL_00ec: ldloca.s V_1 IL_00ee: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_00f3: brtrue.s IL_0131 + IL_00f3: brtrue.s IL_0134 IL_00f5: ldarg.0 IL_00f6: ldc.i4.1 IL_00f7: dup @@ -1337,64 +1352,70 @@ .locals init (int V_0, IL_010b: ldloca.s V_1 IL_010d: ldarg.0 IL_010e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" - IL_0113: leave.s IL_0193 - IL_0115: ldarg.0 - IL_0116: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_011b: stloc.1 - IL_011c: ldarg.0 - IL_011d: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0122: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0128: ldarg.0 - IL_0129: ldc.i4.m1 - IL_012a: dup - IL_012b: stloc.0 - IL_012c: stfld "int Test.d__3.<>1__state" - IL_0131: ldloca.s V_1 - IL_0133: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_0138: pop - IL_0139: ldarg.0 - IL_013a: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_013f: callvirt "bool System.Collections.IEnumerator.MoveNext()" - IL_0144: brtrue.s IL_00d4 - IL_0146: leave.s IL_0160 + IL_0113: leave IL_01a4 + IL_0118: ldarg.0 + IL_0119: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_011e: stloc.1 + IL_011f: ldarg.0 + IL_0120: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0125: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_012b: ldarg.0 + IL_012c: ldc.i4.m1 + IL_012d: dup + IL_012e: stloc.0 + IL_012f: stfld "int Test.d__3.<>1__state" + IL_0134: ldloca.s V_1 + IL_0136: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_013b: pop + IL_013c: ldarg.0 + IL_013d: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0142: callvirt "bool System.Collections.IEnumerator.MoveNext()" + IL_0147: brtrue.s IL_00d4 + IL_0149: leave.s IL_0163 } finally { - IL_0148: ldloc.0 - IL_0149: ldc.i4.0 - IL_014a: bge.s IL_015f - IL_014c: ldarg.0 - IL_014d: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0152: brfalse.s IL_015f - IL_0154: ldarg.0 - IL_0155: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_015a: callvirt "void System.IDisposable.Dispose()" - IL_015f: endfinally + IL_014b: ldloc.0 + IL_014c: ldc.i4.0 + IL_014d: bge.s IL_0162 + IL_014f: ldarg.0 + IL_0150: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0155: brfalse.s IL_0162 + IL_0157: ldarg.0 + IL_0158: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_015d: callvirt "void System.IDisposable.Dispose()" + IL_0162: endfinally } - IL_0160: ldarg.0 - IL_0161: ldnull - IL_0162: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0167: leave.s IL_0180 + IL_0163: ldarg.0 + IL_0164: ldnull + IL_0165: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_016a: leave.s IL_018a } catch System.Exception { - IL_0169: stloc.2 - IL_016a: ldarg.0 - IL_016b: ldc.i4.s -2 - IL_016d: stfld "int Test.d__3.<>1__state" - IL_0172: ldarg.0 - IL_0173: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_0178: ldloc.2 - IL_0179: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" - IL_017e: leave.s IL_0193 + IL_016c: stloc.2 + IL_016d: ldarg.0 + IL_016e: ldc.i4.s -2 + IL_0170: stfld "int Test.d__3.<>1__state" + IL_0175: ldarg.0 + IL_0176: ldnull + IL_0177: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_017c: ldarg.0 + IL_017d: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_0182: ldloc.2 + IL_0183: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" + IL_0188: leave.s IL_01a4 } - IL_0180: ldarg.0 - IL_0181: ldc.i4.s -2 - IL_0183: stfld "int Test.d__3.<>1__state" - IL_0188: ldarg.0 - IL_0189: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_018e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" - IL_0193: ret + IL_018a: ldarg.0 + IL_018b: ldc.i4.s -2 + IL_018d: stfld "int Test.d__3.<>1__state" + IL_0192: ldarg.0 + IL_0193: ldnull + IL_0194: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0199: ldarg.0 + IL_019a: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_019f: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" + IL_01a4: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs index a822b9665647e..99d44c346fa24 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs @@ -1567,7 +1567,7 @@ static async Task Main() var verifier = CompileAndVerify(comp, expectedOutput: ""); verifier.VerifyIL("Program.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"{ - // Code size 426 (0x1aa) + // Code size 454 (0x1c6) .maxstack 3 .locals init (int V_0, object V_1, @@ -1640,7 +1640,7 @@ .locals init (int V_0, IL_0071: ldloca.s V_2 IL_0073: ldarg.0 IL_0074: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.
d__0)"" - IL_0079: leave IL_01a9 + IL_0079: leave IL_01c5 IL_007e: ldarg.0 IL_007f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.
d__0.<>u__1"" IL_0084: stloc.2 @@ -1717,7 +1717,7 @@ .locals init (int V_0, IL_0118: ldloca.s V_2 IL_011a: ldarg.0 IL_011b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.
d__0)"" - IL_0120: leave IL_01a9 + IL_0120: leave IL_01c5 IL_0125: ldarg.0 IL_0126: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.
d__0.<>u__1"" IL_012b: stloc.2 @@ -1750,11 +1750,11 @@ .locals init (int V_0, IL_016e: ldloc.3 IL_016f: ldc.i4.1 IL_0170: bne.un.s IL_0174 - IL_0172: leave.s IL_0196 + IL_0172: leave.s IL_01a4 IL_0174: ldarg.0 IL_0175: ldnull IL_0176: stfld ""object Program.
d__0.<>7__wrap1"" - IL_017b: leave.s IL_0196 + IL_017b: leave.s IL_01a4 } catch System.Exception { @@ -1763,18 +1763,30 @@ .locals init (int V_0, IL_0180: ldc.i4.s -2 IL_0182: stfld ""int Program.
d__0.<>1__state"" IL_0187: ldarg.0 - IL_0188: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_018d: ldloc.s V_4 - IL_018f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0194: leave.s IL_01a9 + IL_0188: ldnull + IL_0189: stfld ""object Program.
d__0.<>7__wrap3"" + IL_018e: ldarg.0 + IL_018f: ldnull + IL_0190: stfld ""object Program.
d__0.<>7__wrap1"" + IL_0195: ldarg.0 + IL_0196: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_019b: ldloc.s V_4 + IL_019d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01a2: leave.s IL_01c5 } - IL_0196: ldarg.0 - IL_0197: ldc.i4.s -2 - IL_0199: stfld ""int Program.
d__0.<>1__state"" - IL_019e: ldarg.0 - IL_019f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_01a4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01a9: ret + IL_01a4: ldarg.0 + IL_01a5: ldc.i4.s -2 + IL_01a7: stfld ""int Program.
d__0.<>1__state"" + IL_01ac: ldarg.0 + IL_01ad: ldnull + IL_01ae: stfld ""object Program.
d__0.<>7__wrap3"" + IL_01b3: ldarg.0 + IL_01b4: ldnull + IL_01b5: stfld ""object Program.
d__0.<>7__wrap1"" + IL_01ba: ldarg.0 + IL_01bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_01c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01c5: ret }"); } @@ -1809,7 +1821,7 @@ static async Task Main() var verifier = CompileAndVerify(comp, expectedOutput: ""); verifier.VerifyIL("Program.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"{ - // Code size 320 (0x140) + // Code size 348 (0x15c) .maxstack 3 .locals init (int V_0, object V_1, @@ -1876,7 +1888,7 @@ .locals init (int V_0, IL_0071: ldloca.s V_2 IL_0073: ldarg.0 IL_0074: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.
d__0)"" - IL_0079: leave IL_013f + IL_0079: leave IL_015b IL_007e: ldarg.0 IL_007f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.
d__0.<>u__1"" IL_0084: stloc.2 @@ -1943,7 +1955,7 @@ .locals init (int V_0, IL_0106: ldfld ""int Program.
d__0.5__2"" IL_010b: ldc.i4.5 IL_010c: blt IL_0016 - IL_0111: leave.s IL_012c + IL_0111: leave.s IL_013a } catch System.Exception { @@ -1952,18 +1964,30 @@ .locals init (int V_0, IL_0116: ldc.i4.s -2 IL_0118: stfld ""int Program.
d__0.<>1__state"" IL_011d: ldarg.0 - IL_011e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_0123: ldloc.s V_4 - IL_0125: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_012a: leave.s IL_013f + IL_011e: ldnull + IL_011f: stfld ""object Program.
d__0.<>7__wrap3"" + IL_0124: ldarg.0 + IL_0125: ldnull + IL_0126: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" + IL_012b: ldarg.0 + IL_012c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_0131: ldloc.s V_4 + IL_0133: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0138: leave.s IL_015b } - IL_012c: ldarg.0 - IL_012d: ldc.i4.s -2 - IL_012f: stfld ""int Program.
d__0.<>1__state"" - IL_0134: ldarg.0 - IL_0135: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_013a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_013f: ret + IL_013a: ldarg.0 + IL_013b: ldc.i4.s -2 + IL_013d: stfld ""int Program.
d__0.<>1__state"" + IL_0142: ldarg.0 + IL_0143: ldnull + IL_0144: stfld ""object Program.
d__0.<>7__wrap3"" + IL_0149: ldarg.0 + IL_014a: ldnull + IL_014b: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" + IL_0150: ldarg.0 + IL_0151: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_0156: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_015b: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs index 999bf6667331d..784ca194a2fd9 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs @@ -597,7 +597,7 @@ public static async Task F(int[] array) v.VerifyIL("Test.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @"{ - // Code size 273 (0x111) + // Code size 287 (0x11f) .maxstack 5 .locals init (int V_0, int V_1, @@ -666,7 +666,7 @@ .locals init (int V_0, IL_007b: ldloca.s V_4 IL_007d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__2)"" IL_0082: nop - IL_0083: leave IL_0110 + IL_0083: leave IL_011e >IL_0088: ldarg.0 IL_0089: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" IL_008e: stloc.3 @@ -704,7 +704,7 @@ .locals init (int V_0, IL_00d8: stfld ""int[] Test.d__2.<>s__4"" -IL_00dd: ldc.i4.1 IL_00de: stloc.1 - IL_00df: leave.s IL_00fb + IL_00df: leave.s IL_0102 } catch System.Exception { @@ -713,21 +713,27 @@ .locals init (int V_0, IL_00e4: ldc.i4.s -2 IL_00e6: stfld ""int Test.d__2.<>1__state"" IL_00eb: ldarg.0 - IL_00ec: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00f1: ldloc.s V_5 - IL_00f3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00f8: nop - IL_00f9: leave.s IL_0110 + IL_00ec: ldnull + IL_00ed: stfld ""int[] Test.d__2.<>s__4"" + IL_00f2: ldarg.0 + IL_00f3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00f8: ldloc.s V_5 + IL_00fa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00ff: nop + IL_0100: leave.s IL_011e } - -IL_00fb: ldarg.0 - IL_00fc: ldc.i4.s -2 - IL_00fe: stfld ""int Test.d__2.<>1__state"" - ~IL_0103: ldarg.0 - IL_0104: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_0109: ldloc.1 - IL_010a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_010f: nop - IL_0110: ret + -IL_0102: ldarg.0 + IL_0103: ldc.i4.s -2 + IL_0105: stfld ""int Test.d__2.<>1__state"" + ~IL_010a: ldarg.0 + IL_010b: ldnull + IL_010c: stfld ""int[] Test.d__2.<>s__4"" + IL_0111: ldarg.0 + IL_0112: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_0117: ldloc.1 + IL_0118: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_011d: nop + IL_011e: ret }", sequencePoints: "Test+d__2.MoveNext"); } @@ -760,7 +766,7 @@ public static async Task F(int[] array) v.VerifyIL("Test.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 251 (0xfb) + // Code size 268 (0x10c) .maxstack 5 .locals init (int V_0, int V_1, @@ -774,7 +780,7 @@ .locals init (int V_0, .try { ~IL_0007: ldloc.0 - IL_0008: brfalse.s IL_007d + IL_0008: brfalse.s IL_0080 -IL_000a: ldarg.0 IL_000b: ldarg.0 IL_000c: ldfld ""int[] Test.d__2.array"" @@ -809,7 +815,7 @@ .locals init (int V_0, IL_0051: stloc.s V_4 ~IL_0053: ldloca.s V_4 IL_0055: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_005a: brtrue.s IL_009a + IL_005a: brtrue.s IL_009d IL_005c: ldarg.0 IL_005d: ldc.i4.0 IL_005e: dup @@ -823,64 +829,70 @@ .locals init (int V_0, IL_0073: ldloca.s V_4 IL_0075: ldarg.0 IL_0076: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__2)"" - IL_007b: leave.s IL_00fa - >IL_007d: ldarg.0 - IL_007e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" - IL_0083: stloc.s V_4 - IL_0085: ldarg.0 - IL_0086: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" - IL_008b: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0091: ldarg.0 - IL_0092: ldc.i4.m1 - IL_0093: dup - IL_0094: stloc.0 - IL_0095: stfld ""int Test.d__2.<>1__state"" - IL_009a: ldloca.s V_4 - IL_009c: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00a1: stloc.2 - IL_00a2: ldarg.0 - IL_00a3: ldfld ""int Test.d__2.<>7__wrap1"" - IL_00a8: ldarg.0 - IL_00a9: ldfld ""int[] Test.d__2.<>7__wrap3"" - IL_00ae: ldc.i4.3 - IL_00af: ldarg.0 - IL_00b0: ldfld ""int Test.d__2.<>7__wrap2"" - IL_00b5: ldloc.2 - IL_00b6: add - IL_00b7: dup - IL_00b8: stloc.3 - IL_00b9: stelem.i4 - IL_00ba: ldloc.3 - IL_00bb: ldc.i4.4 - IL_00bc: call ""int Test.H(int, int, int)"" - IL_00c1: pop - IL_00c2: ldarg.0 - IL_00c3: ldnull - IL_00c4: stfld ""int[] Test.d__2.<>7__wrap3"" - -IL_00c9: ldc.i4.1 - IL_00ca: stloc.1 - IL_00cb: leave.s IL_00e6 + IL_007b: leave IL_010b + >IL_0080: ldarg.0 + IL_0081: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" + IL_0086: stloc.s V_4 + IL_0088: ldarg.0 + IL_0089: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" + IL_008e: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0094: ldarg.0 + IL_0095: ldc.i4.m1 + IL_0096: dup + IL_0097: stloc.0 + IL_0098: stfld ""int Test.d__2.<>1__state"" + IL_009d: ldloca.s V_4 + IL_009f: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_00a4: stloc.2 + IL_00a5: ldarg.0 + IL_00a6: ldfld ""int Test.d__2.<>7__wrap1"" + IL_00ab: ldarg.0 + IL_00ac: ldfld ""int[] Test.d__2.<>7__wrap3"" + IL_00b1: ldc.i4.3 + IL_00b2: ldarg.0 + IL_00b3: ldfld ""int Test.d__2.<>7__wrap2"" + IL_00b8: ldloc.2 + IL_00b9: add + IL_00ba: dup + IL_00bb: stloc.3 + IL_00bc: stelem.i4 + IL_00bd: ldloc.3 + IL_00be: ldc.i4.4 + IL_00bf: call ""int Test.H(int, int, int)"" + IL_00c4: pop + IL_00c5: ldarg.0 + IL_00c6: ldnull + IL_00c7: stfld ""int[] Test.d__2.<>7__wrap3"" + -IL_00cc: ldc.i4.1 + IL_00cd: stloc.1 + IL_00ce: leave.s IL_00f0 } catch System.Exception { - ~IL_00cd: stloc.s V_5 - IL_00cf: ldarg.0 - IL_00d0: ldc.i4.s -2 - IL_00d2: stfld ""int Test.d__2.<>1__state"" - IL_00d7: ldarg.0 - IL_00d8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00dd: ldloc.s V_5 - IL_00df: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00e4: leave.s IL_00fa + ~IL_00d0: stloc.s V_5 + IL_00d2: ldarg.0 + IL_00d3: ldc.i4.s -2 + IL_00d5: stfld ""int Test.d__2.<>1__state"" + IL_00da: ldarg.0 + IL_00db: ldnull + IL_00dc: stfld ""int[] Test.d__2.<>7__wrap3"" + IL_00e1: ldarg.0 + IL_00e2: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00e7: ldloc.s V_5 + IL_00e9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00ee: leave.s IL_010b } - -IL_00e6: ldarg.0 - IL_00e7: ldc.i4.s -2 - IL_00e9: stfld ""int Test.d__2.<>1__state"" - ~IL_00ee: ldarg.0 - IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00f4: ldloc.1 - IL_00f5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_00fa: ret + -IL_00f0: ldarg.0 + IL_00f1: ldc.i4.s -2 + IL_00f3: stfld ""int Test.d__2.<>1__state"" + ~IL_00f8: ldarg.0 + IL_00f9: ldnull + IL_00fa: stfld ""int[] Test.d__2.<>7__wrap3"" + IL_00ff: ldarg.0 + IL_0100: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_0105: ldloc.1 + IL_0106: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_010b: ret }", sequencePoints: "Test+d__2.MoveNext"); } @@ -3579,7 +3591,7 @@ public sealed class JsonSerializerOptions v.VerifyMethodBody("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 184 (0xb8) + // Code size 198 (0xc6) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -3623,7 +3635,7 @@ .locals init (int V_0, IL_003d: ldloca.s V_2 IL_003f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__1)"" IL_0044: nop - IL_0045: leave.s IL_00b7 + IL_0045: leave.s IL_00c5 // async: resume IL_0047: ldarg.0 IL_0048: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1"" @@ -3649,7 +3661,7 @@ .locals init (int V_0, IL_0082: ldarg.0 IL_0083: ldnull IL_0084: stfld ""byte[] Program.d__1.<>s__1"" - IL_0089: leave.s IL_00a3 + IL_0089: leave.s IL_00aa } catch System.Exception { @@ -3659,22 +3671,28 @@ .locals init (int V_0, IL_008d: ldc.i4.s -2 IL_008f: stfld ""int Program.d__1.<>1__state"" IL_0094: ldarg.0 - IL_0095: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" - IL_009a: ldloc.3 - IL_009b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a0: nop - IL_00a1: leave.s IL_00b7 + IL_0095: ldnull + IL_0096: stfld ""byte[] Program.d__1.<>s__1"" + IL_009b: ldarg.0 + IL_009c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" + IL_00a1: ldloc.3 + IL_00a2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a7: nop + IL_00a8: leave.s IL_00c5 } // sequence point: } - IL_00a3: ldarg.0 - IL_00a4: ldc.i4.s -2 - IL_00a6: stfld ""int Program.d__1.<>1__state"" + IL_00aa: ldarg.0 + IL_00ab: ldc.i4.s -2 + IL_00ad: stfld ""int Program.d__1.<>1__state"" // sequence point: - IL_00ab: ldarg.0 - IL_00ac: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" - IL_00b1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00b6: nop - IL_00b7: ret + IL_00b2: ldarg.0 + IL_00b3: ldnull + IL_00b4: stfld ""byte[] Program.d__1.<>s__1"" + IL_00b9: ldarg.0 + IL_00ba: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" + IL_00bf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c4: nop + IL_00c5: ret } "); } @@ -4076,7 +4094,7 @@ Caught NullReferenceException After Assignment a.B.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 184 (0xb8) + // Code size 198 (0xc6) .maxstack 3 .locals init (int V_0, int V_1, @@ -4114,7 +4132,7 @@ .locals init (int V_0, IL_004a: ldloca.s V_2 IL_004c: ldarg.0 IL_004d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_0052: leave.s IL_00b7 + IL_0052: leave.s IL_00c5 IL_0054: ldarg.0 IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_005a: stloc.2 @@ -4136,7 +4154,7 @@ .locals init (int V_0, IL_0084: ldarg.0 IL_0085: ldnull IL_0086: stfld ""B Program.d__0.<>7__wrap1"" - IL_008b: leave.s IL_00a4 + IL_008b: leave.s IL_00ab } catch System.Exception { @@ -4145,18 +4163,24 @@ .locals init (int V_0, IL_008f: ldc.i4.s -2 IL_0091: stfld ""int Program.d__0.<>1__state"" IL_0096: ldarg.0 - IL_0097: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_009c: ldloc.3 - IL_009d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a2: leave.s IL_00b7 + IL_0097: ldnull + IL_0098: stfld ""B Program.d__0.<>7__wrap1"" + IL_009d: ldarg.0 + IL_009e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00a3: ldloc.3 + IL_00a4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a9: leave.s IL_00c5 } - IL_00a4: ldarg.0 - IL_00a5: ldc.i4.s -2 - IL_00a7: stfld ""int Program.d__0.<>1__state"" - IL_00ac: ldarg.0 - IL_00ad: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00b7: ret + IL_00ab: ldarg.0 + IL_00ac: ldc.i4.s -2 + IL_00ae: stfld ""int Program.d__0.<>1__state"" + IL_00b3: ldarg.0 + IL_00b4: ldnull + IL_00b5: stfld ""B Program.d__0.<>7__wrap1"" + IL_00ba: ldarg.0 + IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c5: ret }"); } @@ -4314,7 +4338,7 @@ Caught NullReferenceException After Assignment a.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 181 (0xb5) + // Code size 195 (0xc3) .maxstack 3 .locals init (int V_0, int V_1, @@ -4353,7 +4377,7 @@ .locals init (int V_0, IL_0047: ldloca.s V_2 IL_0049: ldarg.0 IL_004a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_004f: leave.s IL_00b4 + IL_004f: leave.s IL_00c2 IL_0051: ldarg.0 IL_0052: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0057: stloc.2 @@ -4375,7 +4399,7 @@ .locals init (int V_0, IL_0081: ldarg.0 IL_0082: ldnull IL_0083: stfld ""A Program.d__0.<>7__wrap1"" - IL_0088: leave.s IL_00a1 + IL_0088: leave.s IL_00a8 } catch System.Exception { @@ -4384,18 +4408,24 @@ .locals init (int V_0, IL_008c: ldc.i4.s -2 IL_008e: stfld ""int Program.d__0.<>1__state"" IL_0093: ldarg.0 - IL_0094: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_0099: ldloc.3 - IL_009a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_009f: leave.s IL_00b4 + IL_0094: ldnull + IL_0095: stfld ""A Program.d__0.<>7__wrap1"" + IL_009a: ldarg.0 + IL_009b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00a0: ldloc.3 + IL_00a1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a6: leave.s IL_00c2 } - IL_00a1: ldarg.0 - IL_00a2: ldc.i4.s -2 - IL_00a4: stfld ""int Program.d__0.<>1__state"" - IL_00a9: ldarg.0 - IL_00aa: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00b4: ret + IL_00a8: ldarg.0 + IL_00a9: ldc.i4.s -2 + IL_00ab: stfld ""int Program.d__0.<>1__state"" + IL_00b0: ldarg.0 + IL_00b1: ldnull + IL_00b2: stfld ""A Program.d__0.<>7__wrap1"" + IL_00b7: ldarg.0 + IL_00b8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00bd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c2: ret }"); } @@ -4527,7 +4557,7 @@ Caught IndexOutOfRangeException Before Assignment arr[0].y is: True") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 198 (0xc6) + // Code size 212 (0xd4) .maxstack 3 .locals init (int V_0, int V_1, @@ -4569,7 +4599,7 @@ .locals init (int V_0, IL_0052: ldloca.s V_2 IL_0054: ldarg.0 IL_0055: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005a: leave.s IL_00c5 + IL_005a: leave.s IL_00d3 IL_005c: ldarg.0 IL_005d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0062: stloc.2 @@ -4593,7 +4623,7 @@ .locals init (int V_0, IL_0092: ldarg.0 IL_0093: ldnull IL_0094: stfld ""A[] Program.d__0.<>7__wrap1"" - IL_0099: leave.s IL_00b2 + IL_0099: leave.s IL_00b9 } catch System.Exception { @@ -4602,18 +4632,24 @@ .locals init (int V_0, IL_009d: ldc.i4.s -2 IL_009f: stfld ""int Program.d__0.<>1__state"" IL_00a4: ldarg.0 - IL_00a5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00aa: ldloc.3 - IL_00ab: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00b0: leave.s IL_00c5 + IL_00a5: ldnull + IL_00a6: stfld ""A[] Program.d__0.<>7__wrap1"" + IL_00ab: ldarg.0 + IL_00ac: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b1: ldloc.3 + IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00b7: leave.s IL_00d3 } - IL_00b2: ldarg.0 - IL_00b3: ldc.i4.s -2 - IL_00b5: stfld ""int Program.d__0.<>1__state"" - IL_00ba: ldarg.0 - IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c5: ret + IL_00b9: ldarg.0 + IL_00ba: ldc.i4.s -2 + IL_00bc: stfld ""int Program.d__0.<>1__state"" + IL_00c1: ldarg.0 + IL_00c2: ldnull + IL_00c3: stfld ""A[] Program.d__0.<>7__wrap1"" + IL_00c8: ldarg.0 + IL_00c9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00ce: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00d3: ret }"); } @@ -4712,7 +4748,7 @@ Caught IndexOutOfRangeException After Assignment arrCopy[0] is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 176 (0xb0) + // Code size 190 (0xbe) .maxstack 3 .locals init (int V_0, int V_1, @@ -4749,7 +4785,7 @@ .locals init (int V_0, IL_0045: ldloca.s V_2 IL_0047: ldarg.0 IL_0048: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_004d: leave.s IL_00af + IL_004d: leave.s IL_00bd IL_004f: ldarg.0 IL_0050: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0055: stloc.2 @@ -4772,7 +4808,7 @@ .locals init (int V_0, IL_007c: ldarg.0 IL_007d: ldnull IL_007e: stfld ""int[] Program.d__0.<>7__wrap1"" - IL_0083: leave.s IL_009c + IL_0083: leave.s IL_00a3 } catch System.Exception { @@ -4781,18 +4817,24 @@ .locals init (int V_0, IL_0087: ldc.i4.s -2 IL_0089: stfld ""int Program.d__0.<>1__state"" IL_008e: ldarg.0 - IL_008f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_0094: ldloc.3 - IL_0095: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_009a: leave.s IL_00af + IL_008f: ldnull + IL_0090: stfld ""int[] Program.d__0.<>7__wrap1"" + IL_0095: ldarg.0 + IL_0096: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_009b: ldloc.3 + IL_009c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a1: leave.s IL_00bd } - IL_009c: ldarg.0 - IL_009d: ldc.i4.s -2 - IL_009f: stfld ""int Program.d__0.<>1__state"" - IL_00a4: ldarg.0 - IL_00a5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00af: ret + IL_00a3: ldarg.0 + IL_00a4: ldc.i4.s -2 + IL_00a6: stfld ""int Program.d__0.<>1__state"" + IL_00ab: ldarg.0 + IL_00ac: ldnull + IL_00ad: stfld ""int[] Program.d__0.<>7__wrap1"" + IL_00b2: ldarg.0 + IL_00b3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00bd: ret }"); } @@ -4903,7 +4945,7 @@ Caught NullReferenceException After Assignment aCopy.b.c.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 201 (0xc9) + // Code size 215 (0xd7) .maxstack 3 .locals init (int V_0, int V_1, @@ -4944,7 +4986,7 @@ .locals init (int V_0, IL_0051: ldloca.s V_2 IL_0053: ldarg.0 IL_0054: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_0059: leave.s IL_00c8 + IL_0059: leave.s IL_00d6 IL_005b: ldarg.0 IL_005c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0061: stloc.2 @@ -4968,7 +5010,7 @@ .locals init (int V_0, IL_0095: ldarg.0 IL_0096: ldnull IL_0097: stfld ""A Program.d__0.<>7__wrap1"" - IL_009c: leave.s IL_00b5 + IL_009c: leave.s IL_00bc } catch System.Exception { @@ -4977,18 +5019,24 @@ .locals init (int V_0, IL_00a0: ldc.i4.s -2 IL_00a2: stfld ""int Program.d__0.<>1__state"" IL_00a7: ldarg.0 - IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00ad: ldloc.3 - IL_00ae: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00b3: leave.s IL_00c8 + IL_00a8: ldnull + IL_00a9: stfld ""A Program.d__0.<>7__wrap1"" + IL_00ae: ldarg.0 + IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b4: ldloc.3 + IL_00b5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00ba: leave.s IL_00d6 } - IL_00b5: ldarg.0 - IL_00b6: ldc.i4.s -2 - IL_00b8: stfld ""int Program.d__0.<>1__state"" - IL_00bd: ldarg.0 - IL_00be: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00c3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c8: ret + IL_00bc: ldarg.0 + IL_00bd: ldc.i4.s -2 + IL_00bf: stfld ""int Program.d__0.<>1__state"" + IL_00c4: ldarg.0 + IL_00c5: ldnull + IL_00c6: stfld ""A Program.d__0.<>7__wrap1"" + IL_00cb: ldarg.0 + IL_00cc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00d1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00d6: ret }"); } @@ -5100,7 +5148,7 @@ Caught NullReferenceException After Assignment aCopy._b._x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 184 (0xb8) + // Code size 198 (0xc6) .maxstack 3 .locals init (int V_0, int V_1, @@ -5138,7 +5186,7 @@ .locals init (int V_0, IL_004a: ldloca.s V_2 IL_004c: ldarg.0 IL_004d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_0052: leave.s IL_00b7 + IL_0052: leave.s IL_00c5 IL_0054: ldarg.0 IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_005a: stloc.2 @@ -5160,7 +5208,7 @@ .locals init (int V_0, IL_0084: ldarg.0 IL_0085: ldnull IL_0086: stfld ""B Program.d__0.<>7__wrap1"" - IL_008b: leave.s IL_00a4 + IL_008b: leave.s IL_00ab } catch System.Exception { @@ -5169,18 +5217,24 @@ .locals init (int V_0, IL_008f: ldc.i4.s -2 IL_0091: stfld ""int Program.d__0.<>1__state"" IL_0096: ldarg.0 - IL_0097: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_009c: ldloc.3 - IL_009d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a2: leave.s IL_00b7 + IL_0097: ldnull + IL_0098: stfld ""B Program.d__0.<>7__wrap1"" + IL_009d: ldarg.0 + IL_009e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00a3: ldloc.3 + IL_00a4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a9: leave.s IL_00c5 } - IL_00a4: ldarg.0 - IL_00a5: ldc.i4.s -2 - IL_00a7: stfld ""int Program.d__0.<>1__state"" - IL_00ac: ldarg.0 - IL_00ad: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00b7: ret + IL_00ab: ldarg.0 + IL_00ac: ldc.i4.s -2 + IL_00ae: stfld ""int Program.d__0.<>1__state"" + IL_00b3: ldarg.0 + IL_00b4: ldnull + IL_00b5: stfld ""B Program.d__0.<>7__wrap1"" + IL_00ba: ldarg.0 + IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c5: ret }"); } @@ -5282,7 +5336,7 @@ Caught NullReferenceException After Assignment aCopy.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 179 (0xb3) + // Code size 193 (0xc1) .maxstack 3 .locals init (int V_0, int V_1, @@ -5319,7 +5373,7 @@ .locals init (int V_0, IL_0045: ldloca.s V_2 IL_0047: ldarg.0 IL_0048: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_004d: leave.s IL_00b2 + IL_004d: leave.s IL_00c0 IL_004f: ldarg.0 IL_0050: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0055: stloc.2 @@ -5341,7 +5395,7 @@ .locals init (int V_0, IL_007f: ldarg.0 IL_0080: ldnull IL_0081: stfld ""A Program.d__0.<>7__wrap1"" - IL_0086: leave.s IL_009f + IL_0086: leave.s IL_00a6 } catch System.Exception { @@ -5350,18 +5404,24 @@ .locals init (int V_0, IL_008a: ldc.i4.s -2 IL_008c: stfld ""int Program.d__0.<>1__state"" IL_0091: ldarg.0 - IL_0092: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_0097: ldloc.3 - IL_0098: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_009d: leave.s IL_00b2 + IL_0092: ldnull + IL_0093: stfld ""A Program.d__0.<>7__wrap1"" + IL_0098: ldarg.0 + IL_0099: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_009e: ldloc.3 + IL_009f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a4: leave.s IL_00c0 } - IL_009f: ldarg.0 - IL_00a0: ldc.i4.s -2 - IL_00a2: stfld ""int Program.d__0.<>1__state"" - IL_00a7: ldarg.0 - IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00ad: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00b2: ret + IL_00a6: ldarg.0 + IL_00a7: ldc.i4.s -2 + IL_00a9: stfld ""int Program.d__0.<>1__state"" + IL_00ae: ldarg.0 + IL_00af: ldnull + IL_00b0: stfld ""A Program.d__0.<>7__wrap1"" + IL_00b5: ldarg.0 + IL_00b6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00bb: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c0: ret }"); } @@ -5485,7 +5545,7 @@ Caught NullReferenceException After Assignment a.x is: 43") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 202 (0xca) + // Code size 216 (0xd8) .maxstack 3 .locals init (int V_0, A V_1, @@ -5529,7 +5589,7 @@ .locals init (int V_0, IL_0053: ldloca.s V_3 IL_0055: ldarg.0 IL_0056: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005b: leave.s IL_00c9 + IL_005b: leave.s IL_00d7 IL_005d: ldarg.0 IL_005e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0063: stloc.3 @@ -5554,7 +5614,7 @@ .locals init (int V_0, IL_0094: ldarg.0 IL_0095: ldnull IL_0096: stfld ""A Program.d__0.<>7__wrap1"" - IL_009b: leave.s IL_00b6 + IL_009b: leave.s IL_00bd } catch System.Exception { @@ -5563,18 +5623,24 @@ .locals init (int V_0, IL_00a0: ldc.i4.s -2 IL_00a2: stfld ""int Program.d__0.<>1__state"" IL_00a7: ldarg.0 - IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00ad: ldloc.s V_4 - IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00b4: leave.s IL_00c9 + IL_00a8: ldnull + IL_00a9: stfld ""A Program.d__0.<>7__wrap1"" + IL_00ae: ldarg.0 + IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b4: ldloc.s V_4 + IL_00b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00bb: leave.s IL_00d7 } - IL_00b6: ldarg.0 - IL_00b7: ldc.i4.s -2 - IL_00b9: stfld ""int Program.d__0.<>1__state"" - IL_00be: ldarg.0 - IL_00bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00c4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c9: ret + IL_00bd: ldarg.0 + IL_00be: ldc.i4.s -2 + IL_00c0: stfld ""int Program.d__0.<>1__state"" + IL_00c5: ldarg.0 + IL_00c6: ldnull + IL_00c7: stfld ""A Program.d__0.<>7__wrap1"" + IL_00cc: ldarg.0 + IL_00cd: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00d2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00d7: ret }"); } @@ -5705,7 +5771,7 @@ Caught NullReferenceException After Assignment a._x is: 43") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 202 (0xca) + // Code size 216 (0xd8) .maxstack 3 .locals init (int V_0, A V_1, @@ -5749,7 +5815,7 @@ .locals init (int V_0, IL_0053: ldloca.s V_3 IL_0055: ldarg.0 IL_0056: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005b: leave.s IL_00c9 + IL_005b: leave.s IL_00d7 IL_005d: ldarg.0 IL_005e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0063: stloc.3 @@ -5774,7 +5840,7 @@ .locals init (int V_0, IL_0094: ldarg.0 IL_0095: ldnull IL_0096: stfld ""A Program.d__0.<>7__wrap1"" - IL_009b: leave.s IL_00b6 + IL_009b: leave.s IL_00bd } catch System.Exception { @@ -5783,18 +5849,24 @@ .locals init (int V_0, IL_00a0: ldc.i4.s -2 IL_00a2: stfld ""int Program.d__0.<>1__state"" IL_00a7: ldarg.0 - IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00ad: ldloc.s V_4 - IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00b4: leave.s IL_00c9 + IL_00a8: ldnull + IL_00a9: stfld ""A Program.d__0.<>7__wrap1"" + IL_00ae: ldarg.0 + IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b4: ldloc.s V_4 + IL_00b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00bb: leave.s IL_00d7 } - IL_00b6: ldarg.0 - IL_00b7: ldc.i4.s -2 - IL_00b9: stfld ""int Program.d__0.<>1__state"" - IL_00be: ldarg.0 - IL_00bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00c4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c9: ret + IL_00bd: ldarg.0 + IL_00be: ldc.i4.s -2 + IL_00c0: stfld ""int Program.d__0.<>1__state"" + IL_00c5: ldarg.0 + IL_00c6: ldnull + IL_00c7: stfld ""A Program.d__0.<>7__wrap1"" + IL_00cc: ldarg.0 + IL_00cd: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00d2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00d7: ret }"); } @@ -5943,7 +6015,7 @@ Caught NullReferenceException After Assignment b.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 219 (0xdb) + // Code size 250 (0xfa) .maxstack 4 .locals init (int V_0, int V_1, @@ -5956,7 +6028,7 @@ .locals init (int V_0, .try { IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0060 + IL_0008: brfalse.s IL_0063 IL_000a: ldarg.0 IL_000b: ldarg.0 IL_000c: ldfld ""A Program.d__0.a"" @@ -5972,7 +6044,7 @@ .locals init (int V_0, IL_0036: stloc.2 IL_0037: ldloca.s V_2 IL_0039: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003e: brtrue.s IL_007c + IL_003e: brtrue.s IL_007f IL_0040: ldarg.0 IL_0041: ldc.i4.0 IL_0042: dup @@ -5986,58 +6058,70 @@ .locals init (int V_0, IL_0056: ldloca.s V_2 IL_0058: ldarg.0 IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005e: leave.s IL_00da - IL_0060: ldarg.0 - IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_0066: stloc.2 - IL_0067: ldarg.0 - IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0073: ldarg.0 - IL_0074: ldc.i4.m1 - IL_0075: dup - IL_0076: stloc.0 - IL_0077: stfld ""int Program.d__0.<>1__state"" - IL_007c: ldloca.s V_2 - IL_007e: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0083: stloc.1 - IL_0084: ldarg.0 - IL_0085: ldfld ""B Program.d__0.<>7__wrap1"" - IL_008a: ldarg.0 - IL_008b: ldfld ""B Program.d__0.<>7__wrap2"" - IL_0090: ldloc.1 - IL_0091: dup - IL_0092: stloc.3 - IL_0093: stfld ""int B.x"" - IL_0098: ldloc.3 - IL_0099: stfld ""int B.x"" - IL_009e: ldarg.0 - IL_009f: ldnull - IL_00a0: stfld ""B Program.d__0.<>7__wrap1"" - IL_00a5: ldarg.0 - IL_00a6: ldnull - IL_00a7: stfld ""B Program.d__0.<>7__wrap2"" - IL_00ac: leave.s IL_00c7 + IL_005e: leave IL_00f9 + IL_0063: ldarg.0 + IL_0064: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_0069: stloc.2 + IL_006a: ldarg.0 + IL_006b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_0070: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0076: ldarg.0 + IL_0077: ldc.i4.m1 + IL_0078: dup + IL_0079: stloc.0 + IL_007a: stfld ""int Program.d__0.<>1__state"" + IL_007f: ldloca.s V_2 + IL_0081: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_0086: stloc.1 + IL_0087: ldarg.0 + IL_0088: ldfld ""B Program.d__0.<>7__wrap1"" + IL_008d: ldarg.0 + IL_008e: ldfld ""B Program.d__0.<>7__wrap2"" + IL_0093: ldloc.1 + IL_0094: dup + IL_0095: stloc.3 + IL_0096: stfld ""int B.x"" + IL_009b: ldloc.3 + IL_009c: stfld ""int B.x"" + IL_00a1: ldarg.0 + IL_00a2: ldnull + IL_00a3: stfld ""B Program.d__0.<>7__wrap1"" + IL_00a8: ldarg.0 + IL_00a9: ldnull + IL_00aa: stfld ""B Program.d__0.<>7__wrap2"" + IL_00af: leave.s IL_00d8 } catch System.Exception { - IL_00ae: stloc.s V_4 - IL_00b0: ldarg.0 - IL_00b1: ldc.i4.s -2 - IL_00b3: stfld ""int Program.d__0.<>1__state"" - IL_00b8: ldarg.0 - IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00be: ldloc.s V_4 - IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00c5: leave.s IL_00da + IL_00b1: stloc.s V_4 + IL_00b3: ldarg.0 + IL_00b4: ldc.i4.s -2 + IL_00b6: stfld ""int Program.d__0.<>1__state"" + IL_00bb: ldarg.0 + IL_00bc: ldnull + IL_00bd: stfld ""B Program.d__0.<>7__wrap1"" + IL_00c2: ldarg.0 + IL_00c3: ldnull + IL_00c4: stfld ""B Program.d__0.<>7__wrap2"" + IL_00c9: ldarg.0 + IL_00ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00cf: ldloc.s V_4 + IL_00d1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00d6: leave.s IL_00f9 } - IL_00c7: ldarg.0 - IL_00c8: ldc.i4.s -2 - IL_00ca: stfld ""int Program.d__0.<>1__state"" - IL_00cf: ldarg.0 - IL_00d0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00d5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00da: ret + IL_00d8: ldarg.0 + IL_00d9: ldc.i4.s -2 + IL_00db: stfld ""int Program.d__0.<>1__state"" + IL_00e0: ldarg.0 + IL_00e1: ldnull + IL_00e2: stfld ""B Program.d__0.<>7__wrap1"" + IL_00e7: ldarg.0 + IL_00e8: ldnull + IL_00e9: stfld ""B Program.d__0.<>7__wrap2"" + IL_00ee: ldarg.0 + IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00f4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00f9: ret }"); } @@ -6194,7 +6278,7 @@ Caught NullReferenceException After Assignment b._x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 219 (0xdb) + // Code size 250 (0xfa) .maxstack 3 .locals init (int V_0, int V_1, @@ -6207,7 +6291,7 @@ .locals init (int V_0, .try { IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0060 + IL_0008: brfalse.s IL_0063 IL_000a: ldarg.0 IL_000b: ldarg.0 IL_000c: ldfld ""A Program.d__0.a"" @@ -6223,7 +6307,7 @@ .locals init (int V_0, IL_0036: stloc.3 IL_0037: ldloca.s V_3 IL_0039: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003e: brtrue.s IL_007c + IL_003e: brtrue.s IL_007f IL_0040: ldarg.0 IL_0041: ldc.i4.0 IL_0042: dup @@ -6237,58 +6321,70 @@ .locals init (int V_0, IL_0056: ldloca.s V_3 IL_0058: ldarg.0 IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005e: leave.s IL_00da - IL_0060: ldarg.0 - IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_0066: stloc.3 - IL_0067: ldarg.0 - IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0073: ldarg.0 - IL_0074: ldc.i4.m1 - IL_0075: dup - IL_0076: stloc.0 - IL_0077: stfld ""int Program.d__0.<>1__state"" - IL_007c: ldloca.s V_3 - IL_007e: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0083: stloc.1 - IL_0084: ldarg.0 - IL_0085: ldfld ""B Program.d__0.<>7__wrap2"" - IL_008a: ldloc.1 - IL_008b: dup - IL_008c: stloc.2 - IL_008d: callvirt ""void B.x.set"" - IL_0092: ldarg.0 - IL_0093: ldfld ""B Program.d__0.<>7__wrap1"" - IL_0098: ldloc.2 - IL_0099: callvirt ""void B.x.set"" - IL_009e: ldarg.0 - IL_009f: ldnull - IL_00a0: stfld ""B Program.d__0.<>7__wrap1"" - IL_00a5: ldarg.0 - IL_00a6: ldnull - IL_00a7: stfld ""B Program.d__0.<>7__wrap2"" - IL_00ac: leave.s IL_00c7 + IL_005e: leave IL_00f9 + IL_0063: ldarg.0 + IL_0064: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_0069: stloc.3 + IL_006a: ldarg.0 + IL_006b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_0070: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0076: ldarg.0 + IL_0077: ldc.i4.m1 + IL_0078: dup + IL_0079: stloc.0 + IL_007a: stfld ""int Program.d__0.<>1__state"" + IL_007f: ldloca.s V_3 + IL_0081: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_0086: stloc.1 + IL_0087: ldarg.0 + IL_0088: ldfld ""B Program.d__0.<>7__wrap2"" + IL_008d: ldloc.1 + IL_008e: dup + IL_008f: stloc.2 + IL_0090: callvirt ""void B.x.set"" + IL_0095: ldarg.0 + IL_0096: ldfld ""B Program.d__0.<>7__wrap1"" + IL_009b: ldloc.2 + IL_009c: callvirt ""void B.x.set"" + IL_00a1: ldarg.0 + IL_00a2: ldnull + IL_00a3: stfld ""B Program.d__0.<>7__wrap1"" + IL_00a8: ldarg.0 + IL_00a9: ldnull + IL_00aa: stfld ""B Program.d__0.<>7__wrap2"" + IL_00af: leave.s IL_00d8 } catch System.Exception { - IL_00ae: stloc.s V_4 - IL_00b0: ldarg.0 - IL_00b1: ldc.i4.s -2 - IL_00b3: stfld ""int Program.d__0.<>1__state"" - IL_00b8: ldarg.0 - IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00be: ldloc.s V_4 - IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00c5: leave.s IL_00da + IL_00b1: stloc.s V_4 + IL_00b3: ldarg.0 + IL_00b4: ldc.i4.s -2 + IL_00b6: stfld ""int Program.d__0.<>1__state"" + IL_00bb: ldarg.0 + IL_00bc: ldnull + IL_00bd: stfld ""B Program.d__0.<>7__wrap2"" + IL_00c2: ldarg.0 + IL_00c3: ldnull + IL_00c4: stfld ""B Program.d__0.<>7__wrap1"" + IL_00c9: ldarg.0 + IL_00ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00cf: ldloc.s V_4 + IL_00d1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00d6: leave.s IL_00f9 } - IL_00c7: ldarg.0 - IL_00c8: ldc.i4.s -2 - IL_00ca: stfld ""int Program.d__0.<>1__state"" - IL_00cf: ldarg.0 - IL_00d0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00d5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00da: ret + IL_00d8: ldarg.0 + IL_00d9: ldc.i4.s -2 + IL_00db: stfld ""int Program.d__0.<>1__state"" + IL_00e0: ldarg.0 + IL_00e1: ldnull + IL_00e2: stfld ""B Program.d__0.<>7__wrap2"" + IL_00e7: ldarg.0 + IL_00e8: ldnull + IL_00e9: stfld ""B Program.d__0.<>7__wrap1"" + IL_00ee: ldarg.0 + IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00f4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00f9: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 297059bfb94c8..0ba98b0ea7923 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -4236,8 +4236,8 @@ public static async Task F() var v = CompileAndVerify(source, null, options: TestOptions.DebugDll); v.VerifyIL("Test.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" -{ - // Code size 241 (0xf1) + { + // Code size 255 (0xff) .maxstack 3 .locals init (int V_0, int V_1, @@ -4289,7 +4289,7 @@ .locals init (int V_0, IL_0063: ldloca.s V_3 IL_0065: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__2)"" IL_006a: nop - IL_006b: leave IL_00f0 + IL_006b: leave IL_00fe >IL_0070: ldarg.0 IL_0071: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" IL_0076: stloc.2 @@ -4313,7 +4313,7 @@ .locals init (int V_0, IL_00a6: ldfld ""int Test.d__2.<>s__2"" IL_00ab: call ""int S.Mutate(int)"" IL_00b0: stloc.1 - IL_00b1: leave.s IL_00d4 + IL_00b1: leave.s IL_00db } catch System.Exception { @@ -4325,24 +4325,30 @@ .locals init (int V_0, IL_00be: ldnull IL_00bf: stfld ""S[] Test.d__2.5__1"" IL_00c4: ldarg.0 - IL_00c5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00ca: ldloc.s V_4 - IL_00cc: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00d1: nop - IL_00d2: leave.s IL_00f0 + IL_00c5: ldnull + IL_00c6: stfld ""S[] Test.d__2.<>s__3"" + IL_00cb: ldarg.0 + IL_00cc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00d1: ldloc.s V_4 + IL_00d3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00d8: nop + IL_00d9: leave.s IL_00fe } - -IL_00d4: ldarg.0 - IL_00d5: ldc.i4.s -2 - IL_00d7: stfld ""int Test.d__2.<>1__state"" - ~IL_00dc: ldarg.0 - IL_00dd: ldnull - IL_00de: stfld ""S[] Test.d__2.5__1"" - IL_00e3: ldarg.0 - IL_00e4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00e9: ldloc.1 - IL_00ea: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_00ef: nop - IL_00f0: ret + -IL_00db: ldarg.0 + IL_00dc: ldc.i4.s -2 + IL_00de: stfld ""int Test.d__2.<>1__state"" + ~IL_00e3: ldarg.0 + IL_00e4: ldnull + IL_00e5: stfld ""S[] Test.d__2.5__1"" + IL_00ea: ldarg.0 + IL_00eb: ldnull + IL_00ec: stfld ""S[] Test.d__2.<>s__3"" + IL_00f1: ldarg.0 + IL_00f2: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00f7: ldloc.1 + IL_00f8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_00fd: nop + IL_00fe: ret }", sequencePoints: "Test+d__2.MoveNext"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs index 52fe5242f2174..d2097e117506e 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs @@ -3786,7 +3786,7 @@ public async ValueTask DisposeAsync() // The thing to notice here is that the call to GetAsyncEnumerator is a constrained call (we're not boxing to `IAsyncEnumerable`) verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 496 (0x1f0) + // Code size 524 (0x20c) .maxstack 3 .locals init (int V_0, C V_1, @@ -3878,7 +3878,7 @@ .locals init (int V_0, IL_00bd: ldloca.s V_5 IL_00bf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_00c4: nop - IL_00c5: leave IL_01ef + IL_00c5: leave IL_020b IL_00ca: ldarg.0 IL_00cb: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_00d0: stloc.3 @@ -3936,7 +3936,7 @@ .locals init (int V_0, IL_014f: ldloca.s V_5 IL_0151: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0156: nop - IL_0157: leave IL_01ef + IL_0157: leave IL_020b IL_015c: ldarg.0 IL_015d: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" IL_0162: stloc.s V_7 @@ -3976,7 +3976,7 @@ .locals init (int V_0, IL_01b8: ldarg.0 IL_01b9: ldnull IL_01ba: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>s__1"" - IL_01bf: leave.s IL_01db + IL_01bf: leave.s IL_01e9 } catch System.Exception { @@ -3985,20 +3985,32 @@ .locals init (int V_0, IL_01c4: ldc.i4.s -2 IL_01c6: stfld ""int C.
d__0.<>1__state"" IL_01cb: ldarg.0 - IL_01cc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_01d1: ldloc.s V_9 - IL_01d3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01d8: nop - IL_01d9: leave.s IL_01ef + IL_01cc: ldnull + IL_01cd: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>s__1"" + IL_01d2: ldarg.0 + IL_01d3: ldnull + IL_01d4: stfld ""object C.
d__0.<>s__2"" + IL_01d9: ldarg.0 + IL_01da: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_01df: ldloc.s V_9 + IL_01e1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01e6: nop + IL_01e7: leave.s IL_020b } - IL_01db: ldarg.0 - IL_01dc: ldc.i4.s -2 - IL_01de: stfld ""int C.
d__0.<>1__state"" - IL_01e3: ldarg.0 - IL_01e4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_01e9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01ee: nop - IL_01ef: ret + IL_01e9: ldarg.0 + IL_01ea: ldc.i4.s -2 + IL_01ec: stfld ""int C.
d__0.<>1__state"" + IL_01f1: ldarg.0 + IL_01f2: ldnull + IL_01f3: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>s__1"" + IL_01f8: ldarg.0 + IL_01f9: ldnull + IL_01fa: stfld ""object C.
d__0.<>s__2"" + IL_01ff: ldarg.0 + IL_0200: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0205: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_020a: nop + IL_020b: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs index 39bf18e7fc8e2..8ffa09d5d17c5 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs @@ -1121,7 +1121,7 @@ System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 306 (0x132) + // Code size 334 (0x14e) .maxstack 3 .locals init (int V_0, object V_1, @@ -1198,7 +1198,7 @@ .locals init (int V_0, IL_008c: ldloca.s V_4 IL_008e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0093: nop - IL_0094: leave IL_0131 + IL_0094: leave IL_014d IL_0099: ldarg.0 IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_009f: stloc.2 @@ -1236,14 +1236,14 @@ .locals init (int V_0, IL_00ec: ldc.i4.1 IL_00ed: beq.s IL_00f1 IL_00ef: br.s IL_00f3 - IL_00f1: leave.s IL_011d + IL_00f1: leave.s IL_012b IL_00f3: ldarg.0 IL_00f4: ldnull IL_00f5: stfld ""object C.
d__0.<>s__2"" IL_00fa: ldarg.0 IL_00fb: ldnull IL_00fc: stfld ""C C.
d__0.<>s__1"" - IL_0101: leave.s IL_011d + IL_0101: leave.s IL_012b } catch System.Exception { @@ -1252,20 +1252,32 @@ .locals init (int V_0, IL_0106: ldc.i4.s -2 IL_0108: stfld ""int C.
d__0.<>1__state"" IL_010d: ldarg.0 - IL_010e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0113: ldloc.s V_5 - IL_0115: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_011a: nop - IL_011b: leave.s IL_0131 + IL_010e: ldnull + IL_010f: stfld ""C C.
d__0.<>s__1"" + IL_0114: ldarg.0 + IL_0115: ldnull + IL_0116: stfld ""object C.
d__0.<>s__2"" + IL_011b: ldarg.0 + IL_011c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0121: ldloc.s V_5 + IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0128: nop + IL_0129: leave.s IL_014d } - IL_011d: ldarg.0 - IL_011e: ldc.i4.s -2 - IL_0120: stfld ""int C.
d__0.<>1__state"" - IL_0125: ldarg.0 - IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0130: nop - IL_0131: ret + IL_012b: ldarg.0 + IL_012c: ldc.i4.s -2 + IL_012e: stfld ""int C.
d__0.<>1__state"" + IL_0133: ldarg.0 + IL_0134: ldnull + IL_0135: stfld ""C C.
d__0.<>s__1"" + IL_013a: ldarg.0 + IL_013b: ldnull + IL_013c: stfld ""object C.
d__0.<>s__2"" + IL_0141: ldarg.0 + IL_0142: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_014c: nop + IL_014d: ret }"); } @@ -1295,7 +1307,7 @@ public System.Threading.Tasks.ValueTask DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 306 (0x132) + // Code size 334 (0x14e) .maxstack 3 .locals init (int V_0, object V_1, @@ -1372,7 +1384,7 @@ .locals init (int V_0, IL_008c: ldloca.s V_4 IL_008e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0093: nop - IL_0094: leave IL_0131 + IL_0094: leave IL_014d IL_0099: ldarg.0 IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_009f: stloc.2 @@ -1410,14 +1422,14 @@ .locals init (int V_0, IL_00ec: ldc.i4.1 IL_00ed: beq.s IL_00f1 IL_00ef: br.s IL_00f3 - IL_00f1: leave.s IL_011d + IL_00f1: leave.s IL_012b IL_00f3: ldarg.0 IL_00f4: ldnull IL_00f5: stfld ""object C.
d__0.<>s__2"" IL_00fa: ldarg.0 IL_00fb: ldnull IL_00fc: stfld ""C C.
d__0.<>s__1"" - IL_0101: leave.s IL_011d + IL_0101: leave.s IL_012b } catch System.Exception { @@ -1426,20 +1438,32 @@ .locals init (int V_0, IL_0106: ldc.i4.s -2 IL_0108: stfld ""int C.
d__0.<>1__state"" IL_010d: ldarg.0 - IL_010e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0113: ldloc.s V_5 - IL_0115: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_011a: nop - IL_011b: leave.s IL_0131 + IL_010e: ldnull + IL_010f: stfld ""C C.
d__0.<>s__1"" + IL_0114: ldarg.0 + IL_0115: ldnull + IL_0116: stfld ""object C.
d__0.<>s__2"" + IL_011b: ldarg.0 + IL_011c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0121: ldloc.s V_5 + IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0128: nop + IL_0129: leave.s IL_014d } - IL_011d: ldarg.0 - IL_011e: ldc.i4.s -2 - IL_0120: stfld ""int C.
d__0.<>1__state"" - IL_0125: ldarg.0 - IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0130: nop - IL_0131: ret + IL_012b: ldarg.0 + IL_012c: ldc.i4.s -2 + IL_012e: stfld ""int C.
d__0.<>1__state"" + IL_0133: ldarg.0 + IL_0134: ldnull + IL_0135: stfld ""C C.
d__0.<>s__1"" + IL_013a: ldarg.0 + IL_013b: ldnull + IL_013c: stfld ""object C.
d__0.<>s__2"" + IL_0141: ldarg.0 + IL_0142: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_014c: nop + IL_014d: ret } "); } @@ -1470,7 +1494,7 @@ public System.Threading.Tasks.ValueTask DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 306 (0x132) + // Code size 334 (0x14e) .maxstack 3 .locals init (int V_0, object V_1, @@ -1547,7 +1571,7 @@ .locals init (int V_0, IL_008c: ldloca.s V_4 IL_008e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0093: nop - IL_0094: leave IL_0131 + IL_0094: leave IL_014d IL_0099: ldarg.0 IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_009f: stloc.2 @@ -1585,14 +1609,14 @@ .locals init (int V_0, IL_00ec: ldc.i4.1 IL_00ed: beq.s IL_00f1 IL_00ef: br.s IL_00f3 - IL_00f1: leave.s IL_011d + IL_00f1: leave.s IL_012b IL_00f3: ldarg.0 IL_00f4: ldnull IL_00f5: stfld ""object C.
d__0.<>s__2"" IL_00fa: ldarg.0 IL_00fb: ldnull IL_00fc: stfld ""C C.
d__0.<>s__1"" - IL_0101: leave.s IL_011d + IL_0101: leave.s IL_012b } catch System.Exception { @@ -1601,20 +1625,32 @@ .locals init (int V_0, IL_0106: ldc.i4.s -2 IL_0108: stfld ""int C.
d__0.<>1__state"" IL_010d: ldarg.0 - IL_010e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0113: ldloc.s V_5 - IL_0115: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_011a: nop - IL_011b: leave.s IL_0131 + IL_010e: ldnull + IL_010f: stfld ""C C.
d__0.<>s__1"" + IL_0114: ldarg.0 + IL_0115: ldnull + IL_0116: stfld ""object C.
d__0.<>s__2"" + IL_011b: ldarg.0 + IL_011c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0121: ldloc.s V_5 + IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0128: nop + IL_0129: leave.s IL_014d } - IL_011d: ldarg.0 - IL_011e: ldc.i4.s -2 - IL_0120: stfld ""int C.
d__0.<>1__state"" - IL_0125: ldarg.0 - IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0130: nop - IL_0131: ret + IL_012b: ldarg.0 + IL_012c: ldc.i4.s -2 + IL_012e: stfld ""int C.
d__0.<>1__state"" + IL_0133: ldarg.0 + IL_0134: ldnull + IL_0135: stfld ""C C.
d__0.<>s__1"" + IL_013a: ldarg.0 + IL_013b: ldnull + IL_013c: stfld ""object C.
d__0.<>s__2"" + IL_0141: ldarg.0 + IL_0142: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_014c: nop + IL_014d: ret } "); } @@ -1715,7 +1751,7 @@ System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("S.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 298 (0x12a) + // Code size 312 (0x138) .maxstack 3 .locals init (int V_0, object V_1, @@ -1790,7 +1826,7 @@ .locals init (int V_0, IL_008b: ldloca.s V_4 IL_008d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref S.
d__0)"" IL_0092: nop - IL_0093: leave IL_0129 + IL_0093: leave IL_0137 IL_0098: ldarg.0 IL_0099: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter S.
d__0.<>u__1"" IL_009e: stloc.2 @@ -1828,11 +1864,11 @@ .locals init (int V_0, IL_00eb: ldc.i4.1 IL_00ec: beq.s IL_00f0 IL_00ee: br.s IL_00f2 - IL_00f0: leave.s IL_0115 + IL_00f0: leave.s IL_011c IL_00f2: ldarg.0 IL_00f3: ldnull IL_00f4: stfld ""object S.
d__0.<>s__2"" - IL_00f9: leave.s IL_0115 + IL_00f9: leave.s IL_011c } catch System.Exception { @@ -1841,20 +1877,26 @@ .locals init (int V_0, IL_00fe: ldc.i4.s -2 IL_0100: stfld ""int S.
d__0.<>1__state"" IL_0105: ldarg.0 - IL_0106: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_010b: ldloc.s V_5 - IL_010d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0112: nop - IL_0113: leave.s IL_0129 + IL_0106: ldnull + IL_0107: stfld ""object S.
d__0.<>s__2"" + IL_010c: ldarg.0 + IL_010d: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_0112: ldloc.s V_5 + IL_0114: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0119: nop + IL_011a: leave.s IL_0137 } - IL_0115: ldarg.0 - IL_0116: ldc.i4.s -2 - IL_0118: stfld ""int S.
d__0.<>1__state"" - IL_011d: ldarg.0 - IL_011e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0128: nop - IL_0129: ret + IL_011c: ldarg.0 + IL_011d: ldc.i4.s -2 + IL_011f: stfld ""int S.
d__0.<>1__state"" + IL_0124: ldarg.0 + IL_0125: ldnull + IL_0126: stfld ""object S.
d__0.<>s__2"" + IL_012b: ldarg.0 + IL_012c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_0131: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0136: nop + IL_0137: ret }"); } @@ -1884,7 +1926,7 @@ public System.Threading.Tasks.ValueTask DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("S.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 292 (0x124) + // Code size 306 (0x132) .maxstack 3 .locals init (int V_0, object V_1, @@ -1958,7 +2000,7 @@ .locals init (int V_0, IL_0085: ldloca.s V_4 IL_0087: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref S.
d__0)"" IL_008c: nop - IL_008d: leave IL_0123 + IL_008d: leave IL_0131 IL_0092: ldarg.0 IL_0093: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter S.
d__0.<>u__1"" IL_0098: stloc.2 @@ -1996,11 +2038,11 @@ .locals init (int V_0, IL_00e5: ldc.i4.1 IL_00e6: beq.s IL_00ea IL_00e8: br.s IL_00ec - IL_00ea: leave.s IL_010f + IL_00ea: leave.s IL_0116 IL_00ec: ldarg.0 IL_00ed: ldnull IL_00ee: stfld ""object S.
d__0.<>s__2"" - IL_00f3: leave.s IL_010f + IL_00f3: leave.s IL_0116 } catch System.Exception { @@ -2009,20 +2051,26 @@ .locals init (int V_0, IL_00f8: ldc.i4.s -2 IL_00fa: stfld ""int S.
d__0.<>1__state"" IL_00ff: ldarg.0 - IL_0100: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_0105: ldloc.s V_5 - IL_0107: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_010c: nop - IL_010d: leave.s IL_0123 + IL_0100: ldnull + IL_0101: stfld ""object S.
d__0.<>s__2"" + IL_0106: ldarg.0 + IL_0107: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_010c: ldloc.s V_5 + IL_010e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0113: nop + IL_0114: leave.s IL_0131 } - IL_010f: ldarg.0 - IL_0110: ldc.i4.s -2 - IL_0112: stfld ""int S.
d__0.<>1__state"" - IL_0117: ldarg.0 - IL_0118: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_011d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0122: nop - IL_0123: ret + IL_0116: ldarg.0 + IL_0117: ldc.i4.s -2 + IL_0119: stfld ""int S.
d__0.<>1__state"" + IL_011e: ldarg.0 + IL_011f: ldnull + IL_0120: stfld ""object S.
d__0.<>s__2"" + IL_0125: ldarg.0 + IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0130: nop + IL_0131: ret }"); } @@ -2701,7 +2749,7 @@ public async System.Threading.Tasks.ValueTask DisposeAsync() // Sequence point highlights `await using ...` verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 303 (0x12f) + // Code size 331 (0x14b) .maxstack 3 .locals init (int V_0, int V_1, @@ -2786,7 +2834,7 @@ .locals init (int V_0, IL_0084: ldloca.s V_5 IL_0086: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_008b: nop - IL_008c: leave IL_012e + IL_008c: leave IL_014a // async: resume IL_0091: ldarg.0 IL_0092: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" @@ -2837,7 +2885,7 @@ .locals init (int V_0, // sequence point: return 1; IL_00fb: ldc.i4.1 IL_00fc: stloc.1 - IL_00fd: leave.s IL_0119 + IL_00fd: leave.s IL_0127 } catch System.Exception { @@ -2847,23 +2895,35 @@ .locals init (int V_0, IL_0102: ldc.i4.s -2 IL_0104: stfld ""int C.
d__0.<>1__state"" IL_0109: ldarg.0 - IL_010a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_010f: ldloc.s V_6 - IL_0111: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0116: nop - IL_0117: leave.s IL_012e + IL_010a: ldnull + IL_010b: stfld ""C C.
d__0.5__1"" + IL_0110: ldarg.0 + IL_0111: ldnull + IL_0112: stfld ""object C.
d__0.<>s__2"" + IL_0117: ldarg.0 + IL_0118: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_011d: ldloc.s V_6 + IL_011f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0124: nop + IL_0125: leave.s IL_014a } // sequence point: } - IL_0119: ldarg.0 - IL_011a: ldc.i4.s -2 - IL_011c: stfld ""int C.
d__0.<>1__state"" + IL_0127: ldarg.0 + IL_0128: ldc.i4.s -2 + IL_012a: stfld ""int C.
d__0.<>1__state"" // sequence point: - IL_0121: ldarg.0 - IL_0122: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0127: ldloc.1 - IL_0128: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_012d: nop - IL_012e: ret + IL_012f: ldarg.0 + IL_0130: ldnull + IL_0131: stfld ""C C.
d__0.5__1"" + IL_0136: ldarg.0 + IL_0137: ldnull + IL_0138: stfld ""object C.
d__0.<>s__2"" + IL_013d: ldarg.0 + IL_013e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0143: ldloc.1 + IL_0144: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_0149: nop + IL_014a: ret } ", sequencePoints: "C+
d__0.MoveNext", source: source); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs index eb8319ef8c917..a90d3a5f1f79b 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs @@ -1840,7 +1840,7 @@ static async Task GetC2(C c) comp.VerifyIL("C.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 439 (0x1b7) + // Code size 467 (0x1d3) .maxstack 3 .locals init (int V_0, bool V_1, @@ -1878,7 +1878,7 @@ .locals init (int V_0, IL_0049: ldloca.s V_2 IL_004b: ldarg.0 IL_004c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0051: leave IL_01b6 + IL_0051: leave IL_01d2 IL_0056: ldarg.0 IL_0057: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" IL_005c: stloc.2 @@ -1920,7 +1920,7 @@ .locals init (int V_0, IL_00b9: ldloca.s V_3 IL_00bb: ldarg.0 IL_00bc: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_00c1: leave IL_01b6 + IL_00c1: leave IL_01d2 IL_00c6: ldarg.0 IL_00c7: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__2"" IL_00cc: stloc.3 @@ -1958,7 +1958,7 @@ .locals init (int V_0, IL_0121: ldloca.s V_3 IL_0123: ldarg.0 IL_0124: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0129: leave IL_01b6 + IL_0129: leave IL_01d2 IL_012e: ldarg.0 IL_012f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__2"" IL_0134: stloc.3 @@ -1992,7 +1992,7 @@ .locals init (int V_0, IL_0181: ldarg.0 IL_0182: ldnull IL_0183: stfld ""C C.d__2.<>7__wrap3"" - IL_0188: leave.s IL_01a3 + IL_0188: leave.s IL_01b1 } catch System.Exception { @@ -2001,18 +2001,30 @@ .locals init (int V_0, IL_018d: ldc.i4.s -2 IL_018f: stfld ""int C.d__2.<>1__state"" IL_0194: ldarg.0 - IL_0195: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_019a: ldloc.s V_4 - IL_019c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01a1: leave.s IL_01b6 + IL_0195: ldnull + IL_0196: stfld ""C C.d__2.<>7__wrap2"" + IL_019b: ldarg.0 + IL_019c: ldnull + IL_019d: stfld ""C C.d__2.<>7__wrap3"" + IL_01a2: ldarg.0 + IL_01a3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01a8: ldloc.s V_4 + IL_01aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01af: leave.s IL_01d2 } - IL_01a3: ldarg.0 - IL_01a4: ldc.i4.s -2 - IL_01a6: stfld ""int C.d__2.<>1__state"" - IL_01ab: ldarg.0 - IL_01ac: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01b1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01b6: ret + IL_01b1: ldarg.0 + IL_01b2: ldc.i4.s -2 + IL_01b4: stfld ""int C.d__2.<>1__state"" + IL_01b9: ldarg.0 + IL_01ba: ldnull + IL_01bb: stfld ""C C.d__2.<>7__wrap2"" + IL_01c0: ldarg.0 + IL_01c1: ldnull + IL_01c2: stfld ""C C.d__2.<>7__wrap3"" + IL_01c7: ldarg.0 + IL_01c8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01cd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01d2: ret } "); } @@ -2063,7 +2075,7 @@ static async Task GetC(C c) comp.VerifyIL("C.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 453 (0x1c5) + // Code size 484 (0x1e4) .maxstack 3 .locals init (int V_0, C V_1, @@ -2078,7 +2090,7 @@ .locals init (int V_0, IL_0008: switch ( IL_006a, IL_00d2, - IL_015a) + IL_015d) IL_0019: ldarg.0 IL_001a: ldarg.0 IL_001b: ldfld ""bool C.d__2.b"" @@ -2107,7 +2119,7 @@ .locals init (int V_0, IL_005d: ldloca.s V_2 IL_005f: ldarg.0 IL_0060: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0065: leave IL_01c4 + IL_0065: leave IL_01e3 IL_006a: ldarg.0 IL_006b: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" IL_0070: stloc.2 @@ -2145,7 +2157,7 @@ .locals init (int V_0, IL_00c5: ldloca.s V_2 IL_00c7: ldarg.0 IL_00c8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_00cd: leave IL_01c4 + IL_00cd: leave IL_01e3 IL_00d2: ldarg.0 IL_00d3: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" IL_00d8: stloc.2 @@ -2179,7 +2191,7 @@ .locals init (int V_0, IL_0130: stloc.2 IL_0131: ldloca.s V_2 IL_0133: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0138: brtrue.s IL_0176 + IL_0138: brtrue.s IL_0179 IL_013a: ldarg.0 IL_013b: ldc.i4.2 IL_013c: dup @@ -2193,52 +2205,64 @@ .locals init (int V_0, IL_0150: ldloca.s V_2 IL_0152: ldarg.0 IL_0153: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0158: leave.s IL_01c4 - IL_015a: ldarg.0 - IL_015b: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" - IL_0160: stloc.2 - IL_0161: ldarg.0 - IL_0162: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" - IL_0167: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_016d: ldarg.0 - IL_016e: ldc.i4.m1 - IL_016f: dup - IL_0170: stloc.0 - IL_0171: stfld ""int C.d__2.<>1__state"" - IL_0176: ldloca.s V_2 - IL_0178: call ""C System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_017d: stloc.1 - IL_017e: ldarg.0 - IL_017f: ldfld ""int C.d__2.<>7__wrap4"" - IL_0184: ldloc.1 - IL_0185: call ""void C.Test(int, C)"" - IL_018a: ldarg.0 - IL_018b: ldnull - IL_018c: stfld ""C C.d__2.<>7__wrap2"" - IL_0191: ldarg.0 - IL_0192: ldnull - IL_0193: stfld ""C C.d__2.<>7__wrap3"" - IL_0198: leave.s IL_01b1 + IL_0158: leave IL_01e3 + IL_015d: ldarg.0 + IL_015e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" + IL_0163: stloc.2 + IL_0164: ldarg.0 + IL_0165: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" + IL_016a: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0170: ldarg.0 + IL_0171: ldc.i4.m1 + IL_0172: dup + IL_0173: stloc.0 + IL_0174: stfld ""int C.d__2.<>1__state"" + IL_0179: ldloca.s V_2 + IL_017b: call ""C System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_0180: stloc.1 + IL_0181: ldarg.0 + IL_0182: ldfld ""int C.d__2.<>7__wrap4"" + IL_0187: ldloc.1 + IL_0188: call ""void C.Test(int, C)"" + IL_018d: ldarg.0 + IL_018e: ldnull + IL_018f: stfld ""C C.d__2.<>7__wrap2"" + IL_0194: ldarg.0 + IL_0195: ldnull + IL_0196: stfld ""C C.d__2.<>7__wrap3"" + IL_019b: leave.s IL_01c2 } catch System.Exception { - IL_019a: stloc.3 - IL_019b: ldarg.0 - IL_019c: ldc.i4.s -2 - IL_019e: stfld ""int C.d__2.<>1__state"" - IL_01a3: ldarg.0 - IL_01a4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01a9: ldloc.3 - IL_01aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01af: leave.s IL_01c4 + IL_019d: stloc.3 + IL_019e: ldarg.0 + IL_019f: ldc.i4.s -2 + IL_01a1: stfld ""int C.d__2.<>1__state"" + IL_01a6: ldarg.0 + IL_01a7: ldnull + IL_01a8: stfld ""C C.d__2.<>7__wrap2"" + IL_01ad: ldarg.0 + IL_01ae: ldnull + IL_01af: stfld ""C C.d__2.<>7__wrap3"" + IL_01b4: ldarg.0 + IL_01b5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01ba: ldloc.3 + IL_01bb: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01c0: leave.s IL_01e3 } - IL_01b1: ldarg.0 - IL_01b2: ldc.i4.s -2 - IL_01b4: stfld ""int C.d__2.<>1__state"" - IL_01b9: ldarg.0 - IL_01ba: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01bf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01c4: ret + IL_01c2: ldarg.0 + IL_01c3: ldc.i4.s -2 + IL_01c5: stfld ""int C.d__2.<>1__state"" + IL_01ca: ldarg.0 + IL_01cb: ldnull + IL_01cc: stfld ""C C.d__2.<>7__wrap2"" + IL_01d1: ldarg.0 + IL_01d2: ldnull + IL_01d3: stfld ""C C.d__2.<>7__wrap3"" + IL_01d8: ldarg.0 + IL_01d9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01de: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01e3: ret } "); } From 0d40220a47b75bd99ae15f796756bb7543fffaaa Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 14:42:13 -0800 Subject: [PATCH 08/20] Collect hoisted fields when adding to proxies instead --- .../Lowering/MethodToClassRewriter.cs | 1 + .../MethodToStateMachineRewriter.cs | 64 +++++++++++-------- .../Emit/CodeGen/CodeGenAsyncMainTests.cs | 16 ++--- .../Emit/CodeGen/CodeGenAsyncSpillTests.cs | 10 +-- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs index 1f2fa70219430..1f35eeb109ea6 100644 --- a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs @@ -385,6 +385,7 @@ private bool TryReplaceWithProxy(Symbol parameterOrLocal, SyntaxNode syntax, [No return false; } + public sealed override BoundNode VisitParameter(BoundParameter node) { if (TryReplaceWithProxy(node.ParameterSymbol, node.Syntax, out BoundNode? replacement)) diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 83ccb02811418..30d87543e33aa 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -69,6 +69,11 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter /// private Dictionary>? _lazyAvailableReusableHoistedFields; + /// + /// We collect all the hoisted fields for locals, so that we can clear them so the GC can collect references. + /// + private readonly ArrayBuilder _hoistedFieldsForCleanup; + /// /// Fields allocated for temporary variables are given unique names distinguished by a number at the end. /// This counter ensures they are unique within a given translated method. @@ -122,10 +127,11 @@ public MethodToStateMachineRewriter( _hoistedVariables = hoistedVariables; _synthesizedLocalOrdinals = synthesizedLocalOrdinals; _nextFreeHoistedLocalSlot = nextFreeHoistedLocalSlot; + _hoistedFieldsForCleanup = new ArrayBuilder(); foreach (var proxy in nonReusableLocalProxies) { - this.proxies.Add(proxy.Key, proxy.Value); + this.AddProxyAndRegisterForCleanup(proxy.Key, proxy.Value); } // create cache local for reference type "this" in Release @@ -312,7 +318,7 @@ private BoundStatement PossibleIteratorScope(ImmutableArray locals, if (!proxies.TryGetValue(local, out proxy)) { proxy = new CapturedToStateMachineFieldReplacement(GetOrAllocateReusableHoistedField(TypeMap.SubstituteType(local.Type).Type, out reused, local), isReusable: true); - proxies.Add(local, proxy); + AddProxyAndRegisterForCleanup(local, proxy); } // We need to produce hoisted local scope debug information for user locals as well as @@ -430,28 +436,39 @@ private void AddVariableCleanup(ArrayBuilder cleanup, FieldSymb } #nullable enable + private void AddProxyAndRegisterForCleanup(Symbol symbol, CapturedSymbolReplacement replacement) + { + Debug.Assert(replacement is CapturedToStateMachineFieldReplacement or CapturedToExpressionSymbolReplacement); + proxies.Add(symbol, replacement); + + Debug.Assert(symbol is LocalSymbol or ParameterSymbol); + if (symbol is LocalSymbol) + { + if (replacement is CapturedToStateMachineFieldReplacement fieldReplacement) + { + _hoistedFieldsForCleanup.Add(fieldReplacement.HoistedField); + } + else if (replacement is CapturedToExpressionSymbolReplacement expressionReplacement) + { + foreach (var field in expressionReplacement.HoistedFields) + { + _hoistedFieldsForCleanup.Add(field); + } + } + } + } + protected BoundBlock GenerateAllHoistedLocalsCleanup() { var variableCleanup = ArrayBuilder.GetInstance(); var alreadyCleaned = PooledHashSet.GetInstance(); - foreach (var symbol in HoistedVariables) + + foreach (FieldSymbol fieldSymbol in _hoistedFieldsForCleanup) { - if (symbol is LocalSymbol - && proxies.TryGetValue(symbol, out CapturedSymbolReplacement? replacement)) + // Hoisted fields may be re-used for multiple locals, so we can skip those that were cleared already + if (alreadyCleaned.Add(fieldSymbol.Name)) { - Debug.Assert(replacement is CapturedToStateMachineFieldReplacement or CapturedToExpressionSymbolReplacement); - - if (replacement is CapturedToStateMachineFieldReplacement fieldReplacement) - { - addVariableCleanupOnce(variableCleanup, fieldReplacement.HoistedField, alreadyCleaned); - } - else if (replacement is CapturedToExpressionSymbolReplacement expressionReplacement) - { - foreach (var field in expressionReplacement.HoistedFields) - { - addVariableCleanupOnce(variableCleanup, field, alreadyCleaned); - } - } + AddVariableCleanup(variableCleanup, fieldSymbol); } } @@ -461,15 +478,6 @@ protected BoundBlock GenerateAllHoistedLocalsCleanup() alreadyCleaned.Free(); return result; - - void addVariableCleanupOnce(ArrayBuilder variableCleanup, FieldSymbol field, PooledHashSet alreadyCleaned) - { - // Hoisted fields may be re-used, so we can skip those that were cleared already - if (alreadyCleaned.Add(field.Name)) - { - AddVariableCleanup(variableCleanup, field); - } - } } #nullable disable @@ -557,7 +565,7 @@ private BoundExpression HoistRefInitialization(SynthesizedLocal local, BoundAssi var replacement = HoistExpression(right, awaitSyntaxOpt, syntaxOffset, local.RefKind, sideEffects, hoistedFields, ref needsSacrificialEvaluation); - proxies.Add(local, new CapturedToExpressionSymbolReplacement(replacement, hoistedFields.ToImmutableAndFree(), isReusable: true)); + AddProxyAndRegisterForCleanup(local, new CapturedToExpressionSymbolReplacement(replacement, hoistedFields.ToImmutableAndFree(), isReusable: true)); if (needsSacrificialEvaluation) { diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs index 99d44c346fa24..0f1133165e866 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs @@ -1764,10 +1764,10 @@ .locals init (int V_0, IL_0182: stfld ""int Program.
d__0.<>1__state"" IL_0187: ldarg.0 IL_0188: ldnull - IL_0189: stfld ""object Program.
d__0.<>7__wrap3"" + IL_0189: stfld ""object Program.
d__0.<>7__wrap1"" IL_018e: ldarg.0 IL_018f: ldnull - IL_0190: stfld ""object Program.
d__0.<>7__wrap1"" + IL_0190: stfld ""object Program.
d__0.<>7__wrap3"" IL_0195: ldarg.0 IL_0196: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" IL_019b: ldloc.s V_4 @@ -1779,10 +1779,10 @@ .locals init (int V_0, IL_01a7: stfld ""int Program.
d__0.<>1__state"" IL_01ac: ldarg.0 IL_01ad: ldnull - IL_01ae: stfld ""object Program.
d__0.<>7__wrap3"" + IL_01ae: stfld ""object Program.
d__0.<>7__wrap1"" IL_01b3: ldarg.0 IL_01b4: ldnull - IL_01b5: stfld ""object Program.
d__0.<>7__wrap1"" + IL_01b5: stfld ""object Program.
d__0.<>7__wrap3"" IL_01ba: ldarg.0 IL_01bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" IL_01c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" @@ -1965,10 +1965,10 @@ .locals init (int V_0, IL_0118: stfld ""int Program.
d__0.<>1__state"" IL_011d: ldarg.0 IL_011e: ldnull - IL_011f: stfld ""object Program.
d__0.<>7__wrap3"" + IL_011f: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" IL_0124: ldarg.0 IL_0125: ldnull - IL_0126: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" + IL_0126: stfld ""object Program.
d__0.<>7__wrap3"" IL_012b: ldarg.0 IL_012c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" IL_0131: ldloc.s V_4 @@ -1980,10 +1980,10 @@ .locals init (int V_0, IL_013d: stfld ""int Program.
d__0.<>1__state"" IL_0142: ldarg.0 IL_0143: ldnull - IL_0144: stfld ""object Program.
d__0.<>7__wrap3"" + IL_0144: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" IL_0149: ldarg.0 IL_014a: ldnull - IL_014b: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" + IL_014b: stfld ""object Program.
d__0.<>7__wrap3"" IL_0150: ldarg.0 IL_0151: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" IL_0156: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs index 784ca194a2fd9..636b550835617 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs @@ -6277,7 +6277,7 @@ Caught NullReferenceException After Assignment a._b._x is: 42 After Assignment b._x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ + { // Code size 250 (0xfa) .maxstack 3 .locals init (int V_0, @@ -6362,10 +6362,10 @@ .locals init (int V_0, IL_00b6: stfld ""int Program.d__0.<>1__state"" IL_00bb: ldarg.0 IL_00bc: ldnull - IL_00bd: stfld ""B Program.d__0.<>7__wrap2"" + IL_00bd: stfld ""B Program.d__0.<>7__wrap1"" IL_00c2: ldarg.0 IL_00c3: ldnull - IL_00c4: stfld ""B Program.d__0.<>7__wrap1"" + IL_00c4: stfld ""B Program.d__0.<>7__wrap2"" IL_00c9: ldarg.0 IL_00ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" IL_00cf: ldloc.s V_4 @@ -6377,10 +6377,10 @@ .locals init (int V_0, IL_00db: stfld ""int Program.d__0.<>1__state"" IL_00e0: ldarg.0 IL_00e1: ldnull - IL_00e2: stfld ""B Program.d__0.<>7__wrap2"" + IL_00e2: stfld ""B Program.d__0.<>7__wrap1"" IL_00e7: ldarg.0 IL_00e8: ldnull - IL_00e9: stfld ""B Program.d__0.<>7__wrap1"" + IL_00e9: stfld ""B Program.d__0.<>7__wrap2"" IL_00ee: ldarg.0 IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" IL_00f4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" From b52733e21cdd6daa5503eb5c4f1b8a4ff80538ec Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 14:53:29 -0800 Subject: [PATCH 09/20] Revert name changes --- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 40 +++++++++---------- .../Test/Emit/CodeGen/CodeGenAsyncTests.cs | 20 +++++----- .../Test/Emit/CodeGen/CodeGenIterators.cs | 1 + 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 6950456ddee54..01ef3c1fca5a3 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -9438,15 +9438,15 @@ public void AddVariableCleanup_IntLocal() var values = C.Produce(); await foreach (int value in values) { } -System.Console.Write(((int)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((int)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce() { - int s = 42; + int values2 = 42; await System.Threading.Tasks.Task.CompletedTask; - yield return s; + yield return values2; } } """; @@ -9462,18 +9462,18 @@ public void AddVariableCleanup_StringLocal() var values = C.Produce(); await foreach (int value in values) { - System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static async System.Collections.Generic.IAsyncEnumerable Produce() { - string s = "value "; + string values2 = "value "; await System.Threading.Tasks.Task.CompletedTask; yield return 1; - System.Console.Write(s); + System.Console.Write(values2); } } """; @@ -9511,7 +9511,7 @@ .locals init (int V_0, IL_0035: stfld "int C.d__0.<>1__state" IL_003a: ldarg.0 IL_003b: ldstr "value " - IL_0040: stfld "string C.d__0.5__2" + IL_0040: stfld "string C.d__0.5__2" IL_0045: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" IL_004a: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" IL_004f: stloc.1 @@ -9566,7 +9566,7 @@ .locals init (int V_0, IL_00c4: brfalse.s IL_00c8 IL_00c6: leave.s IL_0105 IL_00c8: ldarg.0 - IL_00c9: ldfld "string C.d__0.5__2" + IL_00c9: ldfld "string C.d__0.5__2" IL_00ce: call "void System.Console.Write(string)" IL_00d3: leave.s IL_0105 } @@ -9578,7 +9578,7 @@ .locals init (int V_0, IL_00d9: stfld "int C.d__0.<>1__state" IL_00de: ldarg.0 IL_00df: ldnull - IL_00e0: stfld "string C.d__0.5__2" + IL_00e0: stfld "string C.d__0.5__2" IL_00e5: ldarg.0 IL_00e6: ldc.i4.0 IL_00e7: stfld "int C.d__0.<>2__current" @@ -9596,7 +9596,7 @@ .locals init (int V_0, IL_0108: stfld "int C.d__0.<>1__state" IL_010d: ldarg.0 IL_010e: ldnull - IL_010f: stfld "string C.d__0.5__2" + IL_010f: stfld "string C.d__0.5__2" IL_0114: ldarg.0 IL_0115: ldc.i4.0 IL_0116: stfld "int C.d__0.<>2__current" @@ -9718,13 +9718,13 @@ public void AddVariableCleanup_NestedStringLocal() var enumerator = values.GetAsyncEnumerator(); assert(await enumerator.MoveNextAsync()); assert(enumerator.Current == 1); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); assert(await enumerator.MoveNextAsync()); assert(enumerator.Current == 2); _ = enumerator.MoveNextAsync(); -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); void assert(bool b) { @@ -9737,9 +9737,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - string s = "value "; + string values2 = "value "; yield return 1; - System.Console.Write(s); + System.Console.Write(values2); b = false; } yield return 2; @@ -9892,7 +9892,7 @@ public struct S assert(enumerator.Current == 2); _ = enumerator.MoveNextAsync(); -System.Console.Write(((S)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); +System.Console.Write(((S)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); void assert(bool b) { @@ -9905,9 +9905,9 @@ public static async System.Collections.Generic.IAsyncEnumerable Produce(boo { while (b) { - S s = new S { field = 42 }; + S values2 = new S { field = 42 }; yield return 1; - System.Console.Write(s); + System.Console.Write(values2); b = false; } yield return 2; @@ -9961,7 +9961,7 @@ .locals init (int V_0, IL_004f: ldc.i4.s 42 IL_0051: stfld "int S.field" IL_0056: ldloc.1 - IL_0057: stfld "S C.d__0.5__2" + IL_0057: stfld "S C.d__0.5__2" IL_005c: ldarg.0 IL_005d: ldc.i4.1 IL_005e: stfld "int C.d__0.<>2__current" @@ -9981,7 +9981,7 @@ .locals init (int V_0, IL_0081: brfalse.s IL_0088 IL_0083: leave IL_0181 IL_0088: ldarg.0 - IL_0089: ldfld "S C.d__0.5__2" + IL_0089: ldfld "S C.d__0.5__2" IL_008e: box "S" IL_0093: call "void System.Console.Write(object)" IL_0098: ldarg.0 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 0ba98b0ea7923..d158d17b4677d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -6077,7 +6077,7 @@ public void AddVariableCleanup_NestedStringLocal() object stateMachineBox = callback.Target; object stateMachine = stateMachineBox.GetType().GetField("StateMachine", BindingFlags.Public | BindingFlags.Instance).GetValue(stateMachineBox); -System.Console.Write((string)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine) is null); +System.Console.Write((string)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine) is null); class C { @@ -6085,12 +6085,12 @@ public static async System.Threading.Tasks.Task ProduceAsync(bool b, System { while (b) { - string s = "value "; + string values2 = "value "; await System.Threading.Tasks.Task.CompletedTask; - System.Console.Write(s); + System.Console.Write(values2); b = false; } - await task; // block execution here to check what's in the field for "s" + await task; // block execution here to check what's in the field for "values2" return 42; } } @@ -6120,7 +6120,7 @@ public struct S object stateMachineBox = callback.Target; object stateMachine = stateMachineBox.GetType().GetField("StateMachine", BindingFlags.Public | BindingFlags.Instance).GetValue(stateMachineBox); -System.Console.Write((S)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine)); +System.Console.Write((S)stateMachine.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(stateMachine)); class C { @@ -6128,12 +6128,12 @@ public static async System.Threading.Tasks.Task ProduceAsync(bool b, System { while (b) { - S s = new S { field = 42 }; + S values2 = new S { field = 42 }; await System.Threading.Tasks.Task.CompletedTask; - System.Console.Write(s); + System.Console.Write(values2); b = false; } - await task; // block execution here to check what's in the field for "s" + await task; // block execution here to check what's in the field for "values2" return 10; } } @@ -6168,7 +6168,7 @@ .locals init (int V_0, IL_0021: ldc.i4.s 42 IL_0023: stfld "int S.field" IL_0028: ldloc.2 - IL_0029: stfld "S C.d__0.5__2" + IL_0029: stfld "S C.d__0.5__2" IL_002e: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" IL_0033: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" IL_0038: stloc.3 @@ -6203,7 +6203,7 @@ .locals init (int V_0, IL_0081: ldloca.s V_3 IL_0083: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" IL_0088: ldarg.0 - IL_0089: ldfld "S C.d__0.5__2" + IL_0089: ldfld "S C.d__0.5__2" IL_008e: box "S" IL_0093: call "void System.Console.Write(object)" IL_0098: ldarg.0 diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index 5f3be7001f73f..1e5ae75eef7cb 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3033,6 +3033,7 @@ .maxstack 0 } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_StringLocal() { string src = """ From 3ac01372b645132ddd8b0468e6438034098a41c5 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 15:05:15 -0800 Subject: [PATCH 10/20] Move to local function --- .../AsyncMethodToStateMachineRewriter.cs | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index dd72b1e49ec13..6747529ce7d12 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -156,7 +156,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) // [body] rewrittenBody ), - F.CatchBlocks(GenerateExceptionHandling(exceptionLocal))) + F.CatchBlocks(generateExceptionHandling(exceptionLocal))) ); // ReturnLabel (for the rewritten return expressions in the user's method body) @@ -207,6 +207,42 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) newBody = F.Instrument(newBody, instrumentation); F.CloseMethod(newBody); + return; + + BoundCatchBlock generateExceptionHandling(LocalSymbol exceptionLocal) + { + // catch (Exception ex) + // { + // _state = finishedState; + // + // for each hoisted local: + // <>x__y = default + // + // builder.SetException(ex); OR if (this.combinedTokens != null) this.combinedTokens.Dispose(); _promiseOfValueOrEnd.SetException(ex); /* for async-iterator method */ + // return; + // } + + // _state = finishedState; + BoundStatement assignFinishedState = + F.ExpressionStatement(F.AssignmentExpression(F.Field(F.This(), stateField), F.Literal(StateMachineState.FinishedState))); + + // builder.SetException(ex); OR if (this.combinedTokens != null) this.combinedTokens.Dispose(); _promiseOfValueOrEnd.SetException(ex); + BoundStatement callSetException = GenerateSetExceptionCall(exceptionLocal); + + return new BoundCatchBlock( + F.Syntax, + ImmutableArray.Create(exceptionLocal), + F.Local(exceptionLocal), + exceptionLocal.Type, + exceptionFilterPrologueOpt: null, + exceptionFilterOpt: null, + body: F.Block( + assignFinishedState, // _state = finishedState; + GenerateAllHoistedLocalsCleanup(), + callSetException, // builder.SetException(ex); OR _promiseOfValueOrEnd.SetException(ex); + GenerateReturn(false)), // return; + isSynthesizedAsyncCatchAll: true); + } } protected virtual BoundStatement GenerateTopLevelTry(BoundBlock tryBlock, ImmutableArray catchBlocks) @@ -224,42 +260,6 @@ protected virtual BoundStatement GenerateSetResultCall() : ImmutableArray.Empty)); } - // TODO2 move to local function - protected BoundCatchBlock GenerateExceptionHandling(LocalSymbol exceptionLocal) - { - // catch (Exception ex) - // { - // _state = finishedState; - // - // for each hoisted local: - // <>x__y = default - // - // builder.SetException(ex); OR if (this.combinedTokens != null) this.combinedTokens.Dispose(); _promiseOfValueOrEnd.SetException(ex); /* for async-iterator method */ - // return; - // } - - // _state = finishedState; - BoundStatement assignFinishedState = - F.ExpressionStatement(F.AssignmentExpression(F.Field(F.This(), stateField), F.Literal(StateMachineState.FinishedState))); - - // builder.SetException(ex); OR if (this.combinedTokens != null) this.combinedTokens.Dispose(); _promiseOfValueOrEnd.SetException(ex); - BoundStatement callSetException = GenerateSetExceptionCall(exceptionLocal); - - return new BoundCatchBlock( - F.Syntax, - ImmutableArray.Create(exceptionLocal), - F.Local(exceptionLocal), - exceptionLocal.Type, - exceptionFilterPrologueOpt: null, - exceptionFilterOpt: null, - body: F.Block( - assignFinishedState, // _state = finishedState; - GenerateAllHoistedLocalsCleanup(), - callSetException, // builder.SetException(ex); OR _promiseOfValueOrEnd.SetException(ex); - GenerateReturn(false)), // return; - isSynthesizedAsyncCatchAll: true); - } - protected virtual BoundStatement GenerateSetExceptionCall(LocalSymbol exceptionLocal) { Debug.Assert(!CurrentMethod.IsIterator); // an override handles async-iterators From 37d3b3dba3f02f2eaeae7743ec8ab4d94b3285e3 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 15:07:29 -0800 Subject: [PATCH 11/20] Tweaks --- ...yncIteratorMethodToStateMachineRewriter.cs | 1 - .../Lowering/MethodToClassRewriter.cs | 1 - .../Test/Emit/CodeGen/CodeGenIterators.cs | 20 +++++++++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 360919ddc8d28..2e4f51e71d9ee 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -89,7 +89,6 @@ internal AsyncIteratorMethodToStateMachineRewriter( return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; } #nullable disable - protected override BoundStatement GenerateSetResultCall() { // ... _exprReturnLabel: ... diff --git a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs index 1f35eeb109ea6..1f2fa70219430 100644 --- a/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/MethodToClassRewriter.cs @@ -385,7 +385,6 @@ private bool TryReplaceWithProxy(Symbol parameterOrLocal, SyntaxNode syntax, [No return false; } - public sealed override BoundNode VisitParameter(BoundParameter node) { if (TryReplaceWithProxy(node.ParameterSymbol, node.Syntax, out BoundNode? replacement)) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index 1e5ae75eef7cb..9a5bd1dd7442d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3042,17 +3042,17 @@ public void AddVariableCleanup_StringLocal() var values = C.Produce(); foreach (int value in values) { - System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); + System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values))); } -System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((string)values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - string s = "ran "; + string values2 = "ran "; yield return 42; - System.Console.Write(s); + System.Console.Write(values2); } } """; @@ -3063,7 +3063,7 @@ public static System.Collections.Generic.IEnumerable Produce() .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "string C.d__0.5__2" + IL_0002: stfld "string C.d__0.values2s>5__2" IL_0007: ret } """); @@ -3116,17 +3116,17 @@ public void AddVariableCleanup_IntArrayLocal() var values = C.Produce(); foreach (int value in values) { - System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)).Length); + System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)).Length); } -System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); +System.Console.Write(((int[])values.GetType().GetField("5__2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); class C { public static System.Collections.Generic.IEnumerable Produce() { - int[] s = Enumerable.Range(0, 100).ToArray(); + int[] values2 = Enumerable.Range(0, 100).ToArray(); yield return 42; - System.Console.Write($" {s.Length} "); + System.Console.Write($" {values2.Length} "); } } """; @@ -3138,7 +3138,7 @@ public static System.Collections.Generic.IEnumerable Produce() .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "int[] C.d__0.5__2" + IL_0002: stfld "int[] C.d__0.5__2" IL_0007: ret } """); From e948e85cf0e62448ecee69d3f7b999cacc5b246a Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 15:18:45 -0800 Subject: [PATCH 12/20] Typo --- src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index 9a5bd1dd7442d..3e1b57c517fbd 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3063,7 +3063,7 @@ public static System.Collections.Generic.IEnumerable Produce() .maxstack 2 IL_0000: ldarg.0 IL_0001: ldnull - IL_0002: stfld "string C.d__0.values2s>5__2" + IL_0002: stfld "string C.d__0.5__2" IL_0007: ret } """); From b1a5ebb4a852ac4a257c74b56fe0668df511a3ee Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 16:52:33 -0800 Subject: [PATCH 13/20] Report use-site diagnostic from IsManagedType --- ...yncIteratorMethodToStateMachineRewriter.cs | 7 ++- .../MethodToStateMachineRewriter.cs | 5 ++- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 44 +++++++++++++++++++ .../Test/Emit/CodeGen/CodeGenIterators.cs | 41 +++++++++++++++++ .../Semantic/Semantics/UseSiteErrorTests.cs | 2 + 5 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 2e4f51e71d9ee..4cba75f6958b9 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -320,7 +320,12 @@ public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node protected override BoundStatement MakeAwaitPreamble() { - if (_asyncIteratorInfo.CurrentField.Type.IsManagedTypeNoUseSiteDiagnostics) + var useSiteInfo = new CompoundUseSiteInfo(F.Diagnostics, F.Compilation.Assembly); + var field = _asyncIteratorInfo.CurrentField; + bool isManaged = field.Type.IsManagedType(ref useSiteInfo); + F.Diagnostics.Add(field.GetFirstLocationOrNone(), useSiteInfo); + + if (isManaged) { // _current = default; return GenerateClearCurrent(); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 30d87543e33aa..cc269632a1bc7 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -429,7 +429,10 @@ internal static bool TryUnwrapBoundStateMachineScope(ref BoundStatement statemen ///
private void AddVariableCleanup(ArrayBuilder cleanup, FieldSymbol field) { - if (field.Type.IsManagedTypeNoUseSiteDiagnostics) + var useSiteInfo = new CompoundUseSiteInfo(F.Diagnostics, F.Compilation.Assembly); + bool isManaged = field.Type.IsManagedType(ref useSiteInfo); + F.Diagnostics.Add(field.GetFirstLocationOrNone(), useSiteInfo); + if (isManaged) { cleanup.Add(F.AssignmentExpression(F.Field(F.This(), field), F.NullOrDefault(field.Type))); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 01ef3c1fca5a3..e6146b3569421 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -10257,5 +10257,49 @@ public struct Buffer2 """; CompileAndVerify(src, expectedOutput: ExpectedOutput("False 0 False 1 True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } + + [Fact] + public void AddVariableCleanup_Unmanaged_UseSiteError() + { + var missingLibS1 = CreateCompilation(@" +public struct S1 +{ + public int i; +} +", assemblyName: "libS1", targetFramework: TargetFramework.Net80).ToMetadataReference(); + + var libS2 = CreateCompilation(@" +public struct S2 +{ + public S1 s1; +} +", references: [missingLibS1], assemblyName: "libS2", targetFramework: TargetFramework.Net80).ToMetadataReference(); + + var source = @" +class C +{ + public static async System.Collections.Generic.IAsyncEnumerable M(S2 p) + { + S2 local = p; + await System.Threading.Tasks.Task.CompletedTask; + yield return local; + System.Console.Write(local); + } +} +"; + var comp = CreateCompilation(source, references: [libS2], targetFramework: TargetFramework.Net80); + comp.VerifyEmitDiagnostics( + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1), + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1), + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1), + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1)); + + comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll, references: [libS2, missingLibS1], targetFramework: TargetFramework.Net80); + comp.VerifyEmitDiagnostics(); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index 3e1b57c517fbd..a42df2393ef9f 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -4080,5 +4080,46 @@ .maxstack 2 } """); } + + [Fact] + public void AddVariableCleanup_Unmanaged_UseSiteError() + { + var missingLibS1 = CreateCompilation(@" +public struct S1 +{ + public int i; +} +", assemblyName: "libS1").ToMetadataReference(); + + var libS2 = CreateCompilation(@" +public struct S2 +{ + public S1 s1; +} +", references: [missingLibS1], assemblyName: "libS2").ToMetadataReference(); + + var source = @" +class C +{ + System.Collections.Generic.IEnumerable M1() + { + S2 s2 = M2(); + yield return 42; + System.Console.Write(s2); + } + + S2 M2() => default; +} +"; + var comp = CreateCompilation(source, references: [libS2]); + comp.VerifyEmitDiagnostics( + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1), + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1)); + + comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll, references: [libS2, missingLibS1]); + comp.VerifyEmitDiagnostics(); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs index 172b3255fee4b..5bb1106bc6dc9 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs @@ -2728,6 +2728,8 @@ async Task M1() "; var comp = CreateCompilation(source, references: new[] { UnmanagedUseSiteError_Ref2 }); comp.VerifyEmitDiagnostics( + // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1), // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Diagnostic(ErrorCode.ERR_NoTypeDef).WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(1, 1), // error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. From fdd444cfebc97cc170380f5b3026c6c29f247656 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 15 Nov 2024 17:18:02 -0800 Subject: [PATCH 14/20] Revert "Clear all hoisted locals in async too" This reverts commit e170504bc65e7e549dfe1ec09605561629df2aa4. --- ...yncIteratorMethodToStateMachineRewriter.cs | 9 + .../AsyncMethodToStateMachineRewriter.cs | 30 +- .../Test/Emit/CodeGen/CodeGenAsyncEHTests.cs | 152 ++-- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 38 +- .../Emit/CodeGen/CodeGenAsyncLocalsTests.cs | 221 +++--- .../Emit/CodeGen/CodeGenAsyncMainTests.cs | 84 +- .../Emit/CodeGen/CodeGenAsyncSpillTests.cs | 734 ++++++++---------- .../Test/Emit/CodeGen/CodeGenAsyncTests.cs | 48 +- .../Emit/CodeGen/CodeGenAwaitForeachTests.cs | 46 +- .../Emit/CodeGen/CodeGenAwaitUsingTests.cs | 264 +++---- .../CodeGenRefConditionalOperatorTests.cs | 150 ++-- 11 files changed, 773 insertions(+), 1003 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 4cba75f6958b9..1bee6e668af52 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -88,6 +88,15 @@ internal AsyncIteratorMethodToStateMachineRewriter( return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; } + + protected override BoundStatement GenerateHoistedLocalsCleanupForExit(ImmutableArray hoistedLocals) + { + // We need to clean nested hoisted local variables too (not just top-level ones) + // as they are not cleaned when exiting a block if we exit using a `yield break` + // or if the caller interrupts the enumeration after we reached a `yield return`. + // So we clean both top-level and nested hoisted local variables + return GenerateAllHoistedLocalsCleanup(); + } #nullable disable protected override BoundStatement GenerateSetResultCall() { diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index 6747529ce7d12..98371974c478a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -156,7 +156,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) // [body] rewrittenBody ), - F.CatchBlocks(generateExceptionHandling(exceptionLocal))) + F.CatchBlocks(generateExceptionHandling(exceptionLocal, rootScopeHoistedLocals))) ); // ReturnLabel (for the rewritten return expressions in the user's method body) @@ -177,7 +177,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) // The remaining code is hidden to hide the fact that it can run concurrently with the task's continuation } - bodyBuilder.Add(GenerateAllHoistedLocalsCleanup()); + bodyBuilder.Add(GenerateHoistedLocalsCleanupForExit(rootScopeHoistedLocals)); bodyBuilder.Add(GenerateSetResultCall()); @@ -209,7 +209,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) F.CloseMethod(newBody); return; - BoundCatchBlock generateExceptionHandling(LocalSymbol exceptionLocal) + BoundCatchBlock generateExceptionHandling(LocalSymbol exceptionLocal, ImmutableArray rootHoistedLocals) { // catch (Exception ex) // { @@ -238,7 +238,7 @@ BoundCatchBlock generateExceptionHandling(LocalSymbol exceptionLocal) exceptionFilterOpt: null, body: F.Block( assignFinishedState, // _state = finishedState; - GenerateAllHoistedLocalsCleanup(), + GenerateHoistedLocalsCleanupForExit(rootHoistedLocals), callSetException, // builder.SetException(ex); OR _promiseOfValueOrEnd.SetException(ex); GenerateReturn(false)), // return; isSynthesizedAsyncCatchAll: true); @@ -260,6 +260,28 @@ protected virtual BoundStatement GenerateSetResultCall() : ImmutableArray.Empty)); } + protected virtual BoundStatement GenerateHoistedLocalsCleanupForExit(ImmutableArray rootHoistedLocals) + { + var builder = ArrayBuilder.GetInstance(); + + // Cleanup all hoisted local variables + // so that they can be collected by GC if needed + foreach (var hoistedLocal in rootHoistedLocals) + { + var useSiteInfo = new CompoundUseSiteInfo(F.Diagnostics, F.Compilation.Assembly); + var isManagedType = hoistedLocal.Type.IsManagedType(ref useSiteInfo); + F.Diagnostics.Add(hoistedLocal.GetFirstLocationOrNone(), useSiteInfo); + if (!isManagedType) + { + continue; + } + + builder.Add(F.Assignment(F.Field(F.This(), hoistedLocal), F.NullOrDefault(hoistedLocal.Type))); + } + + return F.Block(builder.ToImmutableAndFree()); + } + protected virtual BoundStatement GenerateSetExceptionCall(LocalSymbol exceptionLocal) { Debug.Assert(!CurrentMethod.IsIterator); // an override handles async-iterators diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs index d334ecedab136..3078e2a20345e 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs @@ -733,7 +733,7 @@ public static void Main() CompileAndVerify(source, expectedOutput: expected). VerifyIL("Test.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 227 (0xe3) + // Code size 210 (0xd2) .maxstack 3 .locals init (int V_0, int V_1, @@ -746,7 +746,7 @@ .locals init (int V_0, .try { IL_0007: ldloc.0 - IL_0008: brfalse.s IL_005b + IL_0008: brfalse.s IL_0058 IL_000a: ldarg.0 IL_000b: ldnull IL_000c: stfld ""object Test.d__1.<>7__wrap1"" @@ -770,7 +770,7 @@ .locals init (int V_0, IL_002e: stloc.3 IL_002f: ldloca.s V_3 IL_0031: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0036: brtrue.s IL_0077 + IL_0036: brtrue.s IL_0074 IL_0038: ldarg.0 IL_0039: ldc.i4.0 IL_003a: dup @@ -784,65 +784,59 @@ .locals init (int V_0, IL_004e: ldloca.s V_3 IL_0050: ldarg.0 IL_0051: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__1)"" - IL_0056: leave IL_00e2 - IL_005b: ldarg.0 - IL_005c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" - IL_0061: stloc.3 - IL_0062: ldarg.0 - IL_0063: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" - IL_0068: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_006e: ldarg.0 - IL_006f: ldc.i4.m1 - IL_0070: dup - IL_0071: stloc.0 - IL_0072: stfld ""int Test.d__1.<>1__state"" - IL_0077: ldloca.s V_3 - IL_0079: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_007e: ldarg.0 - IL_007f: ldfld ""object Test.d__1.<>7__wrap1"" - IL_0084: stloc.2 + IL_0056: leave.s IL_00d1 + IL_0058: ldarg.0 + IL_0059: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" + IL_005e: stloc.3 + IL_005f: ldarg.0 + IL_0060: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" + IL_0065: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_006b: ldarg.0 + IL_006c: ldc.i4.m1 + IL_006d: dup + IL_006e: stloc.0 + IL_006f: stfld ""int Test.d__1.<>1__state"" + IL_0074: ldloca.s V_3 + IL_0076: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_007b: ldarg.0 + IL_007c: ldfld ""object Test.d__1.<>7__wrap1"" + IL_0081: stloc.2 + IL_0082: ldloc.2 + IL_0083: brfalse.s IL_009a IL_0085: ldloc.2 - IL_0086: brfalse.s IL_009d - IL_0088: ldloc.2 - IL_0089: isinst ""System.Exception"" - IL_008e: dup - IL_008f: brtrue.s IL_0093 - IL_0091: ldloc.2 - IL_0092: throw - IL_0093: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" - IL_0098: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" - IL_009d: ldarg.0 - IL_009e: ldnull - IL_009f: stfld ""object Test.d__1.<>7__wrap1"" - IL_00a4: stloc.1 - IL_00a5: leave.s IL_00c7 + IL_0086: isinst ""System.Exception"" + IL_008b: dup + IL_008c: brtrue.s IL_0090 + IL_008e: ldloc.2 + IL_008f: throw + IL_0090: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0095: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_009a: ldarg.0 + IL_009b: ldnull + IL_009c: stfld ""object Test.d__1.<>7__wrap1"" + IL_00a1: stloc.1 + IL_00a2: leave.s IL_00bd } catch System.Exception { - IL_00a7: stloc.s V_4 - IL_00a9: ldarg.0 - IL_00aa: ldc.i4.s -2 - IL_00ac: stfld ""int Test.d__1.<>1__state"" - IL_00b1: ldarg.0 - IL_00b2: ldnull - IL_00b3: stfld ""object Test.d__1.<>7__wrap1"" - IL_00b8: ldarg.0 - IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_00be: ldloc.s V_4 - IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00c5: leave.s IL_00e2 + IL_00a4: stloc.s V_4 + IL_00a6: ldarg.0 + IL_00a7: ldc.i4.s -2 + IL_00a9: stfld ""int Test.d__1.<>1__state"" + IL_00ae: ldarg.0 + IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_00b4: ldloc.s V_4 + IL_00b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00bb: leave.s IL_00d1 } - IL_00c7: ldarg.0 - IL_00c8: ldc.i4.s -2 - IL_00ca: stfld ""int Test.d__1.<>1__state"" - IL_00cf: ldarg.0 - IL_00d0: ldnull - IL_00d1: stfld ""object Test.d__1.<>7__wrap1"" - IL_00d6: ldarg.0 - IL_00d7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_00dc: ldloc.1 - IL_00dd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_00e2: ret + IL_00bd: ldarg.0 + IL_00be: ldc.i4.s -2 + IL_00c0: stfld ""int Test.d__1.<>1__state"" + IL_00c5: ldarg.0 + IL_00c6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_00cb: ldloc.1 + IL_00cc: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_00d1: ret } "); } @@ -991,7 +985,7 @@ public static void Main() v.VerifyIL("Test.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @"{ - // Code size 475 (0x1db) + // Code size 461 (0x1cd) .maxstack 3 .locals init (int V_0, int V_1, @@ -1055,7 +1049,7 @@ .locals init (int V_0, IL_0066: ldloca.s V_3 IL_0068: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__1)"" IL_006d: nop - IL_006e: leave IL_01da + IL_006e: leave IL_01cc >IL_0073: ldarg.0 IL_0074: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" IL_0079: stloc.2 @@ -1120,7 +1114,7 @@ .locals init (int V_0, IL_0108: ldloca.s V_3 IL_010a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__1)"" IL_010f: nop - IL_0110: leave IL_01da + IL_0110: leave IL_01cc >IL_0115: ldarg.0 IL_0116: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__1.<>u__1"" IL_011b: stloc.s V_5 @@ -1170,11 +1164,11 @@ .locals init (int V_0, IL_018b: ldarg.0 IL_018c: ldfld ""int Test.d__1.<>s__4"" IL_0191: stloc.1 - IL_0192: leave.s IL_01be + IL_0192: leave.s IL_01b7 IL_0194: ldarg.0 IL_0195: ldnull IL_0196: stfld ""object Test.d__1.<>s__2"" - IL_019b: leave.s IL_01be + IL_019b: leave.s IL_01b7 } catch System.Exception { @@ -1183,27 +1177,21 @@ .locals init (int V_0, IL_01a0: ldc.i4.s -2 IL_01a2: stfld ""int Test.d__1.<>1__state"" IL_01a7: ldarg.0 - IL_01a8: ldnull - IL_01a9: stfld ""object Test.d__1.<>s__2"" - IL_01ae: ldarg.0 - IL_01af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_01b4: ldloc.s V_6 - IL_01b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01bb: nop - IL_01bc: leave.s IL_01da + IL_01a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_01ad: ldloc.s V_6 + IL_01af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01b4: nop + IL_01b5: leave.s IL_01cc } - -IL_01be: ldarg.0 - IL_01bf: ldc.i4.s -2 - IL_01c1: stfld ""int Test.d__1.<>1__state"" - ~IL_01c6: ldarg.0 - IL_01c7: ldnull - IL_01c8: stfld ""object Test.d__1.<>s__2"" - IL_01cd: ldarg.0 - IL_01ce: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" - IL_01d3: ldloc.1 - IL_01d4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_01d9: nop - IL_01da: ret + -IL_01b7: ldarg.0 + IL_01b8: ldc.i4.s -2 + IL_01ba: stfld ""int Test.d__1.<>1__state"" + ~IL_01bf: ldarg.0 + IL_01c0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__1.<>t__builder"" + IL_01c5: ldloc.1 + IL_01c6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_01cb: nop + IL_01cc: ret }", sequencePoints: "Test+d__1.MoveNext"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index e6146b3569421..16ee5c028e1bc 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -720,7 +720,7 @@ ref struct S verifier.VerifyDiagnostics(); verifier.VerifyIL("C.
d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ { - // Code size 252 (0xfc) + // Code size 238 (0xee) .maxstack 3 .locals init (int V_0, S V_1, //s @@ -782,7 +782,7 @@ .locals init (int V_0, IL_0078: ldloca.s V_3 IL_007a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__1)" IL_007f: nop - IL_0080: leave.s IL_00fb + IL_0080: leave.s IL_00ed IL_0082: ldarg.0 IL_0083: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__1.<>u__1" IL_0088: stloc.2 @@ -804,7 +804,7 @@ .locals init (int V_0, IL_00b6: ldarg.0 IL_00b7: ldnull IL_00b8: stfld "E C.
d__1.<>s__1" - IL_00bd: leave.s IL_00e0 + IL_00bd: leave.s IL_00d9 } catch System.Exception { @@ -813,26 +813,20 @@ .locals init (int V_0, IL_00c2: ldc.i4.s -2 IL_00c4: stfld "int C.
d__1.<>1__state" IL_00c9: ldarg.0 - IL_00ca: ldnull - IL_00cb: stfld "E C.
d__1.<>s__1" - IL_00d0: ldarg.0 - IL_00d1: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" - IL_00d6: ldloc.s V_4 - IL_00d8: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" - IL_00dd: nop - IL_00de: leave.s IL_00fb + IL_00ca: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_00cf: ldloc.s V_4 + IL_00d1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_00d6: nop + IL_00d7: leave.s IL_00ed } - IL_00e0: ldarg.0 - IL_00e1: ldc.i4.s -2 - IL_00e3: stfld "int C.
d__1.<>1__state" - IL_00e8: ldarg.0 - IL_00e9: ldnull - IL_00ea: stfld "E C.
d__1.<>s__1" - IL_00ef: ldarg.0 - IL_00f0: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" - IL_00f5: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" - IL_00fa: nop - IL_00fb: ret + IL_00d9: ldarg.0 + IL_00da: ldc.i4.s -2 + IL_00dc: stfld "int C.
d__1.<>1__state" + IL_00e1: ldarg.0 + IL_00e2: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_00e7: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_00ec: nop + IL_00ed: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs index db85c729f2910..c097674c5be4d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs @@ -1103,40 +1103,28 @@ public static async void M() IL_0317: stfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" IL_031c: ldarg.0 IL_031d: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" -IL_032f: ldarg.0 -IL_0330: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" -IL_0336: ldarg.0 -IL_0337: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" -IL_0345: stloc.0 -IL_0346: stfld ""int Test.d__2.<>1__state"" -IL_0353: ldarg.0 -IL_0354: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_0366: ldarg.0 -IL_0367: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_036e: ldarg.0 -IL_036f: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_037b: ldnull -IL_037c: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_0385: ldc.i4.s -2 -IL_0387: stfld ""int Test.d__2.<>1__state"" -IL_038d: ldnull -IL_038e: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap1"" -IL_0394: ldnull -IL_0395: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap2"" -IL_039b: ldnull -IL_039c: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_03a1: ldarg.0 -IL_03a2: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" -IL_03b0: ldc.i4.s -2 -IL_03b2: stfld ""int Test.d__2.<>1__state"" -IL_03b8: ldnull -IL_03b9: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap1"" -IL_03bf: ldnull -IL_03c0: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap2"" -IL_03c6: ldnull -IL_03c7: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" -IL_03cc: ldarg.0 -IL_03cd: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" +IL_032c: ldarg.0 +IL_032d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" +IL_0333: ldarg.0 +IL_0334: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" +IL_0342: stloc.0 +IL_0343: stfld ""int Test.d__2.<>1__state"" +IL_0350: ldarg.0 +IL_0351: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_0363: ldarg.0 +IL_0364: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_036b: ldarg.0 +IL_036c: ldfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_0378: ldnull +IL_0379: stfld ""System.Collections.Generic.IEnumerator Test.d__2.<>7__wrap3"" +IL_0382: ldc.i4.s -2 +IL_0384: stfld ""int Test.d__2.<>1__state"" +IL_0389: ldarg.0 +IL_038a: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" +IL_0398: ldc.i4.s -2 +IL_039a: stfld ""int Test.d__2.<>1__state"" +IL_039f: ldarg.0 +IL_03a0: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__2.<>t__builder"" ", actual); } @@ -1163,6 +1151,7 @@ public static async void M() var actual = GetFieldLoadsAndStores(c, "Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"); + // TODO2 // make sure we are reusing synthesized iterator locals and that the locals are nulled: AssertEx.AssertEqualToleratingWhitespaceDifferences(@" IL_0000: ldarg.0 @@ -1201,37 +1190,33 @@ public static async void M() IL_0100: stfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" IL_0105: ldarg.0 IL_0106: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" -IL_0118: ldarg.0 -IL_0119: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" -IL_011f: ldarg.0 -IL_0120: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" -IL_012e: stloc.0 -IL_012f: stfld ""int Test.d__3.<>1__state"" -IL_013c: ldarg.0 -IL_013d: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_014f: ldarg.0 -IL_0150: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_0157: ldarg.0 -IL_0158: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_0164: ldnull -IL_0165: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_016e: ldc.i4.s -2 -IL_0170: stfld ""int Test.d__3.<>1__state"" -IL_0176: ldnull -IL_0177: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_017c: ldarg.0 -IL_017d: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" -IL_018b: ldc.i4.s -2 -IL_018d: stfld ""int Test.d__3.<>1__state"" -IL_0193: ldnull -IL_0194: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" -IL_0199: ldarg.0 -IL_019a: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" +IL_0115: ldarg.0 +IL_0116: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" +IL_011c: ldarg.0 +IL_011d: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1"" +IL_012b: stloc.0 +IL_012c: stfld ""int Test.d__3.<>1__state"" +IL_0139: ldarg.0 +IL_013a: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_014c: ldarg.0 +IL_014d: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_0154: ldarg.0 +IL_0155: ldfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_0161: ldnull +IL_0162: stfld ""System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1"" +IL_016b: ldc.i4.s -2 +IL_016d: stfld ""int Test.d__3.<>1__state"" +IL_0172: ldarg.0 +IL_0173: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" +IL_0181: ldc.i4.s -2 +IL_0183: stfld ""int Test.d__3.<>1__state"" +IL_0188: ldarg.0 +IL_0189: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" ", actual); c.VerifyIL("Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ { - // Code size 421 (0x1a5) + // Code size 404 (0x194) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -1280,7 +1265,7 @@ .locals init (int V_0, IL_005e: ldloca.s V_1 IL_0060: ldarg.0 IL_0061: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" - IL_0066: leave IL_01a4 + IL_0066: leave IL_0193 IL_006b: ldarg.0 IL_006c: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" IL_0071: stloc.1 @@ -1326,8 +1311,8 @@ .locals init (int V_0, { IL_00ce: ldloc.0 IL_00cf: ldc.i4.1 - IL_00d0: beq.s IL_0118 - IL_00d2: br.s IL_013c + IL_00d0: beq.s IL_0115 + IL_00d2: br.s IL_0139 IL_00d4: ldarg.0 IL_00d5: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" IL_00da: callvirt "object System.Collections.Generic.IEnumerator.Current.get" @@ -1338,7 +1323,7 @@ .locals init (int V_0, IL_00eb: stloc.1 IL_00ec: ldloca.s V_1 IL_00ee: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_00f3: brtrue.s IL_0134 + IL_00f3: brtrue.s IL_0131 IL_00f5: ldarg.0 IL_00f6: ldc.i4.1 IL_00f7: dup @@ -1352,70 +1337,64 @@ .locals init (int V_0, IL_010b: ldloca.s V_1 IL_010d: ldarg.0 IL_010e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" - IL_0113: leave IL_01a4 - IL_0118: ldarg.0 - IL_0119: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_011e: stloc.1 - IL_011f: ldarg.0 - IL_0120: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0125: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_012b: ldarg.0 - IL_012c: ldc.i4.m1 - IL_012d: dup - IL_012e: stloc.0 - IL_012f: stfld "int Test.d__3.<>1__state" - IL_0134: ldloca.s V_1 - IL_0136: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_013b: pop - IL_013c: ldarg.0 - IL_013d: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0142: callvirt "bool System.Collections.IEnumerator.MoveNext()" - IL_0147: brtrue.s IL_00d4 - IL_0149: leave.s IL_0163 + IL_0113: leave.s IL_0193 + IL_0115: ldarg.0 + IL_0116: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_011b: stloc.1 + IL_011c: ldarg.0 + IL_011d: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" + IL_0122: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0128: ldarg.0 + IL_0129: ldc.i4.m1 + IL_012a: dup + IL_012b: stloc.0 + IL_012c: stfld "int Test.d__3.<>1__state" + IL_0131: ldloca.s V_1 + IL_0133: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0138: pop + IL_0139: ldarg.0 + IL_013a: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_013f: callvirt "bool System.Collections.IEnumerator.MoveNext()" + IL_0144: brtrue.s IL_00d4 + IL_0146: leave.s IL_0160 } finally { - IL_014b: ldloc.0 - IL_014c: ldc.i4.0 - IL_014d: bge.s IL_0162 - IL_014f: ldarg.0 - IL_0150: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0155: brfalse.s IL_0162 - IL_0157: ldarg.0 - IL_0158: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_015d: callvirt "void System.IDisposable.Dispose()" - IL_0162: endfinally + IL_0148: ldloc.0 + IL_0149: ldc.i4.0 + IL_014a: bge.s IL_015f + IL_014c: ldarg.0 + IL_014d: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0152: brfalse.s IL_015f + IL_0154: ldarg.0 + IL_0155: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_015a: callvirt "void System.IDisposable.Dispose()" + IL_015f: endfinally } - IL_0163: ldarg.0 - IL_0164: ldnull - IL_0165: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_016a: leave.s IL_018a + IL_0160: ldarg.0 + IL_0161: ldnull + IL_0162: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" + IL_0167: leave.s IL_0180 } catch System.Exception { - IL_016c: stloc.2 - IL_016d: ldarg.0 - IL_016e: ldc.i4.s -2 - IL_0170: stfld "int Test.d__3.<>1__state" - IL_0175: ldarg.0 - IL_0176: ldnull - IL_0177: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_017c: ldarg.0 - IL_017d: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_0182: ldloc.2 - IL_0183: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" - IL_0188: leave.s IL_01a4 + IL_0169: stloc.2 + IL_016a: ldarg.0 + IL_016b: ldc.i4.s -2 + IL_016d: stfld "int Test.d__3.<>1__state" + IL_0172: ldarg.0 + IL_0173: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_0178: ldloc.2 + IL_0179: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" + IL_017e: leave.s IL_0193 } - IL_018a: ldarg.0 - IL_018b: ldc.i4.s -2 - IL_018d: stfld "int Test.d__3.<>1__state" - IL_0192: ldarg.0 - IL_0193: ldnull - IL_0194: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0199: ldarg.0 - IL_019a: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_019f: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" - IL_01a4: ret + IL_0180: ldarg.0 + IL_0181: ldc.i4.s -2 + IL_0183: stfld "int Test.d__3.<>1__state" + IL_0188: ldarg.0 + IL_0189: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" + IL_018e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" + IL_0193: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs index 0f1133165e866..a822b9665647e 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncMainTests.cs @@ -1567,7 +1567,7 @@ static async Task Main() var verifier = CompileAndVerify(comp, expectedOutput: ""); verifier.VerifyIL("Program.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"{ - // Code size 454 (0x1c6) + // Code size 426 (0x1aa) .maxstack 3 .locals init (int V_0, object V_1, @@ -1640,7 +1640,7 @@ .locals init (int V_0, IL_0071: ldloca.s V_2 IL_0073: ldarg.0 IL_0074: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.
d__0)"" - IL_0079: leave IL_01c5 + IL_0079: leave IL_01a9 IL_007e: ldarg.0 IL_007f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.
d__0.<>u__1"" IL_0084: stloc.2 @@ -1717,7 +1717,7 @@ .locals init (int V_0, IL_0118: ldloca.s V_2 IL_011a: ldarg.0 IL_011b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.
d__0)"" - IL_0120: leave IL_01c5 + IL_0120: leave IL_01a9 IL_0125: ldarg.0 IL_0126: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.
d__0.<>u__1"" IL_012b: stloc.2 @@ -1750,11 +1750,11 @@ .locals init (int V_0, IL_016e: ldloc.3 IL_016f: ldc.i4.1 IL_0170: bne.un.s IL_0174 - IL_0172: leave.s IL_01a4 + IL_0172: leave.s IL_0196 IL_0174: ldarg.0 IL_0175: ldnull IL_0176: stfld ""object Program.
d__0.<>7__wrap1"" - IL_017b: leave.s IL_01a4 + IL_017b: leave.s IL_0196 } catch System.Exception { @@ -1763,30 +1763,18 @@ .locals init (int V_0, IL_0180: ldc.i4.s -2 IL_0182: stfld ""int Program.
d__0.<>1__state"" IL_0187: ldarg.0 - IL_0188: ldnull - IL_0189: stfld ""object Program.
d__0.<>7__wrap1"" - IL_018e: ldarg.0 - IL_018f: ldnull - IL_0190: stfld ""object Program.
d__0.<>7__wrap3"" - IL_0195: ldarg.0 - IL_0196: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_019b: ldloc.s V_4 - IL_019d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01a2: leave.s IL_01c5 + IL_0188: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_018d: ldloc.s V_4 + IL_018f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0194: leave.s IL_01a9 } - IL_01a4: ldarg.0 - IL_01a5: ldc.i4.s -2 - IL_01a7: stfld ""int Program.
d__0.<>1__state"" - IL_01ac: ldarg.0 - IL_01ad: ldnull - IL_01ae: stfld ""object Program.
d__0.<>7__wrap1"" - IL_01b3: ldarg.0 - IL_01b4: ldnull - IL_01b5: stfld ""object Program.
d__0.<>7__wrap3"" - IL_01ba: ldarg.0 - IL_01bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_01c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01c5: ret + IL_0196: ldarg.0 + IL_0197: ldc.i4.s -2 + IL_0199: stfld ""int Program.
d__0.<>1__state"" + IL_019e: ldarg.0 + IL_019f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_01a4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01a9: ret }"); } @@ -1821,7 +1809,7 @@ static async Task Main() var verifier = CompileAndVerify(comp, expectedOutput: ""); verifier.VerifyIL("Program.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"{ - // Code size 348 (0x15c) + // Code size 320 (0x140) .maxstack 3 .locals init (int V_0, object V_1, @@ -1888,7 +1876,7 @@ .locals init (int V_0, IL_0071: ldloca.s V_2 IL_0073: ldarg.0 IL_0074: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.
d__0)"" - IL_0079: leave IL_015b + IL_0079: leave IL_013f IL_007e: ldarg.0 IL_007f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.
d__0.<>u__1"" IL_0084: stloc.2 @@ -1955,7 +1943,7 @@ .locals init (int V_0, IL_0106: ldfld ""int Program.
d__0.5__2"" IL_010b: ldc.i4.5 IL_010c: blt IL_0016 - IL_0111: leave.s IL_013a + IL_0111: leave.s IL_012c } catch System.Exception { @@ -1964,30 +1952,18 @@ .locals init (int V_0, IL_0116: ldc.i4.s -2 IL_0118: stfld ""int Program.
d__0.<>1__state"" IL_011d: ldarg.0 - IL_011e: ldnull - IL_011f: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" - IL_0124: ldarg.0 - IL_0125: ldnull - IL_0126: stfld ""object Program.
d__0.<>7__wrap3"" - IL_012b: ldarg.0 - IL_012c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_0131: ldloc.s V_4 - IL_0133: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0138: leave.s IL_015b + IL_011e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_0123: ldloc.s V_4 + IL_0125: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_012a: leave.s IL_013f } - IL_013a: ldarg.0 - IL_013b: ldc.i4.s -2 - IL_013d: stfld ""int Program.
d__0.<>1__state"" - IL_0142: ldarg.0 - IL_0143: ldnull - IL_0144: stfld ""System.IO.MemoryStream Program.
d__0.<>7__wrap2"" - IL_0149: ldarg.0 - IL_014a: ldnull - IL_014b: stfld ""object Program.
d__0.<>7__wrap3"" - IL_0150: ldarg.0 - IL_0151: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" - IL_0156: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_015b: ret + IL_012c: ldarg.0 + IL_012d: ldc.i4.s -2 + IL_012f: stfld ""int Program.
d__0.<>1__state"" + IL_0134: ldarg.0 + IL_0135: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.
d__0.<>t__builder"" + IL_013a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_013f: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs index 636b550835617..999bf6667331d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs @@ -597,7 +597,7 @@ public static async Task F(int[] array) v.VerifyIL("Test.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @"{ - // Code size 287 (0x11f) + // Code size 273 (0x111) .maxstack 5 .locals init (int V_0, int V_1, @@ -666,7 +666,7 @@ .locals init (int V_0, IL_007b: ldloca.s V_4 IL_007d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__2)"" IL_0082: nop - IL_0083: leave IL_011e + IL_0083: leave IL_0110 >IL_0088: ldarg.0 IL_0089: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" IL_008e: stloc.3 @@ -704,7 +704,7 @@ .locals init (int V_0, IL_00d8: stfld ""int[] Test.d__2.<>s__4"" -IL_00dd: ldc.i4.1 IL_00de: stloc.1 - IL_00df: leave.s IL_0102 + IL_00df: leave.s IL_00fb } catch System.Exception { @@ -713,27 +713,21 @@ .locals init (int V_0, IL_00e4: ldc.i4.s -2 IL_00e6: stfld ""int Test.d__2.<>1__state"" IL_00eb: ldarg.0 - IL_00ec: ldnull - IL_00ed: stfld ""int[] Test.d__2.<>s__4"" - IL_00f2: ldarg.0 - IL_00f3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00f8: ldloc.s V_5 - IL_00fa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00ff: nop - IL_0100: leave.s IL_011e + IL_00ec: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00f1: ldloc.s V_5 + IL_00f3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00f8: nop + IL_00f9: leave.s IL_0110 } - -IL_0102: ldarg.0 - IL_0103: ldc.i4.s -2 - IL_0105: stfld ""int Test.d__2.<>1__state"" - ~IL_010a: ldarg.0 - IL_010b: ldnull - IL_010c: stfld ""int[] Test.d__2.<>s__4"" - IL_0111: ldarg.0 - IL_0112: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_0117: ldloc.1 - IL_0118: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_011d: nop - IL_011e: ret + -IL_00fb: ldarg.0 + IL_00fc: ldc.i4.s -2 + IL_00fe: stfld ""int Test.d__2.<>1__state"" + ~IL_0103: ldarg.0 + IL_0104: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_0109: ldloc.1 + IL_010a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_010f: nop + IL_0110: ret }", sequencePoints: "Test+d__2.MoveNext"); } @@ -766,7 +760,7 @@ public static async Task F(int[] array) v.VerifyIL("Test.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 268 (0x10c) + // Code size 251 (0xfb) .maxstack 5 .locals init (int V_0, int V_1, @@ -780,7 +774,7 @@ .locals init (int V_0, .try { ~IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0080 + IL_0008: brfalse.s IL_007d -IL_000a: ldarg.0 IL_000b: ldarg.0 IL_000c: ldfld ""int[] Test.d__2.array"" @@ -815,7 +809,7 @@ .locals init (int V_0, IL_0051: stloc.s V_4 ~IL_0053: ldloca.s V_4 IL_0055: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_005a: brtrue.s IL_009d + IL_005a: brtrue.s IL_009a IL_005c: ldarg.0 IL_005d: ldc.i4.0 IL_005e: dup @@ -829,70 +823,64 @@ .locals init (int V_0, IL_0073: ldloca.s V_4 IL_0075: ldarg.0 IL_0076: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__2)"" - IL_007b: leave IL_010b - >IL_0080: ldarg.0 - IL_0081: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" - IL_0086: stloc.s V_4 - IL_0088: ldarg.0 - IL_0089: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" - IL_008e: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0094: ldarg.0 - IL_0095: ldc.i4.m1 - IL_0096: dup - IL_0097: stloc.0 - IL_0098: stfld ""int Test.d__2.<>1__state"" - IL_009d: ldloca.s V_4 - IL_009f: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00a4: stloc.2 - IL_00a5: ldarg.0 - IL_00a6: ldfld ""int Test.d__2.<>7__wrap1"" - IL_00ab: ldarg.0 - IL_00ac: ldfld ""int[] Test.d__2.<>7__wrap3"" - IL_00b1: ldc.i4.3 - IL_00b2: ldarg.0 - IL_00b3: ldfld ""int Test.d__2.<>7__wrap2"" - IL_00b8: ldloc.2 - IL_00b9: add - IL_00ba: dup - IL_00bb: stloc.3 - IL_00bc: stelem.i4 - IL_00bd: ldloc.3 - IL_00be: ldc.i4.4 - IL_00bf: call ""int Test.H(int, int, int)"" - IL_00c4: pop - IL_00c5: ldarg.0 - IL_00c6: ldnull - IL_00c7: stfld ""int[] Test.d__2.<>7__wrap3"" - -IL_00cc: ldc.i4.1 - IL_00cd: stloc.1 - IL_00ce: leave.s IL_00f0 + IL_007b: leave.s IL_00fa + >IL_007d: ldarg.0 + IL_007e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" + IL_0083: stloc.s V_4 + IL_0085: ldarg.0 + IL_0086: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" + IL_008b: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0091: ldarg.0 + IL_0092: ldc.i4.m1 + IL_0093: dup + IL_0094: stloc.0 + IL_0095: stfld ""int Test.d__2.<>1__state"" + IL_009a: ldloca.s V_4 + IL_009c: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_00a1: stloc.2 + IL_00a2: ldarg.0 + IL_00a3: ldfld ""int Test.d__2.<>7__wrap1"" + IL_00a8: ldarg.0 + IL_00a9: ldfld ""int[] Test.d__2.<>7__wrap3"" + IL_00ae: ldc.i4.3 + IL_00af: ldarg.0 + IL_00b0: ldfld ""int Test.d__2.<>7__wrap2"" + IL_00b5: ldloc.2 + IL_00b6: add + IL_00b7: dup + IL_00b8: stloc.3 + IL_00b9: stelem.i4 + IL_00ba: ldloc.3 + IL_00bb: ldc.i4.4 + IL_00bc: call ""int Test.H(int, int, int)"" + IL_00c1: pop + IL_00c2: ldarg.0 + IL_00c3: ldnull + IL_00c4: stfld ""int[] Test.d__2.<>7__wrap3"" + -IL_00c9: ldc.i4.1 + IL_00ca: stloc.1 + IL_00cb: leave.s IL_00e6 } catch System.Exception { - ~IL_00d0: stloc.s V_5 - IL_00d2: ldarg.0 - IL_00d3: ldc.i4.s -2 - IL_00d5: stfld ""int Test.d__2.<>1__state"" - IL_00da: ldarg.0 - IL_00db: ldnull - IL_00dc: stfld ""int[] Test.d__2.<>7__wrap3"" - IL_00e1: ldarg.0 - IL_00e2: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00e7: ldloc.s V_5 - IL_00e9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00ee: leave.s IL_010b + ~IL_00cd: stloc.s V_5 + IL_00cf: ldarg.0 + IL_00d0: ldc.i4.s -2 + IL_00d2: stfld ""int Test.d__2.<>1__state"" + IL_00d7: ldarg.0 + IL_00d8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00dd: ldloc.s V_5 + IL_00df: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00e4: leave.s IL_00fa } - -IL_00f0: ldarg.0 - IL_00f1: ldc.i4.s -2 - IL_00f3: stfld ""int Test.d__2.<>1__state"" - ~IL_00f8: ldarg.0 - IL_00f9: ldnull - IL_00fa: stfld ""int[] Test.d__2.<>7__wrap3"" - IL_00ff: ldarg.0 - IL_0100: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_0105: ldloc.1 - IL_0106: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_010b: ret + -IL_00e6: ldarg.0 + IL_00e7: ldc.i4.s -2 + IL_00e9: stfld ""int Test.d__2.<>1__state"" + ~IL_00ee: ldarg.0 + IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00f4: ldloc.1 + IL_00f5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_00fa: ret }", sequencePoints: "Test+d__2.MoveNext"); } @@ -3591,7 +3579,7 @@ public sealed class JsonSerializerOptions v.VerifyMethodBody("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 198 (0xc6) + // Code size 184 (0xb8) .maxstack 3 .locals init (int V_0, System.Runtime.CompilerServices.TaskAwaiter V_1, @@ -3635,7 +3623,7 @@ .locals init (int V_0, IL_003d: ldloca.s V_2 IL_003f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__1)"" IL_0044: nop - IL_0045: leave.s IL_00c5 + IL_0045: leave.s IL_00b7 // async: resume IL_0047: ldarg.0 IL_0048: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1"" @@ -3661,7 +3649,7 @@ .locals init (int V_0, IL_0082: ldarg.0 IL_0083: ldnull IL_0084: stfld ""byte[] Program.d__1.<>s__1"" - IL_0089: leave.s IL_00aa + IL_0089: leave.s IL_00a3 } catch System.Exception { @@ -3671,28 +3659,22 @@ .locals init (int V_0, IL_008d: ldc.i4.s -2 IL_008f: stfld ""int Program.d__1.<>1__state"" IL_0094: ldarg.0 - IL_0095: ldnull - IL_0096: stfld ""byte[] Program.d__1.<>s__1"" - IL_009b: ldarg.0 - IL_009c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" - IL_00a1: ldloc.3 - IL_00a2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a7: nop - IL_00a8: leave.s IL_00c5 + IL_0095: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" + IL_009a: ldloc.3 + IL_009b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a0: nop + IL_00a1: leave.s IL_00b7 } // sequence point: } - IL_00aa: ldarg.0 - IL_00ab: ldc.i4.s -2 - IL_00ad: stfld ""int Program.d__1.<>1__state"" + IL_00a3: ldarg.0 + IL_00a4: ldc.i4.s -2 + IL_00a6: stfld ""int Program.d__1.<>1__state"" // sequence point: - IL_00b2: ldarg.0 - IL_00b3: ldnull - IL_00b4: stfld ""byte[] Program.d__1.<>s__1"" - IL_00b9: ldarg.0 - IL_00ba: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" - IL_00bf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c4: nop - IL_00c5: ret + IL_00ab: ldarg.0 + IL_00ac: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__1.<>t__builder"" + IL_00b1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00b6: nop + IL_00b7: ret } "); } @@ -4094,7 +4076,7 @@ Caught NullReferenceException After Assignment a.B.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 198 (0xc6) + // Code size 184 (0xb8) .maxstack 3 .locals init (int V_0, int V_1, @@ -4132,7 +4114,7 @@ .locals init (int V_0, IL_004a: ldloca.s V_2 IL_004c: ldarg.0 IL_004d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_0052: leave.s IL_00c5 + IL_0052: leave.s IL_00b7 IL_0054: ldarg.0 IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_005a: stloc.2 @@ -4154,7 +4136,7 @@ .locals init (int V_0, IL_0084: ldarg.0 IL_0085: ldnull IL_0086: stfld ""B Program.d__0.<>7__wrap1"" - IL_008b: leave.s IL_00ab + IL_008b: leave.s IL_00a4 } catch System.Exception { @@ -4163,24 +4145,18 @@ .locals init (int V_0, IL_008f: ldc.i4.s -2 IL_0091: stfld ""int Program.d__0.<>1__state"" IL_0096: ldarg.0 - IL_0097: ldnull - IL_0098: stfld ""B Program.d__0.<>7__wrap1"" - IL_009d: ldarg.0 - IL_009e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00a3: ldloc.3 - IL_00a4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a9: leave.s IL_00c5 + IL_0097: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_009c: ldloc.3 + IL_009d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a2: leave.s IL_00b7 } - IL_00ab: ldarg.0 - IL_00ac: ldc.i4.s -2 - IL_00ae: stfld ""int Program.d__0.<>1__state"" - IL_00b3: ldarg.0 - IL_00b4: ldnull - IL_00b5: stfld ""B Program.d__0.<>7__wrap1"" - IL_00ba: ldarg.0 - IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c5: ret + IL_00a4: ldarg.0 + IL_00a5: ldc.i4.s -2 + IL_00a7: stfld ""int Program.d__0.<>1__state"" + IL_00ac: ldarg.0 + IL_00ad: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00b7: ret }"); } @@ -4338,7 +4314,7 @@ Caught NullReferenceException After Assignment a.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 195 (0xc3) + // Code size 181 (0xb5) .maxstack 3 .locals init (int V_0, int V_1, @@ -4377,7 +4353,7 @@ .locals init (int V_0, IL_0047: ldloca.s V_2 IL_0049: ldarg.0 IL_004a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_004f: leave.s IL_00c2 + IL_004f: leave.s IL_00b4 IL_0051: ldarg.0 IL_0052: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0057: stloc.2 @@ -4399,7 +4375,7 @@ .locals init (int V_0, IL_0081: ldarg.0 IL_0082: ldnull IL_0083: stfld ""A Program.d__0.<>7__wrap1"" - IL_0088: leave.s IL_00a8 + IL_0088: leave.s IL_00a1 } catch System.Exception { @@ -4408,24 +4384,18 @@ .locals init (int V_0, IL_008c: ldc.i4.s -2 IL_008e: stfld ""int Program.d__0.<>1__state"" IL_0093: ldarg.0 - IL_0094: ldnull - IL_0095: stfld ""A Program.d__0.<>7__wrap1"" - IL_009a: ldarg.0 - IL_009b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00a0: ldloc.3 - IL_00a1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a6: leave.s IL_00c2 + IL_0094: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_0099: ldloc.3 + IL_009a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_009f: leave.s IL_00b4 } - IL_00a8: ldarg.0 - IL_00a9: ldc.i4.s -2 - IL_00ab: stfld ""int Program.d__0.<>1__state"" - IL_00b0: ldarg.0 - IL_00b1: ldnull - IL_00b2: stfld ""A Program.d__0.<>7__wrap1"" - IL_00b7: ldarg.0 - IL_00b8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00bd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c2: ret + IL_00a1: ldarg.0 + IL_00a2: ldc.i4.s -2 + IL_00a4: stfld ""int Program.d__0.<>1__state"" + IL_00a9: ldarg.0 + IL_00aa: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00b4: ret }"); } @@ -4557,7 +4527,7 @@ Caught IndexOutOfRangeException Before Assignment arr[0].y is: True") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 212 (0xd4) + // Code size 198 (0xc6) .maxstack 3 .locals init (int V_0, int V_1, @@ -4599,7 +4569,7 @@ .locals init (int V_0, IL_0052: ldloca.s V_2 IL_0054: ldarg.0 IL_0055: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005a: leave.s IL_00d3 + IL_005a: leave.s IL_00c5 IL_005c: ldarg.0 IL_005d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0062: stloc.2 @@ -4623,7 +4593,7 @@ .locals init (int V_0, IL_0092: ldarg.0 IL_0093: ldnull IL_0094: stfld ""A[] Program.d__0.<>7__wrap1"" - IL_0099: leave.s IL_00b9 + IL_0099: leave.s IL_00b2 } catch System.Exception { @@ -4632,24 +4602,18 @@ .locals init (int V_0, IL_009d: ldc.i4.s -2 IL_009f: stfld ""int Program.d__0.<>1__state"" IL_00a4: ldarg.0 - IL_00a5: ldnull - IL_00a6: stfld ""A[] Program.d__0.<>7__wrap1"" - IL_00ab: ldarg.0 - IL_00ac: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b1: ldloc.3 - IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00b7: leave.s IL_00d3 + IL_00a5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00aa: ldloc.3 + IL_00ab: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00b0: leave.s IL_00c5 } - IL_00b9: ldarg.0 - IL_00ba: ldc.i4.s -2 - IL_00bc: stfld ""int Program.d__0.<>1__state"" - IL_00c1: ldarg.0 - IL_00c2: ldnull - IL_00c3: stfld ""A[] Program.d__0.<>7__wrap1"" - IL_00c8: ldarg.0 - IL_00c9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00ce: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00d3: ret + IL_00b2: ldarg.0 + IL_00b3: ldc.i4.s -2 + IL_00b5: stfld ""int Program.d__0.<>1__state"" + IL_00ba: ldarg.0 + IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c5: ret }"); } @@ -4748,7 +4712,7 @@ Caught IndexOutOfRangeException After Assignment arrCopy[0] is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 190 (0xbe) + // Code size 176 (0xb0) .maxstack 3 .locals init (int V_0, int V_1, @@ -4785,7 +4749,7 @@ .locals init (int V_0, IL_0045: ldloca.s V_2 IL_0047: ldarg.0 IL_0048: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_004d: leave.s IL_00bd + IL_004d: leave.s IL_00af IL_004f: ldarg.0 IL_0050: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0055: stloc.2 @@ -4808,7 +4772,7 @@ .locals init (int V_0, IL_007c: ldarg.0 IL_007d: ldnull IL_007e: stfld ""int[] Program.d__0.<>7__wrap1"" - IL_0083: leave.s IL_00a3 + IL_0083: leave.s IL_009c } catch System.Exception { @@ -4817,24 +4781,18 @@ .locals init (int V_0, IL_0087: ldc.i4.s -2 IL_0089: stfld ""int Program.d__0.<>1__state"" IL_008e: ldarg.0 - IL_008f: ldnull - IL_0090: stfld ""int[] Program.d__0.<>7__wrap1"" - IL_0095: ldarg.0 - IL_0096: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_009b: ldloc.3 - IL_009c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a1: leave.s IL_00bd + IL_008f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_0094: ldloc.3 + IL_0095: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_009a: leave.s IL_00af } - IL_00a3: ldarg.0 - IL_00a4: ldc.i4.s -2 - IL_00a6: stfld ""int Program.d__0.<>1__state"" - IL_00ab: ldarg.0 - IL_00ac: ldnull - IL_00ad: stfld ""int[] Program.d__0.<>7__wrap1"" - IL_00b2: ldarg.0 - IL_00b3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00bd: ret + IL_009c: ldarg.0 + IL_009d: ldc.i4.s -2 + IL_009f: stfld ""int Program.d__0.<>1__state"" + IL_00a4: ldarg.0 + IL_00a5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00af: ret }"); } @@ -4945,7 +4903,7 @@ Caught NullReferenceException After Assignment aCopy.b.c.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 215 (0xd7) + // Code size 201 (0xc9) .maxstack 3 .locals init (int V_0, int V_1, @@ -4986,7 +4944,7 @@ .locals init (int V_0, IL_0051: ldloca.s V_2 IL_0053: ldarg.0 IL_0054: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_0059: leave.s IL_00d6 + IL_0059: leave.s IL_00c8 IL_005b: ldarg.0 IL_005c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0061: stloc.2 @@ -5010,7 +4968,7 @@ .locals init (int V_0, IL_0095: ldarg.0 IL_0096: ldnull IL_0097: stfld ""A Program.d__0.<>7__wrap1"" - IL_009c: leave.s IL_00bc + IL_009c: leave.s IL_00b5 } catch System.Exception { @@ -5019,24 +4977,18 @@ .locals init (int V_0, IL_00a0: ldc.i4.s -2 IL_00a2: stfld ""int Program.d__0.<>1__state"" IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld ""A Program.d__0.<>7__wrap1"" - IL_00ae: ldarg.0 - IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b4: ldloc.3 - IL_00b5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00ba: leave.s IL_00d6 + IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00ad: ldloc.3 + IL_00ae: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00b3: leave.s IL_00c8 } - IL_00bc: ldarg.0 - IL_00bd: ldc.i4.s -2 - IL_00bf: stfld ""int Program.d__0.<>1__state"" - IL_00c4: ldarg.0 - IL_00c5: ldnull - IL_00c6: stfld ""A Program.d__0.<>7__wrap1"" - IL_00cb: ldarg.0 - IL_00cc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00d1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00d6: ret + IL_00b5: ldarg.0 + IL_00b6: ldc.i4.s -2 + IL_00b8: stfld ""int Program.d__0.<>1__state"" + IL_00bd: ldarg.0 + IL_00be: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00c3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c8: ret }"); } @@ -5148,7 +5100,7 @@ Caught NullReferenceException After Assignment aCopy._b._x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 198 (0xc6) + // Code size 184 (0xb8) .maxstack 3 .locals init (int V_0, int V_1, @@ -5186,7 +5138,7 @@ .locals init (int V_0, IL_004a: ldloca.s V_2 IL_004c: ldarg.0 IL_004d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_0052: leave.s IL_00c5 + IL_0052: leave.s IL_00b7 IL_0054: ldarg.0 IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_005a: stloc.2 @@ -5208,7 +5160,7 @@ .locals init (int V_0, IL_0084: ldarg.0 IL_0085: ldnull IL_0086: stfld ""B Program.d__0.<>7__wrap1"" - IL_008b: leave.s IL_00ab + IL_008b: leave.s IL_00a4 } catch System.Exception { @@ -5217,24 +5169,18 @@ .locals init (int V_0, IL_008f: ldc.i4.s -2 IL_0091: stfld ""int Program.d__0.<>1__state"" IL_0096: ldarg.0 - IL_0097: ldnull - IL_0098: stfld ""B Program.d__0.<>7__wrap1"" - IL_009d: ldarg.0 - IL_009e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00a3: ldloc.3 - IL_00a4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a9: leave.s IL_00c5 + IL_0097: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_009c: ldloc.3 + IL_009d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00a2: leave.s IL_00b7 } - IL_00ab: ldarg.0 - IL_00ac: ldc.i4.s -2 - IL_00ae: stfld ""int Program.d__0.<>1__state"" - IL_00b3: ldarg.0 - IL_00b4: ldnull - IL_00b5: stfld ""B Program.d__0.<>7__wrap1"" - IL_00ba: ldarg.0 - IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c5: ret + IL_00a4: ldarg.0 + IL_00a5: ldc.i4.s -2 + IL_00a7: stfld ""int Program.d__0.<>1__state"" + IL_00ac: ldarg.0 + IL_00ad: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00b7: ret }"); } @@ -5336,7 +5282,7 @@ Caught NullReferenceException After Assignment aCopy.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 193 (0xc1) + // Code size 179 (0xb3) .maxstack 3 .locals init (int V_0, int V_1, @@ -5373,7 +5319,7 @@ .locals init (int V_0, IL_0045: ldloca.s V_2 IL_0047: ldarg.0 IL_0048: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_004d: leave.s IL_00c0 + IL_004d: leave.s IL_00b2 IL_004f: ldarg.0 IL_0050: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0055: stloc.2 @@ -5395,7 +5341,7 @@ .locals init (int V_0, IL_007f: ldarg.0 IL_0080: ldnull IL_0081: stfld ""A Program.d__0.<>7__wrap1"" - IL_0086: leave.s IL_00a6 + IL_0086: leave.s IL_009f } catch System.Exception { @@ -5404,24 +5350,18 @@ .locals init (int V_0, IL_008a: ldc.i4.s -2 IL_008c: stfld ""int Program.d__0.<>1__state"" IL_0091: ldarg.0 - IL_0092: ldnull - IL_0093: stfld ""A Program.d__0.<>7__wrap1"" - IL_0098: ldarg.0 - IL_0099: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_009e: ldloc.3 - IL_009f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00a4: leave.s IL_00c0 + IL_0092: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_0097: ldloc.3 + IL_0098: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_009d: leave.s IL_00b2 } - IL_00a6: ldarg.0 - IL_00a7: ldc.i4.s -2 - IL_00a9: stfld ""int Program.d__0.<>1__state"" - IL_00ae: ldarg.0 - IL_00af: ldnull - IL_00b0: stfld ""A Program.d__0.<>7__wrap1"" - IL_00b5: ldarg.0 - IL_00b6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00bb: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00c0: ret + IL_009f: ldarg.0 + IL_00a0: ldc.i4.s -2 + IL_00a2: stfld ""int Program.d__0.<>1__state"" + IL_00a7: ldarg.0 + IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00ad: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00b2: ret }"); } @@ -5545,7 +5485,7 @@ Caught NullReferenceException After Assignment a.x is: 43") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 216 (0xd8) + // Code size 202 (0xca) .maxstack 3 .locals init (int V_0, A V_1, @@ -5589,7 +5529,7 @@ .locals init (int V_0, IL_0053: ldloca.s V_3 IL_0055: ldarg.0 IL_0056: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005b: leave.s IL_00d7 + IL_005b: leave.s IL_00c9 IL_005d: ldarg.0 IL_005e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0063: stloc.3 @@ -5614,7 +5554,7 @@ .locals init (int V_0, IL_0094: ldarg.0 IL_0095: ldnull IL_0096: stfld ""A Program.d__0.<>7__wrap1"" - IL_009b: leave.s IL_00bd + IL_009b: leave.s IL_00b6 } catch System.Exception { @@ -5623,24 +5563,18 @@ .locals init (int V_0, IL_00a0: ldc.i4.s -2 IL_00a2: stfld ""int Program.d__0.<>1__state"" IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld ""A Program.d__0.<>7__wrap1"" - IL_00ae: ldarg.0 - IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b4: ldloc.s V_4 - IL_00b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00bb: leave.s IL_00d7 + IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00ad: ldloc.s V_4 + IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00b4: leave.s IL_00c9 } - IL_00bd: ldarg.0 - IL_00be: ldc.i4.s -2 - IL_00c0: stfld ""int Program.d__0.<>1__state"" - IL_00c5: ldarg.0 - IL_00c6: ldnull - IL_00c7: stfld ""A Program.d__0.<>7__wrap1"" - IL_00cc: ldarg.0 - IL_00cd: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00d2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00d7: ret + IL_00b6: ldarg.0 + IL_00b7: ldc.i4.s -2 + IL_00b9: stfld ""int Program.d__0.<>1__state"" + IL_00be: ldarg.0 + IL_00bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00c4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c9: ret }"); } @@ -5771,7 +5705,7 @@ Caught NullReferenceException After Assignment a._x is: 43") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 216 (0xd8) + // Code size 202 (0xca) .maxstack 3 .locals init (int V_0, A V_1, @@ -5815,7 +5749,7 @@ .locals init (int V_0, IL_0053: ldloca.s V_3 IL_0055: ldarg.0 IL_0056: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005b: leave.s IL_00d7 + IL_005b: leave.s IL_00c9 IL_005d: ldarg.0 IL_005e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" IL_0063: stloc.3 @@ -5840,7 +5774,7 @@ .locals init (int V_0, IL_0094: ldarg.0 IL_0095: ldnull IL_0096: stfld ""A Program.d__0.<>7__wrap1"" - IL_009b: leave.s IL_00bd + IL_009b: leave.s IL_00b6 } catch System.Exception { @@ -5849,24 +5783,18 @@ .locals init (int V_0, IL_00a0: ldc.i4.s -2 IL_00a2: stfld ""int Program.d__0.<>1__state"" IL_00a7: ldarg.0 - IL_00a8: ldnull - IL_00a9: stfld ""A Program.d__0.<>7__wrap1"" - IL_00ae: ldarg.0 - IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00b4: ldloc.s V_4 - IL_00b6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00bb: leave.s IL_00d7 + IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00ad: ldloc.s V_4 + IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00b4: leave.s IL_00c9 } - IL_00bd: ldarg.0 - IL_00be: ldc.i4.s -2 - IL_00c0: stfld ""int Program.d__0.<>1__state"" - IL_00c5: ldarg.0 - IL_00c6: ldnull - IL_00c7: stfld ""A Program.d__0.<>7__wrap1"" - IL_00cc: ldarg.0 - IL_00cd: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00d2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00d7: ret + IL_00b6: ldarg.0 + IL_00b7: ldc.i4.s -2 + IL_00b9: stfld ""int Program.d__0.<>1__state"" + IL_00be: ldarg.0 + IL_00bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00c4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00c9: ret }"); } @@ -6015,7 +5943,7 @@ Caught NullReferenceException After Assignment b.x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 250 (0xfa) + // Code size 219 (0xdb) .maxstack 4 .locals init (int V_0, int V_1, @@ -6028,7 +5956,7 @@ .locals init (int V_0, .try { IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0063 + IL_0008: brfalse.s IL_0060 IL_000a: ldarg.0 IL_000b: ldarg.0 IL_000c: ldfld ""A Program.d__0.a"" @@ -6044,7 +5972,7 @@ .locals init (int V_0, IL_0036: stloc.2 IL_0037: ldloca.s V_2 IL_0039: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003e: brtrue.s IL_007f + IL_003e: brtrue.s IL_007c IL_0040: ldarg.0 IL_0041: ldc.i4.0 IL_0042: dup @@ -6058,70 +5986,58 @@ .locals init (int V_0, IL_0056: ldloca.s V_2 IL_0058: ldarg.0 IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005e: leave IL_00f9 - IL_0063: ldarg.0 - IL_0064: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_0069: stloc.2 - IL_006a: ldarg.0 - IL_006b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_0070: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0076: ldarg.0 - IL_0077: ldc.i4.m1 - IL_0078: dup - IL_0079: stloc.0 - IL_007a: stfld ""int Program.d__0.<>1__state"" - IL_007f: ldloca.s V_2 - IL_0081: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0086: stloc.1 - IL_0087: ldarg.0 - IL_0088: ldfld ""B Program.d__0.<>7__wrap1"" - IL_008d: ldarg.0 - IL_008e: ldfld ""B Program.d__0.<>7__wrap2"" - IL_0093: ldloc.1 - IL_0094: dup - IL_0095: stloc.3 - IL_0096: stfld ""int B.x"" - IL_009b: ldloc.3 - IL_009c: stfld ""int B.x"" - IL_00a1: ldarg.0 - IL_00a2: ldnull - IL_00a3: stfld ""B Program.d__0.<>7__wrap1"" - IL_00a8: ldarg.0 - IL_00a9: ldnull - IL_00aa: stfld ""B Program.d__0.<>7__wrap2"" - IL_00af: leave.s IL_00d8 + IL_005e: leave.s IL_00da + IL_0060: ldarg.0 + IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_0066: stloc.2 + IL_0067: ldarg.0 + IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0073: ldarg.0 + IL_0074: ldc.i4.m1 + IL_0075: dup + IL_0076: stloc.0 + IL_0077: stfld ""int Program.d__0.<>1__state"" + IL_007c: ldloca.s V_2 + IL_007e: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_0083: stloc.1 + IL_0084: ldarg.0 + IL_0085: ldfld ""B Program.d__0.<>7__wrap1"" + IL_008a: ldarg.0 + IL_008b: ldfld ""B Program.d__0.<>7__wrap2"" + IL_0090: ldloc.1 + IL_0091: dup + IL_0092: stloc.3 + IL_0093: stfld ""int B.x"" + IL_0098: ldloc.3 + IL_0099: stfld ""int B.x"" + IL_009e: ldarg.0 + IL_009f: ldnull + IL_00a0: stfld ""B Program.d__0.<>7__wrap1"" + IL_00a5: ldarg.0 + IL_00a6: ldnull + IL_00a7: stfld ""B Program.d__0.<>7__wrap2"" + IL_00ac: leave.s IL_00c7 } catch System.Exception { - IL_00b1: stloc.s V_4 - IL_00b3: ldarg.0 - IL_00b4: ldc.i4.s -2 - IL_00b6: stfld ""int Program.d__0.<>1__state"" - IL_00bb: ldarg.0 - IL_00bc: ldnull - IL_00bd: stfld ""B Program.d__0.<>7__wrap1"" - IL_00c2: ldarg.0 - IL_00c3: ldnull - IL_00c4: stfld ""B Program.d__0.<>7__wrap2"" - IL_00c9: ldarg.0 - IL_00ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00cf: ldloc.s V_4 - IL_00d1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00d6: leave.s IL_00f9 + IL_00ae: stloc.s V_4 + IL_00b0: ldarg.0 + IL_00b1: ldc.i4.s -2 + IL_00b3: stfld ""int Program.d__0.<>1__state"" + IL_00b8: ldarg.0 + IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00be: ldloc.s V_4 + IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00c5: leave.s IL_00da } - IL_00d8: ldarg.0 - IL_00d9: ldc.i4.s -2 - IL_00db: stfld ""int Program.d__0.<>1__state"" - IL_00e0: ldarg.0 - IL_00e1: ldnull - IL_00e2: stfld ""B Program.d__0.<>7__wrap1"" - IL_00e7: ldarg.0 - IL_00e8: ldnull - IL_00e9: stfld ""B Program.d__0.<>7__wrap2"" - IL_00ee: ldarg.0 - IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00f4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00f9: ret + IL_00c7: ldarg.0 + IL_00c8: ldc.i4.s -2 + IL_00ca: stfld ""int Program.d__0.<>1__state"" + IL_00cf: ldarg.0 + IL_00d0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00d5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00da: ret }"); } @@ -6277,8 +6193,8 @@ Caught NullReferenceException After Assignment a._b._x is: 42 After Assignment b._x is: 42") .VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" - { - // Code size 250 (0xfa) +{ + // Code size 219 (0xdb) .maxstack 3 .locals init (int V_0, int V_1, @@ -6291,7 +6207,7 @@ .locals init (int V_0, .try { IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0063 + IL_0008: brfalse.s IL_0060 IL_000a: ldarg.0 IL_000b: ldarg.0 IL_000c: ldfld ""A Program.d__0.a"" @@ -6307,7 +6223,7 @@ .locals init (int V_0, IL_0036: stloc.3 IL_0037: ldloca.s V_3 IL_0039: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003e: brtrue.s IL_007f + IL_003e: brtrue.s IL_007c IL_0040: ldarg.0 IL_0041: ldc.i4.0 IL_0042: dup @@ -6321,70 +6237,58 @@ .locals init (int V_0, IL_0056: ldloca.s V_3 IL_0058: ldarg.0 IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__0)"" - IL_005e: leave IL_00f9 - IL_0063: ldarg.0 - IL_0064: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_0069: stloc.3 - IL_006a: ldarg.0 - IL_006b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" - IL_0070: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0076: ldarg.0 - IL_0077: ldc.i4.m1 - IL_0078: dup - IL_0079: stloc.0 - IL_007a: stfld ""int Program.d__0.<>1__state"" - IL_007f: ldloca.s V_3 - IL_0081: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0086: stloc.1 - IL_0087: ldarg.0 - IL_0088: ldfld ""B Program.d__0.<>7__wrap2"" - IL_008d: ldloc.1 - IL_008e: dup - IL_008f: stloc.2 - IL_0090: callvirt ""void B.x.set"" - IL_0095: ldarg.0 - IL_0096: ldfld ""B Program.d__0.<>7__wrap1"" - IL_009b: ldloc.2 - IL_009c: callvirt ""void B.x.set"" - IL_00a1: ldarg.0 - IL_00a2: ldnull - IL_00a3: stfld ""B Program.d__0.<>7__wrap1"" - IL_00a8: ldarg.0 - IL_00a9: ldnull - IL_00aa: stfld ""B Program.d__0.<>7__wrap2"" - IL_00af: leave.s IL_00d8 + IL_005e: leave.s IL_00da + IL_0060: ldarg.0 + IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_0066: stloc.3 + IL_0067: ldarg.0 + IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter Program.d__0.<>u__1"" + IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_0073: ldarg.0 + IL_0074: ldc.i4.m1 + IL_0075: dup + IL_0076: stloc.0 + IL_0077: stfld ""int Program.d__0.<>1__state"" + IL_007c: ldloca.s V_3 + IL_007e: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_0083: stloc.1 + IL_0084: ldarg.0 + IL_0085: ldfld ""B Program.d__0.<>7__wrap2"" + IL_008a: ldloc.1 + IL_008b: dup + IL_008c: stloc.2 + IL_008d: callvirt ""void B.x.set"" + IL_0092: ldarg.0 + IL_0093: ldfld ""B Program.d__0.<>7__wrap1"" + IL_0098: ldloc.2 + IL_0099: callvirt ""void B.x.set"" + IL_009e: ldarg.0 + IL_009f: ldnull + IL_00a0: stfld ""B Program.d__0.<>7__wrap1"" + IL_00a5: ldarg.0 + IL_00a6: ldnull + IL_00a7: stfld ""B Program.d__0.<>7__wrap2"" + IL_00ac: leave.s IL_00c7 } catch System.Exception { - IL_00b1: stloc.s V_4 - IL_00b3: ldarg.0 - IL_00b4: ldc.i4.s -2 - IL_00b6: stfld ""int Program.d__0.<>1__state"" - IL_00bb: ldarg.0 - IL_00bc: ldnull - IL_00bd: stfld ""B Program.d__0.<>7__wrap1"" - IL_00c2: ldarg.0 - IL_00c3: ldnull - IL_00c4: stfld ""B Program.d__0.<>7__wrap2"" - IL_00c9: ldarg.0 - IL_00ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00cf: ldloc.s V_4 - IL_00d1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00d6: leave.s IL_00f9 + IL_00ae: stloc.s V_4 + IL_00b0: ldarg.0 + IL_00b1: ldc.i4.s -2 + IL_00b3: stfld ""int Program.d__0.<>1__state"" + IL_00b8: ldarg.0 + IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00be: ldloc.s V_4 + IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00c5: leave.s IL_00da } - IL_00d8: ldarg.0 - IL_00d9: ldc.i4.s -2 - IL_00db: stfld ""int Program.d__0.<>1__state"" - IL_00e0: ldarg.0 - IL_00e1: ldnull - IL_00e2: stfld ""B Program.d__0.<>7__wrap1"" - IL_00e7: ldarg.0 - IL_00e8: ldnull - IL_00e9: stfld ""B Program.d__0.<>7__wrap2"" - IL_00ee: ldarg.0 - IL_00ef: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" - IL_00f4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00f9: ret + IL_00c7: ldarg.0 + IL_00c8: ldc.i4.s -2 + IL_00ca: stfld ""int Program.d__0.<>1__state"" + IL_00cf: ldarg.0 + IL_00d0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.d__0.<>t__builder"" + IL_00d5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00da: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index d158d17b4677d..89482c2907c11 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -4236,8 +4236,8 @@ public static async Task F() var v = CompileAndVerify(source, null, options: TestOptions.DebugDll); v.VerifyIL("Test.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" - { - // Code size 255 (0xff) +{ + // Code size 241 (0xf1) .maxstack 3 .locals init (int V_0, int V_1, @@ -4289,7 +4289,7 @@ .locals init (int V_0, IL_0063: ldloca.s V_3 IL_0065: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Test.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__2)"" IL_006a: nop - IL_006b: leave IL_00fe + IL_006b: leave IL_00f0 >IL_0070: ldarg.0 IL_0071: ldfld ""System.Runtime.CompilerServices.TaskAwaiter Test.d__2.<>u__1"" IL_0076: stloc.2 @@ -4313,7 +4313,7 @@ .locals init (int V_0, IL_00a6: ldfld ""int Test.d__2.<>s__2"" IL_00ab: call ""int S.Mutate(int)"" IL_00b0: stloc.1 - IL_00b1: leave.s IL_00db + IL_00b1: leave.s IL_00d4 } catch System.Exception { @@ -4325,30 +4325,24 @@ .locals init (int V_0, IL_00be: ldnull IL_00bf: stfld ""S[] Test.d__2.5__1"" IL_00c4: ldarg.0 - IL_00c5: ldnull - IL_00c6: stfld ""S[] Test.d__2.<>s__3"" - IL_00cb: ldarg.0 - IL_00cc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00d1: ldloc.s V_4 - IL_00d3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00d8: nop - IL_00d9: leave.s IL_00fe + IL_00c5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00ca: ldloc.s V_4 + IL_00cc: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00d1: nop + IL_00d2: leave.s IL_00f0 } - -IL_00db: ldarg.0 - IL_00dc: ldc.i4.s -2 - IL_00de: stfld ""int Test.d__2.<>1__state"" - ~IL_00e3: ldarg.0 - IL_00e4: ldnull - IL_00e5: stfld ""S[] Test.d__2.5__1"" - IL_00ea: ldarg.0 - IL_00eb: ldnull - IL_00ec: stfld ""S[] Test.d__2.<>s__3"" - IL_00f1: ldarg.0 - IL_00f2: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" - IL_00f7: ldloc.1 - IL_00f8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_00fd: nop - IL_00fe: ret + -IL_00d4: ldarg.0 + IL_00d5: ldc.i4.s -2 + IL_00d7: stfld ""int Test.d__2.<>1__state"" + ~IL_00dc: ldarg.0 + IL_00dd: ldnull + IL_00de: stfld ""S[] Test.d__2.5__1"" + IL_00e3: ldarg.0 + IL_00e4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Test.d__2.<>t__builder"" + IL_00e9: ldloc.1 + IL_00ea: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_00ef: nop + IL_00f0: ret }", sequencePoints: "Test+d__2.MoveNext"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs index d2097e117506e..52fe5242f2174 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs @@ -3786,7 +3786,7 @@ public async ValueTask DisposeAsync() // The thing to notice here is that the call to GetAsyncEnumerator is a constrained call (we're not boxing to `IAsyncEnumerable`) verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 524 (0x20c) + // Code size 496 (0x1f0) .maxstack 3 .locals init (int V_0, C V_1, @@ -3878,7 +3878,7 @@ .locals init (int V_0, IL_00bd: ldloca.s V_5 IL_00bf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_00c4: nop - IL_00c5: leave IL_020b + IL_00c5: leave IL_01ef IL_00ca: ldarg.0 IL_00cb: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_00d0: stloc.3 @@ -3936,7 +3936,7 @@ .locals init (int V_0, IL_014f: ldloca.s V_5 IL_0151: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0156: nop - IL_0157: leave IL_020b + IL_0157: leave IL_01ef IL_015c: ldarg.0 IL_015d: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" IL_0162: stloc.s V_7 @@ -3976,7 +3976,7 @@ .locals init (int V_0, IL_01b8: ldarg.0 IL_01b9: ldnull IL_01ba: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>s__1"" - IL_01bf: leave.s IL_01e9 + IL_01bf: leave.s IL_01db } catch System.Exception { @@ -3985,32 +3985,20 @@ .locals init (int V_0, IL_01c4: ldc.i4.s -2 IL_01c6: stfld ""int C.
d__0.<>1__state"" IL_01cb: ldarg.0 - IL_01cc: ldnull - IL_01cd: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>s__1"" - IL_01d2: ldarg.0 - IL_01d3: ldnull - IL_01d4: stfld ""object C.
d__0.<>s__2"" - IL_01d9: ldarg.0 - IL_01da: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_01df: ldloc.s V_9 - IL_01e1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01e6: nop - IL_01e7: leave.s IL_020b + IL_01cc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_01d1: ldloc.s V_9 + IL_01d3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01d8: nop + IL_01d9: leave.s IL_01ef } - IL_01e9: ldarg.0 - IL_01ea: ldc.i4.s -2 - IL_01ec: stfld ""int C.
d__0.<>1__state"" - IL_01f1: ldarg.0 - IL_01f2: ldnull - IL_01f3: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>s__1"" - IL_01f8: ldarg.0 - IL_01f9: ldnull - IL_01fa: stfld ""object C.
d__0.<>s__2"" - IL_01ff: ldarg.0 - IL_0200: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0205: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_020a: nop - IL_020b: ret + IL_01db: ldarg.0 + IL_01dc: ldc.i4.s -2 + IL_01de: stfld ""int C.
d__0.<>1__state"" + IL_01e3: ldarg.0 + IL_01e4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_01e9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01ee: nop + IL_01ef: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs index 8ffa09d5d17c5..39bf18e7fc8e2 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs @@ -1121,7 +1121,7 @@ System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 334 (0x14e) + // Code size 306 (0x132) .maxstack 3 .locals init (int V_0, object V_1, @@ -1198,7 +1198,7 @@ .locals init (int V_0, IL_008c: ldloca.s V_4 IL_008e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0093: nop - IL_0094: leave IL_014d + IL_0094: leave IL_0131 IL_0099: ldarg.0 IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_009f: stloc.2 @@ -1236,14 +1236,14 @@ .locals init (int V_0, IL_00ec: ldc.i4.1 IL_00ed: beq.s IL_00f1 IL_00ef: br.s IL_00f3 - IL_00f1: leave.s IL_012b + IL_00f1: leave.s IL_011d IL_00f3: ldarg.0 IL_00f4: ldnull IL_00f5: stfld ""object C.
d__0.<>s__2"" IL_00fa: ldarg.0 IL_00fb: ldnull IL_00fc: stfld ""C C.
d__0.<>s__1"" - IL_0101: leave.s IL_012b + IL_0101: leave.s IL_011d } catch System.Exception { @@ -1252,32 +1252,20 @@ .locals init (int V_0, IL_0106: ldc.i4.s -2 IL_0108: stfld ""int C.
d__0.<>1__state"" IL_010d: ldarg.0 - IL_010e: ldnull - IL_010f: stfld ""C C.
d__0.<>s__1"" - IL_0114: ldarg.0 - IL_0115: ldnull - IL_0116: stfld ""object C.
d__0.<>s__2"" - IL_011b: ldarg.0 - IL_011c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0121: ldloc.s V_5 - IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0128: nop - IL_0129: leave.s IL_014d + IL_010e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0113: ldloc.s V_5 + IL_0115: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_011a: nop + IL_011b: leave.s IL_0131 } - IL_012b: ldarg.0 - IL_012c: ldc.i4.s -2 - IL_012e: stfld ""int C.
d__0.<>1__state"" - IL_0133: ldarg.0 - IL_0134: ldnull - IL_0135: stfld ""C C.
d__0.<>s__1"" - IL_013a: ldarg.0 - IL_013b: ldnull - IL_013c: stfld ""object C.
d__0.<>s__2"" - IL_0141: ldarg.0 - IL_0142: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_014c: nop - IL_014d: ret + IL_011d: ldarg.0 + IL_011e: ldc.i4.s -2 + IL_0120: stfld ""int C.
d__0.<>1__state"" + IL_0125: ldarg.0 + IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0130: nop + IL_0131: ret }"); } @@ -1307,7 +1295,7 @@ public System.Threading.Tasks.ValueTask DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 334 (0x14e) + // Code size 306 (0x132) .maxstack 3 .locals init (int V_0, object V_1, @@ -1384,7 +1372,7 @@ .locals init (int V_0, IL_008c: ldloca.s V_4 IL_008e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0093: nop - IL_0094: leave IL_014d + IL_0094: leave IL_0131 IL_0099: ldarg.0 IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_009f: stloc.2 @@ -1422,14 +1410,14 @@ .locals init (int V_0, IL_00ec: ldc.i4.1 IL_00ed: beq.s IL_00f1 IL_00ef: br.s IL_00f3 - IL_00f1: leave.s IL_012b + IL_00f1: leave.s IL_011d IL_00f3: ldarg.0 IL_00f4: ldnull IL_00f5: stfld ""object C.
d__0.<>s__2"" IL_00fa: ldarg.0 IL_00fb: ldnull IL_00fc: stfld ""C C.
d__0.<>s__1"" - IL_0101: leave.s IL_012b + IL_0101: leave.s IL_011d } catch System.Exception { @@ -1438,32 +1426,20 @@ .locals init (int V_0, IL_0106: ldc.i4.s -2 IL_0108: stfld ""int C.
d__0.<>1__state"" IL_010d: ldarg.0 - IL_010e: ldnull - IL_010f: stfld ""C C.
d__0.<>s__1"" - IL_0114: ldarg.0 - IL_0115: ldnull - IL_0116: stfld ""object C.
d__0.<>s__2"" - IL_011b: ldarg.0 - IL_011c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0121: ldloc.s V_5 - IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0128: nop - IL_0129: leave.s IL_014d + IL_010e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0113: ldloc.s V_5 + IL_0115: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_011a: nop + IL_011b: leave.s IL_0131 } - IL_012b: ldarg.0 - IL_012c: ldc.i4.s -2 - IL_012e: stfld ""int C.
d__0.<>1__state"" - IL_0133: ldarg.0 - IL_0134: ldnull - IL_0135: stfld ""C C.
d__0.<>s__1"" - IL_013a: ldarg.0 - IL_013b: ldnull - IL_013c: stfld ""object C.
d__0.<>s__2"" - IL_0141: ldarg.0 - IL_0142: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_014c: nop - IL_014d: ret + IL_011d: ldarg.0 + IL_011e: ldc.i4.s -2 + IL_0120: stfld ""int C.
d__0.<>1__state"" + IL_0125: ldarg.0 + IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0130: nop + IL_0131: ret } "); } @@ -1494,7 +1470,7 @@ public System.Threading.Tasks.ValueTask DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 334 (0x14e) + // Code size 306 (0x132) .maxstack 3 .locals init (int V_0, object V_1, @@ -1571,7 +1547,7 @@ .locals init (int V_0, IL_008c: ldloca.s V_4 IL_008e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_0093: nop - IL_0094: leave IL_014d + IL_0094: leave IL_0131 IL_0099: ldarg.0 IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" IL_009f: stloc.2 @@ -1609,14 +1585,14 @@ .locals init (int V_0, IL_00ec: ldc.i4.1 IL_00ed: beq.s IL_00f1 IL_00ef: br.s IL_00f3 - IL_00f1: leave.s IL_012b + IL_00f1: leave.s IL_011d IL_00f3: ldarg.0 IL_00f4: ldnull IL_00f5: stfld ""object C.
d__0.<>s__2"" IL_00fa: ldarg.0 IL_00fb: ldnull IL_00fc: stfld ""C C.
d__0.<>s__1"" - IL_0101: leave.s IL_012b + IL_0101: leave.s IL_011d } catch System.Exception { @@ -1625,32 +1601,20 @@ .locals init (int V_0, IL_0106: ldc.i4.s -2 IL_0108: stfld ""int C.
d__0.<>1__state"" IL_010d: ldarg.0 - IL_010e: ldnull - IL_010f: stfld ""C C.
d__0.<>s__1"" - IL_0114: ldarg.0 - IL_0115: ldnull - IL_0116: stfld ""object C.
d__0.<>s__2"" - IL_011b: ldarg.0 - IL_011c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0121: ldloc.s V_5 - IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0128: nop - IL_0129: leave.s IL_014d + IL_010e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0113: ldloc.s V_5 + IL_0115: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_011a: nop + IL_011b: leave.s IL_0131 } - IL_012b: ldarg.0 - IL_012c: ldc.i4.s -2 - IL_012e: stfld ""int C.
d__0.<>1__state"" - IL_0133: ldarg.0 - IL_0134: ldnull - IL_0135: stfld ""C C.
d__0.<>s__1"" - IL_013a: ldarg.0 - IL_013b: ldnull - IL_013c: stfld ""object C.
d__0.<>s__2"" - IL_0141: ldarg.0 - IL_0142: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_014c: nop - IL_014d: ret + IL_011d: ldarg.0 + IL_011e: ldc.i4.s -2 + IL_0120: stfld ""int C.
d__0.<>1__state"" + IL_0125: ldarg.0 + IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0130: nop + IL_0131: ret } "); } @@ -1751,7 +1715,7 @@ System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("S.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 312 (0x138) + // Code size 298 (0x12a) .maxstack 3 .locals init (int V_0, object V_1, @@ -1826,7 +1790,7 @@ .locals init (int V_0, IL_008b: ldloca.s V_4 IL_008d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref S.
d__0)"" IL_0092: nop - IL_0093: leave IL_0137 + IL_0093: leave IL_0129 IL_0098: ldarg.0 IL_0099: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter S.
d__0.<>u__1"" IL_009e: stloc.2 @@ -1864,11 +1828,11 @@ .locals init (int V_0, IL_00eb: ldc.i4.1 IL_00ec: beq.s IL_00f0 IL_00ee: br.s IL_00f2 - IL_00f0: leave.s IL_011c + IL_00f0: leave.s IL_0115 IL_00f2: ldarg.0 IL_00f3: ldnull IL_00f4: stfld ""object S.
d__0.<>s__2"" - IL_00f9: leave.s IL_011c + IL_00f9: leave.s IL_0115 } catch System.Exception { @@ -1877,26 +1841,20 @@ .locals init (int V_0, IL_00fe: ldc.i4.s -2 IL_0100: stfld ""int S.
d__0.<>1__state"" IL_0105: ldarg.0 - IL_0106: ldnull - IL_0107: stfld ""object S.
d__0.<>s__2"" - IL_010c: ldarg.0 - IL_010d: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_0112: ldloc.s V_5 - IL_0114: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0119: nop - IL_011a: leave.s IL_0137 + IL_0106: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_010b: ldloc.s V_5 + IL_010d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0112: nop + IL_0113: leave.s IL_0129 } - IL_011c: ldarg.0 - IL_011d: ldc.i4.s -2 - IL_011f: stfld ""int S.
d__0.<>1__state"" - IL_0124: ldarg.0 - IL_0125: ldnull - IL_0126: stfld ""object S.
d__0.<>s__2"" - IL_012b: ldarg.0 - IL_012c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_0131: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0136: nop - IL_0137: ret + IL_0115: ldarg.0 + IL_0116: ldc.i4.s -2 + IL_0118: stfld ""int S.
d__0.<>1__state"" + IL_011d: ldarg.0 + IL_011e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_0123: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0128: nop + IL_0129: ret }"); } @@ -1926,7 +1884,7 @@ public System.Threading.Tasks.ValueTask DisposeAsync() var verifier = CompileAndVerify(comp, expectedOutput: "body DisposeAsync"); verifier.VerifyIL("S.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 306 (0x132) + // Code size 292 (0x124) .maxstack 3 .locals init (int V_0, object V_1, @@ -2000,7 +1958,7 @@ .locals init (int V_0, IL_0085: ldloca.s V_4 IL_0087: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref S.
d__0)"" IL_008c: nop - IL_008d: leave IL_0131 + IL_008d: leave IL_0123 IL_0092: ldarg.0 IL_0093: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter S.
d__0.<>u__1"" IL_0098: stloc.2 @@ -2038,11 +1996,11 @@ .locals init (int V_0, IL_00e5: ldc.i4.1 IL_00e6: beq.s IL_00ea IL_00e8: br.s IL_00ec - IL_00ea: leave.s IL_0116 + IL_00ea: leave.s IL_010f IL_00ec: ldarg.0 IL_00ed: ldnull IL_00ee: stfld ""object S.
d__0.<>s__2"" - IL_00f3: leave.s IL_0116 + IL_00f3: leave.s IL_010f } catch System.Exception { @@ -2051,26 +2009,20 @@ .locals init (int V_0, IL_00f8: ldc.i4.s -2 IL_00fa: stfld ""int S.
d__0.<>1__state"" IL_00ff: ldarg.0 - IL_0100: ldnull - IL_0101: stfld ""object S.
d__0.<>s__2"" - IL_0106: ldarg.0 - IL_0107: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_010c: ldloc.s V_5 - IL_010e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0113: nop - IL_0114: leave.s IL_0131 + IL_0100: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_0105: ldloc.s V_5 + IL_0107: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_010c: nop + IL_010d: leave.s IL_0123 } - IL_0116: ldarg.0 - IL_0117: ldc.i4.s -2 - IL_0119: stfld ""int S.
d__0.<>1__state"" - IL_011e: ldarg.0 - IL_011f: ldnull - IL_0120: stfld ""object S.
d__0.<>s__2"" - IL_0125: ldarg.0 - IL_0126: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" - IL_012b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0130: nop - IL_0131: ret + IL_010f: ldarg.0 + IL_0110: ldc.i4.s -2 + IL_0112: stfld ""int S.
d__0.<>1__state"" + IL_0117: ldarg.0 + IL_0118: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder S.
d__0.<>t__builder"" + IL_011d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0122: nop + IL_0123: ret }"); } @@ -2749,7 +2701,7 @@ public async System.Threading.Tasks.ValueTask DisposeAsync() // Sequence point highlights `await using ...` verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 331 (0x14b) + // Code size 303 (0x12f) .maxstack 3 .locals init (int V_0, int V_1, @@ -2834,7 +2786,7 @@ .locals init (int V_0, IL_0084: ldloca.s V_5 IL_0086: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" IL_008b: nop - IL_008c: leave IL_014a + IL_008c: leave IL_012e // async: resume IL_0091: ldarg.0 IL_0092: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" @@ -2885,7 +2837,7 @@ .locals init (int V_0, // sequence point: return 1; IL_00fb: ldc.i4.1 IL_00fc: stloc.1 - IL_00fd: leave.s IL_0127 + IL_00fd: leave.s IL_0119 } catch System.Exception { @@ -2895,35 +2847,23 @@ .locals init (int V_0, IL_0102: ldc.i4.s -2 IL_0104: stfld ""int C.
d__0.<>1__state"" IL_0109: ldarg.0 - IL_010a: ldnull - IL_010b: stfld ""C C.
d__0.5__1"" - IL_0110: ldarg.0 - IL_0111: ldnull - IL_0112: stfld ""object C.
d__0.<>s__2"" - IL_0117: ldarg.0 - IL_0118: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_011d: ldloc.s V_6 - IL_011f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0124: nop - IL_0125: leave.s IL_014a + IL_010a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_010f: ldloc.s V_6 + IL_0111: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0116: nop + IL_0117: leave.s IL_012e } // sequence point: } - IL_0127: ldarg.0 - IL_0128: ldc.i4.s -2 - IL_012a: stfld ""int C.
d__0.<>1__state"" + IL_0119: ldarg.0 + IL_011a: ldc.i4.s -2 + IL_011c: stfld ""int C.
d__0.<>1__state"" // sequence point: - IL_012f: ldarg.0 - IL_0130: ldnull - IL_0131: stfld ""C C.
d__0.5__1"" - IL_0136: ldarg.0 - IL_0137: ldnull - IL_0138: stfld ""object C.
d__0.<>s__2"" - IL_013d: ldarg.0 - IL_013e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" - IL_0143: ldloc.1 - IL_0144: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" - IL_0149: nop - IL_014a: ret + IL_0121: ldarg.0 + IL_0122: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0127: ldloc.1 + IL_0128: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(int)"" + IL_012d: nop + IL_012e: ret } ", sequencePoints: "C+
d__0.MoveNext", source: source); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs index a90d3a5f1f79b..eb8319ef8c917 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefConditionalOperatorTests.cs @@ -1840,7 +1840,7 @@ static async Task GetC2(C c) comp.VerifyIL("C.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 467 (0x1d3) + // Code size 439 (0x1b7) .maxstack 3 .locals init (int V_0, bool V_1, @@ -1878,7 +1878,7 @@ .locals init (int V_0, IL_0049: ldloca.s V_2 IL_004b: ldarg.0 IL_004c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0051: leave IL_01d2 + IL_0051: leave IL_01b6 IL_0056: ldarg.0 IL_0057: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" IL_005c: stloc.2 @@ -1920,7 +1920,7 @@ .locals init (int V_0, IL_00b9: ldloca.s V_3 IL_00bb: ldarg.0 IL_00bc: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_00c1: leave IL_01d2 + IL_00c1: leave IL_01b6 IL_00c6: ldarg.0 IL_00c7: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__2"" IL_00cc: stloc.3 @@ -1958,7 +1958,7 @@ .locals init (int V_0, IL_0121: ldloca.s V_3 IL_0123: ldarg.0 IL_0124: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0129: leave IL_01d2 + IL_0129: leave IL_01b6 IL_012e: ldarg.0 IL_012f: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__2"" IL_0134: stloc.3 @@ -1992,7 +1992,7 @@ .locals init (int V_0, IL_0181: ldarg.0 IL_0182: ldnull IL_0183: stfld ""C C.d__2.<>7__wrap3"" - IL_0188: leave.s IL_01b1 + IL_0188: leave.s IL_01a3 } catch System.Exception { @@ -2001,30 +2001,18 @@ .locals init (int V_0, IL_018d: ldc.i4.s -2 IL_018f: stfld ""int C.d__2.<>1__state"" IL_0194: ldarg.0 - IL_0195: ldnull - IL_0196: stfld ""C C.d__2.<>7__wrap2"" - IL_019b: ldarg.0 - IL_019c: ldnull - IL_019d: stfld ""C C.d__2.<>7__wrap3"" - IL_01a2: ldarg.0 - IL_01a3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01a8: ldloc.s V_4 - IL_01aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01af: leave.s IL_01d2 + IL_0195: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_019a: ldloc.s V_4 + IL_019c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01a1: leave.s IL_01b6 } - IL_01b1: ldarg.0 - IL_01b2: ldc.i4.s -2 - IL_01b4: stfld ""int C.d__2.<>1__state"" - IL_01b9: ldarg.0 - IL_01ba: ldnull - IL_01bb: stfld ""C C.d__2.<>7__wrap2"" - IL_01c0: ldarg.0 - IL_01c1: ldnull - IL_01c2: stfld ""C C.d__2.<>7__wrap3"" - IL_01c7: ldarg.0 - IL_01c8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01cd: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01d2: ret + IL_01a3: ldarg.0 + IL_01a4: ldc.i4.s -2 + IL_01a6: stfld ""int C.d__2.<>1__state"" + IL_01ab: ldarg.0 + IL_01ac: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01b1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01b6: ret } "); } @@ -2075,7 +2063,7 @@ static async Task GetC(C c) comp.VerifyIL("C.d__2.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" { - // Code size 484 (0x1e4) + // Code size 453 (0x1c5) .maxstack 3 .locals init (int V_0, C V_1, @@ -2090,7 +2078,7 @@ .locals init (int V_0, IL_0008: switch ( IL_006a, IL_00d2, - IL_015d) + IL_015a) IL_0019: ldarg.0 IL_001a: ldarg.0 IL_001b: ldfld ""bool C.d__2.b"" @@ -2119,7 +2107,7 @@ .locals init (int V_0, IL_005d: ldloca.s V_2 IL_005f: ldarg.0 IL_0060: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0065: leave IL_01e3 + IL_0065: leave IL_01c4 IL_006a: ldarg.0 IL_006b: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" IL_0070: stloc.2 @@ -2157,7 +2145,7 @@ .locals init (int V_0, IL_00c5: ldloca.s V_2 IL_00c7: ldarg.0 IL_00c8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_00cd: leave IL_01e3 + IL_00cd: leave IL_01c4 IL_00d2: ldarg.0 IL_00d3: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" IL_00d8: stloc.2 @@ -2191,7 +2179,7 @@ .locals init (int V_0, IL_0130: stloc.2 IL_0131: ldloca.s V_2 IL_0133: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0138: brtrue.s IL_0179 + IL_0138: brtrue.s IL_0176 IL_013a: ldarg.0 IL_013b: ldc.i4.2 IL_013c: dup @@ -2205,64 +2193,52 @@ .locals init (int V_0, IL_0150: ldloca.s V_2 IL_0152: ldarg.0 IL_0153: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__2>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__2)"" - IL_0158: leave IL_01e3 - IL_015d: ldarg.0 - IL_015e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" - IL_0163: stloc.2 - IL_0164: ldarg.0 - IL_0165: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" - IL_016a: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0170: ldarg.0 - IL_0171: ldc.i4.m1 - IL_0172: dup - IL_0173: stloc.0 - IL_0174: stfld ""int C.d__2.<>1__state"" - IL_0179: ldloca.s V_2 - IL_017b: call ""C System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0180: stloc.1 - IL_0181: ldarg.0 - IL_0182: ldfld ""int C.d__2.<>7__wrap4"" - IL_0187: ldloc.1 - IL_0188: call ""void C.Test(int, C)"" - IL_018d: ldarg.0 - IL_018e: ldnull - IL_018f: stfld ""C C.d__2.<>7__wrap2"" - IL_0194: ldarg.0 - IL_0195: ldnull - IL_0196: stfld ""C C.d__2.<>7__wrap3"" - IL_019b: leave.s IL_01c2 + IL_0158: leave.s IL_01c4 + IL_015a: ldarg.0 + IL_015b: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" + IL_0160: stloc.2 + IL_0161: ldarg.0 + IL_0162: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__2.<>u__1"" + IL_0167: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_016d: ldarg.0 + IL_016e: ldc.i4.m1 + IL_016f: dup + IL_0170: stloc.0 + IL_0171: stfld ""int C.d__2.<>1__state"" + IL_0176: ldloca.s V_2 + IL_0178: call ""C System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_017d: stloc.1 + IL_017e: ldarg.0 + IL_017f: ldfld ""int C.d__2.<>7__wrap4"" + IL_0184: ldloc.1 + IL_0185: call ""void C.Test(int, C)"" + IL_018a: ldarg.0 + IL_018b: ldnull + IL_018c: stfld ""C C.d__2.<>7__wrap2"" + IL_0191: ldarg.0 + IL_0192: ldnull + IL_0193: stfld ""C C.d__2.<>7__wrap3"" + IL_0198: leave.s IL_01b1 } catch System.Exception { - IL_019d: stloc.3 - IL_019e: ldarg.0 - IL_019f: ldc.i4.s -2 - IL_01a1: stfld ""int C.d__2.<>1__state"" - IL_01a6: ldarg.0 - IL_01a7: ldnull - IL_01a8: stfld ""C C.d__2.<>7__wrap2"" - IL_01ad: ldarg.0 - IL_01ae: ldnull - IL_01af: stfld ""C C.d__2.<>7__wrap3"" - IL_01b4: ldarg.0 - IL_01b5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01ba: ldloc.3 - IL_01bb: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01c0: leave.s IL_01e3 + IL_019a: stloc.3 + IL_019b: ldarg.0 + IL_019c: ldc.i4.s -2 + IL_019e: stfld ""int C.d__2.<>1__state"" + IL_01a3: ldarg.0 + IL_01a4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01a9: ldloc.3 + IL_01aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01af: leave.s IL_01c4 } - IL_01c2: ldarg.0 - IL_01c3: ldc.i4.s -2 - IL_01c5: stfld ""int C.d__2.<>1__state"" - IL_01ca: ldarg.0 - IL_01cb: ldnull - IL_01cc: stfld ""C C.d__2.<>7__wrap2"" - IL_01d1: ldarg.0 - IL_01d2: ldnull - IL_01d3: stfld ""C C.d__2.<>7__wrap3"" - IL_01d8: ldarg.0 - IL_01d9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" - IL_01de: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_01e3: ret + IL_01b1: ldarg.0 + IL_01b2: ldc.i4.s -2 + IL_01b4: stfld ""int C.d__2.<>1__state"" + IL_01b9: ldarg.0 + IL_01ba: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__2.<>t__builder"" + IL_01bf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_01c4: ret } "); } From 3eb020fe0b54a63bd38b799f99392da6a2a1b0fc Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 18 Nov 2024 08:59:56 -0800 Subject: [PATCH 15/20] Clean up a test --- .../Emit/CodeGen/CodeGenAsyncLocalsTests.cs | 185 ------------------ 1 file changed, 185 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs index c097674c5be4d..caaf685ab21be 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs @@ -1151,7 +1151,6 @@ public static async void M() var actual = GetFieldLoadsAndStores(c, "Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"); - // TODO2 // make sure we are reusing synthesized iterator locals and that the locals are nulled: AssertEx.AssertEqualToleratingWhitespaceDifferences(@" IL_0000: ldarg.0 @@ -1213,190 +1212,6 @@ public static async void M() IL_0188: ldarg.0 IL_0189: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder"" ", actual); - - c.VerifyIL("Test.d__3.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ -{ - // Code size 404 (0x194) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - System.Exception V_2) - IL_0000: ldarg.0 - IL_0001: ldfld "int Test.d__3.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0021 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq IL_00cd - IL_0011: ldarg.0 - IL_0012: call "System.Collections.Generic.IEnumerable Test.GetDynamicEnum()" - IL_0017: callvirt "System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()" - IL_001c: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0021: nop - .try - { - IL_0022: ldloc.0 - IL_0023: brfalse.s IL_006b - IL_0025: br.s IL_008f - IL_0027: ldarg.0 - IL_0028: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_002d: callvirt "dynamic System.Collections.Generic.IEnumerator.Current.get" - IL_0032: pop - IL_0033: ldc.i4.1 - IL_0034: call "System.Threading.Tasks.Task Test.F(int)" - IL_0039: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_003e: stloc.1 - IL_003f: ldloca.s V_1 - IL_0041: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0046: brtrue.s IL_0087 - IL_0048: ldarg.0 - IL_0049: ldc.i4.0 - IL_004a: dup - IL_004b: stloc.0 - IL_004c: stfld "int Test.d__3.<>1__state" - IL_0051: ldarg.0 - IL_0052: ldloc.1 - IL_0053: stfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0058: ldarg.0 - IL_0059: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_005e: ldloca.s V_1 - IL_0060: ldarg.0 - IL_0061: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" - IL_0066: leave IL_0193 - IL_006b: ldarg.0 - IL_006c: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0071: stloc.1 - IL_0072: ldarg.0 - IL_0073: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0078: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_007e: ldarg.0 - IL_007f: ldc.i4.m1 - IL_0080: dup - IL_0081: stloc.0 - IL_0082: stfld "int Test.d__3.<>1__state" - IL_0087: ldloca.s V_1 - IL_0089: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_008e: pop - IL_008f: ldarg.0 - IL_0090: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0095: callvirt "bool System.Collections.IEnumerator.MoveNext()" - IL_009a: brtrue.s IL_0027 - IL_009c: leave.s IL_00b6 - } - finally - { - IL_009e: ldloc.0 - IL_009f: ldc.i4.0 - IL_00a0: bge.s IL_00b5 - IL_00a2: ldarg.0 - IL_00a3: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_00a8: brfalse.s IL_00b5 - IL_00aa: ldarg.0 - IL_00ab: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_00b0: callvirt "void System.IDisposable.Dispose()" - IL_00b5: endfinally - } - IL_00b6: ldarg.0 - IL_00b7: ldnull - IL_00b8: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_00bd: ldarg.0 - IL_00be: call "System.Collections.Generic.IEnumerable Test.GetObjectEnum()" - IL_00c3: callvirt "System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()" - IL_00c8: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_00cd: nop - .try - { - IL_00ce: ldloc.0 - IL_00cf: ldc.i4.1 - IL_00d0: beq.s IL_0115 - IL_00d2: br.s IL_0139 - IL_00d4: ldarg.0 - IL_00d5: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_00da: callvirt "object System.Collections.Generic.IEnumerator.Current.get" - IL_00df: pop - IL_00e0: ldc.i4.2 - IL_00e1: call "System.Threading.Tasks.Task Test.F(int)" - IL_00e6: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_00eb: stloc.1 - IL_00ec: ldloca.s V_1 - IL_00ee: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_00f3: brtrue.s IL_0131 - IL_00f5: ldarg.0 - IL_00f6: ldc.i4.1 - IL_00f7: dup - IL_00f8: stloc.0 - IL_00f9: stfld "int Test.d__3.<>1__state" - IL_00fe: ldarg.0 - IL_00ff: ldloc.1 - IL_0100: stfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0105: ldarg.0 - IL_0106: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_010b: ldloca.s V_1 - IL_010d: ldarg.0 - IL_010e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted, Test.d__3>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Test.d__3)" - IL_0113: leave.s IL_0193 - IL_0115: ldarg.0 - IL_0116: ldfld "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_011b: stloc.1 - IL_011c: ldarg.0 - IL_011d: ldflda "System.Runtime.CompilerServices.TaskAwaiter Test.d__3.<>u__1" - IL_0122: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0128: ldarg.0 - IL_0129: ldc.i4.m1 - IL_012a: dup - IL_012b: stloc.0 - IL_012c: stfld "int Test.d__3.<>1__state" - IL_0131: ldloca.s V_1 - IL_0133: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_0138: pop - IL_0139: ldarg.0 - IL_013a: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_013f: callvirt "bool System.Collections.IEnumerator.MoveNext()" - IL_0144: brtrue.s IL_00d4 - IL_0146: leave.s IL_0160 - } - finally - { - IL_0148: ldloc.0 - IL_0149: ldc.i4.0 - IL_014a: bge.s IL_015f - IL_014c: ldarg.0 - IL_014d: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0152: brfalse.s IL_015f - IL_0154: ldarg.0 - IL_0155: ldfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_015a: callvirt "void System.IDisposable.Dispose()" - IL_015f: endfinally - } - IL_0160: ldarg.0 - IL_0161: ldnull - IL_0162: stfld "System.Collections.Generic.IEnumerator Test.d__3.<>7__wrap1" - IL_0167: leave.s IL_0180 - } - catch System.Exception - { - IL_0169: stloc.2 - IL_016a: ldarg.0 - IL_016b: ldc.i4.s -2 - IL_016d: stfld "int Test.d__3.<>1__state" - IL_0172: ldarg.0 - IL_0173: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_0178: ldloc.2 - IL_0179: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" - IL_017e: leave.s IL_0193 - } - IL_0180: ldarg.0 - IL_0181: ldc.i4.s -2 - IL_0183: stfld "int Test.d__3.<>1__state" - IL_0188: ldarg.0 - IL_0189: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Test.d__3.<>t__builder" - IL_018e: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" - IL_0193: ret -} -"""); } [Fact] From 58ab13eb28f9cf5d3e2095c4a029321a4dce63d3 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 18 Nov 2024 11:02:34 -0800 Subject: [PATCH 16/20] Collect fields to be cleared when they are created --- ...yncIteratorMethodToStateMachineRewriter.cs | 4 +- .../AsyncMethodToStateMachineRewriter.cs | 4 +- .../AsyncRewriter.AsyncIteratorRewriter.cs | 1 + .../Lowering/AsyncRewriter/AsyncRewriter.cs | 1 + .../IteratorMethodToStateMachineRewriter.cs | 4 +- .../IteratorRewriter/IteratorRewriter.cs | 1 + .../MethodToStateMachineRewriter.cs | 66 ++--- .../StateMachineRewriter.cs | 8 +- .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 236 ++++++++++++++++++ 9 files changed, 280 insertions(+), 45 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 1bee6e668af52..e9edcaa87512a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -6,6 +6,7 @@ using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CodeGen; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; @@ -55,13 +56,14 @@ internal AsyncIteratorMethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, + IOrderedReadOnlySet nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) : base(method, methodOrdinal, asyncMethodBuilderMemberCollection, F, - state, builder, instanceIdField, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, + state, builder, instanceIdField, hoistedVariables, nonReusableLocalProxies, nonReusableFieldsForCleanup, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { Debug.Assert(asyncIteratorInfo != null); diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index 98371974c478a..fb50388c517d2 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.CodeGen; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Emit; @@ -73,12 +74,13 @@ internal AsyncMethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, + IOrderedReadOnlySet nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) - : base(F, method, state, instanceIdField, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + : base(F, method, state, instanceIdField, hoistedVariables, nonReusableLocalProxies, nonReusableFieldsForCleanup, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { _method = method; _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection; diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs index 6bde60bf03281..82a95a335b015 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs @@ -703,6 +703,7 @@ protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNex instanceIdField: instanceIdField, hoistedVariables: hoistedVariables, nonReusableLocalProxies: nonReusableLocalProxies, + nonReusableFieldsForCleanup: nonReusableFieldsForCleanup, synthesizedLocalOrdinals: synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt: slotAllocatorOpt, diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs index 7e948c47dccab..1d911bc7155d3 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs @@ -286,6 +286,7 @@ protected virtual void GenerateMoveNext(SynthesizedImplementationMethod moveNext instanceIdField: instanceIdField, hoistedVariables: hoistedVariables, nonReusableLocalProxies: nonReusableLocalProxies, + nonReusableFieldsForCleanup: nonReusableFieldsForCleanup, synthesizedLocalOrdinals: synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt: slotAllocatorOpt, diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs index bf4c244ea2d67..b8c5544592016 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs @@ -12,6 +12,7 @@ using Roslyn.Utilities; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Collections; namespace Microsoft.CodeAnalysis.CSharp { @@ -61,12 +62,13 @@ internal IteratorMethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, + IOrderedReadOnlySet nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) - : base(F, originalMethod, state, instanceIdField, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + : base(F, originalMethod, state, instanceIdField, hoistedVariables, nonReusableLocalProxies, nonReusableFieldsForCleanup, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { _current = current; diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs index 9d444a3eeeaa6..815f497c82f42 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs @@ -335,6 +335,7 @@ private void GenerateMoveNextAndDispose( instanceIdField, hoistedVariables, nonReusableLocalProxies, + nonReusableFieldsForCleanup, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index cc269632a1bc7..c92c69b864772 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis.CodeGen; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Emit; @@ -72,7 +73,7 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter /// /// We collect all the hoisted fields for locals, so that we can clear them so the GC can collect references. /// - private readonly ArrayBuilder _hoistedFieldsForCleanup; + private readonly ArrayBuilder _fieldsForCleanup; /// /// Fields allocated for temporary variables are given unique names distinguished by a number at the end. @@ -104,6 +105,7 @@ public MethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, + IOrderedReadOnlySet nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, @@ -127,11 +129,16 @@ public MethodToStateMachineRewriter( _hoistedVariables = hoistedVariables; _synthesizedLocalOrdinals = synthesizedLocalOrdinals; _nextFreeHoistedLocalSlot = nextFreeHoistedLocalSlot; - _hoistedFieldsForCleanup = new ArrayBuilder(); foreach (var proxy in nonReusableLocalProxies) { - this.AddProxyAndRegisterForCleanup(proxy.Key, proxy.Value); + this.proxies.Add(proxy.Key, proxy.Value); + } + + _fieldsForCleanup = new ArrayBuilder(); + foreach (FieldSymbol fieldForCleanup in nonReusableFieldsForCleanup) + { + _fieldsForCleanup.Add(fieldForCleanup); } // create cache local for reference type "this" in Release @@ -318,7 +325,7 @@ private BoundStatement PossibleIteratorScope(ImmutableArray locals, if (!proxies.TryGetValue(local, out proxy)) { proxy = new CapturedToStateMachineFieldReplacement(GetOrAllocateReusableHoistedField(TypeMap.SubstituteType(local.Type).Type, out reused, local), isReusable: true); - AddProxyAndRegisterForCleanup(local, proxy); + proxies.Add(local, proxy); } // We need to produce hoisted local scope debug information for user locals as well as @@ -439,54 +446,25 @@ private void AddVariableCleanup(ArrayBuilder cleanup, FieldSymb } #nullable enable - private void AddProxyAndRegisterForCleanup(Symbol symbol, CapturedSymbolReplacement replacement) - { - Debug.Assert(replacement is CapturedToStateMachineFieldReplacement or CapturedToExpressionSymbolReplacement); - proxies.Add(symbol, replacement); - - Debug.Assert(symbol is LocalSymbol or ParameterSymbol); - if (symbol is LocalSymbol) - { - if (replacement is CapturedToStateMachineFieldReplacement fieldReplacement) - { - _hoistedFieldsForCleanup.Add(fieldReplacement.HoistedField); - } - else if (replacement is CapturedToExpressionSymbolReplacement expressionReplacement) - { - foreach (var field in expressionReplacement.HoistedFields) - { - _hoistedFieldsForCleanup.Add(field); - } - } - } - } - protected BoundBlock GenerateAllHoistedLocalsCleanup() { var variableCleanup = ArrayBuilder.GetInstance(); - var alreadyCleaned = PooledHashSet.GetInstance(); - foreach (FieldSymbol fieldSymbol in _hoistedFieldsForCleanup) + foreach (FieldSymbol fieldSymbol in _fieldsForCleanup) { - // Hoisted fields may be re-used for multiple locals, so we can skip those that were cleared already - if (alreadyCleaned.Add(fieldSymbol.Name)) - { - AddVariableCleanup(variableCleanup, fieldSymbol); - } + AddVariableCleanup(variableCleanup, fieldSymbol); } var result = F.Block(variableCleanup.SelectAsArray((e, f) => (BoundStatement)f.ExpressionStatement(e), F)); variableCleanup.Free(); - alreadyCleaned.Free(); return result; } -#nullable disable - private StateMachineFieldSymbol GetOrAllocateReusableHoistedField(TypeSymbol type, out bool reused, LocalSymbol local = null) + private StateMachineFieldSymbol GetOrAllocateReusableHoistedField(TypeSymbol type, out bool reused, LocalSymbol? local = null) { - ArrayBuilder fields; + ArrayBuilder? fields; if (_lazyAvailableReusableHoistedFields != null && _lazyAvailableReusableHoistedFields.TryGetValue(type, out fields) && fields.Count > 0) { var field = fields.Last(); @@ -498,14 +476,21 @@ private StateMachineFieldSymbol GetOrAllocateReusableHoistedField(TypeSymbol typ reused = false; var slotIndex = _nextHoistedFieldId++; + StateMachineFieldSymbol createdField; if (local?.SynthesizedKind == SynthesizedLocalKind.UserDefined) { string fieldName = GeneratedNames.MakeHoistedLocalFieldName(SynthesizedLocalKind.UserDefined, slotIndex, local.Name); - return F.StateMachineField(type, fieldName, SynthesizedLocalKind.UserDefined, slotIndex); + createdField = F.StateMachineField(type, fieldName, SynthesizedLocalKind.UserDefined, slotIndex); + } + else + { + createdField = F.StateMachineField(type, GeneratedNames.ReusableHoistedLocalFieldName(slotIndex)); } - return F.StateMachineField(type, GeneratedNames.ReusableHoistedLocalFieldName(slotIndex)); + _fieldsForCleanup.Add(createdField); + return createdField; } +#nullable disable private void FreeReusableHoistedField(StateMachineFieldSymbol field) { @@ -568,7 +553,7 @@ private BoundExpression HoistRefInitialization(SynthesizedLocal local, BoundAssi var replacement = HoistExpression(right, awaitSyntaxOpt, syntaxOffset, local.RefKind, sideEffects, hoistedFields, ref needsSacrificialEvaluation); - AddProxyAndRegisterForCleanup(local, new CapturedToExpressionSymbolReplacement(replacement, hoistedFields.ToImmutableAndFree(), isReusable: true)); + proxies.Add(local, new CapturedToExpressionSymbolReplacement(replacement, hoistedFields.ToImmutableAndFree(), isReusable: true)); if (needsSacrificialEvaluation) { @@ -721,6 +706,7 @@ private BoundExpression HoistExpression( string fieldName = GeneratedNames.MakeHoistedLocalFieldName(kind, slotIndex); hoistedField = F.StateMachineField(expr.Type, fieldName, new LocalSlotDebugInfo(kind, id), slotIndex); + _fieldsForCleanup.Add(hoistedField); } else { diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs index 4720e12ee1dfb..2380a1b0c565f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs @@ -9,7 +9,6 @@ using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; @@ -29,6 +28,7 @@ internal abstract class StateMachineRewriter protected FieldSymbol? stateField; protected FieldSymbol? instanceIdField; protected IReadOnlyDictionary? nonReusableLocalProxies; + protected IOrderedReadOnlySet? nonReusableFieldsForCleanup; protected int nextFreeHoistedLocalSlot; protected IOrderedReadOnlySet? hoistedVariables; protected Dictionary? initialParameters; @@ -123,9 +123,10 @@ protected BoundStatement Rewrite() return new BoundBadStatement(F.Syntax, ImmutableArray.Empty, hasErrors: true); } - CreateNonReusableLocalProxies(variablesToHoist, out this.nonReusableLocalProxies, out this.nextFreeHoistedLocalSlot); + CreateNonReusableLocalProxies(variablesToHoist, out this.nonReusableLocalProxies, out var nonReusableFieldsForCleanup, out this.nextFreeHoistedLocalSlot); this.hoistedVariables = variablesToHoist; + this.nonReusableFieldsForCleanup = nonReusableFieldsForCleanup; GenerateMethodImplementations(); @@ -136,9 +137,11 @@ protected BoundStatement Rewrite() private void CreateNonReusableLocalProxies( IEnumerable variablesToHoist, out IReadOnlyDictionary proxies, + out OrderedSet nonReusableFieldsForCleanup, out int nextFreeHoistedLocalSlot) { var proxiesBuilder = new Dictionary(); + nonReusableFieldsForCleanup = new OrderedSet(); var typeMap = stateMachineType.TypeMap; bool isDebugBuild = F.Compilation.Options.OptimizationLevel == OptimizationLevel.Debug; @@ -221,6 +224,7 @@ private void CreateNonReusableLocalProxies( string fieldName = GeneratedNames.MakeHoistedLocalFieldName(synthesizedKind, slotIndex, local.Name); field = F.StateMachineField(fieldType, fieldName, new LocalSlotDebugInfo(synthesizedKind, id), slotIndex); + nonReusableFieldsForCleanup.Add(field); } if (field != null) diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 16ee5c028e1bc..4459d0c3cc867 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -10252,6 +10252,242 @@ public struct Buffer2 CompileAndVerify(src, expectedOutput: ExpectedOutput("False 0 False 1 True"), verify: Verification.Skipped, targetFramework: TargetFramework.Net80).VerifyDiagnostics(); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] + public void AddVariableCleanup_HoistedFromRefExpression_Debug() + { + string src = """ +using System.Reflection; + +var c = new C(); +var values = Program.Produce(c); +await foreach (int i in values) +{ + System.Console.Write((values.GetType().GetField("<>s__4", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + System.Console.Write($" {i} "); +} +System.Console.Write((values.GetType().GetField("<>s__4", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(values)) is null); + +partial class Program +{ + public static async System.Collections.Generic.IAsyncEnumerable Produce(C x) + { + int i = 0; + foreach (var y in x.F) + { + await System.Threading.Tasks.Task.CompletedTask; + yield return i++; + } + } +} + +class C +{ + public Buffer2 F = default; +} + +[System.Runtime.CompilerServices.InlineArray(2)] +public struct Buffer2 +{ + private T _element0; +} +"""; + var verifier = CompileAndVerify(src, expectedOutput: ExpectedOutput("False 0 False 1 True"), + verify: Verification.Skipped, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ +{ + // Code size 449 (0x1c1) + .maxstack 4 + .locals init (int V_0, + System.Runtime.CompilerServices.TaskAwaiter V_1, + Program.d__1 V_2, + int V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.d__1.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -4 + IL_000a: sub + IL_000b: switch ( + IL_0026, + IL_002b, + IL_0032, + IL_0032, + IL_002d) + IL_0024: br.s IL_0032 + IL_0026: br IL_0118 + IL_002b: br.s IL_0032 + IL_002d: br IL_00ce + IL_0032: ldarg.0 + IL_0033: ldfld "bool Program.d__1.<>w__disposeMode" + IL_0038: brfalse.s IL_003f + IL_003a: leave IL_0183 + IL_003f: ldarg.0 + IL_0040: ldc.i4.m1 + IL_0041: dup + IL_0042: stloc.0 + IL_0043: stfld "int Program.d__1.<>1__state" + IL_0048: nop + IL_0049: ldarg.0 + IL_004a: ldc.i4.0 + IL_004b: stfld "int Program.d__1.5__1" + IL_0050: nop + IL_0051: ldarg.0 + IL_0052: ldarg.0 + IL_0053: ldfld "C Program.d__1.x" + IL_0058: stfld "C Program.d__1.<>s__4" + IL_005d: ldarg.0 + IL_005e: ldfld "C Program.d__1.<>s__4" + IL_0063: ldfld "Buffer2 C.F" + IL_0068: pop + IL_0069: ldarg.0 + IL_006a: ldc.i4.0 + IL_006b: stfld "int Program.d__1.<>s__2" + IL_0070: br IL_013a + IL_0075: ldarg.0 + IL_0076: ldarg.0 + IL_0077: ldfld "C Program.d__1.<>s__4" + IL_007c: ldflda "Buffer2 C.F" + IL_0081: ldarg.0 + IL_0082: ldfld "int Program.d__1.<>s__2" + IL_0087: call "ref int .InlineArrayElementRef, int>(ref Buffer2, int)" + IL_008c: ldind.i4 + IL_008d: stfld "int Program.d__1.5__3" + IL_0092: nop + IL_0093: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get" + IL_0098: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_009d: stloc.1 + IL_009e: ldloca.s V_1 + IL_00a0: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_00a5: brtrue.s IL_00ea + IL_00a7: ldarg.0 + IL_00a8: ldc.i4.0 + IL_00a9: dup + IL_00aa: stloc.0 + IL_00ab: stfld "int Program.d__1.<>1__state" + IL_00b0: ldarg.0 + IL_00b1: ldloc.1 + IL_00b2: stfld "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" + IL_00b7: ldarg.0 + IL_00b8: stloc.2 + IL_00b9: ldarg.0 + IL_00ba: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_00bf: ldloca.s V_1 + IL_00c1: ldloca.s V_2 + IL_00c3: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.d__1)" + IL_00c8: nop + IL_00c9: leave IL_01c0 + IL_00ce: ldarg.0 + IL_00cf: ldfld "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" + IL_00d4: stloc.1 + IL_00d5: ldarg.0 + IL_00d6: ldflda "System.Runtime.CompilerServices.TaskAwaiter Program.d__1.<>u__1" + IL_00db: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00e1: ldarg.0 + IL_00e2: ldc.i4.m1 + IL_00e3: dup + IL_00e4: stloc.0 + IL_00e5: stfld "int Program.d__1.<>1__state" + IL_00ea: ldloca.s V_1 + IL_00ec: call "void System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00f1: nop + IL_00f2: ldarg.0 + IL_00f3: ldarg.0 + IL_00f4: ldfld "int Program.d__1.5__1" + IL_00f9: stloc.3 + IL_00fa: ldarg.0 + IL_00fb: ldloc.3 + IL_00fc: ldc.i4.1 + IL_00fd: add + IL_00fe: stfld "int Program.d__1.5__1" + IL_0103: ldloc.3 + IL_0104: stfld "int Program.d__1.<>2__current" + IL_0109: ldarg.0 + IL_010a: ldc.i4.s -4 + IL_010c: dup + IL_010d: stloc.0 + IL_010e: stfld "int Program.d__1.<>1__state" + IL_0113: leave IL_01b3 + IL_0118: ldarg.0 + IL_0119: ldc.i4.m1 + IL_011a: dup + IL_011b: stloc.0 + IL_011c: stfld "int Program.d__1.<>1__state" + IL_0121: ldarg.0 + IL_0122: ldfld "bool Program.d__1.<>w__disposeMode" + IL_0127: brfalse.s IL_012b + IL_0129: leave.s IL_0183 + IL_012b: nop + IL_012c: ldarg.0 + IL_012d: ldarg.0 + IL_012e: ldfld "int Program.d__1.<>s__2" + IL_0133: ldc.i4.1 + IL_0134: add + IL_0135: stfld "int Program.d__1.<>s__2" + IL_013a: ldarg.0 + IL_013b: ldfld "int Program.d__1.<>s__2" + IL_0140: ldc.i4.2 + IL_0141: blt IL_0075 + IL_0146: ldarg.0 + IL_0147: ldnull + IL_0148: stfld "C Program.d__1.<>s__4" + IL_014d: leave.s IL_0183 + } + catch System.Exception + { + IL_014f: stloc.s V_4 + IL_0151: ldarg.0 + IL_0152: ldc.i4.s -2 + IL_0154: stfld "int Program.d__1.<>1__state" + IL_0159: ldarg.0 + IL_015a: ldnull + IL_015b: stfld "C Program.d__1.<>s__4" + IL_0160: ldarg.0 + IL_0161: ldc.i4.0 + IL_0162: stfld "int Program.d__1.<>2__current" + IL_0167: ldarg.0 + IL_0168: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_016d: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0172: nop + IL_0173: ldarg.0 + IL_0174: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_0179: ldloc.s V_4 + IL_017b: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0180: nop + IL_0181: leave.s IL_01c0 + } + IL_0183: ldarg.0 + IL_0184: ldc.i4.s -2 + IL_0186: stfld "int Program.d__1.<>1__state" + IL_018b: ldarg.0 + IL_018c: ldnull + IL_018d: stfld "C Program.d__1.<>s__4" + IL_0192: ldarg.0 + IL_0193: ldc.i4.0 + IL_0194: stfld "int Program.d__1.<>2__current" + IL_0199: ldarg.0 + IL_019a: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_019f: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_01a4: nop + IL_01a5: ldarg.0 + IL_01a6: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_01ab: ldc.i4.0 + IL_01ac: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_01b1: nop + IL_01b2: ret + IL_01b3: ldarg.0 + IL_01b4: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_01b9: ldc.i4.1 + IL_01ba: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_01bf: nop + IL_01c0: ret +} +"""); + } + [Fact] public void AddVariableCleanup_Unmanaged_UseSiteError() { From 0df2e4ba1c91f0c4562379f423877ecb3d400145 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 18 Nov 2024 11:41:31 -0800 Subject: [PATCH 17/20] Rename parameter --- .../AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index e9edcaa87512a..042ac5ae7b960 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -91,7 +91,7 @@ internal AsyncIteratorMethodToStateMachineRewriter( return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; } - protected override BoundStatement GenerateHoistedLocalsCleanupForExit(ImmutableArray hoistedLocals) + protected override BoundStatement GenerateHoistedLocalsCleanupForExit(ImmutableArray rootHoistedLocals) { // We need to clean nested hoisted local variables too (not just top-level ones) // as they are not cleaned when exiting a block if we exit using a `yield break` From 0f63ecdfa883d784dea0299fd2724f584c795ca3 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 18 Nov 2024 12:04:12 -0800 Subject: [PATCH 18/20] Use ImmutableArray --- .../AsyncIteratorMethodToStateMachineRewriter.cs | 2 +- .../AsyncMethodToStateMachineRewriter.cs | 2 +- .../IteratorMethodToStateMachineRewriter.cs | 2 +- .../MethodToStateMachineRewriter.cs | 3 ++- .../StateMachineRewriter/StateMachineRewriter.cs | 12 ++++++------ 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 042ac5ae7b960..6ebf22efb8dbf 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -56,7 +56,7 @@ internal AsyncIteratorMethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, - IOrderedReadOnlySet nonReusableFieldsForCleanup, + ImmutableArray nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index fb50388c517d2..477f599bba4a3 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -74,7 +74,7 @@ internal AsyncMethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, - IOrderedReadOnlySet nonReusableFieldsForCleanup, + ImmutableArray nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs index b8c5544592016..b726ebdf52dda 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs @@ -62,7 +62,7 @@ internal IteratorMethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, - IOrderedReadOnlySet nonReusableFieldsForCleanup, + ImmutableArray nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index c92c69b864772..5592b00ddf390 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -105,7 +105,7 @@ public MethodToStateMachineRewriter( FieldSymbol? instanceIdField, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, - IOrderedReadOnlySet nonReusableFieldsForCleanup, + ImmutableArray nonReusableFieldsForCleanup, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator? slotAllocatorOpt, @@ -117,6 +117,7 @@ public MethodToStateMachineRewriter( Debug.Assert(originalMethod != null); Debug.Assert(state != null); Debug.Assert(nonReusableLocalProxies != null); + Debug.Assert(!nonReusableFieldsForCleanup.IsDefault); Debug.Assert(diagnostics != null); Debug.Assert(hoistedVariables != null); Debug.Assert(nextFreeHoistedLocalSlot >= 0); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs index 2380a1b0c565f..a6911a94549f4 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs @@ -28,7 +28,7 @@ internal abstract class StateMachineRewriter protected FieldSymbol? stateField; protected FieldSymbol? instanceIdField; protected IReadOnlyDictionary? nonReusableLocalProxies; - protected IOrderedReadOnlySet? nonReusableFieldsForCleanup; + protected ImmutableArray nonReusableFieldsForCleanup; protected int nextFreeHoistedLocalSlot; protected IOrderedReadOnlySet? hoistedVariables; protected Dictionary? initialParameters; @@ -123,10 +123,9 @@ protected BoundStatement Rewrite() return new BoundBadStatement(F.Syntax, ImmutableArray.Empty, hasErrors: true); } - CreateNonReusableLocalProxies(variablesToHoist, out this.nonReusableLocalProxies, out var nonReusableFieldsForCleanup, out this.nextFreeHoistedLocalSlot); + CreateNonReusableLocalProxies(variablesToHoist, out this.nonReusableLocalProxies, out this.nonReusableFieldsForCleanup, out this.nextFreeHoistedLocalSlot); this.hoistedVariables = variablesToHoist; - this.nonReusableFieldsForCleanup = nonReusableFieldsForCleanup; GenerateMethodImplementations(); @@ -137,11 +136,11 @@ protected BoundStatement Rewrite() private void CreateNonReusableLocalProxies( IEnumerable variablesToHoist, out IReadOnlyDictionary proxies, - out OrderedSet nonReusableFieldsForCleanup, + out ImmutableArray nonReusableFieldsForCleanup, out int nextFreeHoistedLocalSlot) { var proxiesBuilder = new Dictionary(); - nonReusableFieldsForCleanup = new OrderedSet(); + var nonReusableFieldsForCleanupBuilder = ArrayBuilder.GetInstance(); var typeMap = stateMachineType.TypeMap; bool isDebugBuild = F.Compilation.Options.OptimizationLevel == OptimizationLevel.Debug; @@ -224,7 +223,7 @@ private void CreateNonReusableLocalProxies( string fieldName = GeneratedNames.MakeHoistedLocalFieldName(synthesizedKind, slotIndex, local.Name); field = F.StateMachineField(fieldType, fieldName, new LocalSlotDebugInfo(synthesizedKind, id), slotIndex); - nonReusableFieldsForCleanup.Add(field); + nonReusableFieldsForCleanupBuilder.Add(field); } if (field != null) @@ -266,6 +265,7 @@ private void CreateNonReusableLocalProxies( } proxies = proxiesBuilder; + nonReusableFieldsForCleanup = nonReusableFieldsForCleanupBuilder.ToImmutableAndFree(); } private bool ShouldPreallocateNonReusableProxy(LocalSymbol local) From 5529fd62f521136c2aecc356369d8393808cd960 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 18 Nov 2024 12:20:38 -0800 Subject: [PATCH 19/20] usings --- .../AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs | 1 - .../Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs | 1 - .../IteratorRewriter/IteratorMethodToStateMachineRewriter.cs | 1 - .../StateMachineRewriter/MethodToStateMachineRewriter.cs | 1 - 4 files changed, 4 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 6ebf22efb8dbf..c798e8da909df 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -6,7 +6,6 @@ using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CodeGen; -using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index 477f599bba4a3..cd922695633ba 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.CodeGen; -using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Emit; diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs index b726ebdf52dda..f022c87dd9e40 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs @@ -12,7 +12,6 @@ using Roslyn.Utilities; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.Emit; -using Microsoft.CodeAnalysis.Collections; namespace Microsoft.CodeAnalysis.CSharp { diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 5592b00ddf390..6fc3c598986ff 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis.CodeGen; -using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Emit; From 57cafd72c1599594d38c861571ded26369218ac2 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 19 Nov 2024 08:49:43 -0800 Subject: [PATCH 20/20] Address feedback --- .../AsyncIteratorMethodToStateMachineRewriter.cs | 2 +- .../AsyncRewriter/AsyncMethodToStateMachineRewriter.cs | 6 +++--- .../StateMachineRewriter/MethodToStateMachineRewriter.cs | 7 ++----- src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs | 1 - 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index c798e8da909df..496c04f657904 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -90,7 +90,7 @@ internal AsyncIteratorMethodToStateMachineRewriter( return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; } - protected override BoundStatement GenerateHoistedLocalsCleanupForExit(ImmutableArray rootHoistedLocals) + protected override BoundStatement GenerateCleanupForExit(ImmutableArray rootHoistedLocals) { // We need to clean nested hoisted local variables too (not just top-level ones) // as they are not cleaned when exiting a block if we exit using a `yield break` diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index cd922695633ba..585ec65c29724 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -178,7 +178,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) // The remaining code is hidden to hide the fact that it can run concurrently with the task's continuation } - bodyBuilder.Add(GenerateHoistedLocalsCleanupForExit(rootScopeHoistedLocals)); + bodyBuilder.Add(GenerateCleanupForExit(rootScopeHoistedLocals)); bodyBuilder.Add(GenerateSetResultCall()); @@ -239,7 +239,7 @@ BoundCatchBlock generateExceptionHandling(LocalSymbol exceptionLocal, ImmutableA exceptionFilterOpt: null, body: F.Block( assignFinishedState, // _state = finishedState; - GenerateHoistedLocalsCleanupForExit(rootHoistedLocals), + GenerateCleanupForExit(rootHoistedLocals), callSetException, // builder.SetException(ex); OR _promiseOfValueOrEnd.SetException(ex); GenerateReturn(false)), // return; isSynthesizedAsyncCatchAll: true); @@ -261,7 +261,7 @@ protected virtual BoundStatement GenerateSetResultCall() : ImmutableArray.Empty)); } - protected virtual BoundStatement GenerateHoistedLocalsCleanupForExit(ImmutableArray rootHoistedLocals) + protected virtual BoundStatement GenerateCleanupForExit(ImmutableArray rootHoistedLocals) { var builder = ArrayBuilder.GetInstance(); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index 6fc3c598986ff..4221e9de09565 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -135,11 +135,8 @@ public MethodToStateMachineRewriter( this.proxies.Add(proxy.Key, proxy.Value); } - _fieldsForCleanup = new ArrayBuilder(); - foreach (FieldSymbol fieldForCleanup in nonReusableFieldsForCleanup) - { - _fieldsForCleanup.Add(fieldForCleanup); - } + _fieldsForCleanup = new ArrayBuilder(nonReusableFieldsForCleanup.Length); + _fieldsForCleanup.AddRange(nonReusableFieldsForCleanup); // create cache local for reference type "this" in Release var thisParameter = originalMethod.ThisParameter; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs index a42df2393ef9f..5ab7b180a4923 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs @@ -3033,7 +3033,6 @@ .maxstack 0 } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75666")] - public void AddVariableCleanup_StringLocal() { string src = """