/// <summary> /// Locate field on native format type and fill in the field access flags and offset. /// </summary> /// <param name="type">Metadata reader for the declaring type</param> /// <param name="fieldName">Field name</param> /// <param name="fieldAccessMetadata">Output - metadata information for field accessor construction</param> /// <returns>true when found, false otherwise</returns> private static bool TryGetFieldAccessMetadataForNativeFormatType( TypeDesc type, string fieldName, ref FieldAccessMetadata fieldAccessMetadata) { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING FieldDesc fieldDesc = type.GetField(fieldName); if (fieldDesc == null) { return false; } fieldAccessMetadata.MappingTableModule = IntPtr.Zero; #if SUPPORTS_R2R_LOADING fieldAccessMetadata.MappingTableModule = ModuleList.Instance.GetModuleForMetadataReader(((NativeFormatType)type.GetTypeDefinition()).MetadataReader); #endif fieldAccessMetadata.Offset = fieldDesc.Offset; fieldAccessMetadata.Flags = FieldTableFlags.HasMetadataHandle; if (fieldDesc.IsThreadStatic) { // Specify that the data is thread local fieldAccessMetadata.Flags |= FieldTableFlags.ThreadStatic; // Specify that the general purpose field access routine that only relies on offset should be used. fieldAccessMetadata.Flags |= FieldTableFlags.IsUniversalCanonicalEntry; } else if (fieldDesc.IsStatic) { uint nonGcStaticsRVA = 0; uint gcStaticsRVA = 0; bool nonGenericCase = false; if (type is MetadataType) { // Static fields on Non-Generic types are contained within the module, and their offsets // are adjusted by their static rva base. nonGenericCase = true; #if SUPPORTS_R2R_LOADING if (!TryGetStaticsTableEntry((MetadataType)type, nonGcStaticsRVA: out nonGcStaticsRVA, gcStaticsRVA: out gcStaticsRVA)) #endif { Environment.FailFast( "Failed to locate statics table entry for for field '" + fieldName + "' on type " + type.ToString()); } } if (fieldDesc.HasGCStaticBase) { if ((gcStaticsRVA == 0) && nonGenericCase) { Environment.FailFast( "GC statics region was not found for field '" + fieldName + "' on type " + type.ToString()); } fieldAccessMetadata.Offset += (int)gcStaticsRVA; fieldAccessMetadata.Flags |= FieldTableFlags.IsGcSection; } else { if ((nonGcStaticsRVA == 0) && nonGenericCase) { Environment.FailFast( "Non-GC statics region was not found for field '" + fieldName + "' on type " + type.ToString()); } fieldAccessMetadata.Offset += (int)nonGcStaticsRVA; } fieldAccessMetadata.Flags |= FieldTableFlags.Static; return true; } else { // Instance field fieldAccessMetadata.Flags |= FieldTableFlags.Instance; } return true; #else return false; #endif }