private static MetadataReference GetIntrinsicAssemblyReference()
        {
            var source =
                @".assembly extern mscorlib { }
.class public Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods
{
  .method public static object GetObjectAtAddress(uint64 address)
  {
    ldnull
    throw
  }
  .method public static class [mscorlib]System.Exception GetException()
  {
    ldnull
    throw
  }
  .method public static class [mscorlib]System.Exception GetStowedException()
  {
    ldnull
    throw
  }
  .method public static object GetReturnValue(int32 index)
  {
    ldnull
    throw
  }
  .method public static void CreateVariable(class [mscorlib]System.Type 'type', string name, valuetype [mscorlib]System.Guid customTypeInfoPayloadTypeId, uint8[] customTypeInfoPayload)
  {
    ldnull
    throw
  }
  .method public static object GetObjectByAlias(string name)
  {
    ldnull
    throw
  }
  .method public static !!T& GetVariableAddress<T>(string name)
  {
    ldnull
    throw
  }
}";

            return(CommonTestBase.CompileIL(source));
        }
Example #2
0
        internal static ModuleInstance GetModuleInstanceForIL(string ilSource)
        {
            ImmutableArray <byte> peBytes;
            ImmutableArray <byte> pdbBytes;

            CommonTestBase.EmitILToArray(
                ilSource,
                appendDefaultHeader: true,
                includePdb: true,
                assemblyBytes: out peBytes,
                pdbBytes: out pdbBytes
                );
            return(ModuleInstance.Create(
                       peBytes,
                       SymReaderFactory.CreateReader(pdbBytes),
                       includeLocalSignatures: true
                       ));
        }
Example #3
0
        internal static MetadataReference CreateReflectionEmitAssembly(Action <ModuleBuilder> create)
        {
            using (var file = new DisposableFile(extension: ".dll"))
            {
                var name      = Path.GetFileName(file.Path);
                var appDomain = AppDomain.CurrentDomain;
                var assembly  = appDomain.DefineDynamicAssembly(
                    new AssemblyName(name),
                    AssemblyBuilderAccess.Save,
                    Path.GetDirectoryName(file.Path)
                    );
                var module = assembly.DefineDynamicModule(CommonTestBase.GetUniqueName(), name);
                create(module);
                assembly.Save(name);

                var image = CommonTestBase.ReadFromFile(file.Path);
                return(MetadataReference.CreateFromImage(image));
            }
        }
Example #4
0
        static internal CommonTestBase.CompilationVerifier ReflectionEmit(
            CommonTestBase test,
            Compilation compilation,
            IEnumerable <ModuleData> dependencies,
            TestEmitters emitOptions,
            IEnumerable <ResourceDescription> manifestResources,
            SignatureDescription[] expectedSignatures,
            string expectedOutput,
            Action <PEAssembly, TestEmitters> assemblyValidator,
            Action <IModuleSymbol, TestEmitters> symbolValidator,
            bool collectEmittedAssembly,
            bool verify)
        {
            CommonTestBase.CompilationVerifier verifier = null;

            ReflectionEmitter emit = (refEmitSupported, fallback) =>
            {
                bool requestPEImage = verify || assemblyValidator != null || symbolValidator != null;
                ImmutableArray <byte> peImage;

                // TODO(tomat): we should ref.emit in the AppDomain where we load all the dependencies, otherwise ref.emit fails to emit compilation-compilation references.
                bool emitSuccess = ReflectionEmitInternal(compilation,
                                                          expectedOutput,
                                                          requestPEImage,
                                                          out peImage,
                                                          refEmitSupported,
                                                          fallback,
                                                          collectEmittedAssembly,
                                                          peVerify: verify,
                                                          tempRoot: verifier.Temp);

                Assert.Equal(!peImage.IsDefault, requestPEImage && emitSuccess);

                if (!peImage.IsDefault)
                {
                    // TODO(tomat):
                    // We assume that we CompileAndVerify(verify: true) is called if we are going to use VerifyIL.
                    // Ideally expected IL would be a parameter of CompileAndVerify so we know that we need to get the pe image.
                    verifier.EmittedAssemblyData = peImage;
                }

                return(emitSuccess);
            };

            if (emitOptions != TestEmitters.RefEmitBug)
            {
                verifier = new CommonTestBase.CompilationVerifier(test, compilation, dependencies);

                if (emitOptions == TestEmitters.RefEmitUnsupported)
                {
                    // Test that Ref.Emit fails.
                    // The code contains features not supported by Ref.Emit, don't fall back to CCI to test the failure.
                    Assert.False(
                        emit(refEmitSupported: false, fallback: false));

                    // test that Emit falls back to CCI:
                    Assert.True(
                        emit(refEmitSupported: false, fallback: true));
                }
                else
                {
                    // The code should only contain features supported by Ref.Emit.
                    Assert.True(
                        emit(refEmitSupported: true, fallback: false));
                }

                // We're dual-purposing EmitOptions here.  In this context, it
                // tells the validator the version of Emit that is calling it.
                CommonTestBase.RunValidators(verifier, TestEmitters.RefEmit, assemblyValidator, symbolValidator);
            }

            return((emitOptions == TestEmitters.RefEmit) ? verifier : null);
        }
Example #5
0
        private static bool ReflectionEmitInternal(
            Compilation compilation,
            string expectedOutput,
            bool peImageRequested,
            out ImmutableArray <byte> peImage,
            bool refEmitSupported,
            bool fallback,
            bool collectEmittedAssembly,
            bool peVerify,
            TempRoot tempRoot)
        {
            peImage = default(ImmutableArray <byte>);

            var success = false;
            var compilationDependencies = new List <ModuleData>();
            var diagnostics             = new DiagnosticBag();

            HostedRuntimeEnvironment.EmitReferences(compilation, compilationDependencies, diagnostics);

            // allow warnings
            if (diagnostics.HasAnyErrors())
            {
                // this will throw if there are errors
                diagnostics.Verify();
            }

            bool doExecute = expectedOutput != null;

            string fileName;
            string fileNameExt;
            string fileDir;

            TempFile outputFile;
            AssemblyBuilderAccess access;

            if (peImageRequested)
            {
                access = doExecute ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Save;

                // Until HostedExecutionEnvironment supports ref emit, we need to generate a unique temp file.
                // Otherwise, the file will be held open the next time we Emit this same compilation (done in CompileAndVerify).
                outputFile = tempRoot.CreateFile("RefEmit_", ".dll");

                fileNameExt = Path.GetFileName(outputFile.Path);
                fileName    = Path.GetFileNameWithoutExtension(fileNameExt);
                fileDir     = Path.GetDirectoryName(outputFile.Path);
            }
            else
            {
                outputFile = null;

                fileName    = CommonTestBase.GetUniqueName();
                fileNameExt = fileName + ".dll";
                fileDir     = null;

                access = collectEmittedAssembly ? AssemblyBuilderAccess.RunAndCollect : AssemblyBuilderAccess.Run;
            }

            var             assemblyName = new AssemblyIdentity(fileName).ToAssemblyName();
            AssemblyBuilder abuilder     = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, access, fileDir);
            ModuleBuilder   mbuilder     = abuilder.DefineDynamicModule("Module", fileNameExt, emitSymbolInfo: false);

            using (var assemblyManager = new RuntimeAssemblyManager())
            {
                assemblyManager.AddModuleData(compilationDependencies);

                DiagnosticBag emitDiagnostics = DiagnosticBag.GetInstance();
                MethodInfo    entryPoint;

                byte[] compiledAssemblyImage;

                success = compilation.Emit(
                    moduleBuilder: mbuilder,
                    assemblyLoader: new AssemblyLoader(assemblyManager),
                    assemblySymbolMapper: null,
                    recoverOnError: !refEmitSupported && fallback,
                    diagnostics: emitDiagnostics,
                    cancellationToken: default(CancellationToken),
                    entryPoint: out entryPoint,
                    compiledAssemblyImage: out compiledAssemblyImage
                    );

                emitDiagnostics.Free();

                if (success && peImageRequested)
                {
                    if (fallback)
                    {
                        peImage = compiledAssemblyImage.AsImmutableOrNull();
                    }
                    else
                    {
                        abuilder.Save(fileNameExt);
                        peImage = CommonTestBase.ReadFromFile(outputFile.Path);
                    }
                }

                if (refEmitSupported)
                {
                    Assert.True(success, "Expected Ref.Emit success");
                    Assert.Null(compiledAssemblyImage);
                }
                else if (fallback)
                {
                    Assert.True(success, "Expected fallback to CCI");
                    Assert.NotNull(compiledAssemblyImage);
                }
                else
                {
                    Assert.False(success, "Expected emit failure but it succeeded");
                    Assert.Null(compiledAssemblyImage);
                }

                if (success)
                {
                    if (peVerify)
                    {
                        Assert.False(peImage.IsDefault);

                        // Saving AssemblyBuilder to disk changes its manifest module MVID.
                        Guid mvid;
                        using (var metadata = ModuleMetadata.CreateFromImage(peImage))
                        {
                            mvid = metadata.GetModuleVersionId();
                        }

                        assemblyManager.AddMainModuleMvid(mvid);
#if !(ARM)
                        Assert.Equal(String.Empty, CLRHelpers.PeVerify(peImage).Concat());
#endif
                    }

                    if (doExecute)
                    {
                        Assert.NotNull(entryPoint);
                        assemblyManager.AddMainModuleMvid(entryPoint.Module.ModuleVersionId);

                        Action main = GetEntryPointAction(entryPoint);
                        ConsoleOutput.AssertEqual(main, expectedOutput, "");
                    }
                }

                return(success);
            }
        }
Example #6
0
        public void TypeVariables()
        {
            var intrinsicSource =
                @".class private abstract sealed beforefieldinit specialname '<>c__TypeVariables'<T,U,V>
{
  .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
}";
            ImmutableArray <byte> assemblyBytes;
            ImmutableArray <byte> pdbBytes;

            CommonTestBase.EmitILToArray(
                intrinsicSource,
                appendDefaultHeader: true,
                includePdb: false,
                assemblyBytes: out assemblyBytes,
                pdbBytes: out pdbBytes
                );
            var assembly       = ReflectionUtilities.Load(assemblyBytes);
            var reflectionType = assembly
                                 .GetType(ExpressionCompilerConstants.TypeVariablesClassName)
                                 .MakeGenericType(new[] { typeof(object), typeof(object), typeof(object[]) });
            var value = CreateDkmClrValue(
                value: null,
                type: reflectionType,
                valueFlags: DkmClrValueFlags.Synthetic
                );
            var evalResult = FormatResult(
                "typevars",
                "typevars",
                value,
                new DkmClrType((TypeImpl)reflectionType),
                MakeCustomTypeInfo(false, true, false, false, true)
                );

            Verify(
                evalResult,
                EvalResult(
                    "Type variables",
                    "",
                    "",
                    null,
                    DkmEvaluationResultFlags.Expandable | DkmEvaluationResultFlags.ReadOnly,
                    DkmEvaluationResultCategory.Data
                    )
                );
            var children = GetChildren(evalResult);

            Verify(
                children,
                EvalResult(
                    "T",
                    "dynamic",
                    "dynamic",
                    null,
                    DkmEvaluationResultFlags.ReadOnly,
                    DkmEvaluationResultCategory.Data
                    ),
                EvalResult(
                    "U",
                    "object",
                    "object",
                    null,
                    DkmEvaluationResultFlags.ReadOnly,
                    DkmEvaluationResultCategory.Data
                    ),
                EvalResult(
                    "V",
                    "dynamic[]",
                    "dynamic[]",
                    null,
                    DkmEvaluationResultFlags.ReadOnly,
                    DkmEvaluationResultCategory.Data
                    )
                );
        }