internal Internal.TypeSystem.Ecma.EcmaModule ResolveEcmaModule(EcmaModuleInfo module)
        {
            if (_ecmaModules == null)
            {
                _ecmaModules = new ModuleToEcmaModuleHashtable(this);
            }

            return(_ecmaModules.GetOrCreateValue(module));
        }
        partial void BindEcmaByteArray(byte[] rawAssembly, byte[] rawSymbolStore, ref AssemblyBindResult bindResult, ref Exception exception, ref bool?result)
        {
            // 1. Load byte[] into immutable array for use by PEReader/MetadataReader
            ImmutableArray <byte> assemblyData = ImmutableArray.Create(rawAssembly);
            PEReader       pe     = new PEReader(assemblyData);
            MetadataReader reader = pe.GetMetadataReader();

            // 2. Create AssemblyName from MetadataReader
            RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader);
            AssemblyName        asmName             = new AssemblyName();

            runtimeAssemblyName.CopyToAssemblyName(asmName);

            lock (s_ecmaLoadedAssemblies)
            {
                // 3. Attempt to bind to already loaded assembly
                if (Bind(asmName, out bindResult, out exception))
                {
                    result = true;
                    return;
                }
                exception = null;

                // 4. If that fails, then add newly created metareader to global cache of byte array loaded modules
                PEInfo peinfo = new PEInfo(asmName, reader, pe);

                s_ecmaLoadedAssemblies.Add(peinfo);
                ModuleList moduleList    = ModuleList.Instance;
                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                moduleList.RegisterModule(newModuleInfo);

                // 5. Then try to load by name again. This load should always succeed
                if (Bind(asmName, out bindResult, out exception))
                {
                    result = true;
                    return;
                }

                result = false;
                Debug.Assert(exception != null); // We must have an error on load. At this time this could happen due to ambiguous name matching
            }
        }
        internal TypeDesc GetTypeDescFromQHandle(QTypeDefinition qTypeDefinition)
        {
#if ECMA_METADATA_SUPPORT
            if (qTypeDefinition.IsNativeFormatMetadataBased)
#endif
            {
                MetadataReader           nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader;
                TypeDefinitionHandle     typeDefinitionHandle       = qTypeDefinition.NativeFormatHandle;
                NativeFormatModuleInfo   module           = ModuleList.Instance.GetModuleInfoForMetadataReader(nativeFormatMetadataReader);
                NativeFormatMetadataUnit metadataUnit     = ResolveMetadataUnit(module);
                NativeFormatType         nativeFormatType = (NativeFormatType)metadataUnit.GetType(typeDefinitionHandle);
                return(nativeFormatType);
            }
#if ECMA_METADATA_SUPPORT
            else if (qTypeDefinition.IsEcmaFormatMetadataBased)
            {
                EcmaModuleInfo  module     = ModuleList.Instance.GetModuleInfoForMetadataReader(qTypeDefinition.EcmaFormatReader);
                Ecma.EcmaModule ecmaModule = ResolveEcmaModule(module);
                Ecma.EcmaType   ecmaType   = (Ecma.EcmaType)ecmaModule.GetType(qTypeDefinition.EcmaFormatHandle);
                return(ecmaType);
            }
#endif
            return(null);
        }
        private void BindEcma(PEReader pe, MemoryMappedViewAccessor?memoryMappedView, out AssemblyBindResult bindResult, out Exception?exception, out bool?result)
        {
            MetadataReader reader = pe.GetMetadataReader();

            // 1. Create AssemblyName from MetadataReader
            RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader);

            lock (s_ecmaLoadedAssemblies)
            {
                // 2. Attempt to bind to already loaded assembly
                if (Bind(runtimeAssemblyName, cacheMissedLookups: false, out bindResult, out exception))
                {
                    result = true;
                    return;
                }
                exception = null;

                // 3. If that fails, then add newly created metareader to global cache of loaded modules
                PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, pe, memoryMappedView);

                s_ecmaLoadedAssemblies.Add(peinfo);
                ModuleList moduleList    = ModuleList.Instance;
                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                moduleList.RegisterModule(newModuleInfo);

                // 4. Then try to load by name again. This load should always succeed
                if (Bind(runtimeAssemblyName, cacheMissedLookups: true, out bindResult, out exception))
                {
                    result = true;
                    return;
                }

                result = false;
                Debug.Assert(exception != null); // We must have an error on load. At this time this could happen due to ambiguous name matching
            }
        }
Exemple #5
0
 public void SetRuntimeModuleInfoUNSAFE(EcmaModuleInfo moduleInfo)
 {
     RuntimeModuleInfo = moduleInfo;
 }
        partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, bool cacheMissedLookups, ref AssemblyBindResult result, ref Exception exception, ref Exception preferredException, ref bool foundMatch)
        {
            lock (s_ecmaLoadedAssemblies)
            {
                for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++)
                {
                    PEInfo info = s_ecmaLoadedAssemblies[i];
                    if (AssemblyNameMatches(refName, info.Name, ref preferredException))
                    {
                        if (foundMatch)
                        {
                            exception = new AmbiguousMatchException();
                            return;
                        }

                        result.EcmaMetadataReader = info.Reader;
                        foundMatch = result.EcmaMetadataReader != null;

                        // For failed matches, we will never be able to succeed, so return now
                        if (!foundMatch)
                        {
                            return;
                        }
                    }
                }

                if (!foundMatch)
                {
                    try
                    {
                        // Not found in already loaded list, attempt to source assembly from disk
                        foreach (string filePath in FilePathsForAssembly(refName))
                        {
                            FileStream ownedFileStream = null;
                            PEReader   ownedPEReader   = null;
                            try
                            {
                                if (!RuntimeAugments.FileExists(filePath))
                                {
                                    continue;
                                }

                                try
                                {
                                    ownedFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                                }
                                catch (System.IO.IOException)
                                {
                                    // Failure to open a file is not fundamentally an assembly load error, but it does indicate this file cannot be used
                                    continue;
                                }

                                ownedPEReader = new PEReader(ownedFileStream);
                                // FileStream ownership transferred to ownedPEReader
                                ownedFileStream = null;

                                if (!ownedPEReader.HasMetadata)
                                {
                                    continue;
                                }

                                MetadataReader reader = ownedPEReader.GetMetadataReader();
                                // Create AssemblyName from MetadataReader
                                RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader).CanonicalizePublicKeyToken();

                                // If assembly name doesn't match, it isn't the one we're looking for. Continue to look for more assemblies
                                if (!AssemblyNameMatches(refName, runtimeAssemblyName, ref preferredException))
                                {
                                    continue;
                                }

                                // This is the one we are looking for, add it to the list of loaded assemblies
                                PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, ownedPEReader);

                                s_ecmaLoadedAssemblies.Add(peinfo);

                                // At this point the PE reader is no longer owned by this code, but is owned by the s_ecmaLoadedAssemblies list
                                PEReader pe = ownedPEReader;
                                ownedPEReader = null;

                                ModuleList moduleList    = ModuleList.Instance;
                                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                                moduleList.RegisterModule(newModuleInfo);

                                foundMatch = true;
                                result.EcmaMetadataReader = peinfo.Reader;
                                break;
                            }
                            finally
                            {
                                if (ownedFileStream != null)
                                {
                                    ownedFileStream.Dispose();
                                }

                                if (ownedPEReader != null)
                                {
                                    ownedPEReader.Dispose();
                                }
                            }
                        }
                    }
                    catch (System.IO.IOException)
                    { }
                    catch (System.ArgumentException)
                    { }
                    catch (System.BadImageFormatException badImageFormat)
                    {
                        exception = badImageFormat;
                    }

                    // Cache missed lookups
                    if (cacheMissedLookups && !foundMatch)
                    {
                        PEInfo peinfo = new PEInfo(refName, null, null);
                        s_ecmaLoadedAssemblies.Add(peinfo);
                    }
                }
            }
        }