private void CreateAssemblyManager(IEnumerable <ModuleData> compilationDependencies, ModuleData mainModule) { var allModules = compilationDependencies; if (_additionalDependencies != null) { allModules = allModules.Concat(_additionalDependencies); } // We need to add the main module so that it gets checked against already loaded assembly names. // If an assembly is loaded directly via PEVerify(image) another assembly of the same full name // can't be loaded as a dependency (via Assembly.ReflectionOnlyLoad) in the same domain. if (mainModule != null) { allModules = allModules.Concat(new[] { mainModule }); } allModules = allModules.ToArray(); string conflict = DetectNameCollision(allModules); if (conflict != null && !CLRHelpers.IsRunningOnMono()) { Type appDomainProxyType = typeof(RuntimeAssemblyManager); Assembly thisAssembly = appDomainProxyType.Assembly; AppDomain appDomain = null; RuntimeAssemblyManager manager; try { appDomain = AppDomain.CreateDomain("HostedRuntimeEnvironment", null, AppDomain.CurrentDomain.BaseDirectory, null, false); manager = (RuntimeAssemblyManager)appDomain.CreateInstanceAndUnwrap(thisAssembly.FullName, appDomainProxyType.FullName); } catch { if (appDomain != null) { AppDomain.Unload(appDomain); } throw; } _domain = appDomain; _assemblyManager = manager; } else { _assemblyManager = new RuntimeAssemblyManager(); } _assemblyManager.AddModuleData(allModules); if (mainModule != null) { _assemblyManager.AddMainModuleMvid(mainModule.Mvid); } }
private void AssemblyLoad(object sender, AssemblyLoadEventArgs args) { var assembly = args.LoadedAssembly; // ModuleResolve needs to be hooked up for the main assembly once its loaded. // We won't get an AssemblyResolve event for the main assembly so we need to do it here. if (_mainMvids.Contains(assembly.ManifestModule.ModuleVersionId) && _loadedAssemblies.Add(assembly)) { if (!CLRHelpers.IsRunningOnMono()) { assembly.ModuleResolve += ModuleResolve; } } }
internal static bool EmitCompilation( Compilation compilation, IEnumerable <ResourceDescription> manifestResources, List <ModuleData> dependencies, DiagnosticBag diagnostics, CompilationTestData testData, out ImmutableArray <byte> assembly, out ImmutableArray <byte> pdb ) { assembly = default(ImmutableArray <byte>); pdb = default(ImmutableArray <byte>); EmitReferences(compilation, dependencies, diagnostics); using (var executableStream = new MemoryStream()) { MemoryStream pdbStream = CLRHelpers.IsRunningOnMono() ? null : new MemoryStream(); EmitResult result; try { result = compilation.Emit( executableStream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: manifestResources, options: EmitOptions.Default, testData: testData, getHostDiagnostics: null, cancellationToken: default(CancellationToken)); } finally { if (pdbStream != null) { pdb = pdbStream.ToImmutable(); pdbStream.Dispose(); } } diagnostics.AddRange(result.Diagnostics); assembly = executableStream.ToImmutable(); return(result.Success); } }
internal Assembly GetAssembly(string fullName, bool reflectionOnly) { ModuleData data; if (!_modules.TryGetValue(fullName, out data)) { return(null); } ConcurrentDictionary <Guid, Assembly> cache = reflectionOnly ? s_domainReflectionOnlyAssemblyCache : s_domainAssemblyCache; var assembly = cache.GetOrAdd(data.Mvid, _ => LoadAsAssembly(data.Image, reflectionOnly)); if (!CLRHelpers.IsRunningOnMono()) { assembly.ModuleResolve += ModuleResolve; } _loadedAssemblies.Add(assembly); return(assembly); }
internal static ImmutableArray <byte> EmitToArray( this Compilation compilation, EmitOptions options = null, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null, Stream pdbStream = null) { var stream = new MemoryStream(); if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug) { if (CLRHelpers.IsRunningOnMono()) { options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb); } pdbStream = new MemoryStream(); } var emitResult = compilation.Emit( peStream: stream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: null, options: options, testData: testData, getHostDiagnostics: null, cancellationToken: default(CancellationToken)); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return(stream.ToImmutable()); }
public void Dispose() { // clean up our handlers, so that they don't accumulate AppDomain.CurrentDomain.AssemblyResolve -= AssemblyResolve; AppDomain.CurrentDomain.AssemblyLoad -= AssemblyLoad; CLRHelpers.ReflectionOnlyAssemblyResolve -= ReflectionOnlyAssemblyResolve; foreach (var assembly in _loadedAssemblies) { if (!CLRHelpers.IsRunningOnMono()) { assembly.ModuleResolve -= ModuleResolve; } } //EDMAURER Some RuntimeAssemblyManagers are created via reflection in an AppDomain of our creation. //Sometimes those AppDomains are not released. I don't fully understand how that appdomain roots //a RuntimeAssemblyManager, but according to heap dumps, it does. Even though the appdomain is not //unloaded, its RuntimeAssemblyManager is explicitly disposed. So make sure that it cleans up this //memory hog - the modules dictionary. _modules.Clear(); }
public static void IlasmTempAssembly(string declarations, bool appendDefaultHeader, bool includePdb, out string assemblyPath, out string pdbPath) { if (declarations == null) { throw new ArgumentNullException(nameof(declarations)); } using (var sourceFile = new DisposableFile(extension: ".il")) { string sourceFileName = Path.GetFileNameWithoutExtension(sourceFile.Path); assemblyPath = Path.Combine( TempRoot.Root, Path.ChangeExtension(Path.GetFileName(sourceFile.Path), "dll")); string completeIL; if (appendDefaultHeader) { completeIL = string.Format( @".assembly '{0}' {{}} .assembly extern mscorlib {{ .publickeytoken = (B7 7A 5C 56 19 34 E0 89) .ver 4:0:0:0 }} {1}", sourceFileName, declarations); } else { completeIL = declarations.Replace("<<GeneratedFileName>>", sourceFileName); } sourceFile.WriteAllText(completeIL); var ilasmPath = Path.Combine( Path.GetDirectoryName(typeof(object).Assembly.Location), "ilasm.exe"); var arguments = string.Format( "\"{0}\" /DLL /OUT=\"{1}\"", sourceFile.Path, assemblyPath); if (includePdb && !CLRHelpers.IsRunningOnMono()) { pdbPath = Path.ChangeExtension(assemblyPath, "pdb"); arguments += string.Format(" /PDB=\"{0}\"", pdbPath); } else { pdbPath = null; } var program = ilasmPath; if (CLRHelpers.IsRunningOnMono()) { arguments = string.Format("{0} {1}", ilasmPath, arguments); arguments = arguments.Replace("\"", ""); arguments = arguments.Replace("=", ":"); program = "mono"; } var result = ProcessLauncher.Run(program, arguments); if (result.ContainsErrors) { throw new ArgumentException( "The provided IL cannot be compiled." + Environment.NewLine + program + " " + arguments + Environment.NewLine + result, "declarations"); } } }