public void Emit(Compilation mainCompilation, IEnumerable <ResourceDescription> manifestResources)
        {
            var diagnostics  = DiagnosticBag.GetInstance();
            var dependencies = new List <ModuleData>();

            testData.Methods.Clear();

            ImmutableArray <byte> mainImage, mainPdb;
            bool succeeded = EmitCompilation(mainCompilation, manifestResources, dependencies, diagnostics, 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);
                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.
            }
        }
        internal Assembly GetOrLoad(ModuleData moduleData, bool reflectionOnly)
        {
            var cache = reflectionOnly ? _reflectionOnlyAssemblyCache : _assemblyCache;

            lock (s_guard)
            {
                Assembly assembly;
                if (cache.TryGetValue(moduleData.Mvid, out assembly))
                {
                    return(assembly);
                }

                var loadedAssembly = RuntimeAssemblyManager.LoadAsAssembly(moduleData.SimpleName, moduleData.Image, reflectionOnly);

                // Validate the loaded assembly matches the value that we now have in the cache.
                if (!cache.TryGetValue(moduleData.Mvid, out assembly))
                {
                    throw new Exception("Explicit assembly load didn't update the proper cache");
                }

                if (loadedAssembly != assembly)
                {
                    throw new Exception("Cache entry doesn't match result of load");
                }

                return(assembly);
            }
        }
        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;
        }
        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 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 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 usePdbForDebugging = false)
        {
            _testData.Methods.Clear();

            var diagnostics  = DiagnosticBag.GetInstance();
            var dependencies = new List <ModuleData>();
            var mainOutput   = EmitCompilation(mainCompilation, manifestResources, dependencies, diagnostics, _testData);

            _emitData             = new EmitData();
            _emitData.Diagnostics = diagnostics.ToReadOnlyAndFree();

            if (mainOutput.HasValue)
            {
                var mainImage = mainOutput.Value.Assembly;
                var mainPdb   = mainOutput.Value.Pdb;
                _emitData.MainModule = new ModuleData(
                    mainCompilation.Assembly.Identity,
                    mainCompilation.Options.OutputKind,
                    mainImage,
                    pdb: usePdbForDebugging ? mainPdb : default(ImmutableArray <byte>),
                    inMemoryModule: true);
                _emitData.MainModulePdb = mainPdb;
                _emitData.AllModuleData = dependencies;

                // 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.
                _emitData.AllModuleData.Insert(0, _emitData.MainModule);
                _emitData.RuntimeData = CreateAndInitializeRuntimeData(dependencies, _emitData.MainModule.Id);
            }
            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(_emitData.Diagnostics, dumpDir);
            }
        }
        private RuntimeAssemblyManager 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);
            RuntimeAssemblyManager manager;

            if (conflict != null)
            {
                Type     appDomainProxyType = typeof(RuntimeAssemblyManager);
                Assembly thisAssembly       = appDomainProxyType.Assembly;
                this.domain = AppDomain.CreateDomain("HostedRuntimeEnvironment", null, Environment.CurrentDirectory, null, false);
                manager     = (RuntimeAssemblyManager)domain.CreateInstanceAndUnwrap(thisAssembly.FullName, appDomainProxyType.FullName);
            }
            else
            {
                manager = new RuntimeAssemblyManager();
            }

            manager.AddModuleData(allModules);

            if (mainModule != null)
            {
                manager.AddMainModuleMvid(mainModule.Mvid);
            }

            return(manager);
        }
示例#10
0
        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;
        }
        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;
        }
 internal RuntimeData(RuntimeAssemblyManager manager, AppDomain appDomain)
 {
     Manager   = manager;
     AppDomain = appDomain;
 }
示例#13
0
 public AssemblyLoader(RuntimeAssemblyManager manager)
 {
     _manager = manager;
 }
示例#14
0
        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.
            }
        }
 internal RuntimeData(RuntimeAssemblyManager manager, AppDomain appDomain)
 {
     Manager = manager;
     AppDomain = appDomain;
 }
示例#16
0
        internal string[] PeVerifyModules(string[] modulesToVerify, bool throwOnError = true)
        {
            peVerifyRequested = true;

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

            return assemblyManager.PeVerifyModules(modulesToVerify, throwOnError);
        }
示例#17
0
        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;
        }
示例#18
0
        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;
        }