提交 2af841cc 编写于 作者: C Charles Stoner

Merge pull request #1102 from cston/1115030

Add hoisted catch block exception to the local scope so the local is available to the EE
......@@ -893,6 +893,12 @@ private void EmitCatchBlock(BoundCatchBlock catchBlock)
Debug.Assert(!left.FieldSymbol.IsStatic, "Not supported");
Debug.Assert(!left.ReceiverOpt.Type.IsTypeParameter());
var stateMachineField = left.FieldSymbol as StateMachineFieldSymbol;
if (((object)stateMachineField != null) && (stateMachineField.SlotIndex >= 0))
{
_builder.DefineUserDefinedStateMachineHoistedLocal(stateMachineField.SlotIndex);
}
// When assigning to a field
// we need to push param address below the exception
var temp = AllocateTemp(exceptionSource.Type, exceptionSource.Syntax);
......
......@@ -1470,6 +1470,7 @@ .maxstack 3
<forward declaringType=""C"" methodName=""F"" />
<hoistedLocalScopes>
<slot startOffset=""0xe"" endOffset=""0xed"" />
<slot startOffset=""0x29"" endOffset=""0x32"" />
</hoistedLocalScopes>
<encLocalSlotMap>
<slot kind=""27"" offset=""0"" />
......
......@@ -344,6 +344,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
Case BoundKind.FieldAccess
Dim left = DirectCast(exceptionSource, BoundFieldAccess)
If Not left.FieldSymbol.IsShared Then
Dim stateMachineField = TryCast(left.FieldSymbol, StateMachineFieldSymbol)
If (stateMachineField IsNot Nothing) AndAlso (stateMachineField.SlotIndex >= 0) Then
DefineUserDefinedStateMachineHoistedLocal(stateMachineField)
End If
' When assigning to a field
' we need to push param address below the exception
Dim temp = AllocateTemp(exceptionSource.Type, exceptionSource.Syntax)
......@@ -1414,30 +1420,28 @@ OtherExpressions:
' 817 // we skip loading this lifted field since it is out of scope.
For Each field In scope.Fields
Dim name As String = Nothing
Dim index As Integer = 0
Dim parsedOk As Boolean = GeneratedNames.TryParseStateMachineHoistedUserVariableName(field.Name, name, index)
Debug.Assert(parsedOk)
Debug.Assert(index >= 0)
If parsedOk Then
Dim fakePdbOnlyLocal = New LocalDefinition(
DefineUserDefinedStateMachineHoistedLocal(DirectCast(field, StateMachineFieldSymbol))
Next
EmitStatement(scope.Statement)
_builder.CloseLocalScope()
End Sub
Private Sub DefineUserDefinedStateMachineHoistedLocal(field As StateMachineFieldSymbol)
Debug.Assert(field.SlotIndex >= 0)
Dim fakePdbOnlyLocal = New LocalDefinition(
symbolOpt:=Nothing,
nameOpt:=field.Name,
type:=Nothing,
slot:=index,
slot:=field.SlotIndex,
synthesizedKind:=SynthesizedLocalKind.EmitterTemp,
id:=Nothing,
pdbAttributes:=Cci.PdbWriter.DefaultLocalAttributesValue,
constraints:=LocalSlotConstraints.None,
isDynamic:=False,
dynamicTransformFlags:=Nothing)
_builder.AddLocalToScope(fakePdbOnlyLocal)
End If
Next
EmitStatement(scope.Statement)
_builder.CloseLocalScope()
_builder.AddLocalToScope(fakePdbOnlyLocal)
End Sub
Private Sub EmitUnstructuredExceptionResumeSwitch(node As BoundUnstructuredExceptionResumeSwitch)
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.Cci
Imports Microsoft.CodeAnalysis.CodeGen
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic
''' <summary>
''' Represents a synthesized state machine helper field.
''' </summary>
Friend Class StateMachineFieldSymbol
Friend NotInheritable Class StateMachineFieldSymbol
Inherits SynthesizedFieldSymbol
Implements ISynthesizedMethodBodyImplementationSymbol
......
......@@ -2333,7 +2333,7 @@ .maxstack 1
}
[WorkItem(1115030)]
[Fact(Skip = "1115030")]
[Fact]
public void CatchInAsyncStateMachine()
{
var source =
......@@ -2392,6 +2392,69 @@ .maxstack 1
locals.Free();
}
[WorkItem(1115030)]
[Fact]
public void CatchInIteratorStateMachine()
{
var source =
@"using System;
using System.Collections;
class C
{
static object F()
{
throw new ArgumentException();
}
static IEnumerable M()
{
object o;
try
{
o = F();
}
catch (Exception e)
{
#line 999
o = e;
}
yield return o;
}
}";
var compilation0 = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
var runtime = CreateRuntimeInstance(compilation0);
var context = CreateMethodContext(
runtime,
methodName: "C.<M>d__1.MoveNext",
atLineNumber: 999);
var testData = new CompilationTestData();
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
VerifyLocal(testData, typeName, locals[0], "<>m0", "o", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""object C.<M>d__1.<o>5__1""
IL_0006: ret
}");
VerifyLocal(testData, typeName, locals[1], "<>m1", "e", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
bool V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""System.Exception C.<M>d__1.<e>5__2""
IL_0006: ret
}");
locals.Free();
}
[WorkItem(947)]
[Fact]
public void DuplicateEditorBrowsableAttributes()
......
......@@ -2356,7 +2356,7 @@ End Class
End Sub
<WorkItem(1115030)>
<Fact(Skip:="1115030")>
<Fact>
Public Sub CatchInAsyncStateMachine()
Const source =
"Imports System
......@@ -2414,6 +2414,66 @@ End Class"
locals.Free()
End Sub
<WorkItem(1115030)>
<Fact>
Public Sub CatchInIteratorStateMachine()
Const source =
"Imports System
Imports System.Collections
Class C
Shared Function F() As Object
Throw New ArgumentException()
End Function
Shared Iterator Function M() As IEnumerable
Dim o As Object
Try
o = F()
Catch e As Exception
#ExternalSource(""test"", 999)
o = e
#End ExternalSource
End Try
Yield o
End Function
End Class"
Dim comp = CreateCompilationWithReferences(
MakeSources(source),
{MscorlibRef_v4_0_30316_17626, MsvbRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929},
TestOptions.DebugDll)
Dim runtime = CreateRuntimeInstance(comp)
Dim context = CreateMethodContext(
runtime,
methodName:="C.VB$StateMachine_2_M.MoveNext",
atLineNumber:=999)
Dim testData = New CompilationTestData()
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim typeName As String = Nothing
Dim assembly = context.CompileGetLocals(locals, argumentsOnly:=False, typeName:=typeName, testData:=testData)
VerifyLocal(testData, typeName, locals(0), "<>m0", "o", expectedILOpt:=
"{
// Code size 7 (0x7)
.maxstack 1
.locals init (Boolean V_0,
Integer V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""C.VB$StateMachine_2_M.$VB$ResumableLocal_o$0 As Object""
IL_0006: ret
}")
VerifyLocal(testData, typeName, locals(1), "<>m1", "e", expectedILOpt:=
"{
// Code size 7 (0x7)
.maxstack 1
.locals init (Boolean V_0,
Integer V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""C.VB$StateMachine_2_M.$VB$ResumableLocal_e$1 As System.Exception""
IL_0006: ret
}")
locals.Free()
End Sub
<WorkItem(947)>
<Fact>
Public Sub DuplicateEditorBrowsableAttributes()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册