internal static void EnsureFieldLayoutLoadedForGenericType(DefType type) { if (type.NativeLayoutFields != null) { return; } if (!type.IsTemplateUniversal()) { // We can hit this case where the template of type in question is not a universal canonical type. // Example: // BaseType<T> { ... } // DerivedType<T, U> : BaseType<T> { ... } // and an instantiation like DerivedType<string, int>. In that case, BaseType<string> will have a non-universal // template type, and requires special handling to compute its size and field layout. EnsureFieldLayoutLoadedForNonUniversalType(type); } else { TypeBuilderState state = type.GetOrCreateTypeBuilderState(); NativeParser typeInfoParser = state.GetParserForNativeLayoutInfo(); NativeParser fieldLayoutParser = typeInfoParser.GetParserForBagElementKind(BagElementKind.FieldLayout); EnsureFieldLayoutLoadedForUniversalType(type, state.NativeLayoutInfo.LoadContext, fieldLayoutParser); } }
private static void EnsureFieldLayoutLoadedForNonUniversalType(DefType type) { Debug.Assert(type.HasInstantiation); Debug.Assert(!type.ComputeTemplate().IsCanonicalSubtype(CanonicalFormKind.Universal)); if (type.NativeLayoutFields != null) { return; } // Look up the universal template for this type. Only the universal template has field layout // information, so we have to use it to parse the field layout. NativeLayoutInfoLoadContext universalLayoutLoadContext; NativeLayoutInfo universalLayoutInfo; NativeParser typeInfoParser = type.GetOrCreateTypeBuilderState().GetParserForUniversalNativeLayoutInfo(out universalLayoutLoadContext, out universalLayoutInfo); if (typeInfoParser.IsNull) { throw new TypeBuilder.MissingTemplateException(); } // Now parse that layout into the NativeLayoutFields array. NativeParser fieldLayoutParser = typeInfoParser.GetParserForBagElementKind(BagElementKind.FieldLayout); type.NativeLayoutFields = ParseFieldLayout(type, universalLayoutLoadContext, fieldLayoutParser); }
private bool ComputeHasDictionaryInVTable() { if (!HasDictionarySlotInVTable) { return(false); } if (TypeBeingBuilt.RetrieveRuntimeTypeHandleIfPossible()) { // Type was already constructed return(TypeBeingBuilt.RuntimeTypeHandle.GetDictionary() != IntPtr.Zero); } else { // Type is being newly constructed if (TemplateType != null) { NativeParser parser = GetParserForNativeLayoutInfo(); // Template type loader case #if GENERICS_FORCE_USG bool isTemplateUniversalCanon = state.TemplateType.IsCanonicalSubtype(CanonicalFormKind.UniversalCanonLookup); if (isTemplateUniversalCanon && type.CanShareNormalGenericCode()) { TypeBuilderState tempState = new TypeBuilderState(); tempState.NativeLayoutInfo = new NativeLayoutInfo(); tempState.TemplateType = type.Context.TemplateLookup.TryGetNonUniversalTypeTemplate(type, ref tempState.NativeLayoutInfo); if (tempState.TemplateType != null) { Debug.Assert(!tempState.TemplateType.IsCanonicalSubtype(CanonicalFormKind.UniversalCanonLookup)); parser = GetNativeLayoutInfoParser(type, ref tempState.NativeLayoutInfo); } } #endif var dictionaryLayoutParser = parser.GetParserForBagElementKind(BagElementKind.DictionaryLayout); return(!dictionaryLayoutParser.IsNull); } else { NativeParser parser = GetParserForReadyToRunNativeLayoutInfo(); // ReadyToRun case // Dictionary is directly encoded instead of the NativeLayout being a collection of bags if (parser.IsNull) { return(false); } // First unsigned value in the native layout is the number of dictionary entries return(parser.GetUnsigned() != 0); } } }
public override DefType[] ComputeRuntimeInterfaces(TypeDesc type) { TypeBuilderState state = type.GetOrCreateTypeBuilderState(); int totalInterfaces = RuntimeAugments.GetInterfaceCount(state.TemplateType.RuntimeTypeHandle); TypeLoaderLogger.WriteLine("Building runtime interfaces for type " + type.ToString() + " (total interfaces = " + totalInterfaces.LowLevelToString() + ") ..."); DefType[] interfaces = new DefType[totalInterfaces]; int numInterfaces = 0; // // Copy over all interfaces from base class // if (type.BaseType != null) { foreach (var baseInterface in type.BaseType.RuntimeInterfaces) { // There should be no duplicates Debug.Assert(!InterfaceInSet(interfaces, numInterfaces, baseInterface)); interfaces[numInterfaces++] = baseInterface; TypeLoaderLogger.WriteLine(" -> Added basetype interface " + baseInterface.ToString() + " on type " + type.ToString()); } } NativeParser typeInfoParser = state.GetParserForNativeLayoutInfo(); NativeParser interfaceParser = typeInfoParser.GetParserForBagElementKind(BagElementKind.ImplementedInterfaces); TypeDesc[] implementedInterfaces; if (!interfaceParser.IsNull) { implementedInterfaces = state.NativeLayoutInfo.LoadContext.GetTypeSequence(ref interfaceParser); } else { implementedInterfaces = TypeDesc.EmptyTypes; } // Note that the order in which the interfaces are added to the list is same as the order in which the MDIL binder adds them. // It is required for correctness foreach (TypeDesc interfaceType in implementedInterfaces) { DefType interfaceTypeAsDefType = (DefType)interfaceType; // Skip duplicates if (InterfaceInSet(interfaces, numInterfaces, interfaceTypeAsDefType)) { continue; } interfaces[numInterfaces++] = interfaceTypeAsDefType; TypeLoaderLogger.WriteLine(" -> Added interface " + interfaceTypeAsDefType.ToString() + " on type " + type.ToString()); foreach (var inheritedInterface in interfaceTypeAsDefType.RuntimeInterfaces) { // Skip duplicates if (InterfaceInSet(interfaces, numInterfaces, inheritedInterface)) { continue; } interfaces[numInterfaces++] = inheritedInterface; TypeLoaderLogger.WriteLine(" -> Added inherited interface " + inheritedInterface.ToString() + " on type " + type.ToString()); } } // TODO: Handle the screwy cases of generic interface folding Debug.Assert(numInterfaces == totalInterfaces, "Unexpected number of interfaces"); return(interfaces); }