/// <summary> /// Get a pointer to a pointer to the nongc static field data of a type. This function works for all generic types /// </summary> public IntPtr TryGetNonGcStaticFieldData(RuntimeTypeHandle runtimeTypeHandle) { unsafe { // Non-generic, non-dynamic static data is found via the FieldAccessMap EEType *typeAsEEType = runtimeTypeHandle.ToEETypePtr(); // Non-generic, non-dynamic types need special handling. Debug.Assert(typeAsEEType->IsDynamicType || typeAsEEType->IsGeneric); } // Search hashtable for static entry ExternalReferencesTable staticInfoLookup; var parser = GetStaticInfo(runtimeTypeHandle, out staticInfoLookup); if (!parser.IsNull) { var index = parser.GetUnsignedForBagElementKind(BagElementKind.NonGcStaticData); return(index.HasValue ? staticInfoLookup.GetIntPtrFromIndex(index.Value) : IntPtr.Zero); } // Not found in hashtable... must be a dynamically created type Debug.Assert(runtimeTypeHandle.IsDynamicType()); return(RuntimeAugments.GetNonGcStaticFieldData(runtimeTypeHandle)); }
public unsafe static IntPtr TryGetStaticClassConstructionContext(RuntimeTypeHandle typeHandle) { if (RuntimeAugments.HasCctor(typeHandle)) { if (RuntimeAugments.IsDynamicType(typeHandle)) { // For dynamic types, its always possible to get the non-gc static data section directly. byte *ptr = (byte *)*(IntPtr *)RuntimeAugments.GetNonGcStaticFieldData(typeHandle); // what we have now is the base address of the non-gc statics of the type // what we need is the cctor context, which is just before that ptr = ptr - sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); return((IntPtr)ptr); } else { // Non-dynamic types do not provide a way to directly get at the non-gc static region. // Use the CctorContextMap instead. var moduleHandle = RuntimeAugments.GetModuleFromTypeHandle(typeHandle); Debug.Assert(moduleHandle != IntPtr.Zero); NativeReader typeMapReader; if (TryGetNativeReaderForBlob(moduleHandle, ReflectionMapBlob.CCtorContextMap, out typeMapReader)) { NativeParser typeMapParser = new NativeParser(typeMapReader, 0); NativeHashtable typeHashtable = new NativeHashtable(typeMapParser); ExternalReferencesTable externalReferences = default(ExternalReferencesTable); externalReferences.InitializeCommonFixupsTable(moduleHandle); var lookup = typeHashtable.Lookup(typeHandle.GetHashCode()); NativeParser entryParser; while (!(entryParser = lookup.GetNext()).IsNull) { RuntimeTypeHandle foundType = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned()); if (foundType.Equals(typeHandle)) { byte *pNonGcStaticBase = (byte *)externalReferences.GetIntPtrFromIndex(entryParser.GetUnsigned()); // cctor context is located before the non-GC static base return((IntPtr)(pNonGcStaticBase - sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext))); } } } } } return(IntPtr.Zero); }