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)); }
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 )); }
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)); } }
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); }
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); } }
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 ) ); }