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

                this.domain = appDomain;
                this.assemblyManager = manager;
            }
            else
            {
                this.assemblyManager = new RuntimeAssemblyManager();
            }

            this.assemblyManager.AddModuleData(allModules);

            if (mainModule != null)
            {
                this.assemblyManager.AddMainModuleMvid(mainModule.Mvid);
            }
        }
 internal RuntimeData(RuntimeAssemblyManager manager, AppDomain appDomain)
 {
     Manager = manager;
     AppDomain = appDomain;
 }
        void IDisposable.Dispose()
        {
            if (disposed)
            {
                return;
            }

            if (domain == null)
            {
                if (assemblyManager != null)
                {
                    assemblyManager.Dispose();

                    assemblyManager = null;
                }
            }
            else
            {
                // KevinH - I'm adding this for debugging...we seem to be getting to AppDomain.Unload when we shouldn't
                // (causing intermittant failures on the build machine).  We should never be creating a separate
                // AppDomain without its own assemblyManager.
                if (assemblyManager == null)
                {
                    throw new InvalidOperationException("assemblyManager should never be null if a remote domain was created");
                }
                else
                {
                    assemblyManager.Dispose();

                    if (IsSafeToUnloadDomain)
                    {
                        AppDomain.Unload(domain);
                    }

                    assemblyManager = null;
                }

                domain = null;
            }

            disposed = true;
        }
        internal string[] PeVerifyModules(string[] modulesToVerify, bool throwOnError = true)
        {
            peVerifyRequested = true;

            if (assemblyManager == null)
            {
                assemblyManager = CreateAssemblyManager(new ModuleData[0], null);
            }

            return assemblyManager.PeVerifyModules(modulesToVerify, throwOnError);
        }
        public void Emit(Compilation mainCompilation, IEnumerable<ResourceDescription> manifestResources, bool emitPdb)
        {
            var diagnostics = DiagnosticBag.GetInstance();
            var dependencies = new List<ModuleData>();

            testData.Methods.Clear();

            ImmutableArray<byte> mainImage, mainPdb;
            bool succeeded = EmitCompilation(mainCompilation, manifestResources, dependencies, diagnostics, emitPdb, testData, out mainImage, out mainPdb);

            this.lazyDiagnostics = diagnostics.ToReadOnlyAndFree();

            if (succeeded)
            {
                this.mainModule = new ModuleData(mainCompilation.Assembly.Identity, mainCompilation.Options.OutputKind, mainImage, mainPdb, inMemoryModule: true);
                this.allModuleData = dependencies;
                this.allModuleData.Insert(0, mainModule);
                this.assemblyManager = CreateAssemblyManager(dependencies, mainModule);
            }
            else
            {
                string dumpDir;
                RuntimeAssemblyManager.DumpAssemblyData(dependencies, out dumpDir);

                // This method MUST throw if compilation did not succeed.  If compilation succeeded and there were errors, that is bad.
                // Please see KevinH if you intend to change this behavior as many tests expect the Exception to indicate failure.
                throw new EmitException(this.lazyDiagnostics, dumpDir); // ToArray for serializability.
            }
        }
Example #6
0
 public AssemblyLoader(RuntimeAssemblyManager manager)
 {
     _manager = manager;
 }
        void IDisposable.Dispose()
        {
            if (disposed)
            {
                return;
            }

            if (domain == null)
            {
                if (assemblyManager != null)
                {
                    assemblyManager.Dispose();
                    assemblyManager = null;
                }
            }
            else
            {
                Debug.Assert(assemblyManager != null);
                assemblyManager.Dispose();

                if (IsSafeToUnloadDomain)
                {
                    AppDomain.Unload(domain);
                }

                assemblyManager = null;
                domain = null;
            }

            disposed = true;
        }
        void IDisposable.Dispose()
        {
            if (_disposed)
            {
                return;
            }

            if (_domain == null)
            {
                if (_assemblyManager != null)
                {
                    _assemblyManager.Dispose();
                    _assemblyManager = null;
                }
            }
            else
            {
                Debug.Assert(_assemblyManager != null);
                _assemblyManager.Dispose();

                if (IsSafeToUnloadDomain)
                {
                    AppDomain.Unload(_domain);
                }

                _assemblyManager = null;
                _domain = null;
            }

            _disposed = true;
        }