/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/StaticLocalsTests.vb
302 строки
11 KB
Tomáš Matoušek
Improve handling bad metadata in EE (#76878)
23 янв 2025, 23:41
Не верифицирован
23 янв 2025, 23:41
00977b1
Код
Авторство
О чём код?
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.ExpressionEvaluator Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests Imports Microsoft.DiaSymReader Imports Roslyn.Test.Utilities Imports Xunit Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests Public Class StaticLocalsTests Inherits ExpressionCompilerTestBase <Fact> Public Sub StaticLocals() Const source = "Class C Shared Function F(b As Boolean) As Object If b Then Static x As New C() Return x Else Static y = 2 Return y End If End Function Sub M() Static x = Nothing End Sub End Class" Dim comp = CreateCompilationWithMscorlib40({source}, {MsvbRef}, options:=TestOptions.DebugDll) WithRuntimeInstance(comp, Sub(runtime) ' Shared method. Dim context = CreateMethodContext(runtime, "C.F") Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileExpression("If(x, y)", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 15 (0xf) .maxstack 2 .locals init (Object V_0, //F Boolean V_1, Boolean V_2, Boolean V_3) IL_0000: ldsfld ""C.$STATIC$F$011C2$x As C"" IL_0005: dup IL_0006: brtrue.s IL_000e IL_0008: pop IL_0009: ldsfld ""C.$STATIC$F$011C2$y As Object"" IL_000e: ret }") ' Instance method. context = CreateMethodContext(runtime, "C.M") testData = New CompilationTestData() context.CompileExpression("If(x, Me)", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 12 (0xc) .maxstack 2 .locals init (Boolean V_0) IL_0000: ldarg.0 IL_0001: ldfld ""C.$STATIC$M$2001$x As Object"" IL_0006: dup IL_0007: brtrue.s IL_000b IL_0009: pop IL_000a: ldarg.0 IL_000b: ret }") End Sub) End Sub <Fact> Public Sub AssignStaticLocals() Const source = "Class C Shared Sub M() Static x = Nothing Static y = 1 End Sub Sub N() Static z As New C() End Sub End Class" Dim comp = CreateCompilationWithMscorlib40({source}, {MsvbRef}, options:=TestOptions.DebugDll) WithRuntimeInstance(comp, Sub(runtime) ' Shared method. Dim context = CreateMethodContext(runtime, "C.M") Dim errorMessage As String = Nothing Dim testData = New CompilationTestData() context.CompileAssignment("x", "y", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 16 (0x10) .maxstack 1 .locals init (Boolean V_0, Boolean V_1) IL_0000: ldsfld ""C.$STATIC$M$001$y As Object"" IL_0005: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" IL_000a: stsfld ""C.$STATIC$M$001$x As Object"" IL_000f: ret }") ' Instance method. context = CreateMethodContext(runtime, "C.N") testData = New CompilationTestData() context.CompileAssignment("z", "Nothing", errorMessage, testData) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ // Code size 8 (0x8) .maxstack 2 .locals init (Boolean V_0) IL_0000: ldarg.0 IL_0001: ldnull IL_0002: stfld ""C.$STATIC$N$2001$z As C"" IL_0007: ret }") End Sub) End Sub ''' <summary> ''' Static locals not exposed in the EE from lambdas. ''' This matches Dev12 EE behavior since there is no ''' map from the lambda to the containing method. ''' </summary> <Fact> Public Sub StaticLocalsReferenceInLambda() Const source = "Class C Sub M(x As Object) Static y As Object Dim f = Function() Return If(x, y) End Function f() End Sub Shared Sub M(x As Integer) Static z As Integer Dim f = Function() Return x + z End Function f() End Sub End Class" Dim comp = CreateCompilationWithMscorlib40({source}, {MsvbRef}, options:=TestOptions.DebugDll) WithRuntimeInstance(comp, Sub(runtime) ' Instance method. Dim context = CreateMethodContext(runtime, "C._Closure$__1-0._Lambda$__0") Dim errorMessage As String = Nothing context.CompileExpression("If(x, y)", errorMessage) Assert.Equal(errorMessage, "error BC30451: 'y' is not declared. It may be inaccessible due to its protection level.") ' Shared method. context = CreateMethodContext(runtime, "C._Closure$__2-0._Lambda$__0") context.CompileExpression("x + z", errorMessage) Assert.Equal(errorMessage, "error BC30451: 'z' is not declared. It may be inaccessible due to its protection level.") End Sub) End Sub <Fact> Public Sub GetLocals() Const source = "Class C Shared Function F(b As Boolean) As Object If b Then Static x As New C() Return x Else Static y As Integer = 2 Return y End If End Function Shared Function F(i As Integer) As Object Static x = 3 Return x End Function End Class" Dim comp = CreateCompilationWithMscorlib40({source}, {MsvbRef}, options:=TestOptions.DebugDll) WithRuntimeInstance(comp, Sub(runtime) Dim blocks As ImmutableArray(Of MetadataBlock) = Nothing Dim moduleId As ModuleId = Nothing Dim symReader As ISymUnmanagedReader = Nothing Dim methodToken = 0 Dim localSignatureToken = 0 GetContextState(runtime, "C.F(Boolean)", blocks, moduleId, symReader, methodToken, localSignatureToken) Dim context = CreateMethodContext( New AppDomain(), blocks, MakeDummyLazyAssemblyReaders(), symReader, moduleId, methodToken, methodVersion:=1, ilOffset:=0, localSignatureToken:=localSignatureToken, kind:=MakeAssemblyReferencesKind.AllAssemblies) 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) Assert.Equal(4, locals.Count) VerifyLocal(testData, typeName, locals(0), "<>m0", "b") VerifyLocal(testData, typeName, locals(1), "<>m1", "F") VerifyLocal(testData, typeName, locals(2), "<>m2", "x", expectedILOpt:= "{ // Code size 6 (0x6) .maxstack 1 .locals init (Object V_0, //F Boolean V_1, Boolean V_2, Boolean V_3) IL_0000: ldsfld ""C.$STATIC$F$011C2$x As C"" IL_0005: ret }") VerifyLocal(testData, typeName, locals(3), "<>m3", "y", expectedILOpt:= "{ // Code size 6 (0x6) .maxstack 1 .locals init (Object V_0, //F Boolean V_1, Boolean V_2, Boolean V_3) IL_0000: ldsfld ""C.$STATIC$F$011C2$y As Integer"" IL_0005: ret }") locals.Free() GetContextState(runtime, "C.F(Int32)", blocks, moduleId, symReader, methodToken, localSignatureToken) context = CreateMethodContext( New AppDomain(), blocks, MakeDummyLazyAssemblyReaders(), symReader, moduleId, methodToken, methodVersion:=1, ilOffset:=0, localSignatureToken:=localSignatureToken, kind:=MakeAssemblyReferencesKind.AllAssemblies) testData = New CompilationTestData() locals = ArrayBuilder(Of LocalAndMethod).GetInstance() assembly = context.CompileGetLocals(locals, argumentsOnly:=False, typeName:=typeName, testData:=testData) Assert.Equal(3, locals.Count) VerifyLocal(testData, typeName, locals(0), "<>m0", "i") VerifyLocal(testData, typeName, locals(1), "<>m1", "F") VerifyLocal(testData, typeName, locals(2), "<>m2", "x", expectedILOpt:=" { // Code size 6 (0x6) .maxstack 1 .locals init (Object V_0, //F Boolean V_1) IL_0000: ldsfld ""C.$STATIC$F$011C8$x As Object"" IL_0005: ret } ") locals.Free() End Sub) End Sub ''' <summary> ''' Static locals not exposed in the EE from lambdas. ''' This matches Dev12 EE behavior since there is no ''' map from the lambda to the containing method. ''' </summary> <Fact> Public Sub GetLocalsInLambda() Const source = "Class C Sub M(x As Object) Static y As Object Dim f = Function() Return If(x, y) End Function f() End Sub End Class" Dim comp = CreateCompilationWithMscorlib40({source}, {MsvbRef}, options:=TestOptions.DebugDll) WithRuntimeInstance(comp, Sub(runtime) Dim context = CreateMethodContext(runtime, "C._Closure$__1-0._Lambda$__0") 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) Assert.Equal(2, locals.Count) VerifyLocal(testData, typeName, locals(0), "<>m0", "Me") VerifyLocal(testData, typeName, locals(1), "<>m1", "x") locals.Free() End Sub) End Sub End Class End Namespace