internal RuntimeInstance CreateRuntimeInstance(
            string assemblyName,
            ImmutableArray<MetadataReference> references,
            byte[] exeBytes,
            ISymUnmanagedReader symReader,
            bool includeLocalSignatures = true)
        {
            var exeReference = AssemblyMetadata.CreateFromImage(exeBytes).GetReference(display: assemblyName);
            var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            // Create modules for the references
            modulesBuilder.AddRange(references.Select(r => r.ToModuleInstance(fullImage: null, symReader: null, includeLocalSignatures: includeLocalSignatures)));
            // Create a module for the exe.
            modulesBuilder.Add(exeReference.ToModuleInstance(exeBytes, symReader, includeLocalSignatures: includeLocalSignatures));

            var modules = modulesBuilder.ToImmutableAndFree();
            modules.VerifyAllModules();

            var instance = new RuntimeInstance(modules);
            _runtimeInstances.Add(instance);
            return instance;
        }
        internal static void GetContextState(
            RuntimeInstance runtime,
            string methodOrTypeName,
            out ImmutableArray<MetadataBlock> blocks,
            out Guid moduleVersionId,
            out ISymUnmanagedReader symReader,
            out int methodOrTypeToken,
            out int localSignatureToken)
        {
            var moduleInstances = runtime.Modules;
            blocks = moduleInstances.SelectAsArray(m => m.MetadataBlock);

            var compilation = blocks.ToCompilation();

            var methodOrType = GetMethodOrTypeBySignature(compilation, methodOrTypeName);

            var module = (PEModuleSymbol)methodOrType.ContainingModule;
            var id = module.Module.GetModuleVersionIdOrThrow();
            var moduleInstance = moduleInstances.First(m => m.ModuleVersionId == id);

            moduleVersionId = id;
            symReader = (ISymUnmanagedReader)moduleInstance.SymReader;

            EntityHandle methodOrTypeHandle;
            if (methodOrType.Kind == SymbolKind.Method)
            {
                methodOrTypeHandle = ((PEMethodSymbol)methodOrType).Handle;
                localSignatureToken = moduleInstance.GetLocalSignatureToken((MethodDefinitionHandle)methodOrTypeHandle);
            }
            else
            {
                methodOrTypeHandle = ((PENamedTypeSymbol)methodOrType).Handle;
                localSignatureToken = -1;
            }

            MetadataReader reader = null; // null should be ok
            methodOrTypeToken = reader.GetToken(methodOrTypeHandle);
        }
Beispiel #3
0
 private static void GetLocals(RuntimeInstance runtime, string methodName, bool argumentsOnly, ArrayBuilder<LocalAndMethod> locals, int count, out string typeName, out CompilationTestData testData)
 {
     var context = CreateMethodContext(runtime, methodName);
     testData = new CompilationTestData();
     var assembly = context.CompileGetLocals(locals, argumentsOnly, out typeName, testData);
     Assert.NotNull(assembly);
     if (count == 0)
     {
         Assert.Equal(0, assembly.Count);
     }
     else
     {
         Assert.InRange(assembly.Count, 0, int.MaxValue);
     }
     Assert.Equal(count, locals.Count);
 }
        public void TypeOutsideModule()
        {
            var sourceA =
@"using System;
public class A<T>
{
    public static void M(Action f)
    {
        object o;
        try
        {
            f();
        }
        catch (Exception)
        {
        }
    }
}";
            var sourceB =
@"using System;
class E : Exception
{
    internal object F;
}
class B
{
    static void Main()
    {
        A<int>.M(() => { throw new E(); });
    }
}";
            var assemblyNameA = "0A93FF0B-31A2-47C8-B24D-16A2D77AB5C5";
            var compilationA = CreateCompilationWithMscorlib(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA);
            byte[] exeA;
            byte[] pdbA;
            ImmutableArray<MetadataReference> referencesA;
            compilationA.EmitAndGetReferences(out exeA, out pdbA, out referencesA);
            var metadataA = AssemblyMetadata.CreateFromImage(exeA);
            var referenceA = metadataA.GetReference();

            var assemblyNameB = "9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9";
            var compilationB = CreateCompilationWithMscorlib(sourceB, options: TestOptions.DebugExe, references: new[] { referenceA }, assemblyName: assemblyNameB);
            byte[] exeB;
            byte[] pdbB;
            ImmutableArray<MetadataReference> referencesB;
            compilationB.EmitAndGetReferences(out exeB, out pdbB, out referencesB);
            var metadataB = AssemblyMetadata.CreateFromImage(exeB);
            var referenceB = metadataB.GetReference();

            var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            modulesBuilder.Add(MscorlibRef.ToModuleInstance(fullImage: null, symReader: null));
            modulesBuilder.Add(referenceA.ToModuleInstance(fullImage: exeA, symReader: new SymReader(pdbA)));
            modulesBuilder.Add(referenceB.ToModuleInstance(fullImage: exeB, symReader: new SymReader(pdbB)));
            modulesBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null));

            using (var runtime = new RuntimeInstance(modulesBuilder.ToImmutableAndFree()))
            {
                var context = CreateMethodContext(
                    runtime,
                    "A.M");
                var aliases = ImmutableArray.Create(
                        ExceptionAlias("E, 9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"),
                    ObjectIdAlias(1, "A`1[[B, 9BAC6622-86EB-4EC5-94A1-9A1E6D0C24B9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], 0A93FF0B-31A2-47C8-B24D-16A2D77AB5C5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"));
                string error;
                var testData = new CompilationTestData();
                context.CompileExpression(
                    "$exception",
                    DkmEvaluationFlags.TreatAsExpression,
                    aliases,
                    out error,
                    testData);
                Assert.Null(error);
                testData.GetMethodData("<>x<T>.<>m0").VerifyIL(
@"{
  // Code size       11 (0xb)
  .maxstack  1
  .locals init (object V_0) //o
  IL_0000:  call       ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()""
  IL_0005:  castclass  ""E""
  IL_000a:  ret
}");
                ResultProperties resultProperties;
                ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
                testData = new CompilationTestData();
                context.CompileAssignment(
                    "o",
                    "$1",
                    aliases,
                    DiagnosticFormatter.Instance,
                    out resultProperties,
                    out error,
                    out missingAssemblyIdentities,
                    EnsureEnglishUICulture.PreferredOrNull,
                    testData);
                Assert.Empty(missingAssemblyIdentities);
                Assert.Null(error);
                testData.GetMethodData("<>x<T>.<>m0").VerifyIL(
@"{
  // Code size       17 (0x11)
  .maxstack  1
  .locals init (object V_0) //o
  IL_0000:  ldstr      ""$1""
  IL_0005:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
  IL_000a:  castclass  ""A<B>""
  IL_000f:  stloc.0
  IL_0010:  ret
}");
            }
        }
Beispiel #5
0
 private static ImportChain GetImports(RuntimeInstance runtime, string methodName, Syntax.ExpressionSyntax syntax)
 {
     var evalContext = CreateMethodContext(
         runtime,
         methodName: methodName);
     var compContext = evalContext.CreateCompilationContext(syntax);
     return compContext.NamespaceBinder.ImportChain;
 }
Beispiel #6
0
        public void AssemblyQualifiedNameResolutionWithUnification()
        {
            var source1 = @"
using SI = System.Int32;

public class C1
{
    void M()
    {
    }
}
";

            var source2 = @"
public class C2 : C1
{
}
";
            ImmutableArray<MetadataReference> unused;

            var comp1 = CreateCompilation(source1, new[] { MscorlibRef_v20 }, TestOptions.DebugDll, assemblyName: "A");
            byte[] dllBytes1;
            byte[] pdbBytes1;
            comp1.EmitAndGetReferences(out dllBytes1, out pdbBytes1, out unused);
            var ref1 = AssemblyMetadata.CreateFromImage(dllBytes1).GetReference(display: "A");

            var comp2 = CreateCompilation(source2, new[] { MscorlibRef_v4_0_30316_17626, ref1 }, TestOptions.DebugDll, assemblyName: "B");
            byte[] dllBytes2;
            byte[] pdbBytes2;
            comp2.EmitAndGetReferences(out dllBytes2, out pdbBytes2, out unused);
            var ref2 = AssemblyMetadata.CreateFromImage(dllBytes2).GetReference(display: "B");

            var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            modulesBuilder.Add(ref1.ToModuleInstance(dllBytes1, SymReaderFactory.CreateReader(pdbBytes1)));
            modulesBuilder.Add(ref2.ToModuleInstance(dllBytes2, SymReaderFactory.CreateReader(pdbBytes2)));
            modulesBuilder.Add(MscorlibRef_v4_0_30316_17626.ToModuleInstance(fullImage: null, symReader: null));
            modulesBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null));

            using (var runtime = new RuntimeInstance(modulesBuilder.ToImmutableAndFree()))
            {
                var context = CreateMethodContext(runtime, "C1.M");

                string error;
                var testData = new CompilationTestData();
                context.CompileExpression("typeof(SI)", out error, testData);
                Assert.Null(error);

                testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldtoken    ""int""
  IL_0005:  call       ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
  IL_000a:  ret
}
");
            }
        }
        public void ModuleWithBadImageFormat()
        {
            var source = @"
class C
{
    int F = 1;
    static void M()
    {
    }
}";
            var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll, assemblyName: GetUniqueName());
            byte[] exeBytes;
            byte[] pdbBytes;
            ImmutableArray<MetadataReference> references;
            comp.EmitAndGetReferences(out exeBytes, out pdbBytes, out references);
            var exeReference = AssemblyMetadata.CreateFromImage(exeBytes).GetReference(display: Guid.NewGuid().ToString("D"));

            var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            var corruptMetadata = new ModuleInstance(
                metadataReference: null,
                moduleMetadata: null,
                moduleVersionId: default(Guid),
                fullImage: null,
                metadataOnly: CommonResources.NoValidTables,
                symReader: null,
                includeLocalSignatures: false);

            modulesBuilder.Add(corruptMetadata);
            modulesBuilder.Add(exeReference.ToModuleInstance(exeBytes, new SymReader(pdbBytes)));
            modulesBuilder.AddRange(references.Select(r => r.ToModuleInstance(fullImage: null, symReader: null)));
            var modules = modulesBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                var context = CreateMethodContext(runtime, "C.M");
                ResultProperties resultProperties;
                string error;
                var testData = new CompilationTestData();
                // Verify that we can still evaluate expressions for modules that are not corrupt.
                context.CompileExpression("(new C()).F", out resultProperties, out error, testData);
                Assert.Null(error);
                Assert.Equal(DkmClrCompilationResultFlags.None, resultProperties.Flags);
                testData.GetMethodData("<>x.<>m0").VerifyIL(@"
{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  newobj     ""C..ctor()""
  IL_0005:  ldfld      ""int C.F""
  IL_000a:  ret
}");
            }
        }
        internal static EvaluationContext CreateMethodContext(
            RuntimeInstance runtime,
            string methodName,
            int atLineNumber = -1)
        {
            ImmutableArray<MetadataBlock> blocks;
            Guid moduleVersionId;
            ISymUnmanagedReader symReader;
            int methodToken;
            int localSignatureToken;
            GetContextState(runtime, methodName, out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);

            uint ilOffset = ExpressionCompilerTestHelpers.GetOffset(methodToken, symReader, atLineNumber);

            return EvaluationContext.CreateMethodContext(
                default(CSharpMetadataContext),
                blocks,
                symReader,
                moduleVersionId,
                methodToken: methodToken,
                methodVersion: 1,
                ilOffset: ilOffset,
                localSignatureToken: localSignatureToken);
        }
 internal static EvaluationContext CreateTypeContext(
     RuntimeInstance runtime,
     string typeName)
 {
     ImmutableArray<MetadataBlock> blocks;
     Guid moduleVersionId;
     ISymUnmanagedReader symReader;
     int typeToken;
     int localSignatureToken;
     GetContextState(runtime, typeName, out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
     return EvaluationContext.CreateTypeContext(
         default(CSharpMetadataContext),
         blocks,
         moduleVersionId,
         typeToken);
 }
        public void MissingMscorlib()
        {
            var sourceA =
@"public class A
{
}
class B
{
}
class C
{
}";
            var sourceB =
@"public class B : A
{
}";
            var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationA = CreateCompilation(
                sourceA,
                references: new MetadataReference[] { SystemRuntimePP7Ref },
                options: TestOptions.DebugDll,
                assemblyName: assemblyNameA);
            byte[] exeBytesA;
            byte[] pdbBytesA;
            ImmutableArray<MetadataReference> referencesA;
            compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA);
            var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA);
            var identityA = referenceA.GetAssemblyIdentity();
            var moduleA = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA));

            var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationB = CreateCompilation(
                sourceB,
                references: new MetadataReference[] { SystemRuntimePP7Ref, referenceA },
                options: TestOptions.DebugDll,
                assemblyName: assemblyNameB);
            byte[] exeBytesB;
            byte[] pdbBytesB;
            ImmutableArray<MetadataReference> referencesB;
            compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB);
            var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
            var moduleB = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB));

            // At runtime System.Runtime.dll contract assembly is replaced
            // by mscorlib.dll and System.Runtime.dll facade assemblies.
            var moduleBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            moduleBuilder.Add(MscorlibFacadeRef.ToModuleInstance(null, null));
            moduleBuilder.Add(SystemRuntimeFacadeRef.ToModuleInstance(null, null));
            moduleBuilder.Add(moduleA);
            moduleBuilder.Add(moduleB);
            var modules = moduleBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                ImmutableArray<MetadataBlock> blocks;
                Guid moduleVersionId;
                ISymUnmanagedReader symReader;
                int typeToken;
                int localSignatureToken;
                GetContextState(runtime, "C", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
                string errorMessage;
                CompilationTestData testData;
                int attempts = 0;
                ExpressionCompiler.CreateContextDelegate contextFactory = (b, u) =>
                {
                    attempts++;
                    return EvaluationContext.CreateTypeContext(
                        ToCompilation(b, u, moduleVersionId),
                        moduleVersionId,
                        typeToken);
                };

                // Compile: [DebuggerDisplay("{new B()}")]
                const string expr = "new B()";
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, expr, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                Assert.Equal(2, attempts);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  newobj     ""B..ctor()""
  IL_0005:  ret
}");
            }
        }
Beispiel #11
0
        public void PIATypeAndEmbeddedType()
        {
            var sourcePIA =
@"using System.Runtime.InteropServices;
[assembly: PrimaryInteropAssembly(0, 0)]
[assembly: Guid(""863D5BC0-46A1-49AC-97AA-A5F0D441A9DC"")]
[ComImport]
[Guid(""863D5BC0-46A1-49AD-97AA-A5F0D441A9DC"")]
public interface I
{
    object F();
}";
            var sourceA =
@"public class A
{
    public static void M(I x)
    {
    }
}";
            var sourceB =
@"class B
{
    static void Main()
    {
        I y = null;
        A.M(y);
    }
}";
            var compilationPIA = CreateCompilationWithMscorlib(sourcePIA, options: TestOptions.DebugDll);
            byte[] exePIA;
            byte[] pdbPIA;
            ImmutableArray<MetadataReference> referencesPIA;
            compilationPIA.EmitAndGetReferences(out exePIA, out pdbPIA, out referencesPIA);
            var metadataPIA = AssemblyMetadata.CreateFromImage(exePIA);
            var referencePIA = metadataPIA.GetReference();

            // csc /t:library /l:PIA.dll A.cs
            var compilationA = CreateCompilationWithMscorlib(
                sourceA,
                options: TestOptions.DebugDll,
                assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(),
                references: new MetadataReference[] { metadataPIA.GetReference(embedInteropTypes: true) });
            byte[] exeA;
            byte[] pdbA;
            ImmutableArray<MetadataReference> referencesA;
            compilationA.EmitAndGetReferences(out exeA, out pdbA, out referencesA);
            var metadataA = AssemblyMetadata.CreateFromImage(exeA);
            var referenceA = metadataA.GetReference();

            // csc /r:A.dll /r:PIA.dll B.cs
            var compilationB = CreateCompilationWithMscorlib(
                sourceB,
                options: TestOptions.DebugExe,
                assemblyName: Guid.NewGuid().ToString("D"),
                references: new MetadataReference[] { metadataA.GetReference(), metadataPIA.GetReference() });
            byte[] exeB;
            byte[] pdbB;
            ImmutableArray<MetadataReference> referencesB;
            compilationB.EmitAndGetReferences(out exeB, out pdbB, out referencesB);
            var metadataB = AssemblyMetadata.CreateFromImage(exeB);
            var referenceB = metadataB.GetReference();

            // Create runtime from modules { mscorlib, PIA, A, B }.
            var modulesBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            modulesBuilder.Add(MscorlibRef.ToModuleInstance(fullImage: null, symReader: null));
            modulesBuilder.Add(referenceA.ToModuleInstance(fullImage: exeA, symReader: new SymReader(pdbA)));
            modulesBuilder.Add(referencePIA.ToModuleInstance(fullImage: null, symReader: null));
            modulesBuilder.Add(referenceB.ToModuleInstance(fullImage: exeB, symReader: new SymReader(pdbB)));

            using (var runtime = new RuntimeInstance(modulesBuilder.ToImmutableAndFree()))
            {
                var context = CreateMethodContext(runtime, "A.M");
                ResultProperties resultProperties;
                string error;

                // Bind to local of embedded PIA type.
                var testData = new CompilationTestData();
                context.CompileExpression("x", out error, testData);
                Assert.Null(error);
                testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  ret
}");

                // Binding to method on original PIA should fail
                // since it was not included in embedded type.
                ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
                context.CompileExpression(
                    "x.F()",
                    DkmEvaluationFlags.TreatAsExpression,
                    NoAliases,
                    DebuggerDiagnosticFormatter.Instance,
                    out resultProperties,
                    out error,
                    out missingAssemblyIdentities,
                    EnsureEnglishUICulture.PreferredOrNull,
                    testData: null);
                AssertEx.SetEqual(missingAssemblyIdentities, EvaluationContextBase.SystemCoreIdentity);
                Assert.Equal(error, "error CS1061: 'I' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'I' could be found (are you missing a using directive or an assembly reference?)");

                // Binding to method on original PIA should succeed
                // in assembly referencing PIA.dll.
                context = CreateMethodContext(runtime, "B.Main");
                testData = new CompilationTestData();
                context.CompileExpression("y.F()", out error, testData);
                Assert.Null(error);
                testData.GetMethodData("<>x.<>m0").VerifyIL(
@"{
  // Code size        7 (0x7)
  .maxstack  1
  .locals init (I V_0) //y
  IL_0000:  ldloc.0
  IL_0001:  callvirt   ""object I.F()""
  IL_0006:  ret
}");
            }
        }
        public void DuplicateTypesAndMethodsDifferentAssemblies()
        {
            var sourceA =
@"using N;
namespace N
{
    class C1 { }
    public static class E
    {
        public static A F(this A o) { return o; }
    }
}
class C2 { }
public class A
{
    public static void M()
    {
        var x = new A();
        var y = x.F();
    }
}";
            var sourceB =
@"using N;
namespace N
{
    class C1 { }
    public static class E
    {
        public static int F(this A o) { return 2; }
    }
}
class C2 { }
public class B
{
    static void M()
    {
        var x = new A();
    }
}";
            var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA);
            byte[] exeBytesA;
            byte[] pdbBytesA;
            ImmutableArray<MetadataReference> referencesA;
            compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA);
            var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA);
            var identityA = referenceA.GetAssemblyIdentity();
            var moduleA = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA));

            var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, assemblyName: assemblyNameB, references: new[] { referenceA });
            byte[] exeBytesB;
            byte[] pdbBytesB;
            ImmutableArray<MetadataReference> referencesB;
            compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB);
            var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
            var moduleB = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB));

            var moduleBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            moduleBuilder.AddRange(referencesA.Select(r => r.ToModuleInstance(null, null)));
            moduleBuilder.Add(moduleA);
            moduleBuilder.Add(moduleB);
            var modules = moduleBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                ImmutableArray<MetadataBlock> blocks;
                Guid moduleVersionId;
                ISymUnmanagedReader symReader;
                int typeToken;
                int methodToken;
                int localSignatureToken;
                GetContextState(runtime, "B", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
                string errorMessage;
                CompilationTestData testData;
                var contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken);

                // Duplicate type in namespace, at type scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both "));

                GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken);

                // Duplicate type in namespace, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both "));

                // Duplicate type in global namespace, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.True(errorMessage.StartsWith("error CS0433: The type 'C2' exists in both "));

                // Duplicate extension method, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Equal(errorMessage, "(1,3): error CS0121: The call is ambiguous between the following methods or properties: 'N.E.F(A)' and 'N.E.F(A)'");

                // Same tests as above but in library that does not directly reference duplicates.
                GetContextState(runtime, "A", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
                contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken);

                // Duplicate type in namespace, at type scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  newobj     ""N.C1..ctor()""
  IL_0005:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());

                GetContextState(runtime, "A.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken);

                // Duplicate type in global namespace, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size        6 (0x6)
  .maxstack  1
  .locals init (A V_0, //x
                A V_1) //y
  IL_0000:  newobj     ""C2..ctor()""
  IL_0005:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());

                // Duplicate extension method, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size        7 (0x7)
  .maxstack  1
  .locals init (A V_0, //x
                A V_1) //y
  IL_0000:  ldloc.0
  IL_0001:  call       ""A N.E.F(A)""
  IL_0006:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());
            }
        }
 private static void VerifyAssemblyReferences(
     MetadataReference target,
     ImmutableArray<MetadataReference> references,
     ImmutableArray<AssemblyIdentity> expectedIdentities)
 {
     Assert.True(references.Contains(target));
     var modules = references.SelectAsArray(r => r.ToModuleInstance(fullImage: null, symReader: null, includeLocalSignatures: false));
     using (var runtime = new RuntimeInstance(modules))
     {
         var moduleVersionId = target.GetModuleVersionId();
         var blocks = runtime.Modules.SelectAsArray(m => m.MetadataBlock);
         var actualReferences = blocks.MakeAssemblyReferences(moduleVersionId, Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CompilationExtensions.IdentityComparer);
         // Verify identities.
         var actualIdentities = actualReferences.SelectAsArray(r => r.GetAssemblyIdentity());
         AssertEx.Equal(expectedIdentities, actualIdentities);
         // Verify identities are unique.
         var uniqueIdentities = actualIdentities.Distinct();
         Assert.Equal(actualIdentities.Length, uniqueIdentities.Length);
     }
 }
Beispiel #14
0
        private static void GetLocals(RuntimeInstance runtime, string methodName, MethodDebugInfoBytes debugInfo, ArrayBuilder<LocalAndMethod> locals, int count)
        {
            ImmutableArray<MetadataBlock> blocks;
            Guid moduleVersionId;
            ISymUnmanagedReader unused;
            int methodToken;
            int localSignatureToken;
            GetContextState(runtime, methodName, out blocks, out moduleVersionId, out unused, out methodToken, out localSignatureToken);

            var symReader = new MockSymUnmanagedReader(
                new Dictionary<int, MethodDebugInfoBytes>()
                {
                    {methodToken, debugInfo}
                }.ToImmutableDictionary());
            var context = EvaluationContext.CreateMethodContext(
                default(CSharpMetadataContext),
                blocks,
                symReader,
                moduleVersionId,
                methodToken,
                methodVersion: 1,
                ilOffset: 0,
                localSignatureToken: localSignatureToken);

            string typeName;
            var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: null);

            Assert.NotNull(assembly);
            if (count == 0)
            {
                Assert.Equal(0, assembly.Count);
            }
            else
            {
                Assert.InRange(assembly.Count, 0, int.MaxValue);
            }
            Assert.Equal(count, locals.Count);
        }
        public void DuplicateTypesInMscorlib()
        {
            var sourceConsole =
@"namespace System
{
    public class Console
    {
    }
}";
            var sourceObjectModel =
@"namespace System.Collections.ObjectModel
{
    public class ReadOnlyDictionary<K, V>
    {
    }
}";
            var source =
@"class C
{
    static void Main()
    {
        var t = typeof(System.Console);
        var o = (System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null;
    }
}";
            var systemConsoleComp = CreateCompilationWithMscorlib(sourceConsole, options: TestOptions.DebugDll, assemblyName: "System.Console");
            var systemConsoleRef = systemConsoleComp.EmitToImageReference();
            var systemObjectModelComp = CreateCompilationWithMscorlib(sourceObjectModel, options: TestOptions.DebugDll, assemblyName: "System.ObjectModel");
            var systemObjectModelRef = systemObjectModelComp.EmitToImageReference();
            var identityObjectModel = systemObjectModelRef.GetAssemblyIdentity();

            // At runtime System.Runtime.dll contract assembly is replaced
            // by mscorlib.dll and System.Runtime.dll facade assemblies;
            // System.Console.dll and System.ObjectModel.dll are not replaced.

            // Test different ordering of modules containing duplicates:
            // { System.Console, mscorlib } and { mscorlib, System.ObjectModel }.
            var contractReferences = ImmutableArray.Create(systemConsoleRef, SystemRuntimePP7Ref, systemObjectModelRef);
            var runtimeReferences = ImmutableArray.Create(systemConsoleRef, MscorlibFacadeRef, SystemRuntimeFacadeRef, systemObjectModelRef);

            // Verify the compiler reports duplicate types with facade assemblies.
            var compilation = CreateCompilation(
                source,
                references: runtimeReferences,
                options: TestOptions.DebugDll,
                assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
            compilation.VerifyDiagnostics(
                // (5,31): error CS0433: The type 'Console' exists in both 'System.Console, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
                //         var t = typeof(System.Console);
                Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "Console").WithArguments("System.Console, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Console", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(5, 31),
                // (6,49): error CS0433: The type 'ReadOnlyDictionary<K, V>' exists in both 'System.ObjectModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
                //         var o = (System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null;
                Diagnostic(ErrorCode.ERR_SameFullNameAggAgg, "ReadOnlyDictionary<object, object>").WithArguments("System.ObjectModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "System.Collections.ObjectModel.ReadOnlyDictionary<K, V>", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").WithLocation(6, 49));

            // EE should not report duplicate type when the original source
            // is compiled with contract assemblies and the EE expression
            // is compiled with facade assemblies.
            compilation = CreateCompilation(
                source,
                references: contractReferences,
                options: TestOptions.DebugDll,
                assemblyName: ExpressionCompilerUtilities.GenerateUniqueName());
            var reference = compilation.EmitToImageReference();

            var modules = runtimeReferences.Add(reference).SelectAsArray(r => r.ToModuleInstance(null, null));
            using (var runtime = new RuntimeInstance(modules))
            {
                var context = CreateMethodContext(runtime, "C.Main");
                string errorMessage;
                // { System.Console, mscorlib }
                var testData = new CompilationTestData();
                context.CompileExpression("typeof(System.Console)", out errorMessage, testData);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldtoken    ""System.Console""
  IL_0005:  call       ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
  IL_000a:  ret
}");
                // { mscorlib, System.ObjectModel }
                testData = new CompilationTestData();
                context.CompileExpression("(System.Collections.ObjectModel.ReadOnlyDictionary<object, object>)null", out errorMessage, testData);
                methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size        2 (0x2)
  .maxstack  1
  IL_0000:  ldnull
  IL_0001:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityObjectModel.GetDisplayName());
            }
        }
        public void IntrinsicMethods()
        {
            var sourceA =
@"public class A { }";
            var sourceB =
@"public class A { }
public class B
{
    static void M(A a)
    {
    }
}";
            var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA);
            byte[] exeBytesA;
            byte[] pdbBytesA;
            ImmutableArray<MetadataReference> referencesA;
            compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA);
            var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA);
            var identityA = referenceA.GetAssemblyIdentity();
            var moduleA = referenceA.ToModuleInstance(exeBytesA, SymReaderFactory.CreateReader(pdbBytesA));

            var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, assemblyName: assemblyNameB, references: new[] { referenceA });
            byte[] exeBytesB;
            byte[] pdbBytesB;
            ImmutableArray<MetadataReference> referencesB;
            compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB);
            var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
            var moduleB = referenceB.ToModuleInstance(exeBytesB, SymReaderFactory.CreateReader(pdbBytesB));

            var moduleBuilder = ArrayBuilder<ModuleInstance>.GetInstance();
            moduleBuilder.AddRange(referencesA.Select(r => r.ToModuleInstance(null, null)));
            moduleBuilder.Add(moduleA);
            moduleBuilder.Add(moduleB);
            moduleBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null));
            var modules = moduleBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                ImmutableArray<MetadataBlock> blocks;
                Guid moduleVersionId;
                ISymUnmanagedReader symReader;
                int methodToken;
                int localSignatureToken;
                GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                var aliases = ImmutableArray.Create(
                    ExceptionAlias(typeof(ArgumentException)),
                    ReturnValueAlias(2, typeof(string)),
                    ObjectIdAlias(1, typeof(object)));
                int attempts = 0;
                ExpressionCompiler.CreateContextDelegate contextFactory = (b, u) =>
                {
                    attempts++;
                    return EvaluationContext.CreateMethodContext(
                        ToCompilation(b, u, moduleVersionId),
                        symReader,
                        moduleVersionId,
                        methodToken,
                        methodVersion: 1,
                        ilOffset: 0,
                        localSignatureToken: localSignatureToken);
                };
                string errorMessage;
                CompilationTestData testData;
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                    blocks,
                    "(object)new A() ?? $exception ?? $1 ?? $ReturnValue2",
                    aliases,
                    contextFactory,
                    getMetaDataBytesPtr: null,
                    errorMessage: out errorMessage,
                    testData: out testData);
                Assert.Null(errorMessage);
                Assert.Equal(2, attempts);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
@"{
  // Code size       49 (0x31)
  .maxstack  2
  IL_0000:  newobj     ""A..ctor()""
  IL_0005:  dup
  IL_0006:  brtrue.s   IL_0030
  IL_0008:  pop
  IL_0009:  call       ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()""
  IL_000e:  castclass  ""System.ArgumentException""
  IL_0013:  dup
  IL_0014:  brtrue.s   IL_0030
  IL_0016:  pop
  IL_0017:  ldstr      ""$1""
  IL_001c:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
  IL_0021:  dup
  IL_0022:  brtrue.s   IL_0030
  IL_0024:  pop
  IL_0025:  ldc.i4.2
  IL_0026:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)""
  IL_002b:  castclass  ""string""
  IL_0030:  ret
}");
            }
        }