diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/DynamicTypeDecoder.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/DynamicTypeDecoder.cs index 96fccab642bd433806eb90ea7b09973031c5bc8d..72df0e9d1876480682f621bff07f914fe315ea60 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/DynamicTypeDecoder.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/DynamicTypeDecoder.cs @@ -28,9 +28,14 @@ internal struct DynamicTypeDecoder private readonly ImmutableArray _dynamicTransformFlags; private readonly AssemblySymbol _containingAssembly; private readonly bool _haveCustomModifierFlags; + private readonly bool _checkLength; + + /// + /// Should be accessed through , , and . + /// private int _index; - private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool haveCustomModifierFlags, AssemblySymbol containingAssembly) + private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool haveCustomModifierFlags, bool checkLength, AssemblySymbol containingAssembly) { Debug.Assert(!dynamicTransformFlags.IsEmpty); Debug.Assert((object)containingAssembly != null); @@ -38,6 +43,7 @@ private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool have _dynamicTransformFlags = dynamicTransformFlags; _containingAssembly = containingAssembly; _haveCustomModifierFlags = haveCustomModifierFlags; + _checkLength = checkLength; _index = 0; } @@ -63,7 +69,8 @@ private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool have { return TransformTypeInternal(metadataType, containingModule.ContainingAssembly, targetSymbolCustomModifierCount, targetSymbolRefKind, dynamicTransformFlags, - haveCustomModifierFlags: true); + haveCustomModifierFlags: true, + checkLength: true); } // No DynamicAttribute applied to the target symbol, return unchanged metadataType. @@ -74,10 +81,18 @@ private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool have TypeSymbol type, AssemblySymbol containingAssembly, RefKind targetSymbolRefKind, - ImmutableArray dynamicTransformFlags) + ImmutableArray dynamicTransformFlags, + bool checkLength = true) { Debug.Assert(containingAssembly is SourceAssemblySymbol); // Doesn't happen during decoding. - return TransformTypeInternal(type, containingAssembly, 0, targetSymbolRefKind, dynamicTransformFlags, haveCustomModifierFlags: false); + return TransformTypeInternal( + type, + containingAssembly, + 0, + targetSymbolRefKind, + dynamicTransformFlags, + haveCustomModifierFlags: false, + checkLength: checkLength); } private static TypeSymbol TransformTypeInternal( @@ -86,7 +101,8 @@ private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool have int targetSymbolCustomModifierCount, RefKind targetSymbolRefKind, ImmutableArray dynamicTransformFlags, - bool haveCustomModifierFlags) + bool haveCustomModifierFlags, + bool checkLength) { Debug.Assert((object)metadataType != null); Debug.Assert((object)containingAssembly != null); @@ -97,15 +113,17 @@ private DynamicTypeDecoder(ImmutableArray dynamicTransformFlags, bool have return new UnsupportedMetadataTypeSymbol(); } - var decoder = new DynamicTypeDecoder(dynamicTransformFlags, haveCustomModifierFlags, containingAssembly); + var decoder = new DynamicTypeDecoder(dynamicTransformFlags, haveCustomModifierFlags, checkLength, containingAssembly); // Native compiler encodes bools (always false) for custom modifiers and parameter ref-kinds, if ref-kind is ref or out. if (decoder.HandleCustomModifiers(targetSymbolCustomModifierCount) && decoder.HandleParameterRefKind(targetSymbolRefKind)) { TypeSymbol transformedType = decoder.TransformType(metadataType); - if ((object)transformedType != null && decoder._index == dynamicTransformFlags.Length) + if ((object)transformedType != null && (!checkLength || decoder._index == dynamicTransformFlags.Length)) { + // Even when we're not checking the length, there shouldn't be any unconsumed "true"s. + Debug.Assert(checkLength || decoder._dynamicTransformFlags.LastIndexOf(true) < decoder._index); return transformedType; } } @@ -118,9 +136,10 @@ private TypeSymbol TransformType(TypeSymbol type) { Debug.Assert(_index >= 0); - if (_index >= _dynamicTransformFlags.Length || - _dynamicTransformFlags[_index] && type.SpecialType != SpecialType.System_Object) + if (!HasFlag || + PeekFlag() && type.SpecialType != SpecialType.System_Object) { + // Bail, since flags are invalid. return null; } @@ -131,7 +150,7 @@ private TypeSymbol TransformType(TypeSymbol type) if (type.SpecialType == SpecialType.System_Object) { // Replace the given System.Object type with dynamic type if the corresponding dynamicTransformFlag is set to true. - return _dynamicTransformFlags[_index++] ? DynamicTypeSymbol.Instance : type; + return ConsumeFlag() ? DynamicTypeSymbol.Instance : type; } return TransformNamedType((NamedTypeSymbol)type); @@ -144,12 +163,12 @@ private TypeSymbol TransformType(TypeSymbol type) case SymbolKind.DynamicType: Debug.Assert(!_haveCustomModifierFlags, "This shouldn't happen during decoding."); - return _dynamicTransformFlags[_index++] + return ConsumeFlag() ? type : _containingAssembly.GetSpecialType(SpecialType.System_Object); default: - _index++; + ConsumeFlag(); return HandleCustomModifiers(type.CustomModifierCount()) ? type : null; } } @@ -167,20 +186,12 @@ private bool HandleCustomModifiers(int customModifiersCount) Debug.Assert(customModifiersCount >= 0); - if (customModifiersCount > 0) + for (int i = 0; i < customModifiersCount; i++) { - if (_index + customModifiersCount > _dynamicTransformFlags.Length) + if (!HasFlag || ConsumeFlag()) { return false; } - - for (int i = 0; i < customModifiersCount; i++, _index++) - { - if (_dynamicTransformFlags[_index]) - { - return false; - } - } } return true; @@ -190,18 +201,16 @@ private bool HandleCustomModifiers(int customModifiersCount) private bool HandleParameterRefKind(RefKind refKind) { Debug.Assert(_index >= 0); - return refKind == RefKind.None || - _index < _dynamicTransformFlags.Length && !_dynamicTransformFlags[_index++]; + return refKind == RefKind.None || !ConsumeFlag(); } private NamedTypeSymbol TransformNamedType(NamedTypeSymbol namedType, bool isContaining = false) { - Debug.Assert(!_dynamicTransformFlags[_index] || isContaining); - // Native compiler encodes a bool for the given namedType, but none for its containing types. if (!isContaining) { - _index++; + var flag = ConsumeFlag(); + Debug.Assert(!flag); } NamedTypeSymbol containingType = namedType.ContainingType; @@ -279,9 +288,9 @@ private ImmutableArray TransformTypeArguments(ImmutableArray _index < _dynamicTransformFlags.Length || !_checkLength; + + private bool PeekFlag() => _index < _dynamicTransformFlags.Length && _dynamicTransformFlags[_index]; + + private bool ConsumeFlag() + { + var result = PeekFlag(); + _index++; + return result; + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs index 927fea285734d41000c0555b4a081ea56c0f317e..e776688eb42958f0a7b545b14db83cdb16873527 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs @@ -3434,5 +3434,68 @@ static void Main() CompileAndVerify(compilation2, expectedOutput: @"4"); } + [Fact] + public void IncorrectArrayLength() + { + var il = @" +.assembly extern mscorlib { } +.assembly extern System.Core { } +.assembly IncorrectArrayLength { } + +.class private auto ansi beforefieldinit D + extends [mscorlib]System.Object +{ + .field public class Generic`2 MissingTrue + .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor(bool[]) + = {bool[2](false true)} + + .field public class Generic`2 MissingFalse + .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor(bool[]) + = {bool[2](false true)} + + .field public class Generic`2 ExtraTrue + .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor(bool[]) + = {bool[4](false true false true)} + + .field public class Generic`2 ExtraFalse + .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor(bool[]) + = {bool[4](false true false false)} + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + ldarg.0 + call instance void [mscorlib]System.Object::.ctor() + ret + } +} // end of class D + +.class public auto ansi beforefieldinit Generic`2 + extends [mscorlib]System.Object +{ + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method Generic`2::.ctor + +} // end of class Generic`2 +"; + var comp = CreateCompilationWithCustomILSource("", il, new[] { SystemCoreRef }, appendDefaultHeader: false); + var global = comp.GlobalNamespace; + var typeD = global.GetMember("D"); + var typeG = global.GetMember("Generic"); + var typeObject = comp.GetSpecialType(SpecialType.System_Object); + var typeGConstructed = typeG.Construct(typeObject, typeObject); + + Assert.Equal(typeGConstructed, typeD.GetMember("MissingTrue").Type); + Assert.Equal(typeGConstructed, typeD.GetMember("MissingFalse").Type); + Assert.Equal(typeGConstructed, typeD.GetMember("ExtraTrue").Type); + Assert.Equal(typeGConstructed, typeD.GetMember("ExtraFalse").Type); + } } } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.cs index 76482cfb82c48108abd1a7a5c294a98dc9b47388..bae4890fd2f8a4218539c5a2f870e8fe2bb2a44c 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.cs @@ -109,7 +109,9 @@ private PlaceholderLocalSymbol LookupPlaceholder(string name) return null; } - return CreatePlaceholderLocal(_typeNameDecoder, _containingMethod, new Alias(kind, id, id, typeName)); + // The old API (GetObjectTypeNameById) doesn't return custom type info, + // but the new one (GetAliases) will. + return CreatePlaceholderLocal(_typeNameDecoder, _containingMethod, new Alias(kind, id, id, typeName, default(CustomTypeInfo))); } internal static PlaceholderLocalSymbol CreatePlaceholderLocal( @@ -123,6 +125,22 @@ private PlaceholderLocalSymbol LookupPlaceholder(string name) var type = typeNameDecoder.GetTypeSymbolForSerializedType(typeName); Debug.Assert((object)type != null); + var dynamicFlagsInfo = alias.CustomTypeInfo.ToDynamicFlagsCustomTypeInfo(); + if (dynamicFlagsInfo.Any()) + { + var flagsBuilder = ArrayBuilder.GetInstance(); + dynamicFlagsInfo.CopyTo(flagsBuilder); + var dynamicType = DynamicTypeDecoder.TransformTypeWithoutCustomModifierFlags( + type, + containingMethod.ContainingAssembly, + RefKind.None, + flagsBuilder.ToImmutableAndFree(), + checkLength: false); + Debug.Assert(dynamicType != null); + Debug.Assert(dynamicType != type); + type = dynamicType; + } + var id = alias.FullName; switch (alias.Kind) { diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.cs index 6e261f223976df84262a7153c6153b40733d7f6c..505abe71ee34fa34538c8d6d54def6afb54fec63 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.cs @@ -2,9 +2,11 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.ExpressionEvaluator; +using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Linq; namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator { @@ -59,16 +61,21 @@ internal static BoundNode Rewrite(CSharpCompilation compilation, EENamedTypeSymb var typeType = compilation.GetWellKnownType(WellKnownType.System_Type); var stringType = compilation.GetSpecialType(SpecialType.System_String); + var guidConstructor = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Guid__ctor); // CreateVariable(Type type, string name) var method = PlaceholderLocalSymbol.GetIntrinsicMethod(compilation, ExpressionCompilerConstants.CreateVariableMethodName); var type = new BoundTypeOfOperator(syntax, new BoundTypeExpression(syntax, aliasOpt: null, type: local.Type), null, typeType); var name = new BoundLiteral(syntax, ConstantValue.Create(local.Name), stringType); + + bool hasCustomTypeInfoPayload; + var customTypeInfoPayload = GetCustomTypeInfoPayload(local, syntax, compilation, out hasCustomTypeInfoPayload); + var customTypeInfoPayloadId = GetCustomTypeInfoPayloadId(syntax, guidConstructor, hasCustomTypeInfoPayload); var call = BoundCall.Synthesized( syntax, receiverOpt: null, method: method, - arguments: ImmutableArray.Create(type, name)); + arguments: ImmutableArray.Create(type, name, customTypeInfoPayloadId, customTypeInfoPayload)); statements.Add(new BoundExpressionStatement(syntax, call)); var initializer = node.InitializerOpt; @@ -85,5 +92,51 @@ internal static BoundNode Rewrite(CSharpCompilation compilation, EENamedTypeSymb statements.Add(new BoundExpressionStatement(syntax, assignment)); } } + + private static BoundExpression GetCustomTypeInfoPayloadId(CSharpSyntaxNode syntax, MethodSymbol guidConstructor, bool hasCustomTypeInfoPayload) + { + if (!hasCustomTypeInfoPayload) + { + return new BoundDefaultOperator(syntax, guidConstructor.ContainingType); + } + + var value = ConstantValue.Create(DynamicFlagsCustomTypeInfo.PayloadTypeId.ToString()); + return new BoundObjectCreationExpression( + syntax, + guidConstructor, + new BoundLiteral(syntax, value, guidConstructor.ContainingType)); + } + + private static BoundExpression GetCustomTypeInfoPayload(LocalSymbol local, CSharpSyntaxNode syntax, CSharpCompilation compilation, out bool hasCustomTypeInfoPayload) + { + var byteArrayType = new ArrayTypeSymbol( + compilation.Assembly, + compilation.GetSpecialType(SpecialType.System_Byte)); + + var flags = CSharpCompilation.DynamicTransformsEncoder.Encode(local.Type, customModifiersCount: 0, refKind: RefKind.None).ToArray(); + var bytes = new DynamicFlagsCustomTypeInfo(new BitArray(flags)).GetCustomTypeInfoPayload(); + hasCustomTypeInfoPayload = bytes != null; + if (!hasCustomTypeInfoPayload) + { + return new BoundLiteral(syntax, ConstantValue.Null, byteArrayType); + } + + var byteType = byteArrayType.ElementType; + var intType = compilation.GetSpecialType(SpecialType.System_Int32); + + var numBytes = bytes.Length; + var initializerExprs = ArrayBuilder.GetInstance(numBytes); + foreach (var b in bytes) + { + initializerExprs.Add(new BoundLiteral(syntax, ConstantValue.Create(b), byteType)); + } + + var lengthExpr = new BoundLiteral(syntax, ConstantValue.Create(numBytes), intType); + return new BoundArrayCreation( + syntax, + ImmutableArray.Create(lengthExpr), + new BoundArrayInitialization(syntax, initializerExprs.ToImmutableAndFree()), + byteArrayType); + } } } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/SymbolExtensions.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/SymbolExtensions.cs index 845a1eff254b5c3c1a1eaed8326abdebc5181d3c..9cb93f022258fb9f50662db43e888a4d3903acf5 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/SymbolExtensions.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/SymbolExtensions.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Immutable; -using System.Collections.ObjectModel; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.ExpressionEvaluator; @@ -19,7 +18,7 @@ internal static ImmutableArray GetAllTypeParameters(this Me return builder.ToImmutableAndFree(); } - internal static ReadOnlyCollection GetCustomTypeInfoPayload(this MethodSymbol method) + internal static byte[] GetCustomTypeInfoPayload(this MethodSymbol method) { bool[] dynamicFlags = CSharpCompilation.DynamicTransformsEncoder.Encode(method.ReturnType, method.ReturnTypeCustomModifiers.Length, RefKind.None).ToArray(); var dynamicFlagsInfo = new DynamicFlagsCustomTypeInfo(new BitArray(dynamicFlags)); diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DeclarationTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DeclarationTests.cs index 31174e89203c1509396ee14dca9c19a592f0f4e3..89276e998bf15c410e3ee90ded156edcd9a1b729 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DeclarationTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DeclarationTests.cs @@ -56,28 +56,37 @@ static void M(object x) Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 65 (0x41) - .maxstack 2 + // Code size 85 (0x55) + .maxstack 4 .locals init (object V_0, //y bool V_1, - object V_2) + object V_2, + System.Guid V_3) IL_0000: ldtoken ""int"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""z"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""z"" - IL_0019: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldc.i4.1 - IL_001f: stind.i4 - IL_0020: ldtoken ""int"" - IL_0025: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_002a: ldstr ""F"" - IL_002f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" + IL_000f: ldloca.s V_3 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.3 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""z"" + IL_0023: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldc.i4.1 + IL_0029: stind.i4 + IL_002a: ldtoken ""int"" + IL_002f: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0034: ldstr ""F"" - IL_0039: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_003e: ldc.i4.2 - IL_003f: stind.i4 - IL_0040: ret + IL_0039: ldloca.s V_3 + IL_003b: initobj ""System.Guid"" + IL_0041: ldloc.3 + IL_0042: ldnull + IL_0043: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_0048: ldstr ""F"" + IL_004d: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0052: ldc.i4.2 + IL_0053: stind.i4 + IL_0054: ret }"); } @@ -335,20 +344,25 @@ static void M() Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 52 (0x34) - .maxstack 2 + // Code size 62 (0x3e) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""System.ValueType"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""C"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""C"" - IL_0019: call ""System.ValueType Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldstr ""3"" - IL_0023: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" - IL_0028: unbox.any ""int"" - IL_002d: box ""int"" - IL_0032: stind.ref - IL_0033: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""C"" + IL_0023: call ""System.ValueType Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldstr ""3"" + IL_002d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_0032: unbox.any ""int"" + IL_0037: box ""int"" + IL_003c: stind.ref + IL_003d: ret }"); } @@ -388,17 +402,82 @@ static void M() Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 33 (0x21) - .maxstack 2 + // Code size 43 (0x2b) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""int"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""x"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""x"" - IL_0019: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldc.i4.1 - IL_001f: stind.i4 - IL_0020: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""x"" + IL_0023: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldc.i4.1 + IL_0029: stind.i4 + IL_002a: ret +}"); + } + + [WorkItem(1087216)] + [Fact] + public void Dynamic() + { + var source = +@"class C +{ + static void M() + { + } +}"; + var compilation0 = CreateCompilationWithMscorlib( + source, + options: TestOptions.DebugDll, + assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); + var runtime = CreateRuntimeInstance(compilation0); + var context = CreateMethodContext( + runtime, + methodName: "C.M"); + ResultProperties resultProperties; + string error; + ImmutableArray missingAssemblyIdentities; + var testData = new CompilationTestData(); + context.CompileExpression( + InspectionContextFactory.Empty, + "dynamic d = 1;", + DkmEvaluationFlags.None, + DiagnosticFormatter.Instance, + out resultProperties, + out error, + out missingAssemblyIdentities, + EnsureEnglishUICulture.PreferredOrNull, + testData); + Assert.Empty(missingAssemblyIdentities); + Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult); + testData.GetMethodData("<>x.<>m0").VerifyIL( +@"{ + // Code size 58 (0x3a) + .maxstack 7 + IL_0000: ldtoken ""object"" + IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_000a: ldstr ""d"" + IL_000f: ldstr ""826d6ec1-dc4b-46af-be05-cd3f1a1fd4ac"" + IL_0014: newobj ""System.Guid..ctor(string)"" + IL_0019: ldc.i4.1 + IL_001a: newarr ""byte"" + IL_001f: dup + IL_0020: ldc.i4.0 + IL_0021: ldc.i4.1 + IL_0022: stelem.i1 + IL_0023: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_0028: ldstr ""d"" + IL_002d: call ""dynamic Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0032: ldc.i4.1 + IL_0033: box ""int"" + IL_0038: stind.ref + IL_0039: ret }"); } @@ -581,30 +660,39 @@ static void M() Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 95 (0x5f) - .maxstack 2 - .locals init (T V_0) + // Code size 115 (0x73) + .maxstack 4 + .locals init (System.Guid V_0, + T V_1) IL_0000: ldtoken ""T"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""x"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""x"" - IL_0019: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldloca.s V_0 - IL_0020: initobj ""T"" - IL_0026: ldloc.0 - IL_0027: stobj ""T"" - IL_002c: ldtoken ""T"" - IL_0031: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0036: ldstr ""y"" - IL_003b: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""x"" + IL_0023: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldloca.s V_1 + IL_002a: initobj ""T"" + IL_0030: ldloc.1 + IL_0031: stobj ""T"" + IL_0036: ldtoken ""T"" + IL_003b: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0040: ldstr ""y"" - IL_0045: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_004a: ldstr ""x"" - IL_004f: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" - IL_0054: unbox.any ""T"" - IL_0059: stobj ""T"" - IL_005e: ret + IL_0045: ldloca.s V_0 + IL_0047: initobj ""System.Guid"" + IL_004d: ldloc.0 + IL_004e: ldnull + IL_004f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_0054: ldstr ""y"" + IL_0059: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_005e: ldstr ""x"" + IL_0063: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_0068: unbox.any ""T"" + IL_006d: stobj ""T"" + IL_0072: ret }"); } @@ -649,22 +737,27 @@ static void M() Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 47 (0x2f) - .maxstack 3 + // Code size 57 (0x39) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""object"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""o"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""o"" - IL_0019: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_001e: ldstr ""o"" - IL_0023: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" - IL_0028: dup - IL_0029: brtrue.s IL_002d - IL_002b: pop - IL_002c: ldnull - IL_002d: stind.ref - IL_002e: ret + IL_0023: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldstr ""o"" + IL_002d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_0032: dup + IL_0033: brtrue.s IL_0037 + IL_0035: pop + IL_0036: ldnull + IL_0037: stind.ref + IL_0038: ret }"); testData = new CompilationTestData(); context.CompileExpression( @@ -680,21 +773,26 @@ .maxstack 3 Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 53 (0x35) - .maxstack 3 + // Code size 63 (0x3f) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""string"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""s"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""s"" - IL_0019: call ""string Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" IL_001e: ldstr ""s"" - IL_0023: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" - IL_0028: castclass ""string"" - IL_002d: ldc.i4.0 - IL_002e: callvirt ""string string.Substring(int)"" - IL_0033: stind.ref - IL_0034: ret + IL_0023: call ""string Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldstr ""s"" + IL_002d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_0032: castclass ""string"" + IL_0037: ldc.i4.0 + IL_0038: callvirt ""string string.Substring(int)"" + IL_003d: stind.ref + IL_003e: ret }"); } @@ -918,22 +1016,31 @@ static void M() Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 62 (0x3e) - .maxstack 2 + // Code size 82 (0x52) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""object"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""class"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldtoken ""object"" - IL_0019: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_001e: ldstr ""this"" - IL_0023: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldtoken ""object"" + IL_0023: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_0028: ldstr ""this"" - IL_002d: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_0032: ldstr ""class"" - IL_0037: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" - IL_003c: stind.ref - IL_003d: ret + IL_002d: ldloca.s V_0 + IL_002f: initobj ""System.Guid"" + IL_0035: ldloc.0 + IL_0036: ldnull + IL_0037: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_003c: ldstr ""this"" + IL_0041: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0046: ldstr ""class"" + IL_004b: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_0050: stind.ref + IL_0051: ret }"); } @@ -974,17 +1081,22 @@ static void M() Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 33 (0x21) - .maxstack 2 + // Code size 43 (0x2b) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""int"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""x"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""x"" - IL_0019: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldc.i4.1 - IL_001f: stind.i4 - IL_0020: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""x"" + IL_0023: call ""int Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldc.i4.1 + IL_0029: stind.i4 + IL_002a: ret }"); } @@ -1023,17 +1135,22 @@ static void M(T x) Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 37 (0x25) - .maxstack 2 + // Code size 47 (0x2f) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""T"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""y"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""y"" - IL_0019: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldarg.0 - IL_001f: stobj ""T"" - IL_0024: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""y"" + IL_0023: call ""T Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldarg.0 + IL_0029: stobj ""T"" + IL_002e: ret }"); } @@ -1163,25 +1280,30 @@ static void M() Assert.Empty(missingAssemblyIdentities); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ - // Code size 63 (0x3f) - .maxstack 3 + // Code size 73 (0x49) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""System.Action"" IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" IL_000a: ldstr ""b"" - IL_000f: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string)"" - IL_0014: ldstr ""b"" - IL_0019: call ""System.Action Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" - IL_001e: ldsfld ""System.Action <>x.<>c.<>9__0_0"" - IL_0023: dup - IL_0024: brtrue.s IL_003d - IL_0026: pop - IL_0027: ldsfld ""<>x.<>c <>x.<>c.<>9"" - IL_002c: ldftn ""void <>x.<>c.<<>m0>b__0_0()"" - IL_0032: newobj ""System.Action..ctor(object, System.IntPtr)"" - IL_0037: dup - IL_0038: stsfld ""System.Action <>x.<>c.<>9__0_0"" - IL_003d: stind.ref - IL_003e: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_001e: ldstr ""b"" + IL_0023: call ""System.Action Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(string)"" + IL_0028: ldsfld ""System.Action <>x.<>c.<>9__0_0"" + IL_002d: dup + IL_002e: brtrue.s IL_0047 + IL_0030: pop + IL_0031: ldsfld ""<>x.<>c <>x.<>c.<>9"" + IL_0036: ldftn ""void <>x.<>c.<<>m0>b__0_0()"" + IL_003c: newobj ""System.Action..ctor(object, System.IntPtr)"" + IL_0041: dup + IL_0042: stsfld ""System.Action <>x.<>c.<>9__0_0"" + IL_0047: stind.ref + IL_0048: ret }"); } diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs index ff1e0e1f04cca6f08fc3667da5ca75fef3519634..7918312b0779e23de7d87e3acc5f3db6c9b4ff65 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/DynamicTests.cs @@ -1,12 +1,16 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections; +using System.Collections.Generic; using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.Linq; using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.ExpressionEvaluator; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.VisualStudio.Debugger.Evaluation; using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation; using Roslyn.Test.PdbUtilities; using Roslyn.Test.Utilities; @@ -393,10 +397,6 @@ public class Outer { public class Inner { - public enum E - { - A - } } } "; @@ -429,6 +429,124 @@ .maxstack 1 result = context.CompileAssignment("d", "d", out error); Assert.Null(error); VerifyCustomTypeInfo(result, null); + + ResultProperties resultProperties; + ImmutableArray missingAssemblyIdentities; + testData = new CompilationTestData(); + result = context.CompileExpression( + InspectionContextFactory.Empty, + "var dd = d;", + DkmEvaluationFlags.None, + DiagnosticFormatter.Instance, + out resultProperties, + out error, + out missingAssemblyIdentities, + EnsureEnglishUICulture.PreferredOrNull, + testData); + Assert.Null(error); + VerifyCustomTypeInfo(result, null); + Assert.Empty(missingAssemblyIdentities); + Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult); + testData.GetMethodData("<>x.<>m0").VerifyIL( +@"{ + // Code size 57 (0x39) + .maxstack 7 + IL_0000: ldtoken ""Outer.Inner[], dynamic>"" + IL_0005: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_000a: ldstr ""dd"" + IL_000f: ldstr ""826d6ec1-dc4b-46af-be05-cd3f1a1fd4ac"" + IL_0014: newobj ""System.Guid..ctor(string)"" + IL_0019: ldc.i4.2 + IL_001a: newarr ""byte"" + IL_001f: dup + IL_0020: ldc.i4.0 + IL_0021: ldc.i4.4 + IL_0022: stelem.i1 + IL_0023: dup + IL_0024: ldc.i4.1 + IL_0025: ldc.i4.3 + IL_0026: stelem.i1 + IL_0027: call ""void Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, string, System.Guid, byte[])"" + IL_002c: ldstr ""dd"" + IL_0031: call ""Outer.Inner[], dynamic> Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress.Inner[], dynamic>>(string)"" + IL_0036: ldarg.0 + IL_0037: stind.ref + IL_0038: ret +}"); + } + + [Fact] + public void DynamicAliases() + { + var source = +@"class C +{ + static void M() + { + } +}"; + var compilation0 = CreateCompilationWithMscorlib( + source, + options: TestOptions.DebugDll, + assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); + var runtime = CreateRuntimeInstance(compilation0); + var context = CreateMethodContext(runtime, methodName: "C.M"); + var locals = ArrayBuilder.GetInstance(); + string typeName; + var diagnostics = DiagnosticBag.GetInstance(); + var builder = ArrayBuilder.GetInstance(); + builder.Add(new Alias( + AliasKind.DeclaredLocal, + "d1", + "d1", + typeof(object).AssemblyQualifiedName, + MakeCustomTypeInfo(true))); + builder.Add(new Alias( + AliasKind.DeclaredLocal, + "d2", + "d2", + typeof(Dictionary>, object>).AssemblyQualifiedName, + MakeCustomTypeInfo(false, false, true, false, false, false, false, true, false))); + var aliases = new ReadOnlyCollection(builder.ToArrayAndFree()); + + var testData = new CompilationTestData(); + context.CompileGetLocals( + aliases, + locals, + argumentsOnly: false, + diagnostics: diagnostics, + typeName: out typeName, + testData: testData); + diagnostics.Free(); + Assert.Equal(locals.Count, 2); + + VerifyCustomTypeInfo(locals[0], 0x01); + VerifyLocal(testData, typeName, locals[0], "<>m0", "d1", expectedILOpt: +@"{ + // Code size 11 (0xb) + .maxstack 1 + IL_0000: ldstr ""d1"" + IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_000a: ret +}"); + + VerifyCustomTypeInfo(locals[1], 0x84, 0x00); // Note: read flags right-to-left in each byte: 0010 0001 0(000 0000) + VerifyLocal(testData, typeName, locals[1], "<>m1", "d2", expectedILOpt: +@"{ + // Code size 16 (0x10) + .maxstack 1 + IL_0000: ldstr ""d2"" + IL_0005: call ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)"" + IL_000a: castclass ""System.Collections.Generic.Dictionary>, object>"" + IL_000f: ret +}"); + locals.Free(); + } + + private static CustomTypeInfo MakeCustomTypeInfo(params bool[] flags) + { + var dynamicFlagsInfo = new DynamicFlagsCustomTypeInfo(new BitArray(flags)); + return new CustomTypeInfo(DynamicFlagsCustomTypeInfo.PayloadTypeId, dynamicFlagsInfo.GetCustomTypeInfoPayload()); } [Fact] diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs index 0d2d072353a63822d74a4e580bb6c0792e71b1a7..73df5a0b8d90694a7267736a223246b944ae6574 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs @@ -231,11 +231,11 @@ void M(object o) string typeName; var diagnostics = DiagnosticBag.GetInstance(); var builder = ArrayBuilder.GetInstance(); - builder.Add(new Alias(AliasKind.Exception, "Error", "$exception", typeof(System.IO.IOException).AssemblyQualifiedName)); - builder.Add(new Alias(AliasKind.ReturnValue, "F returned", "$ReturnValue2", typeof(string).AssemblyQualifiedName)); - builder.Add(new Alias(AliasKind.ReturnValue, "G returned", "$ReturnValue", typeof(object).AssemblyQualifiedName)); - builder.Add(new Alias(AliasKind.ObjectId, "2", "2", typeof(bool).AssemblyQualifiedName)); - builder.Add(new Alias(AliasKind.DeclaredLocal, "o", "o", "C")); + builder.Add(new Alias(AliasKind.Exception, "Error", "$exception", typeof(System.IO.IOException).AssemblyQualifiedName, default(CustomTypeInfo))); + builder.Add(new Alias(AliasKind.ReturnValue, "F returned", "$ReturnValue2", typeof(string).AssemblyQualifiedName, default(CustomTypeInfo))); + builder.Add(new Alias(AliasKind.ReturnValue, "G returned", "$ReturnValue", typeof(object).AssemblyQualifiedName, default(CustomTypeInfo))); + builder.Add(new Alias(AliasKind.ObjectId, "2", "2", typeof(bool).AssemblyQualifiedName, default(CustomTypeInfo))); + builder.Add(new Alias(AliasKind.DeclaredLocal, "o", "o", "C", default(CustomTypeInfo))); var aliases = new ReadOnlyCollection(builder.ToArrayAndFree()); var testData = new CompilationTestData(); diff --git a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/CustomTypeInfo.cs b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/CustomTypeInfo.cs index 2aee952fba5b562b1c41541f0e6abf85272ccd1b..9f6ba82a5202f7da3f08f110510ef866a34e1549 100644 --- a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/CustomTypeInfo.cs +++ b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/CustomTypeInfo.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections; using System.Collections.ObjectModel; using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation; @@ -14,19 +15,26 @@ namespace Microsoft.CodeAnalysis.ExpressionEvaluator internal struct CustomTypeInfo { public Guid PayloadTypeId; - public ReadOnlyCollection Payload; + public byte[] Payload; - public CustomTypeInfo(Guid payloadTypeId, ReadOnlyCollection payload) + public CustomTypeInfo(Guid payloadTypeId, byte[] payload) { this.PayloadTypeId = payloadTypeId; this.Payload = payload; } + public DynamicFlagsCustomTypeInfo ToDynamicFlagsCustomTypeInfo() + { + return PayloadTypeId == DynamicFlagsCustomTypeInfo.PayloadTypeId + ? new DynamicFlagsCustomTypeInfo(new BitArray(Payload)) + : default(DynamicFlagsCustomTypeInfo); + } + public DkmClrCustomTypeInfo ToDkmClrCustomTypeInfo() { return Payload == null ? null - : DkmClrCustomTypeInfo.Create(PayloadTypeId, Payload); + : DkmClrCustomTypeInfo.Create(PayloadTypeId, new ReadOnlyCollection(Payload)); } } } diff --git a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/DynamicFlagsCustomTypeInfo.cs b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/DynamicFlagsCustomTypeInfo.cs index f25afd12bb1a277fc001abf97316616be4df94e4..e2639695e735cfac3e0d3c9d44ecf50a4ce2d77c 100644 --- a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/DynamicFlagsCustomTypeInfo.cs +++ b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/DynamicFlagsCustomTypeInfo.cs @@ -45,7 +45,26 @@ public DynamicFlagsCustomTypeInfo(DkmClrCustomTypeInfo typeInfo) } } - internal ReadOnlyCollection GetCustomTypeInfoPayload() + /// + /// Not guarantee to add the same number of flags as would + /// appear in a . + /// It may have more (for padding) or fewer (for compactness) falses. + /// It is, however, guaranteed to include the last true. + /// + internal void CopyTo(ArrayBuilder builder) + { + if (_bits == null) + { + return; + } + + for (int b = 0; b < _bits.Length; b++) + { + builder.Add(_bits[b]); + } + } + + internal byte[] GetCustomTypeInfoPayload() { if (!Any()) { @@ -69,13 +88,13 @@ internal ReadOnlyCollection GetCustomTypeInfoPayload() } } - return new ReadOnlyCollection(bytes); + return bytes; } public DkmClrCustomTypeInfo GetCustomTypeInfo() { var payload = GetCustomTypeInfoPayload(); - return payload == null ? null : DkmClrCustomTypeInfo.Create(PayloadTypeId, payload); + return payload == null ? null : DkmClrCustomTypeInfo.Create(PayloadTypeId, new ReadOnlyCollection(payload)); } public DynamicFlagsCustomTypeInfo SkipOne() diff --git a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/PseudoVariableUtilities.cs b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/PseudoVariableUtilities.cs index 9b251f01190535b9c4c8c027785ac2c3cb35f7c1..05ddb01e40d688d3f20445181176572f92b67c1b 100644 --- a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/PseudoVariableUtilities.cs +++ b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/PseudoVariableUtilities.cs @@ -3,7 +3,6 @@ using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation; using Roslyn.Utilities; using System; -using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; @@ -21,31 +20,26 @@ internal enum AliasKind internal struct Alias { - internal Alias(AliasKind kind, string name, string fullName, string type, ReadOnlyCollection customTypeInfo = null, Guid customTypeInfoId = default(Guid)) + internal Alias(AliasKind kind, string name, string fullName, string type, CustomTypeInfo customTypeInfo) { Debug.Assert(kind != AliasKind.None); Debug.Assert(!string.IsNullOrEmpty(fullName)); Debug.Assert(!string.IsNullOrEmpty(type)); - Debug.Assert((customTypeInfo == null) == (customTypeInfoId == default(Guid))); this.Kind = kind; this.Name = name; this.FullName = fullName; this.Type = type; this.CustomTypeInfo = customTypeInfo; - this.CustomTypeInfoId = customTypeInfoId; } internal readonly AliasKind Kind; internal readonly string Name; internal readonly string FullName; internal readonly string Type; - internal readonly ReadOnlyCollection CustomTypeInfo; - internal readonly Guid CustomTypeInfoId; + internal readonly CustomTypeInfo CustomTypeInfo; } - internal delegate ReadOnlyCollection GetAliases(); - internal static class PseudoVariableUtilities { internal static bool TryParseVariableName(string name, bool caseSensitive, out AliasKind kind, out string id, out int index) diff --git a/src/ExpressionEvaluator/Core/Source/ResultProvider/NetFX20/Helpers/Placeholders.cs b/src/ExpressionEvaluator/Core/Source/ResultProvider/NetFX20/Helpers/Placeholders.cs index 06c5c271a544530fe36c119e1091d6057860c58d..b3f0d98aeeef03bb0cdff4c2c86134feb2876fd0 100644 --- a/src/ExpressionEvaluator/Core/Source/ResultProvider/NetFX20/Helpers/Placeholders.cs +++ b/src/ExpressionEvaluator/Core/Source/ResultProvider/NetFX20/Helpers/Placeholders.cs @@ -48,6 +48,14 @@ internal class ExtensionAttribute : Attribute { } + /// + /// This satisfies a cref on . + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue)] + internal class DynamicAttribute : Attribute + { + } + /// /// This satisfies a cref on . /// diff --git a/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/ExpressionCompilerTestHelpers.cs b/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/ExpressionCompilerTestHelpers.cs index 94e94681e488c861e00bb50c8c37c7d90b0cd435..8d94b1f32121f5427b8cf00fb28896cd1c8cbd7b 100644 --- a/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/ExpressionCompilerTestHelpers.cs +++ b/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/ExpressionCompilerTestHelpers.cs @@ -505,7 +505,7 @@ private static MetadataReference GetIntrinsicAssemblyReference() ldnull throw } - .method public static void CreateVariable(class [mscorlib]System.Type 'type', string name) + .method public static void CreateVariable(class [mscorlib]System.Type 'type', string name, valuetype [mscorlib]System.Guid customTypeInfoPayloadTypeId, uint8[] customTypeInfoPayload) { ldnull throw diff --git a/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/InspectionContextFactory.cs b/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/InspectionContextFactory.cs index c287173d33c03d4ddfd35a4f8812cf12825cd350..0d7567d69f6ae915d5f1313dbb35650d7d71155e 100644 --- a/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/InspectionContextFactory.cs +++ b/src/ExpressionEvaluator/Core/Test/ExpressionCompiler/InspectionContextFactory.cs @@ -21,16 +21,16 @@ internal InspectionContextImpl(ReadOnlyCollection variables) _variables = variables; } - internal InspectionContextImpl Add(string id, Type type) + internal InspectionContextImpl Add(string id, Type type, CustomTypeInfo customTypeInfo = default(CustomTypeInfo)) { - return Add(id, type.AssemblyQualifiedName); + return Add(id, type.AssemblyQualifiedName, customTypeInfo); } - internal InspectionContextImpl Add(string id, string typeName) + internal InspectionContextImpl Add(string id, string typeName, CustomTypeInfo customTypeInfo = default(CustomTypeInfo)) { var builder = ArrayBuilder.GetInstance(); builder.AddRange(_variables); - builder.Add(new Alias(GetPseudoVariableKind(id), id, id, typeName)); + builder.Add(new Alias(GetPseudoVariableKind(id), id, id, typeName, customTypeInfo)); return new InspectionContextImpl(new ReadOnlyCollection(builder.ToArrayAndFree())); } diff --git a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.vb b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.vb index a4895542a09871f75008ac978641add0cb6a0984..527e13de5e1fd01b50d008ffbf44215ee0f97a3b 100644 --- a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.vb +++ b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Binders/PlaceholderLocalBinder.vb @@ -113,7 +113,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator Return Nothing End If - Return CreatePlaceholderLocal(_typeNameDecoder, _containingMethod, New [Alias](kind, id, id, typeName)) + ' The old API (GetObjectTypeNameById) doesn't return custom type info, + ' but the new one (GetAliases) will. + Return CreatePlaceholderLocal(_typeNameDecoder, _containingMethod, New [Alias](kind, id, id, typeName, customTypeInfo:=Nothing)) End Function Friend Shared Function CreatePlaceholderLocal( diff --git a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.vb b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.vb index 72386cad25c35b3a07ce89bec5362eb9ecc82b61..0f3fbf0dfd5698051291802bf9848618c0b3519a 100644 --- a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.vb +++ b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/Rewriters/LocalDeclarationRewriter.vb @@ -56,17 +56,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator Dim typeType = compilation.GetWellKnownType(WellKnownType.System_Type) Dim stringType = compilation.GetSpecialType(SpecialType.System_String) + Dim guidType = compilation.GetWellKnownType(WellKnownType.System_Guid) + Dim byteArrayType = New ArrayTypeSymbol( + compilation.GetSpecialType(SpecialType.System_Byte), + ImmutableArray(Of CustomModifier).Empty, + rank:=1, + compilation:=compilation) ' CreateVariable(type As Type, name As String) Dim method = PlaceholderLocalSymbol.GetIntrinsicMethod(compilation, ExpressionCompilerConstants.CreateVariableMethodName) Dim type = New BoundGetType(syntax, New BoundTypeExpression(syntax, local.Type), typeType) Dim name = New BoundLiteral(syntax, ConstantValue.Create(local.Name), stringType) + Dim customTypeInfoPayloadId = New BoundObjectCreationExpression(syntax, Nothing, ImmutableArray(Of BoundExpression).Empty, Nothing, guidType) + Dim customTypeInfoPayload = New BoundLiteral(syntax, ConstantValue.Null, byteArrayType) Dim expr = New BoundCall( syntax, method, methodGroupOpt:=Nothing, receiverOpt:=Nothing, - arguments:=ImmutableArray.Create(Of BoundExpression)(type, name), + arguments:=ImmutableArray.Create(Of BoundExpression)(type, name, customTypeInfoPayloadId, customTypeInfoPayload), constantValueOpt:=Nothing, suppressObjectClone:=False, type:=method.ReturnType) diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DeclarationTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DeclarationTests.vb index 0258354c278f62022232bc8bd6c318ffc0c866be..9882a25206db3aea84f2f26af2f8f70ee396f070 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DeclarationTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DeclarationTests.vb @@ -48,23 +48,28 @@ End Class" Assert.Equal(resultProperties.Flags, DkmClrCompilationResultFlags.PotentialSideEffect Or DkmClrCompilationResultFlags.ReadOnlyResult) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 52 (0x34) - .maxstack 2 + // Code size 62 (0x3e) + .maxstack 4 .locals init (Object V_0, //y Boolean V_1, - Object V_2) + Object V_2, + System.Guid V_3) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""z"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""z"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: ldstr ""3"" - IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_0028: unbox.any ""Integer"" - IL_002d: box ""Integer"" - IL_0032: stind.ref - IL_0033: ret + IL_000f: ldloca.s V_3 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.3 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""z"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldstr ""3"" + IL_002d: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0032: unbox.any ""Integer"" + IL_0037: box ""Integer"" + IL_003c: stind.ref + IL_003d: ret }") End Sub @@ -195,20 +200,25 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 52 (0x34) - .maxstack 2 + // Code size 62 (0x3e) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""s"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""s"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" IL_001e: ldstr ""s"" - IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_0028: call ""Function Microsoft.VisualBasic.CompilerServices.Conversions.ToString(Object) As String"" - IL_002d: call ""Function M.F(String) As String"" - IL_0032: stind.ref - IL_0033: ret + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldstr ""s"" + IL_002d: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0032: call ""Function Microsoft.VisualBasic.CompilerServices.Conversions.ToString(Object) As String"" + IL_0037: call ""Function M.F(String) As String"" + IL_003c: stind.ref + IL_003d: ret }") testData = New CompilationTestData() context.CompileExpression( @@ -224,22 +234,27 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 55 (0x37) - .maxstack 2 + // Code size 65 (0x41) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""t"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""t"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_001e: dup - IL_001f: brtrue.s IL_002c - IL_0021: pop - IL_0022: ldstr ""t"" - IL_0027: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_002c: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" - IL_0031: call ""Sub M.M(Object)"" - IL_0036: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""t"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0028: dup + IL_0029: brtrue.s IL_0036 + IL_002b: pop + IL_002c: ldstr ""t"" + IL_0031: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0036: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" + IL_003b: call ""Sub M.M(Object)"" + IL_0040: ret }") End Sub @@ -275,17 +290,22 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 37 (0x25) - .maxstack 2 + // Code size 47 (0x2f) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""o"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""o"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: call ""Function M.F(Of Object)(ByRef Object) As Object"" - IL_0023: pop - IL_0024: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""o"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: call ""Function M.F(Of Object)(ByRef Object) As Object"" + IL_002d: pop + IL_002e: ret }") End Sub @@ -316,19 +336,24 @@ End Class" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 47 (0x2f) - .maxstack 2 + // Code size 57 (0x39) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""me"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""me"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: ldstr ""class"" - IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_0028: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" - IL_002d: stind.ref - IL_002e: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""me"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldstr ""class"" + IL_002d: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0032: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" + IL_0037: stind.ref + IL_0038: ret }") End Sub @@ -359,18 +384,23 @@ End Class" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 38 (0x26) - .maxstack 2 + // Code size 48 (0x30) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""y"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""y"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: ldarg.0 - IL_001f: box ""T"" - IL_0024: stind.ref - IL_0025: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""y"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldarg.0 + IL_0029: box ""T"" + IL_002e: stind.ref + IL_002f: ret }") End Sub @@ -405,18 +435,23 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 38 (0x26) - .maxstack 2 + // Code size 48 (0x30) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: ldc.i4.3 - IL_001f: box ""Integer"" - IL_0024: stind.ref - IL_0025: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldc.i4.3 + IL_0029: box ""Integer"" + IL_002e: stind.ref + IL_002f: ret }") ' Integer @@ -434,17 +469,22 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 33 (0x21) - .maxstack 2 + // Code size 43 (0x2b) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Integer"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Integer)(String) As Integer"" - IL_001e: ldc.i4.3 - IL_001f: stind.i4 - IL_0020: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Integer)(String) As Integer"" + IL_0028: ldc.i4.3 + IL_0029: stind.i4 + IL_002a: ret }") ' Long @@ -462,18 +502,23 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 34 (0x22) - .maxstack 2 + // Code size 44 (0x2c) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Long"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Long)(String) As Long"" - IL_001e: ldc.i4.3 - IL_001f: conv.i8 - IL_0020: stind.i8 - IL_0021: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Long)(String) As Long"" + IL_0028: ldc.i4.3 + IL_0029: conv.i8 + IL_002a: stind.i8 + IL_002b: ret }") ' Single @@ -491,17 +536,22 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 37 (0x25) - .maxstack 2 + // Code size 47 (0x2f) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Single"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Single)(String) As Single"" - IL_001e: ldc.r4 3 - IL_0023: stind.r4 - IL_0024: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Single)(String) As Single"" + IL_0028: ldc.r4 3 + IL_002d: stind.r4 + IL_002e: ret }") ' Double @@ -519,17 +569,22 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 41 (0x29) - .maxstack 2 + // Code size 51 (0x33) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Double"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Double)(String) As Double"" - IL_001e: ldc.r8 3 - IL_0027: stind.r8 - IL_0028: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Double)(String) As Double"" + IL_0028: ldc.r8 3 + IL_0031: stind.r8 + IL_0032: ret }") ' String @@ -547,18 +602,23 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 38 (0x26) - .maxstack 2 + // Code size 48 (0x30) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""String"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of String)(String) As String"" - IL_001e: ldc.i4.3 - IL_001f: call ""Function Microsoft.VisualBasic.CompilerServices.Conversions.ToString(Integer) As String"" - IL_0024: stind.ref - IL_0025: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of String)(String) As String"" + IL_0028: ldc.i4.3 + IL_0029: call ""Function Microsoft.VisualBasic.CompilerServices.Conversions.ToString(Integer) As String"" + IL_002e: stind.ref + IL_002f: ret }") ' Decimal @@ -576,19 +636,24 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 43 (0x2b) - .maxstack 2 + // Code size 53 (0x35) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Decimal"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Decimal)(String) As Decimal"" - IL_001e: ldc.i4.3 - IL_001f: conv.i8 - IL_0020: newobj ""Sub Decimal..ctor(Long)"" - IL_0025: stobj ""Decimal"" - IL_002a: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Decimal)(String) As Decimal"" + IL_0028: ldc.i4.3 + IL_0029: conv.i8 + IL_002a: newobj ""Sub Decimal..ctor(Long)"" + IL_002f: stobj ""Decimal"" + IL_0034: ret }") End Sub @@ -695,18 +760,23 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 38 (0x26) - .maxstack 2 + // Code size 48 (0x30) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""a"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""a"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: ldc.i4.4 - IL_001f: newarr ""Object"" - IL_0024: stind.ref - IL_0025: ret + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""a"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldc.i4.4 + IL_0029: newarr ""Object"" + IL_002e: stind.ref + IL_002f: ret }") testData = New CompilationTestData() context.CompileExpression( @@ -722,22 +792,27 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 58 (0x3a) - .maxstack 3 + // Code size 68 (0x44) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""a"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""a"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" IL_001e: ldstr ""a"" - IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_0028: castclass ""System.Array"" - IL_002d: ldc.i4.4 - IL_002e: newarr ""Object"" - IL_0033: call ""Function Microsoft.VisualBasic.CompilerServices.Utils.CopyArray(System.Array, System.Array) As System.Array"" - IL_0038: stind.ref - IL_0039: ret + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldstr ""a"" + IL_002d: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0032: castclass ""System.Array"" + IL_0037: ldc.i4.4 + IL_0038: newarr ""Object"" + IL_003d: call ""Function Microsoft.VisualBasic.CompilerServices.Utils.CopyArray(System.Array, System.Array) As System.Array"" + IL_0042: stind.ref + IL_0043: ret }") End Sub @@ -769,21 +844,26 @@ End Module" Assert.Empty(missingAssemblyIdentities) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 53 (0x35) - .maxstack 3 + // Code size 63 (0x3f) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" IL_001e: ldstr ""x"" - IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_0028: ldc.i4.1 - IL_0029: box ""Integer"" - IL_002e: call ""Function Microsoft.VisualBasic.CompilerServices.Operators.AddObject(Object, Object) As Object"" - IL_0033: stind.ref - IL_0034: ret + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldstr ""x"" + IL_002d: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0032: ldc.i4.1 + IL_0033: box ""Integer"" + IL_0038: call ""Function Microsoft.VisualBasic.CompilerServices.Operators.AddObject(Object, Object) As Object"" + IL_003d: stind.ref + IL_003e: ret }") End Sub @@ -856,19 +936,24 @@ End Class" ' Note that all x's are lowercase (i.e. normalized). testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 47 (0x2f) - .maxstack 2 + // Code size 57 (0x39) + .maxstack 4 + .locals init (System.Guid V_0) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_000f: ldloca.s V_0 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.0 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" IL_001e: ldstr ""x"" - IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" - IL_0028: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" - IL_002d: stind.ref - IL_002e: ret + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldstr ""x"" + IL_002d: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(String) As Object"" + IL_0032: call ""Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object"" + IL_0037: stind.ref + IL_0038: ret } ") End Sub diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/LocalsTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/LocalsTests.vb index 5c5d62fd32d4d3767b6e22451052e2b5a29d71aa..8c6c038e87012892a4ae4d7173bd021b40024755 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/LocalsTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/LocalsTests.vb @@ -137,11 +137,11 @@ End Class" Dim typeName As String = Nothing Dim diagnostics = DiagnosticBag.GetInstance() Dim builder = ArrayBuilder(Of [Alias]).GetInstance() - builder.Add(New [Alias](AliasKind.Exception, "Error", "$exception", GetType(System.IO.IOException).AssemblyQualifiedName)) - builder.Add(New [Alias](AliasKind.ReturnValue, "F returned", "$ReturnValue2", GetType(String).AssemblyQualifiedName)) - builder.Add(New [Alias](AliasKind.ReturnValue, "G returned", "$ReturnValue", GetType(Object).AssemblyQualifiedName)) - builder.Add(New [Alias](AliasKind.ObjectId, "2", "2", GetType(Boolean).AssemblyQualifiedName)) - builder.Add(New [Alias](AliasKind.DeclaredLocal, "o", "o", "C")) + builder.Add(New [Alias](AliasKind.Exception, "Error", "$exception", GetType(System.IO.IOException).AssemblyQualifiedName, customTypeInfo:=Nothing)) + builder.Add(New [Alias](AliasKind.ReturnValue, "F returned", "$ReturnValue2", GetType(String).AssemblyQualifiedName, customTypeInfo:=Nothing)) + builder.Add(New [Alias](AliasKind.ReturnValue, "G returned", "$ReturnValue", GetType(Object).AssemblyQualifiedName, customTypeInfo:=Nothing)) + builder.Add(New [Alias](AliasKind.ObjectId, "2", "2", GetType(Boolean).AssemblyQualifiedName, customTypeInfo:=Nothing)) + builder.Add(New [Alias](AliasKind.DeclaredLocal, "o", "o", "C", customTypeInfo:=Nothing)) Dim aliases = New ReadOnlyCollection(Of [Alias])(builder.ToArrayAndFree()) Dim testData = New CompilationTestData() diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/PseudoVariableTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/PseudoVariableTests.vb index f92611468fff7a94e98e58dbafec12e427664e7f..c4ec6f9a189c378207eb9e901dbd5095d4804800 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/PseudoVariableTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/PseudoVariableTests.vb @@ -802,18 +802,23 @@ End Class Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 33 (0x21) - .maxstack 2 - .locals init (T V_0) //F + // Code size 43 (0x2b) + .maxstack 4 + .locals init (T V_0, //F + System.Guid V_1) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: ldnull - IL_001f: stind.ref - IL_0020: ret + IL_000f: ldloca.s V_1 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.1 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: ldnull + IL_0029: stind.ref + IL_002a: ret }") testData = New CompilationTestData() context.CompileExpression( @@ -830,18 +835,23 @@ End Class Assert.Null(errorMessage) testData.GetMethodData("<>x.<>m0").VerifyIL( "{ - // Code size 37 (0x25) - .maxstack 2 - .locals init (T V_0) //F + // Code size 47 (0x2f) + .maxstack 4 + .locals init (T V_0, //F + System.Guid V_1) IL_0000: ldtoken ""Object"" IL_0005: call ""Function System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) As System.Type"" IL_000a: ldstr ""x"" - IL_000f: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String)"" - IL_0014: ldstr ""x"" - IL_0019: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" - IL_001e: call ""Function C.F(Of Object)(ByRef Object) As Object"" - IL_0023: pop - IL_0024: ret + IL_000f: ldloca.s V_1 + IL_0011: initobj ""System.Guid"" + IL_0017: ldloc.1 + IL_0018: ldnull + IL_0019: call ""Sub Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.CreateVariable(System.Type, String, System.Guid, Byte())"" + IL_001e: ldstr ""x"" + IL_0023: call ""Function Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetVariableAddress(Of Object)(String) As Object"" + IL_0028: call ""Function C.F(Of Object)(ByRef Object) As Object"" + IL_002d: pop + IL_002e: ret }") End Sub