/// <summary> /// Try to look up field access info for given canon in metadata blobs for all available modules. /// </summary> /// <param name="metadataReader">Metadata reader for the declaring type</param> /// <param name="declaringTypeHandle">Declaring type for the method</param> /// <param name="fieldHandle">Field handle</param> /// <param name="canonFormKind">Canonical form to use</param> /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param> /// <returns>true when found, false otherwise</returns> private unsafe static bool TryGetFieldAccessMetadataFromFieldAccessMap( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle, CanonicalFormKind canonFormKind, ref FieldAccessMetadata fieldAccessMetadata) { CanonicallyEquivalentEntryLocator canonWrapper = new CanonicallyEquivalentEntryLocator(declaringTypeHandle, canonFormKind); TypeManagerHandle fieldHandleModule = ModuleList.Instance.GetModuleForMetadataReader(metadataReader); bool isDynamicType = RuntimeAugments.IsDynamicType(declaringTypeHandle); string fieldName = null; RuntimeTypeHandle declaringTypeHandleDefinition = Instance.GetTypeDefinition(declaringTypeHandle); foreach (NativeFormatModuleInfo mappingTableModule in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(declaringTypeHandle))) { NativeReader fieldMapReader; if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.FieldAccessMap, out fieldMapReader)) { continue; } NativeParser fieldMapParser = new NativeParser(fieldMapReader, 0); NativeHashtable fieldHashtable = new NativeHashtable(fieldMapParser); ExternalReferencesTable externalReferences = default(ExternalReferencesTable); if (!externalReferences.InitializeCommonFixupsTable(mappingTableModule)) { continue; } var lookup = fieldHashtable.Lookup(canonWrapper.LookupHashCode); NativeParser entryParser; while (!(entryParser = lookup.GetNext()).IsNull) { // Grammar of a hash table entry: // Flags + DeclaringType + MdHandle or Name + Cookie or Ordinal or Offset FieldTableFlags entryFlags = (FieldTableFlags)entryParser.GetUnsigned(); if ((canonFormKind == CanonicalFormKind.Universal) != ((entryFlags & FieldTableFlags.IsUniversalCanonicalEntry) != 0)) { continue; } RuntimeTypeHandle entryDeclaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle) && !canonWrapper.IsCanonicallyEquivalent(entryDeclaringTypeHandle)) { continue; } if ((entryFlags & FieldTableFlags.HasMetadataHandle) != 0) { Handle entryFieldHandle = (((int)HandleType.Field << 24) | (int)entryParser.GetUnsigned()).AsHandle(); if (!fieldHandle.Equals(entryFieldHandle)) { continue; } } else { if (fieldName == null) { QTypeDefinition qTypeDefinition; bool success = Instance.TryGetMetadataForNamedType( declaringTypeHandleDefinition, out qTypeDefinition); Debug.Assert(success); MetadataReader nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader; fieldName = nativeFormatMetadataReader.GetString(fieldHandle.GetField(nativeFormatMetadataReader).Name); } string entryFieldName = entryParser.GetString(); if (fieldName != entryFieldName) { continue; } } int fieldOffset = -1; int threadStaticsStartOffset = -1; IntPtr fieldAddressCookie = IntPtr.Zero; if (canonFormKind == CanonicalFormKind.Universal) { if (!TypeLoaderEnvironment.Instance.TryGetFieldOffset(declaringTypeHandle, entryParser.GetUnsigned() /* field ordinal */, out fieldOffset)) { Debug.Assert(false); return(false); } } else { if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic) { if ((entryFlags & FieldTableFlags.FieldOffsetEncodedDirectly) != 0) { if ((entryFlags & FieldTableFlags.IsAnyCanonicalEntry) == 0) { int rvaToThreadStaticFieldOffsets = (int)externalReferences.GetRvaFromIndex(entryParser.GetUnsigned()); fieldAddressCookie = RvaToNonGenericStaticFieldAddress(mappingTableModule.Handle, rvaToThreadStaticFieldOffsets); threadStaticsStartOffset = *(int *)fieldAddressCookie.ToPointer(); } fieldOffset = (int)entryParser.GetUnsigned(); } else { int rvaToThreadStaticFieldOffsets = (int)externalReferences.GetRvaFromIndex(entryParser.GetUnsigned()); fieldAddressCookie = RvaToNonGenericStaticFieldAddress(mappingTableModule.Handle, rvaToThreadStaticFieldOffsets); ThreadStaticFieldOffsets *pThreadStaticFieldOffsets = (ThreadStaticFieldOffsets *)fieldAddressCookie.ToPointer(); threadStaticsStartOffset = (int)pThreadStaticFieldOffsets->StartingOffsetInTlsBlock; fieldOffset = (int)pThreadStaticFieldOffsets->FieldOffset; } } else { if ((entryFlags & FieldTableFlags.FieldOffsetEncodedDirectly) != 0) { fieldOffset = (int)entryParser.GetUnsigned(); } else { #if PROJECTN fieldOffset = (int)externalReferences.GetRvaFromIndex(entryParser.GetUnsigned()); #else fieldOffset = 0; fieldAddressCookie = externalReferences.GetAddressFromIndex(entryParser.GetUnsigned()); if ((entryFlags & FieldTableFlags.IsGcSection) != 0) { fieldOffset = (int)entryParser.GetUnsigned(); } #endif } } } if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic) { // TODO: CoreRT support if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle)) { if (!TypeLoaderEnvironment.Instance.TryGetThreadStaticStartOffset(declaringTypeHandle, out threadStaticsStartOffset)) { return(false); } } fieldAddressCookie = new IntPtr(threadStaticsStartOffset); } fieldAccessMetadata.MappingTableModule = mappingTableModule.Handle; fieldAccessMetadata.Cookie = fieldAddressCookie; fieldAccessMetadata.Flags = entryFlags; fieldAccessMetadata.Offset = fieldOffset; return(true); } } return(false); }
private MethodNameAndSignature GetMethodNameAndSignatureFromNativeReader(NativeReader nativeLayoutReader, TypeManagerHandle moduleHandle, uint nativeLayoutOffset) { NativeParser parser = new NativeParser(nativeLayoutReader, nativeLayoutOffset); string methodName = parser.GetString(); // Signatures are indirected to through a relative offset so that we don't have to parse them // when not comparing signatures (parsing them requires resolving types and is tremendously // expensive). NativeParser sigParser = parser.GetParserFromRelativeOffset(); RuntimeSignature methodSig = RuntimeSignature.CreateFromNativeLayoutSignature(moduleHandle, sigParser.Offset); return(new MethodNameAndSignature(methodName, methodSig)); }
/// <summary> /// Try to look up field acccess info for given canon in metadata blobs for all available modules. /// </summary> /// <param name="metadataReader">Metadata reader for the declaring type</param> /// <param name="declaringTypeHandle">Declaring type for the method</param> /// <param name="fieldHandle">Field handle</param> /// <param name="canonFormKind">Canonical form to use</param> /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param> /// <returns>true when found, false otherwise</returns> private static bool TryGetFieldAccessMetadataFromFieldAccessMap( MetadataReader metadataReader, RuntimeTypeHandle declaringTypeHandle, FieldHandle fieldHandle, CanonicalFormKind canonFormKind, ref FieldAccessMetadata fieldAccessMetadata) { CanonicallyEquivalentEntryLocator canonWrapper = new CanonicallyEquivalentEntryLocator(declaringTypeHandle, canonFormKind); TypeManagerHandle fieldHandleModule = ModuleList.Instance.GetModuleForMetadataReader(metadataReader); bool isDynamicType = RuntimeAugments.IsDynamicType(declaringTypeHandle); string fieldName = null; RuntimeTypeHandle declaringTypeHandleDefinition = Instance.GetTypeDefinition(declaringTypeHandle); foreach (NativeFormatModuleInfo mappingTableModule in ModuleList.EnumerateModules(RuntimeAugments.GetModuleFromTypeHandle(declaringTypeHandle))) { NativeReader fieldMapReader; if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.FieldAccessMap, out fieldMapReader)) { continue; } NativeParser fieldMapParser = new NativeParser(fieldMapReader, 0); NativeHashtable fieldHashtable = new NativeHashtable(fieldMapParser); ExternalReferencesTable externalReferences = default(ExternalReferencesTable); if (!externalReferences.InitializeCommonFixupsTable(mappingTableModule)) { continue; } var lookup = fieldHashtable.Lookup(canonWrapper.LookupHashCode); NativeParser entryParser; while (!(entryParser = lookup.GetNext()).IsNull) { // Grammar of a hash table entry: // Flags + DeclaringType + MdHandle or Name + Cookie or Ordinal or Offset FieldTableFlags entryFlags = (FieldTableFlags)entryParser.GetUnsigned(); if ((canonFormKind == CanonicalFormKind.Universal) != entryFlags.HasFlag(FieldTableFlags.IsUniversalCanonicalEntry)) { continue; } RuntimeTypeHandle entryDeclaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle) && !canonWrapper.IsCanonicallyEquivalent(entryDeclaringTypeHandle)) { continue; } if (entryFlags.HasFlag(FieldTableFlags.HasMetadataHandle)) { Handle entryFieldHandle = (((int)HandleType.Field << 24) | (int)entryParser.GetUnsigned()).AsHandle(); if (!fieldHandle.Equals(entryFieldHandle)) { continue; } } else { if (fieldName == null) { QTypeDefinition qTypeDefinition; bool success = Instance.TryGetMetadataForNamedType( declaringTypeHandleDefinition, out qTypeDefinition); Debug.Assert(success); MetadataReader nativeFormatMetadataReader = qTypeDefinition.NativeFormatReader; fieldName = nativeFormatMetadataReader.GetString(fieldHandle.GetField(nativeFormatMetadataReader).Name); } string entryFieldName = entryParser.GetString(); if (fieldName != entryFieldName) { continue; } } int cookieOrOffsetOrOrdinal = (int)entryParser.GetUnsigned(); int fieldOffset; IntPtr fieldAddressCookie = IntPtr.Zero; if (canonFormKind == CanonicalFormKind.Universal) { if (!TypeLoaderEnvironment.Instance.TryGetFieldOffset(declaringTypeHandle, (uint)cookieOrOffsetOrOrdinal, out fieldOffset)) { Debug.Assert(false); return(false); } } else { #if CORERT fieldOffset = cookieOrOffsetOrOrdinal; #else fieldOffset = (int)externalReferences.GetRvaFromIndex((uint)cookieOrOffsetOrOrdinal); #endif } if ((entryFlags & FieldTableFlags.StorageClass) == FieldTableFlags.ThreadStatic) { if (canonFormKind != CanonicalFormKind.Universal) { fieldAddressCookie = RvaToNonGenericStaticFieldAddress(mappingTableModule.Handle, fieldOffset); } if (!entryDeclaringTypeHandle.Equals(declaringTypeHandle)) { // In this case we didn't find an exact match, but we did find a canonically equivalent match // We might be in the dynamic type case, or the canonically equivalent, but not the same case. if (!RuntimeAugments.IsDynamicType(declaringTypeHandle)) { int offsetToCreateCookieFor = fieldOffset; // We're working with a statically generated type, but we didn't find an exact match in the tables if (canonFormKind != CanonicalFormKind.Universal) { offsetToCreateCookieFor = checked ((int)TypeLoaderEnvironment.GetThreadStaticTypeOffsetFromThreadStaticCookie(fieldAddressCookie)); } fieldAddressCookie = TypeLoaderEnvironment.Instance.TryGetThreadStaticFieldOffsetCookieForTypeAndFieldOffset(declaringTypeHandle, checked ((uint)offsetToCreateCookieFor)); } } } fieldAccessMetadata.MappingTableModule = mappingTableModule.Handle; fieldAccessMetadata.Cookie = fieldAddressCookie; fieldAccessMetadata.Flags = entryFlags; fieldAccessMetadata.Offset = fieldOffset; return(true); } } return(false); }
public static RuntimeTypeHandle GetTypeFromNativeLayoutSignature(ref NativeParser parser, TypeManagerHandle moduleHandle, uint offset) { RuntimeTypeHandle typeHandle; parser.Offset = offset; TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(ref parser, moduleHandle, null, null, out typeHandle); return(typeHandle); }
/// <summary> /// Construct the underlying module info enumerator used to iterate the module map /// </summary> /// <param name="moduleMap">Module map to enumerate</param> /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param> internal ModuleHandleEnumerator(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle) { _moduleInfoEnumerator = new ModuleInfoEnumerator(moduleMap, preferredModuleHandle); }
/// <summary> /// Construct the underlying module info enumerator used to iterate the module map /// </summary> /// <param name="moduleMap">Module map to enumerate</param> /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param> internal MetadataReaderEnumerator(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle) { _moduleInfoEnumerator = new NativeFormatModuleInfoEnumerator(moduleMap, preferredModuleHandle); }
/// <summary> /// Enumerate modules. Specify a module that should be enumerated first /// - this is used as an optimization in cases when a certain binary module is more probable /// to contain a certain information. /// </summary> /// <param name="preferredModule">Handle to the module which should be enumerated first</param> public static NativeFormatModuleInfoEnumerable EnumerateModules(TypeManagerHandle preferredModule) { return(new NativeFormatModuleInfoEnumerable(Instance._loadedModuleMap, preferredModule)); }
/// <summary> /// Initialize module info and construct per-module metadata reader. /// </summary> /// <param name="moduleHandle">Handle (address) of module to initialize</param> internal NativeFormatModuleInfo(TypeManagerHandle moduleHandle, ModuleType moduleType, IntPtr pBlob, int cbBlob) : base(moduleHandle, moduleType) { MetadataReader = new MetadataReader((IntPtr)pBlob, (int)cbBlob); }
/// <summary> /// Initialize module info and construct per-module metadata reader. /// </summary> /// <param name="moduleHandle">Handle (address) of module to initialize</param> internal EcmaModuleInfo(TypeManagerHandle moduleHandle, PEReader pe, MetadataReader reader) : base(moduleHandle, ModuleType.Ecma) { PE = pe; MetadataReader = reader; }
/// <summary> /// Locate module info for a given module. Fail if not found or before the module registry /// gets initialized. Must only be called for modules described as native format (not the mrt module, or an ECMA module) /// </summary> /// <param name="moduleHandle">Handle of module to look up</param> public NativeFormatModuleInfo GetModuleInfoByHandle(TypeManagerHandle moduleHandle) { ModuleMap moduleMap = _loadedModuleMap; return((NativeFormatModuleInfo)moduleMap.Modules[moduleMap.HandleToModuleIndex[moduleHandle]]); }
internal override bool MatchParsedEntry(ref NativeParser entryParser, ref ExternalReferencesTable externalReferencesLookup, TypeManagerHandle moduleHandle) { // Compare entry with inputs as we parse it. If we get a mismatch, stop parsing and move to the next entry... RuntimeTypeHandle parsedDeclaringTypeHandle = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); if (!parsedDeclaringTypeHandle.Equals(_declaringType)) { return(false); } // Hash table names / sigs are indirected through to the native layout info MethodNameAndSignature nameAndSignature; if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned(), out nameAndSignature)) { return(false); } if (!nameAndSignature.Equals(_nameAndSignature)) { return(false); } int parsedArity = (int)entryParser.GetSequenceCount(); int lookupArity = (_methodToLookup != null ? _methodToLookup.Instantiation.Length : _genericMethodArgumentHandles.Length); if (parsedArity != lookupArity) { return(false); } for (int i = 0; i < parsedArity; i++) { RuntimeTypeHandle parsedArg = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); RuntimeTypeHandle lookupArg = (_methodToLookup != null ? _methodToLookup.Instantiation[i].RuntimeTypeHandle : _genericMethodArgumentHandles[i]); if (!parsedArg.Equals(lookupArg)) { return(false); } } return(true); }
internal override bool MatchParsedEntry(ref NativeParser entryParser, ref ExternalReferencesTable externalReferencesLookup, TypeManagerHandle moduleHandle) { // // Entries read from the hashtable are loaded as GenericMethodDescs, and compared to the input. // This lookup is slower than the lookups using RuntimeTypeHandles, but can handle cases where we don't have // RuntimeTypeHandle values for all of the components of the input GenericMethodDesc, but still need to look it up in case the // method dictionary statically really exists // TypeSystemContext context = _methodToLookup.Context; RuntimeTypeHandle parsedDeclaringTypeHandle = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); // Hash table names / sigs are indirected through to the native layout info MethodNameAndSignature nameAndSignature; if (!TypeLoaderEnvironment.Instance.TryGetMethodNameAndSignatureFromNativeLayoutOffset(moduleHandle, entryParser.GetUnsigned(), out nameAndSignature)) { return(false); } RuntimeTypeHandle[] parsedArgsHandles = GetTypeSequence(ref externalReferencesLookup, ref entryParser); DefType parsedDeclaringType = context.ResolveRuntimeTypeHandle(parsedDeclaringTypeHandle) as DefType; Instantiation parsedArgs = context.ResolveRuntimeTypeHandles(parsedArgsHandles); InstantiatedMethod parsedGenericMethod = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, parsedDeclaringType, nameAndSignature, parsedArgs, IntPtr.Zero, false); return(parsedGenericMethod == _methodToLookup); }
internal abstract bool MatchParsedEntry(ref NativeParser entryParser, ref ExternalReferencesTable externalReferencesLookup, TypeManagerHandle moduleHandle);
private object TryParseNativeSignatureWorker(TypeSystemContext typeSystemContext, TypeManagerHandle moduleHandle, ref NativeParser parser, RuntimeTypeHandle[] typeGenericArgumentHandles, RuntimeTypeHandle[] methodGenericArgumentHandles, bool isMethodSignature) { Instantiation typeGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(typeGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>()); Instantiation methodGenericArguments = typeSystemContext.ResolveRuntimeTypeHandles(methodGenericArgumentHandles ?? Array.Empty<RuntimeTypeHandle>()); NativeLayoutInfoLoadContext nativeLayoutContext = new NativeLayoutInfoLoadContext(); nativeLayoutContext._module = ModuleList.GetModuleInfoByHandle(moduleHandle); nativeLayoutContext._typeSystemContext = typeSystemContext; nativeLayoutContext._typeArgumentHandles = typeGenericArguments; nativeLayoutContext._methodArgumentHandles = methodGenericArguments; if (isMethodSignature) return nativeLayoutContext.GetMethod(ref parser); else return nativeLayoutContext.GetType(ref parser); }
/// <summary> /// Enumerate metadata readers. Specify a module that should be enumerated first /// - this is used as an optimization in cases when a certain binary module is more probable /// to contain a certain information. /// </summary> /// <param name="preferredModule">Handle to the module which should be enumerated first</param> public static MetadataReaderEnumerable EnumerateMetadataReaders(TypeManagerHandle preferredModule) { return(new MetadataReaderEnumerable(Instance._loadedModuleMap, preferredModule)); }
public static unsafe bool FindBlob(TypeManagerHandle typeManager, int blobId, IntPtr ppbBlob, IntPtr pcbBlob) { return(RuntimeImports.RhFindBlob(typeManager, (uint)blobId, (byte **)ppbBlob, (uint *)pcbBlob)); }
/// <summary> /// Enumerate module handles (simplified version for code that only needs the module addresses). /// Specify a module that should be enumerated first /// - this is used as an optimization in cases when a certain binary module is more probable /// to contain a certain information. /// </summary> /// <param name="preferredModule">Handle to the module which should be enumerated first</param> public static ModuleHandleEnumerable Enumerate(TypeManagerHandle preferredModule) { return(new ModuleHandleEnumerable(Instance._loadedModuleMap, preferredModule)); }
/// <summary> /// Store module map and preferred module to pass to the enumerator upon construction. /// </summary> /// <param name="moduleMap">Module map to enumerate</param> /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param> internal NativeFormatModuleInfoEnumerable(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle) { _moduleMap = moduleMap; _preferredModuleHandle = preferredModuleHandle; }
/// <summary> /// Resolve a given 32-bit integer (staticFieldRVA) representing a static field address. /// For "local" static fields residing in the module given by moduleHandle, staticFieldRVA /// directly contains the RVA of the static field. For remote static fields residing in other /// modules, staticFieldRVA has the highest bit set (FieldAccessFlags.RemoteStaticFieldRVA) /// and it contains the RVA of a RemoteStaticFieldDescriptor structure residing in the module /// given by moduleHandle that holds a pointer to the indirection cell /// of the remote static field and its offset within the cell. /// </summary> /// <param name="moduleHandle">Reference module handle used for static field lookup</param> /// <param name="staticFieldRVA"> /// RVA of static field for local fields; for remote fields, RVA of a RemoteStaticFieldDescriptor /// structure for the field or-ed with the FieldAccessFlags.RemoteStaticFieldRVA bit /// </param> public static unsafe IntPtr RvaToNonGenericStaticFieldAddress(TypeManagerHandle moduleHandle, int staticFieldRVA) { // TODO: implement for CoreRT throw new NotImplementedException(); }
/// <summary> /// Store module map and preferred module to pass to the enumerator upon construction. /// </summary> /// <param name="moduleMap">Module map to enumerate</param> /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param> internal MetadataReaderEnumerable(ModuleMap moduleMap, TypeManagerHandle preferredModuleHandle) { _moduleMap = moduleMap; _preferredModuleHandle = preferredModuleHandle; }
private bool CompareTypeSigWithType(ref NativeParser parser, TypeManagerHandle moduleHandle, Handle typeHandle) { while (typeHandle.HandleType == HandleType.TypeSpecification) { typeHandle = typeHandle .ToTypeSpecificationHandle(_metadataReader) .GetTypeSpecification(_metadataReader) .Signature; } // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader // expects to read it in. uint startOffset = parser.Offset; uint data; var typeSignatureKind = parser.GetTypeSignatureKind(out data); switch (typeSignatureKind) { case TypeSignatureKind.Lookback: { NativeParser lookbackParser = parser.GetLookbackParser(data); return(CompareTypeSigWithType(ref lookbackParser, moduleHandle, typeHandle)); } case TypeSignatureKind.Modifier: { // Ensure the modifier kind (vector, pointer, byref) is the same TypeModifierKind modifierKind = (TypeModifierKind)data; switch (modifierKind) { case TypeModifierKind.Array: if (typeHandle.HandleType == HandleType.SZArraySignature) { return(CompareTypeSigWithType(ref parser, moduleHandle, typeHandle .ToSZArraySignatureHandle(_metadataReader) .GetSZArraySignature(_metadataReader) .ElementType)); } return(false); case TypeModifierKind.ByRef: if (typeHandle.HandleType == HandleType.ByReferenceSignature) { return(CompareTypeSigWithType(ref parser, moduleHandle, typeHandle .ToByReferenceSignatureHandle(_metadataReader) .GetByReferenceSignature(_metadataReader) .Type)); } return(false); case TypeModifierKind.Pointer: if (typeHandle.HandleType == HandleType.PointerSignature) { return(CompareTypeSigWithType(ref parser, moduleHandle, typeHandle .ToPointerSignatureHandle(_metadataReader) .GetPointerSignature(_metadataReader) .Type)); } return(false); default: Debug.Assert(null == "invalid type modifier kind"); return(false); } } case TypeSignatureKind.Variable: { bool isMethodVar = (data & 0x1) == 1; uint index = data >> 1; if (isMethodVar) { if (typeHandle.HandleType == HandleType.MethodTypeVariableSignature) { return(index == typeHandle .ToMethodTypeVariableSignatureHandle(_metadataReader) .GetMethodTypeVariableSignature(_metadataReader) .Number); } } else { if (typeHandle.HandleType == HandleType.TypeVariableSignature) { return(index == typeHandle .ToTypeVariableSignatureHandle(_metadataReader) .GetTypeVariableSignature(_metadataReader) .Number); } } return(false); } case TypeSignatureKind.MultiDimArray: { if (typeHandle.HandleType != HandleType.ArraySignature) { return(false); } ArraySignature sig = typeHandle .ToArraySignatureHandle(_metadataReader) .GetArraySignature(_metadataReader); if (data != sig.Rank) { return(false); } if (!CompareTypeSigWithType(ref parser, moduleHandle, sig.ElementType)) { return(false); } uint boundCount1 = parser.GetUnsigned(); for (uint i = 0; i < boundCount1; i++) { parser.GetUnsigned(); } uint lowerBoundCount1 = parser.GetUnsigned(); for (uint i = 0; i < lowerBoundCount1; i++) { parser.GetUnsigned(); } break; } case TypeSignatureKind.FunctionPointer: { // callingConvention is in data uint argCount1 = parser.GetUnsigned(); for (uint i = 0; i < argCount1; i++) { if (!CompareTypeSigWithType(ref parser, moduleHandle, typeHandle)) { return(false); } } return(false); } case TypeSignatureKind.Instantiation: { if (typeHandle.HandleType != HandleType.TypeInstantiationSignature) { return(false); } TypeInstantiationSignature sig = typeHandle .ToTypeInstantiationSignatureHandle(_metadataReader) .GetTypeInstantiationSignature(_metadataReader); if (!CompareTypeSigWithType(ref parser, moduleHandle, sig.GenericType)) { return(false); } uint genericArgIndex = 0; foreach (Handle genericArgumentTypeHandle in sig.GenericTypeArguments) { if (genericArgIndex >= data) { // The metadata generic has more parameters than the native layour return(false); } if (!CompareTypeSigWithType(ref parser, moduleHandle, genericArgumentTypeHandle)) { return(false); } genericArgIndex++; } // Make sure all generic parameters have been matched return(genericArgIndex == data); } case TypeSignatureKind.BuiltIn: case TypeSignatureKind.External: { RuntimeTypeHandle type2; switch (typeHandle.HandleType) { case HandleType.TypeDefinition: if (!TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata( new QTypeDefinition(_metadataReader, typeHandle.ToTypeDefinitionHandle(_metadataReader)), out type2)) { return(false); } break; case HandleType.TypeReference: if (!TypeLoaderEnvironment.TryResolveNamedTypeForTypeReference( _metadataReader, typeHandle.ToTypeReferenceHandle(_metadataReader), out type2)) { return(false); } break; default: return(false); } RuntimeTypeHandle type1 = default(RuntimeTypeHandle); if (typeSignatureKind == TypeSignatureKind.External) { type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, moduleHandle, startOffset); } else { type1 = ((Internal.TypeSystem.WellKnownType)data).GetRuntimeTypeHandle(); } return(type1.Equals(type2)); } default: return(false); } return(true); }
/// <summary> /// Register all modules which were added (Registered) to the runtime and are not already registered with the TypeLoader. /// </summary> /// <param name="moduleType">Type to assign to all new modules.</param> public void RegisterNewModules(ModuleType moduleType) { // prevent multiple threads from registering modules concurrently using (LockHolder.Hold(_moduleRegistrationLock)) { // Fetch modules that have already been registered with the runtime int loadedModuleCount = RuntimeAugments.GetLoadedModules(null); TypeManagerHandle[] loadedModuleHandles = new TypeManagerHandle[loadedModuleCount]; int loadedModuleCountUpdated = RuntimeAugments.GetLoadedModules(loadedModuleHandles); Debug.Assert(loadedModuleCount == loadedModuleCountUpdated); LowLevelList <TypeManagerHandle> newModuleHandles = new LowLevelList <TypeManagerHandle>(loadedModuleHandles.Length); foreach (TypeManagerHandle moduleHandle in loadedModuleHandles) { // Skip already registered modules. int oldModuleIndex; if (_loadedModuleMap.HandleToModuleIndex.TryGetValue(moduleHandle, out oldModuleIndex)) { continue; } newModuleHandles.Add(moduleHandle); } // Copy existing modules to new dictionary int oldModuleCount = _loadedModuleMap.Modules.Length; ModuleInfo[] updatedModules = new ModuleInfo[oldModuleCount + newModuleHandles.Count]; if (oldModuleCount > 0) { Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount); } for (int newModuleIndex = 0; newModuleIndex < newModuleHandles.Count; newModuleIndex++) { ModuleInfo newModuleInfo; unsafe { byte *pBlob; uint cbBlob; if (RuntimeAugments.FindBlob(newModuleHandles[newModuleIndex], (int)ReflectionMapBlob.EmbeddedMetadata, new IntPtr(&pBlob), new IntPtr(&cbBlob))) { newModuleInfo = new NativeFormatModuleInfo(newModuleHandles[newModuleIndex], moduleType, (IntPtr)pBlob, (int)cbBlob); } else { newModuleInfo = new ModuleInfo(newModuleHandles[newModuleIndex], moduleType); } } updatedModules[oldModuleCount + newModuleIndex] = newModuleInfo; if (_moduleRegistrationCallbacks != null) { _moduleRegistrationCallbacks(newModuleInfo); } } // Atomically update the module map _loadedModuleMap = new ModuleMap(updatedModules); } }
public abstract IntPtr GetThreadStaticGCDescForDynamicType(TypeManagerHandle handle, int index);