Skip to content

Commit

Permalink
Prepare VB iterators for EnC support (dotnet#61488)
Browse files Browse the repository at this point in the history
* Remove unused parameters

* Separate iterator finalizer states from resumable states.

* Remove unused
  • Loading branch information
tmat authored May 26, 2022
1 parent affb2c7 commit 9945a43
Show file tree
Hide file tree
Showing 9 changed files with 467 additions and 463 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

''' <summary>
''' The "state" of the state machine that is the translation of the iterator method.
Expand Down Expand Up @@ -64,16 +65,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' </summary>
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)
Expand All @@ -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)
Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
176 changes: 89 additions & 87 deletions src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ End Module

c.VerifyIL("Form1.VB$StateMachine_1_f.MoveNext", <![CDATA[
{
// Code size 233 (0xe9)
// Code size 239 (0xef)
.maxstack 3
.locals init (Integer V_0,
Integer V_1,
Expand All @@ -1641,103 +1641,105 @@ End Module
.try
{
IL_0007: ldloc.1
IL_0008: ldc.i4.1
IL_0009: pop
IL_000a: pop
IL_000b: nop
IL_0008: ldc.i4.s -3
IL_000a: beq.s IL_000e
IL_000c: ldloc.1
IL_000d: pop
IL_000e: nop
.try
{
IL_000c: ldloc.1
IL_000d: brfalse.s IL_0065
IL_000f: ldloc.1
IL_0010: ldc.i4.1
IL_0011: bne.un.s IL_0021
IL_0013: ldarg.0
IL_0014: ldc.i4.m1
IL_0015: dup
IL_0016: stloc.1
IL_0017: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_001c: leave IL_00e8
IL_0021: ldstr "2 "
IL_0026: call "Sub System.Console.Write(String)"
IL_002b: call "Function System.Threading.Tasks.Task.Yield() As System.Runtime.CompilerServices.YieldAwaitable"
IL_0030: stloc.3
IL_0031: ldloca.s V_3
IL_0033: call "Function System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter() As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0038: stloc.2
IL_0039: ldloca.s V_2
IL_003b: call "Function System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.get_IsCompleted() As Boolean"
IL_0040: brtrue.s IL_0081
IL_0042: ldarg.0
IL_0043: ldc.i4.0
IL_0044: dup
IL_0045: stloc.1
IL_0046: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_004b: ldarg.0
IL_004c: ldloc.2
IL_004d: stfld "Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0052: ldarg.0
IL_0053: ldflda "Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_0058: ldloca.s V_2
IL_005a: ldarg.0
IL_005b: call "Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).AwaitUnsafeOnCompleted(Of System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, Form1.VB$StateMachine_1_f)(ByRef System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ByRef Form1.VB$StateMachine_1_f)"
IL_0060: leave IL_00e8
IL_0065: ldarg.0
IL_0066: ldc.i4.m1
IL_0067: dup
IL_0068: stloc.1
IL_0069: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_006e: ldarg.0
IL_006f: ldfld "Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0074: stloc.2
IL_0075: ldarg.0
IL_0076: ldflda "Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_007b: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0081: ldloca.s V_2
IL_0083: call "Sub System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()"
IL_0088: ldloca.s V_2
IL_008a: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0090: ldstr "3 "
IL_0095: call "Sub System.Console.Write(String)"
IL_009a: ldc.i4.s 123
IL_009c: stloc.0
IL_009d: leave.s IL_00d2
IL_0010: ldc.i4.s -3
IL_0012: beq.s IL_0019
IL_0014: ldloc.1
IL_0015: brfalse.s IL_006b
IL_0017: br.s IL_0027
IL_0019: ldarg.0
IL_001a: ldc.i4.m1
IL_001b: dup
IL_001c: stloc.1
IL_001d: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_0022: leave IL_00ee
IL_0027: ldstr "2 "
IL_002c: call "Sub System.Console.Write(String)"
IL_0031: call "Function System.Threading.Tasks.Task.Yield() As System.Runtime.CompilerServices.YieldAwaitable"
IL_0036: stloc.3
IL_0037: ldloca.s V_3
IL_0039: call "Function System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter() As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_003e: stloc.2
IL_003f: ldloca.s V_2
IL_0041: call "Function System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.get_IsCompleted() As Boolean"
IL_0046: brtrue.s IL_0087
IL_0048: ldarg.0
IL_0049: ldc.i4.0
IL_004a: dup
IL_004b: stloc.1
IL_004c: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_0051: ldarg.0
IL_0052: ldloc.2
IL_0053: stfld "Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0058: ldarg.0
IL_0059: ldflda "Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_005e: ldloca.s V_2
IL_0060: ldarg.0
IL_0061: call "Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).AwaitUnsafeOnCompleted(Of System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, Form1.VB$StateMachine_1_f)(ByRef System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ByRef Form1.VB$StateMachine_1_f)"
IL_0066: leave IL_00ee
IL_006b: ldarg.0
IL_006c: ldc.i4.m1
IL_006d: dup
IL_006e: stloc.1
IL_006f: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_0074: ldarg.0
IL_0075: ldfld "Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_007a: stloc.2
IL_007b: ldarg.0
IL_007c: ldflda "Form1.VB$StateMachine_1_f.$A0 As System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0081: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0087: ldloca.s V_2
IL_0089: call "Sub System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()"
IL_008e: ldloca.s V_2
IL_0090: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter"
IL_0096: ldstr "3 "
IL_009b: call "Sub System.Console.Write(String)"
IL_00a0: ldc.i4.s 123
IL_00a2: stloc.0
IL_00a3: leave.s IL_00d8
}
finally
{
IL_009f: ldloc.1
IL_00a0: ldc.i4.0
IL_00a1: bge.s IL_00ad
IL_00a3: ldstr "4 "
IL_00a8: call "Sub System.Console.Write(String)"
IL_00ad: endfinally
IL_00a5: ldloc.1
IL_00a6: ldc.i4.0
IL_00a7: bge.s IL_00b3
IL_00a9: ldstr "4 "
IL_00ae: call "Sub System.Console.Write(String)"
IL_00b3: endfinally
}
}
catch System.Exception
{
IL_00ae: dup
IL_00af: call "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"
IL_00b4: stloc.s V_4
IL_00b6: ldarg.0
IL_00b7: ldc.i4.s -2
IL_00b9: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_00be: ldarg.0
IL_00bf: ldflda "Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00c4: ldloc.s V_4
IL_00c6: call "Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetException(System.Exception)"
IL_00cb: call "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"
IL_00d0: leave.s IL_00e8
IL_00b4: dup
IL_00b5: call "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"
IL_00ba: stloc.s V_4
IL_00bc: ldarg.0
IL_00bd: ldc.i4.s -2
IL_00bf: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_00c4: ldarg.0
IL_00c5: ldflda "Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00ca: ldloc.s V_4
IL_00cc: call "Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetException(System.Exception)"
IL_00d1: call "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"
IL_00d6: leave.s IL_00ee
}
IL_00d2: ldarg.0
IL_00d3: ldc.i4.s -2
IL_00d5: dup
IL_00d6: stloc.1
IL_00d7: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_00dc: ldarg.0
IL_00dd: ldflda "Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00e2: ldloc.0
IL_00e3: call "Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetResult(Integer)"
IL_00e8: ret
IL_00d8: ldarg.0
IL_00d9: ldc.i4.s -2
IL_00db: dup
IL_00dc: stloc.1
IL_00dd: stfld "Form1.VB$StateMachine_1_f.$State As Integer"
IL_00e2: ldarg.0
IL_00e3: ldflda "Form1.VB$StateMachine_1_f.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer)"
IL_00e8: ldloc.0
IL_00e9: call "Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Integer).SetResult(Integer)"
IL_00ee: ret
}
]]>)
End Sub
Expand Down
Loading

0 comments on commit 9945a43

Please sign in to comment.