diff --git a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb index d00ff85c332ca..d67f29bc420c9 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb @@ -66,13 +66,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic builder As FieldSymbol, hoistedVariables As IReadOnlySet(Of Symbol), nonReusableLocalProxies As Dictionary(Of Symbol, CapturedSymbolOrExpression), - synthesizedLocalOrdinals As SynthesizedLocalOrdinalsDispenser, slotAllocatorOpt As VariableSlotAllocator, - nextFreeHoistedLocalSlot As Integer, owner As AsyncRewriter, diagnostics As BindingDiagnosticBag) - MyBase.New(F, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + MyBase.New(F, state, hoistedVariables, nonReusableLocalProxies, slotAllocatorOpt, diagnostics) Me._method = method Me._builder = builder diff --git a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb index 44ab8aff4fcf2..80eccb8a90524 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb @@ -250,19 +250,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Function Private Sub GenerateMoveNext(moveNextMethod As MethodSymbol) - Dim rewriter = New AsyncMethodToClassRewriter(method:=Me.Method, - F:=Me.F, - state:=Me.StateField, - builder:=Me._builderField, - hoistedVariables:=Me.hoistedVariables, - nonReusableLocalProxies:=Me.nonReusableLocalProxies, - synthesizedLocalOrdinals:=Me.SynthesizedLocalOrdinals, - slotAllocatorOpt:=Me.SlotAllocatorOpt, - nextFreeHoistedLocalSlot:=Me.nextFreeHoistedLocalSlot, - owner:=Me, - diagnostics:=Diagnostics) - - rewriter.GenerateMoveNext(Me.Body, moveNextMethod) + Dim rewriter = New AsyncMethodToClassRewriter( + method:=Method, + F:=F, + state:=StateField, + builder:=_builderField, + hoistedVariables:=hoistedVariables, + nonReusableLocalProxies:=nonReusableLocalProxies, + slotAllocatorOpt:=SlotAllocatorOpt, + owner:=Me, + diagnostics:=Diagnostics) + + rewriter.GenerateMoveNext(Body, moveNextMethod) End Sub Friend Overrides Function RewriteBodyIfNeeded(body As BoundStatement, topMethod As MethodSymbol, currentMethod As MethodSymbol) As BoundStatement diff --git a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb index 91e05f949170d..ce00cd5b7bf72 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb @@ -24,20 +24,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Private _methodValue As LocalSymbol Private _tryNestingLevel As Integer - Friend Sub New(method As MethodSymbol, - F As SyntheticBoundNodeFactory, + Friend Sub New(F As SyntheticBoundNodeFactory, state As FieldSymbol, current As FieldSymbol, hoistedVariables As IReadOnlySet(Of Symbol), localProxies As Dictionary(Of Symbol, FieldSymbol), - SynthesizedLocalOrdinals As SynthesizedLocalOrdinalsDispenser, slotAllocatorOpt As VariableSlotAllocator, - nextFreeHoistedLocalSlot As Integer, diagnostics As BindingDiagnosticBag) - MyBase.New(F, state, hoistedVariables, localProxies, SynthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + MyBase.New(F, state, hoistedVariables, localProxies, slotAllocatorOpt, diagnostics) - Me._current = current + _current = current End Sub Public Sub GenerateMoveNextAndDispose(Body As BoundStatement, diff --git a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb index 355bbf36b7af8..e5d4b2b0bc25f 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb @@ -341,16 +341,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Property Private Sub GenerateMoveNextAndDispose(moveNextMethod As SynthesizedMethod, disposeMethod As SynthesizedMethod) - Dim rewriter = New IteratorMethodToClassRewriter(method:=Me.Method, - F:=Me.F, - state:=Me.StateField, - current:=Me._currentField, - hoistedVariables:=Me.hoistedVariables, - localProxies:=Me.nonReusableLocalProxies, - SynthesizedLocalOrdinals:=Me.SynthesizedLocalOrdinals, - slotAllocatorOpt:=Me.SlotAllocatorOpt, - nextFreeHoistedLocalSlot:=Me.nextFreeHoistedLocalSlot, - diagnostics:=Diagnostics) + Dim rewriter = New IteratorMethodToClassRewriter( + F:=F, + state:=StateField, + current:=_currentField, + hoistedVariables:=hoistedVariables, + localProxies:=nonReusableLocalProxies, + slotAllocatorOpt:=SlotAllocatorOpt, + diagnostics:=Diagnostics) rewriter.GenerateMoveNextAndDispose(Body, moveNextMethod, disposeMethod) End Sub diff --git a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb index 2de9fcd320811..7003970ca9c60 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb @@ -16,7 +16,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Inherits MethodToClassRewriter(Of TProxy) Protected Friend ReadOnly F As SyntheticBoundNodeFactory - Protected NextState As Integer = 0 + Protected NextState As Integer = StateMachineStates.InitialIteratorState + Protected NextFinalizerState As Integer = StateMachineStates.FirstIteratorFinalizeState ''' ''' The "state" of the state machine that is the translation of the iterator method. @@ -64,16 +65,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ''' Private ReadOnly _hoistedVariables As IReadOnlySet(Of Symbol) = Nothing - Private ReadOnly _synthesizedLocalOrdinals As SynthesizedLocalOrdinalsDispenser - Private ReadOnly _nextFreeHoistedLocalSlot As Integer - Public Sub New(F As SyntheticBoundNodeFactory, stateField As FieldSymbol, hoistedVariables As IReadOnlySet(Of Symbol), initialProxies As Dictionary(Of Symbol, TProxy), - synthesizedLocalOrdinals As SynthesizedLocalOrdinalsDispenser, slotAllocatorOpt As VariableSlotAllocator, - nextFreeHoistedLocalSlot As Integer, diagnostics As BindingDiagnosticBag) MyBase.New(slotAllocatorOpt, F.CompilationState, diagnostics, preserveOriginalLocals:=False) @@ -82,15 +78,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Debug.Assert(stateField IsNot Nothing) Debug.Assert(hoistedVariables IsNot Nothing) Debug.Assert(initialProxies IsNot Nothing) - Debug.Assert(nextFreeHoistedLocalSlot >= 0) Debug.Assert(diagnostics IsNot Nothing) Me.F = F Me.StateField = stateField Me.CachedState = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int32), SynthesizedLocalKind.StateMachineCachedState, F.Syntax) Me._hoistedVariables = hoistedVariables - Me._synthesizedLocalOrdinals = synthesizedLocalOrdinals - Me._nextFreeHoistedLocalSlot = nextFreeHoistedLocalSlot For Each p In initialProxies Me.Proxies.Add(p.Key, p.Value) @@ -153,8 +146,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If If Not Me._hasFinalizerState Then - Me._currentFinalizerState = Me.NextState - Me.NextState += 1 + Me._currentFinalizerState = Me.NextFinalizerState + Me.NextFinalizerState -= 1 Me._hasFinalizerState = True End If diff --git a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineStates.vb b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineStates.vb index 0d427fa25e6bf..37c44a7f4a81e 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineStates.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineStates.vb @@ -9,10 +9,12 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic - Friend Module StateMachineStates - Public FinishedStateMachine As Integer = -2 - Public NotStartedStateMachine As Integer = -1 - Public FirstUnusedState As Integer = 0 - End Module + Friend NotInheritable Class StateMachineStates + Public Const FirstIteratorFinalizeState As Integer = -3 + Public Const InitialIteratorState As Integer = 0 + Public Const FinishedStateMachine As Integer = -2 + Public Const NotStartedStateMachine As Integer = -1 + Public Const FirstUnusedState As Integer = 0 + End Class End Namespace diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb index b7bb966fc5357..5d2a3784c0724 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb @@ -1628,7 +1628,7 @@ End Module c.VerifyIL("Form1.VB$StateMachine_1_f.MoveNext", ) End Sub diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb index f580e60a704a1..30a10a1236414 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIterators.vb @@ -627,7 +627,7 @@ End Module CompileAndVerify(source, expectedOutput:="12345").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", ).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", ).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", ) End Sub diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.vb index c5e5054703328..3d530b740ddf1 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.vb @@ -590,7 +590,7 @@ End Class Dim v0 = CompileAndVerify(compilation:=compilation0) v0.VerifyIL("C.VB$StateMachine_2_M.MoveNext()", " { - // Code size 192 (0xc0) + // Code size 204 (0xcc) .maxstack 3 .locals init (Boolean V_0, Integer V_1) @@ -598,104 +598,108 @@ End Class IL_0001: ldfld ""C.VB$StateMachine_2_M.$State As Integer"" IL_0006: stloc.1 IL_0007: ldloc.1 - IL_0008: switch ( - IL_001f, - IL_0021, - IL_0021, - IL_0023) - IL_001d: br.s IL_0028 - IL_001f: br.s IL_002a - IL_0021: br.s IL_0046 - IL_0023: br IL_00b3 - IL_0028: ldc.i4.0 - IL_0029: ret - IL_002a: ldarg.0 - IL_002b: ldc.i4.m1 - IL_002c: dup - IL_002d: stloc.1 - IL_002e: stfld ""C.VB$StateMachine_2_M.$State As Integer"" - IL_0033: nop - IL_0034: nop + IL_0008: ldc.i4.s -3 + IL_000a: sub + IL_000b: switch ( + IL_002a, + IL_0033, + IL_0033, + IL_002c, + IL_002a, + IL_002e) + IL_0028: br.s IL_0033 + IL_002a: br.s IL_0051 + IL_002c: br.s IL_0035 + IL_002e: br IL_00bf + IL_0033: ldc.i4.0 + IL_0034: ret IL_0035: ldarg.0 - IL_0036: ldarg.0 - IL_0037: ldfld ""C.VB$StateMachine_2_M.$VB$Me As C"" - IL_003c: callvirt ""Function C.F() As System.IDisposable"" - IL_0041: stfld ""C.VB$StateMachine_2_M.$S0 As System.IDisposable"" - IL_0046: nop + IL_0036: ldc.i4.m1 + IL_0037: dup + IL_0038: stloc.1 + IL_0039: stfld ""C.VB$StateMachine_2_M.$State As Integer"" + IL_003e: nop + IL_003f: nop + IL_0040: ldarg.0 + IL_0041: ldarg.0 + IL_0042: ldfld ""C.VB$StateMachine_2_M.$VB$Me As C"" + IL_0047: callvirt ""Function C.F() As System.IDisposable"" + IL_004c: stfld ""C.VB$StateMachine_2_M.$S0 As System.IDisposable"" + IL_0051: nop .try { - IL_0047: ldloc.1 - IL_0048: ldc.i4.1 - IL_0049: beq.s IL_0053 - IL_004b: br.s IL_004d - IL_004d: ldloc.1 - IL_004e: ldc.i4.2 - IL_004f: beq.s IL_0055 - IL_0051: br.s IL_0057 - IL_0053: br.s IL_007a - IL_0055: br.s IL_0059 - IL_0057: br.s IL_0066 - IL_0059: ldarg.0 - IL_005a: ldc.i4.m1 - IL_005b: dup - IL_005c: stloc.1 - IL_005d: stfld ""C.VB$StateMachine_2_M.$State As Integer"" - IL_0062: ldc.i4.1 - IL_0063: stloc.0 - IL_0064: leave.s IL_00be - IL_0066: ldarg.0 - IL_0067: ldc.i4.1 - IL_0068: stfld ""C.VB$StateMachine_2_M.$Current As Integer"" - IL_006d: ldarg.0 + IL_0052: ldloc.1 + IL_0053: ldc.i4.s -3 + IL_0055: beq.s IL_005f + IL_0057: br.s IL_0059 + IL_0059: ldloc.1 + IL_005a: ldc.i4.1 + IL_005b: beq.s IL_0061 + IL_005d: br.s IL_0063 + IL_005f: br.s IL_0065 + IL_0061: br.s IL_0086 + IL_0063: br.s IL_0072 + IL_0065: ldarg.0 + IL_0066: ldc.i4.m1 + IL_0067: dup + IL_0068: stloc.1 + IL_0069: stfld ""C.VB$StateMachine_2_M.$State As Integer"" IL_006e: ldc.i4.1 - IL_006f: dup - IL_0070: stloc.1 - IL_0071: stfld ""C.VB$StateMachine_2_M.$State As Integer"" - IL_0076: ldc.i4.1 - IL_0077: stloc.0 - IL_0078: leave.s IL_00be - IL_007a: ldarg.0 - IL_007b: ldc.i4.m1 - IL_007c: dup - IL_007d: stloc.1 - IL_007e: stfld ""C.VB$StateMachine_2_M.$State As Integer"" - IL_0083: leave.s IL_00a1 + IL_006f: stloc.0 + IL_0070: leave.s IL_00ca + IL_0072: ldarg.0 + IL_0073: ldc.i4.1 + IL_0074: stfld ""C.VB$StateMachine_2_M.$Current As Integer"" + IL_0079: ldarg.0 + IL_007a: ldc.i4.1 + IL_007b: dup + IL_007c: stloc.1 + IL_007d: stfld ""C.VB$StateMachine_2_M.$State As Integer"" + IL_0082: ldc.i4.1 + IL_0083: stloc.0 + IL_0084: leave.s IL_00ca + IL_0086: ldarg.0 + IL_0087: ldc.i4.m1 + IL_0088: dup + IL_0089: stloc.1 + IL_008a: stfld ""C.VB$StateMachine_2_M.$State As Integer"" + IL_008f: leave.s IL_00ad } finally { - IL_0085: ldloc.1 - IL_0086: ldc.i4.0 - IL_0087: bge.s IL_00a0 - IL_0089: nop - IL_008a: ldarg.0 - IL_008b: ldfld ""C.VB$StateMachine_2_M.$S0 As System.IDisposable"" - IL_0090: brfalse.s IL_009e - IL_0092: ldarg.0 - IL_0093: ldfld ""C.VB$StateMachine_2_M.$S0 As System.IDisposable"" - IL_0098: callvirt ""Sub System.IDisposable.Dispose()"" - IL_009d: nop - IL_009e: br.s IL_00a0 - IL_00a0: endfinally + IL_0091: ldloc.1 + IL_0092: ldc.i4.0 + IL_0093: bge.s IL_00ac + IL_0095: nop + IL_0096: ldarg.0 + IL_0097: ldfld ""C.VB$StateMachine_2_M.$S0 As System.IDisposable"" + IL_009c: brfalse.s IL_00aa + IL_009e: ldarg.0 + IL_009f: ldfld ""C.VB$StateMachine_2_M.$S0 As System.IDisposable"" + IL_00a4: callvirt ""Sub System.IDisposable.Dispose()"" + IL_00a9: nop + IL_00aa: br.s IL_00ac + IL_00ac: endfinally } - IL_00a1: ldarg.0 - IL_00a2: ldc.i4.2 - IL_00a3: stfld ""C.VB$StateMachine_2_M.$Current As Integer"" - IL_00a8: ldarg.0 - IL_00a9: ldc.i4.3 - IL_00aa: dup - IL_00ab: stloc.1 - IL_00ac: stfld ""C.VB$StateMachine_2_M.$State As Integer"" - IL_00b1: ldc.i4.1 - IL_00b2: ret - IL_00b3: ldarg.0 - IL_00b4: ldc.i4.m1 - IL_00b5: dup - IL_00b6: stloc.1 - IL_00b7: stfld ""C.VB$StateMachine_2_M.$State As Integer"" - IL_00bc: ldc.i4.0 - IL_00bd: ret - IL_00be: ldloc.0 - IL_00bf: ret + IL_00ad: ldarg.0 + IL_00ae: ldc.i4.2 + IL_00af: stfld ""C.VB$StateMachine_2_M.$Current As Integer"" + IL_00b4: ldarg.0 + IL_00b5: ldc.i4.2 + IL_00b6: dup + IL_00b7: stloc.1 + IL_00b8: stfld ""C.VB$StateMachine_2_M.$State As Integer"" + IL_00bd: ldc.i4.1 + IL_00be: ret + IL_00bf: ldarg.0 + IL_00c0: ldc.i4.m1 + IL_00c1: dup + IL_00c2: stloc.1 + IL_00c3: stfld ""C.VB$StateMachine_2_M.$State As Integer"" + IL_00c8: ldc.i4.0 + IL_00c9: ret + IL_00ca: ldloc.0 + IL_00cb: ret } ") v0.VerifyPdb("C+VB$StateMachine_2_M.MoveNext", " @@ -713,19 +717,19 @@ End Class - +