提交 12a04c7d 编写于 作者: K Kevin Halverson

Merge pull request #2315 from KevinH-MS/LocalsInAsyncLambdas

Fix Locals in async lambdas...
......@@ -619,7 +619,7 @@ private static BoundStatement BindAssignment(Binder binder, ExpressionSyntax syn
BinderFlags.UncheckedRegion |
BinderFlags.AllowManagedAddressOf |
BinderFlags.AllowAwaitInUnsafeContext);
var hasImports = !importRecordGroups.IsDefault;
var hasImports = !importRecordGroups.IsDefaultOrEmpty;
var numImportStringGroups = hasImports ? importRecordGroups.Length : 0;
var currentStringGroup = numImportStringGroups - 1;
......
......@@ -21,56 +21,59 @@ internal static class SymUnmanagedReaderExtensions
var importStringGroups = reader.GetCSharpGroupedImportStrings(methodToken, methodVersion, out externAliasStrings);
Debug.Assert(importStringGroups.IsDefault == externAliasStrings.IsDefault);
if (importStringGroups.IsDefault)
ArrayBuilder<ImmutableArray<ImportRecord>> importRecordGroupBuilder = null;
ArrayBuilder<ExternAliasRecord> externAliasRecordBuilder = null;
if (!importStringGroups.IsDefault)
{
return default(MethodDebugInfo);
}
var importRecordGroupBuilder = ArrayBuilder<ImmutableArray<ImportRecord>>.GetInstance(importStringGroups.Length);
foreach (var importStringGroup in importStringGroups)
{
var groupBuilder = ArrayBuilder<ImportRecord>.GetInstance(importStringGroup.Length);
foreach (var importString in importStringGroup)
importRecordGroupBuilder = ArrayBuilder<ImmutableArray<ImportRecord>>.GetInstance(importStringGroups.Length);
foreach (var importStringGroup in importStringGroups)
{
ImportRecord record;
if (NativeImportRecord.TryCreateFromCSharpImportString(importString, out record))
var groupBuilder = ArrayBuilder<ImportRecord>.GetInstance(importStringGroup.Length);
foreach (var importString in importStringGroup)
{
groupBuilder.Add(record);
}
else
{
Debug.WriteLine($"Failed to parse import string {importString}");
ImportRecord record;
if (NativeImportRecord.TryCreateFromCSharpImportString(importString, out record))
{
groupBuilder.Add(record);
}
else
{
Debug.WriteLine($"Failed to parse import string {importString}");
}
}
importRecordGroupBuilder.Add(groupBuilder.ToImmutableAndFree());
}
importRecordGroupBuilder.Add(groupBuilder.ToImmutableAndFree());
}
var externAliasRecordBuilder = ArrayBuilder<ExternAliasRecord>.GetInstance(externAliasStrings.Length);
foreach (string externAliasString in externAliasStrings)
{
string alias;
string externAlias;
string target;
ImportTargetKind kind;
if (!CustomDebugInfoReader.TryParseCSharpImportString(externAliasString, out alias, out externAlias, out target, out kind))
if (!externAliasStrings.IsDefault)
{
Debug.WriteLine($"Unable to parse extern alias '{externAliasString}'");
continue;
}
externAliasRecordBuilder = ArrayBuilder<ExternAliasRecord>.GetInstance(externAliasStrings.Length);
foreach (string externAliasString in externAliasStrings)
{
string alias;
string externAlias;
string target;
ImportTargetKind kind;
if (!CustomDebugInfoReader.TryParseCSharpImportString(externAliasString, out alias, out externAlias, out target, out kind))
{
Debug.WriteLine($"Unable to parse extern alias '{externAliasString}'");
continue;
}
Debug.Assert(kind == ImportTargetKind.Assembly, "Programmer error: How did a non-assembly get in the extern alias list?");
Debug.Assert(alias != null); // Name of the extern alias.
Debug.Assert(externAlias == null); // Not used.
Debug.Assert(target != null); // Name of the target assembly.
Debug.Assert(kind == ImportTargetKind.Assembly, "Programmer error: How did a non-assembly get in the extern alias list?");
Debug.Assert(alias != null); // Name of the extern alias.
Debug.Assert(externAlias == null); // Not used.
Debug.Assert(target != null); // Name of the target assembly.
AssemblyIdentity targetIdentity;
if (!AssemblyIdentity.TryParseDisplayName(target, out targetIdentity))
{
Debug.WriteLine($"Unable to parse target of extern alias '{externAliasString}'");
continue;
}
AssemblyIdentity targetIdentity;
if (!AssemblyIdentity.TryParseDisplayName(target, out targetIdentity))
{
Debug.WriteLine($"Unable to parse target of extern alias '{externAliasString}'");
continue;
}
externAliasRecordBuilder.Add(new NativeExternAliasRecord<AssemblySymbol>(alias, targetIdentity));
externAliasRecordBuilder.Add(new NativeExternAliasRecord<AssemblySymbol>(alias, targetIdentity));
}
}
}
var hoistedLocalScopeRecords = ImmutableArray<HoistedLocalScopeRecord>.Empty;
......@@ -97,11 +100,10 @@ internal static class SymUnmanagedReaderExtensions
out dynamicLocalConstantMap);
}
return new MethodDebugInfo(
hoistedLocalScopeRecords,
importRecordGroupBuilder.ToImmutableAndFree(),
externAliasRecordBuilder.ToImmutableAndFree(),
importRecordGroupBuilder?.ToImmutableAndFree() ?? ImmutableArray<ImmutableArray<ImportRecord>>.Empty,
externAliasRecordBuilder?.ToImmutableAndFree() ?? ImmutableArray<ExternAliasRecord>.Empty,
dynamicLocalMap,
dynamicLocalConstantMap,
defaultNamespaceName: ""); // Unused in C#.
......
......@@ -1588,6 +1588,54 @@ .maxstack 1
locals.Free();
}
[WorkItem(2240)]
[Fact]
public void AsyncLambda()
{
var source =
@"using System;
using System.Threading.Tasks;
class C
{
static void M()
{
Func<int, Task> f = async (x) =>
{
var y = 42;
};
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll);
var runtime = CreateRuntimeInstance(compilation);
var context = CreateMethodContext(runtime, methodName: "C.<>c.<<M>b__0_0>d.MoveNext");
var locals = ArrayBuilder<LocalAndMethod>.GetInstance();
string typeName;
var testData = new CompilationTestData();
context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData);
Assert.Equal(locals.Count, 2);
VerifyLocal(testData, "<>x", locals[0], "<>m0", "x", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c.<<M>b__0_0>d.x""
IL_0006: ret
}");
VerifyLocal(testData, "<>x", locals[1], "<>m1", "y", expectedILOpt:
@"{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0,
System.Exception V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<>c.<<M>b__0_0>d.<y>5__1""
IL_0006: ret
}");
locals.Free();
}
[WorkItem(996571)]
[Fact]
public void MissingReference()
......
......@@ -1647,6 +1647,58 @@ End Class"
locals.Free()
End Sub
<WorkItem(2240)>
<Fact>
Public Sub AsyncLambda()
Const source =
"Imports System
Imports System.Threading.Tasks
Class C
Shared Sub M()
Dim f As Func(Of Integer, Task) = Async Function (x)
Dim y = 42
End Function
End Sub
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._Closure$__.VB$StateMachine___Lambda$__1-0.MoveNext")
Dim testData As New CompilationTestData()
Dim locals = ArrayBuilder(Of LocalAndMethod).GetInstance()
Dim typeName As String = Nothing
context.CompileGetLocals(locals, argumentsOnly:=False, typeName:=typeName, testData:=testData)
Assert.Equal(2, locals.Count)
VerifyLocal(testData, typeName, locals(0), "<>m0", "x", expectedILOpt:=
"{
// Code size 7 (0x7)
.maxstack 1
.locals init (Integer V_0,
System.Threading.Tasks.Task V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""C._Closure$__.VB$StateMachine___Lambda$__1-0.$VB$Local_x As Integer""
IL_0006: ret
}")
VerifyLocal(testData, typeName, locals(1), "<>m1", "y", expectedILOpt:=
"{
// Code size 7 (0x7)
.maxstack 1
.locals init (Integer V_0,
System.Threading.Tasks.Task V_1,
System.Exception V_2)
IL_0000: ldarg.0
IL_0001: ldfld ""C._Closure$__.VB$StateMachine___Lambda$__1-0.$VB$ResumableLocal_y$0 As Integer""
IL_0006: ret
}")
locals.Free()
End Sub
<WorkItem(996571)>
<Fact>
Public Sub MissingReference()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册