/// <summary> /// Computes the GC pointer map of the thread static region of the type. /// </summary> public static GCPointerMap FromThreadStaticLayout(DefType type) { GCPointerMapBuilder builder = new GCPointerMapBuilder(type.ThreadStaticFieldSize, type.Context.Target.PointerSize); foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic || field.HasRva || field.IsLiteral || !field.IsThreadStatic) continue; TypeDesc fieldType = field.FieldType; if (fieldType.IsGCPointer) { builder.MarkGCPointer(field.Offset); } else if (fieldType.IsValueType) { var fieldDefType = (DefType)fieldType; if (fieldDefType.ContainsGCPointers) { GCPointerMapBuilder innerBuilder = builder.GetInnerBuilder(field.Offset, fieldDefType.InstanceByteCount); FromInstanceLayoutHelper(ref innerBuilder, fieldDefType); } } } return builder.ToGCMap(); }
protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForDefType(DefType type) { if (type.RetrieveRuntimeTypeHandleIfPossible() && !type.IsGenericDefinition) { // If the type is already constructed, use the NoMetadataRuntimeInterfacesAlgorithm. // its more efficient than loading from native layout or metadata. return s_noMetadataRuntimeInterfacesAlgorithm; } else if (type.HasNativeLayout) { return s_nativeLayoutInterfacesAlgorithm; } else if (type is NoMetadataType) { return s_noMetadataRuntimeInterfacesAlgorithm; } else if (type is MetadataType) { return s_metadataRuntimeInterfacesAlgorithm; } else { Debug.Assert(false); return null; } }
internal CanonicallyEquivalentEntryLocator(DefType typeToFind, CanonicalFormKind kind) { _genericArgs = null; _genericDefinition = default(RuntimeTypeHandle); _typeToFind = default(RuntimeTypeHandle); _canonKind = kind; _defType = typeToFind; }
/// <summary> /// Computes the GC pointer map for the instance fields of <paramref name="type"/>. /// </summary> public static GCPointerMap FromInstanceLayout(DefType type) { Debug.Assert(type.ContainsGCPointers); GCPointerMapBuilder builder = new GCPointerMapBuilder(type.InstanceByteCount, type.Context.Target.PointerSize); FromInstanceLayoutHelper(ref builder, type); return builder.ToGCMap(); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) { if (!type.IsTemplateUniversal() && (layoutKind == InstanceLayoutKind.TypeOnly)) { // Non universal generics can just use the template's layout DefType template = (DefType)type.ComputeTemplate(); return _noMetadataFieldLayoutAlgorithm.ComputeInstanceLayout(template, InstanceLayoutKind.TypeOnly); } // Only needed for universal generics, or when looking up an offset for a field for a universal generic LowLevelList<int> fieldOffsets; int[] position = ComputeTypeSizeAndAlignment(type, FieldLoadState.Instance, out fieldOffsets); int numInstanceFields = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (!field.IsStatic) { numInstanceFields++; } } int byteCountAlignment = position[InstanceAlignmentEntry]; byteCountAlignment = type.Context.Target.GetObjectAlignment(byteCountAlignment); ComputedInstanceFieldLayout layout = new ComputedInstanceFieldLayout() { Offsets = new FieldAndOffset[numInstanceFields], ByteCountAlignment = byteCountAlignment, ByteCountUnaligned = position[(int)NativeFormat.FieldStorage.Instance], PackValue = 0 // TODO, as we add more metadata handling logic, find out if its necessary to use a meaningful value here }; if (!type.IsValueType) { layout.FieldAlignment = type.Context.Target.PointerSize; layout.FieldSize = type.Context.Target.PointerSize; } else { layout.FieldAlignment = position[InstanceAlignmentEntry]; layout.FieldSize = MemoryHelpers.AlignUp(position[(int)NativeFormat.FieldStorage.Instance], layout.FieldAlignment); } int curInstanceField = 0; foreach (NativeLayoutFieldDesc field in type.NativeLayoutFields) { if (!field.IsStatic) { layout.Offsets[curInstanceField] = new FieldAndOffset(field, fieldOffsets[curInstanceField]); curInstanceField++; } } return layout; }
/// <summary> /// Checks if the interface exists in the list of interfaces /// </summary> private static bool InterfaceInSet(DefType[] interfaces, int numInterfaces, DefType interfaceType) { for (int i = 0; i < numInterfaces; i++) { if (interfaces[i].Equals(interfaceType)) return true; } return false; }
public ValueTypeShapeCharacteristicsTests() { _context = new TestTypeSystemContext(TargetArchitecture.X64); var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly"); _context.SetSystemModule(systemModule); _testModule = systemModule; _singleType = _context.GetWellKnownType(WellKnownType.Single); _doubleType = _context.GetWellKnownType(WellKnownType.Double); }
public VirtualFunctionOverrideTests() { _context = new TestTypeSystemContext(TargetArchitecture.X64); var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly"); _context.SetSystemModule(systemModule); _testModule = systemModule; _stringType = _context.GetWellKnownType(WellKnownType.String); _voidType = _context.GetWellKnownType(WellKnownType.Void); }
public override DefType[] ComputeRuntimeInterfaces(TypeDesc type) { int numInterfaces = RuntimeAugments.GetInterfaceCount(type.RuntimeTypeHandle); DefType[] interfaces = new DefType[numInterfaces]; for (int i = 0; i < numInterfaces; i++) { RuntimeTypeHandle itfHandle = RuntimeAugments.GetInterface(type.RuntimeTypeHandle, i); TypeDesc itfType = type.Context.ResolveRuntimeTypeHandle(itfHandle); interfaces[i] = (DefType)itfType; } return interfaces; }
public void AppendName(StringBuilder sb, DefType type) { if (!type.IsTypeDefinition) { AppendNameForInstantiatedType(sb, type); } else { DefType containingType = type.ContainingType; if (containingType != null) AppendNameForNestedType(sb, type, containingType); else AppendNameForNamespaceType(sb, type); } }
/// <summary> /// Add an interface and its required interfaces to the interfacesArray /// </summary> private void BuildPostOrderInterfaceList(DefType iface, ref ArrayBuilder<DefType> interfacesArray) { if (interfacesArray.Contains(iface)) return; foreach (DefType implementedInterface in iface.RuntimeInterfaces) { BuildPostOrderInterfaceList(implementedInterface, ref interfacesArray); } if (interfacesArray.Contains(iface)) return; interfacesArray.Add(iface); }
public CanonicallyEquivalentEntryLocator(RuntimeTypeHandle typeToFind, CanonicalFormKind kind) { if (RuntimeAugments.IsGenericType(typeToFind)) { _genericDefinition = RuntimeAugments.GetGenericInstantiation(typeToFind, out _genericArgs); } else { _genericArgs = null; _genericDefinition = default(RuntimeTypeHandle); } _typeToFind = typeToFind; _canonKind = kind; _defType = null; }
public unsafe override bool ComputeContainsGCPointers(DefType type) { if (type.IsTemplateCanonical()) { return type.ComputeTemplate().RuntimeTypeHandle.ToEETypePtr()->HasGCPointers; } else { if (type.RetrieveRuntimeTypeHandleIfPossible()) { return type.RuntimeTypeHandle.ToEETypePtr()->HasGCPointers; } return type.GetOrCreateTypeBuilderState().InstanceGCLayout != null; } }
private DefType[] InitializeImplementedInterfaces() { var interfaceHandles = _typeDefinition.GetInterfaceImplementations(); int count = interfaceHandles.Count; if (count == 0) return (_implementedInterfaces = Array.Empty<DefType>()); DefType[] implementedInterfaces = new DefType[count]; int i = 0; foreach (var interfaceHandle in interfaceHandles) { var interfaceImplementation = this.MetadataReader.GetInterfaceImplementation(interfaceHandle); implementedInterfaces[i++] = (DefType)_module.GetType(interfaceImplementation.Interface); } return (_implementedInterfaces = implementedInterfaces); }
private DefType[] InitializeImplementedInterfaces() { var interfaceHandles = _typeDefinition.Interfaces; int count = interfaceHandles.Count; if (count == 0) return (_implementedInterfaces = Array.Empty<DefType>()); DefType[] implementedInterfaces = new DefType[count]; int i = 0; foreach (var interfaceHandle in interfaceHandles) { implementedInterfaces[i++] = (DefType)_metadataUnit.GetType(interfaceHandle); } // TODO Add duplicate detection return (_implementedInterfaces = implementedInterfaces); }
public NoMetadataType(TypeSystemContext context, RuntimeTypeHandle genericTypeDefinition, DefType genericTypeDefinitionAsDefType, Instantiation instantiation, int hashcode) { _hashcode = hashcode; _context = context; _genericTypeDefinition = genericTypeDefinition; _genericTypeDefinitionAsDefType = genericTypeDefinitionAsDefType; if (_genericTypeDefinitionAsDefType == null) _genericTypeDefinitionAsDefType = this; _instantiation = instantiation; // Instantiation must either be: // Something valid (if the type is generic, or a generic type definition) // or Empty (if the type isn't a generic of any form) unsafe { Debug.Assert(((_instantiation.Length > 0) && _genericTypeDefinition.ToEETypePtr()->IsGenericTypeDefinition) || ((_instantiation.Length == 0) && !_genericTypeDefinition.ToEETypePtr()->IsGenericTypeDefinition)); } }
public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type) { if (type.RetrieveRuntimeTypeHandleIfPossible()) { // If the type is already constructed, use the NoMetadataFieldLayoutAlgorithm. // its more efficient than loading from native layout or metadata. return s_noMetadataFieldLayoutAlgorithm; } if (type.HasNativeLayout) { return s_nativeLayoutFieldAlgorithm; } else if (type is NoMetadataType) { return s_noMetadataFieldLayoutAlgorithm; } else { return s_metadataFieldLayoutAlgorithm; } }
private DefType[] InitializeImplementedInterfaces() { var interfaceHandles = _typeDefinition.GetInterfaceImplementations(); int count = interfaceHandles.Count; if (count == 0) return (_implementedInterfaces = Array.Empty<DefType>()); DefType[] implementedInterfaces = new DefType[count]; int i = 0; foreach (var interfaceHandle in interfaceHandles) { var interfaceImplementation = this.MetadataReader.GetInterfaceImplementation(interfaceHandle); DefType interfaceType = _module.GetType(interfaceImplementation.Interface) as DefType; if (interfaceType == null) throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadBadFormat, this); implementedInterfaces[i++] = interfaceType; } return (_implementedInterfaces = implementedInterfaces); }
protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type) { switch (type.Category) { case TypeFlags.Void: sb.Append("void"); return; case TypeFlags.Boolean: sb.Append("bool"); return; case TypeFlags.Char: sb.Append("char"); return; case TypeFlags.SByte: sb.Append("int8"); return; case TypeFlags.Byte: sb.Append("uint8"); return; case TypeFlags.Int16: sb.Append("int16"); return; case TypeFlags.UInt16: sb.Append("uint16"); return; case TypeFlags.Int32: sb.Append("int32"); return; case TypeFlags.UInt32: sb.Append("uint32"); return; case TypeFlags.Int64: sb.Append("int64"); return; case TypeFlags.UInt64: sb.Append("uint64"); return; case TypeFlags.IntPtr: sb.Append("native int"); return; case TypeFlags.UIntPtr: sb.Append("native uint"); return; case TypeFlags.Single: sb.Append("float32"); return; case TypeFlags.Double: sb.Append("float64"); return; } if (type.IsString) { sb.Append("string"); return; } if (type.IsObject) { sb.Append("object"); return; } AppendNameForNamespaceTypeWithoutAliases(sb, type); }
public override DefType ComputeHomogeneousFloatAggregateElementType(DefType type) { return(null); }
/// <summary> /// Abstraction to allow the type system context to affect the field layout /// algorithm used by types to lay themselves out. /// </summary> public abstract FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type);
public override bool ComputeContainsPointers(DefType type) { bool someFieldContainsPointers = false; foreach (var field in type.GetFields()) { if (field.IsStatic) continue; TypeDesc fieldType = field.FieldType; if (fieldType.IsValueType) { if (fieldType.IsPrimitive) continue; if (((MetadataType)fieldType).ContainsPointers) { someFieldContainsPointers = true; break; } } else if (fieldType is DefType || fieldType is ArrayType || fieldType.IsByRef) { someFieldContainsPointers = true; break; } } return someFieldContainsPointers; }
protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) { AppendNameForNamespaceType(sb, containingType); sb.Append('+'); string ns = GetTypeNamespace(nestedType); if (ns.Length > 0) { AppendEscapedIdentifier(sb, ns); sb.Append('.'); } AppendEscapedIdentifier(sb, GetTypeName(nestedType)); }
public unsafe override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind) { MetadataType type = (MetadataType)defType; int numStaticFields = 0; foreach (var field in type.GetFields()) { if (!field.IsStatic || field.HasRva || field.IsLiteral) { continue; } numStaticFields++; } ComputedStaticFieldLayout result; result.GcStatics = new StaticsBlock(); result.NonGcStatics = new StaticsBlock(); result.ThreadStatics = new StaticsBlock(); if (numStaticFields == 0) { result.Offsets = Array.Empty <FieldAndOffset>(); return(result); } result.Offsets = new FieldAndOffset[numStaticFields]; PrepareRuntimeSpecificStaticFieldLayout(type.Context, ref result); int index = 0; foreach (var field in type.GetFields()) { // Nonstatic fields, literal fields, and RVA mapped fields don't participate in layout if (!field.IsStatic || field.HasRva || field.IsLiteral) { continue; } StaticsBlock *block = field.IsThreadStatic ? &result.ThreadStatics : field.HasGCStaticBase ? &result.GcStatics : &result.NonGcStatics; SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, type.Context.Target.DefaultPackingSize); block->Size = AlignmentHelper.AlignUp(block->Size, sizeAndAlignment.Alignment); result.Offsets[index] = new FieldAndOffset(field, block->Size); block->Size = checked (block->Size + sizeAndAlignment.Size); block->LargestAlignment = Math.Max(block->LargestAlignment, sizeAndAlignment.Alignment); index++; } FinalizeRuntimeSpecificStaticFieldLayout(type.Context, ref result); return(result); }
/// <summary> /// Retrieves the size of a well known type. /// </summary> public int GetWellKnownTypeSize(DefType type) { switch (type.Category) { case TypeFlags.Void: return PointerSize; case TypeFlags.Boolean: return 1; case TypeFlags.Char: return 2; case TypeFlags.Byte: case TypeFlags.SByte: return 1; case TypeFlags.UInt16: case TypeFlags.Int16: return 2; case TypeFlags.UInt32: case TypeFlags.Int32: return 4; case TypeFlags.UInt64: case TypeFlags.Int64: return 8; case TypeFlags.Single: return 4; case TypeFlags.Double: return 8; case TypeFlags.UIntPtr: case TypeFlags.IntPtr: return PointerSize; } // Add new well known types if necessary throw new InvalidOperationException(); }
private static DefaultInterfaceMethodResolution ResolveInterfaceMethodToDefaultImplementationOnType(MethodDesc interfaceMethod, MetadataType currentType, out MethodDesc impl) { TypeDesc interfaceMethodOwningType = interfaceMethod.OwningType; MetadataType mostSpecificInterface = null; bool diamondCase = false; impl = null; DefType[] consideredInterfaces; if (!currentType.IsInterface) { // If this is not an interface, only things on the interface list could provide // default implementations. consideredInterfaces = currentType.RuntimeInterfaces; } else { // If we're asking about an interface, include the interface in the list. consideredInterfaces = new DefType[currentType.RuntimeInterfaces.Length + 1]; Array.Copy(currentType.RuntimeInterfaces, consideredInterfaces, currentType.RuntimeInterfaces.Length); consideredInterfaces[consideredInterfaces.Length - 1] = (DefType)currentType.InstantiateAsOpen(); } foreach (MetadataType runtimeInterface in consideredInterfaces) { if (runtimeInterface == interfaceMethodOwningType) { // Also consider the default interface method implementation on the interface itself // if we don't have anything else yet if (mostSpecificInterface == null && !interfaceMethod.IsAbstract) { mostSpecificInterface = runtimeInterface; impl = interfaceMethod; } } else if (Array.IndexOf(runtimeInterface.RuntimeInterfaces, interfaceMethodOwningType) != -1) { // This interface might provide a default implementation MethodImplRecord[] possibleImpls = runtimeInterface.FindMethodsImplWithMatchingDeclName(interfaceMethod.Name); if (possibleImpls != null) { foreach (MethodImplRecord implRecord in possibleImpls) { if (implRecord.Decl == interfaceMethod) { // This interface provides a default implementation. // Is it also most specific? if (mostSpecificInterface == null || Array.IndexOf(runtimeInterface.RuntimeInterfaces, mostSpecificInterface) != -1) { mostSpecificInterface = runtimeInterface; impl = implRecord.Body; diamondCase = false; } else if (Array.IndexOf(mostSpecificInterface.RuntimeInterfaces, runtimeInterface) == -1) { diamondCase = true; } break; } } } } } if (diamondCase) { impl = null; return(DefaultInterfaceMethodResolution.Diamond); } else if (impl == null) { return(DefaultInterfaceMethodResolution.None); } else if (impl.IsAbstract) { return(DefaultInterfaceMethodResolution.Reabstraction); } return(DefaultInterfaceMethodResolution.DefaultImplementation); }
// Todo: This is looking up the hierarchy to DefType and ParameterizedType. It should really // call a virtual or an outside type to handle those parts internal bool RetrieveRuntimeTypeHandleIfPossible() { TypeDesc type = this; if (!type.RuntimeTypeHandle.IsNull()) { return(true); } TypeBuilderState state = GetTypeBuilderStateIfExist(); if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle) { return(false); } if (type is DefType) { DefType typeAsDefType = (DefType)type; TypeDesc typeDefinition = typeAsDefType.GetTypeDefinition(); RuntimeTypeHandle typeDefHandle = typeDefinition.RuntimeTypeHandle; if (typeDefHandle.IsNull()) { #if SUPPORTS_NATIVE_METADATA_TYPE_LOADING NativeFormat.NativeFormatType mdType = typeDefinition as NativeFormat.NativeFormatType; if (mdType != null) { // Look up the runtime type handle in the module metadata if (TypeLoaderEnvironment.Instance.TryGetNamedTypeForMetadata(mdType.MetadataReader, mdType.Handle, out typeDefHandle)) { typeDefinition.SetRuntimeTypeHandleUnsafe(typeDefHandle); } } #endif } if (!typeDefHandle.IsNull()) { Instantiation instantiation = typeAsDefType.Instantiation; if ((instantiation.Length > 0) && !typeAsDefType.IsGenericDefinition) { // Generic type. First make sure we have type handles for the arguments, then check // the instantiation. bool argumentsRegistered = true; bool arrayArgumentsFound = false; for (int i = 0; i < instantiation.Length; i++) { if (!instantiation[i].RetrieveRuntimeTypeHandleIfPossible()) { argumentsRegistered = false; arrayArgumentsFound = arrayArgumentsFound || (instantiation[i] is ArrayType); } } RuntimeTypeHandle rtth; // If at least one of the arguments is not known to the runtime, we take a slower // path to compare the current type we need a handle for to the list of generic // types statically available, by loading them as DefTypes and doing a DefType comparaison if ((argumentsRegistered && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.HandleBasedGenericTypeLookup(typeAsDefType), out rtth)) || (arrayArgumentsFound && TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(new TypeLoaderEnvironment.DefTypeBasedGenericTypeLookup(typeAsDefType), out rtth))) { typeAsDefType.SetRuntimeTypeHandleUnsafe(rtth); return(true); } } else { // Nongeneric, or generic type def types are just the type handle of the type definition as found above type.SetRuntimeTypeHandleUnsafe(typeDefHandle); return(true); } } } else if (type is ParameterizedType) { ParameterizedType typeAsParameterType = (ParameterizedType)type; if (typeAsParameterType.ParameterType.RetrieveRuntimeTypeHandleIfPossible()) { RuntimeTypeHandle rtth; if ((type is ArrayType && (TypeLoaderEnvironment.Instance.TryGetArrayTypeForElementType_LookupOnly(typeAsParameterType.ParameterType.RuntimeTypeHandle, type.IsMdArray, type.IsMdArray ? ((ArrayType)type).Rank : -1, out rtth) || TypeLoaderEnvironment.Instance.TryGetArrayTypeHandleForNonDynamicArrayTypeFromTemplateTable(type as ArrayType, out rtth))) || (type is PointerType && TypeSystemContext.PointerTypesCache.TryGetValue(typeAsParameterType.ParameterType.RuntimeTypeHandle, out rtth))) { typeAsParameterType.SetRuntimeTypeHandleUnsafe(rtth); return(true); } else if (type is ByRefType) { // Byref types don't have any associated type handles, so return success at this point // since we were able to resolve the typehandle of the element type return(true); } } } else if (type is SignatureVariable) { // SignatureVariables do not have RuntimeTypeHandles } else { Debug.Assert(false); } // Make a note on the type build state that we have attempted to retrieve RuntimeTypeHandle but there is not one GetOrCreateTypeBuilderState().AttemptedAndFailedToRetrieveTypeHandle = true; return(false); }
/// <summary> /// Find matching a matching method by name and sig on a type. (Restricted to virtual methods only) Only search amongst methods with the same vtable slot. /// </summary> /// <param name="method"></param> /// <param name="currentType"></param> /// <param name="reverseMethodSearch">Used to control the order of the search. For historical purposes to /// match .NET Framework behavior, this is typically true, but not always. There is no particular rationale /// for the particular orders other than to attempt to be consistent in virtual method override behavior /// betweeen runtimes.</param> /// <returns></returns> private static MethodDesc FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(MethodDesc method, DefType currentType, bool reverseMethodSearch) { return(FindMatchingVirtualMethodOnTypeByNameAndSig(method, currentType, reverseMethodSearch, nameSigMatchMethodIsValidCandidate: s_VerifyMethodsHaveTheSameVirtualSlot)); }
/// <summary> /// Find matching a matching method by name and sig on a type. (Restricted to virtual methods only) /// </summary> /// <param name="targetMethod"></param> /// <param name="currentType"></param> /// <param name="reverseMethodSearch">Used to control the order of the search. For historical purposes to /// match .NET Framework behavior, this is typically true, but not always. There is no particular rationale /// for the particular orders other than to attempt to be consistent in virtual method override behavior /// betweeen runtimes.</param> /// <param name="nameSigMatchMethodIsValidCandidate"></param> /// <returns></returns> private static MethodDesc FindMatchingVirtualMethodOnTypeByNameAndSig(MethodDesc targetMethod, DefType currentType, bool reverseMethodSearch, Func <MethodDesc, MethodDesc, bool> nameSigMatchMethodIsValidCandidate) { string name = targetMethod.Name; MethodSignature sig = targetMethod.Signature; MethodDesc implMethod = null; foreach (MethodDesc candidate in currentType.GetAllVirtualMethods()) { if (candidate.Name == name) { if (candidate.Signature.Equals(sig)) { if (nameSigMatchMethodIsValidCandidate == null || nameSigMatchMethodIsValidCandidate(targetMethod, candidate)) { implMethod = candidate; // If reverseMethodSearch is enabled, we want to find the last match on this type, not the first // (reverseMethodSearch is used for most matches except for searches for name/sig method matches for interface methods on the most derived type) if (!reverseMethodSearch) { return(implMethod); } } } } } return(implMethod); }
private string GetTypeNamespace(DefType type) { return(type.Namespace); }
protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) { AppendName(sb, containingType); sb.Append('/'); sb.Append(nestedType.Name); }
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { if (!type.IsValueType) { return(ValueTypeShapeCharacteristics.None); } ValueTypeShapeCharacteristics result = ComputeHomogeneousFloatAggregateCharacteristic(type); // TODO: System V AMD64 characteristics (https://github.com/dotnet/corert/issues/158) return(result); }
protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type) { if (type.IsPrimitive) { sb.Append(type.Name); } else { string ns = type.Namespace; if (ns.Length > 0) { sb.Append(ns); sb.Append('.'); } sb.Append(type.Name); } }
private ValueTypeShapeCharacteristics ComputeHomogeneousFloatAggregateCharacteristic(DefType type) { Debug.Assert(type.IsValueType); MetadataType metadataType = (MetadataType)type; // No HFAs with explicit layout. There may be cases where explicit layout may be still // eligible for HFA, but it is hard to tell the real intent. Make it simple and just // unconditionally disable HFAs for explicit layout. if (metadataType.IsExplicitLayout) { return(ValueTypeShapeCharacteristics.None); } switch (metadataType.Category) { case TypeFlags.Single: case TypeFlags.Double: // These are the primitive types that constitute a HFA type. return(ValueTypeShapeCharacteristics.HomogenousFloatAggregate); case TypeFlags.ValueType: DefType expectedElementType = null; foreach (FieldDesc field in metadataType.GetFields()) { if (field.IsStatic) { continue; } // If a field isn't a DefType, then this type cannot be an HFA type // If a field isn't a HFA type, then this type cannot be an HFA type DefType fieldType = field.FieldType as DefType; if (fieldType == null || !fieldType.IsHfa) { return(ValueTypeShapeCharacteristics.None); } if (expectedElementType == null) { // If we hadn't yet figured out what form of HFA this type might be, we've // now found one case. expectedElementType = fieldType.HfaElementType; Debug.Assert(expectedElementType != null); } else if (expectedElementType != fieldType.HfaElementType) { // If we had already determined the possible HFA type of the current type, but // the field we've encountered is not of that type, then the current type cannot // be an HFA type. return(ValueTypeShapeCharacteristics.None); } } // No fields means this is not HFA. if (expectedElementType == null) { return(ValueTypeShapeCharacteristics.None); } // Note that we check the total size, but do not perform any checks on number of fields: // - Type of fields can be HFA valuetype itself // - Managed C++ HFA valuetypes have just one <alignment member> of type float to signal that // the valuetype is HFA and explicitly specified size int maxSize = expectedElementType.InstanceFieldSize * expectedElementType.Context.Target.MaximumHfaElementCount; if (type.InstanceFieldSize > maxSize) { return(ValueTypeShapeCharacteristics.None); } // All the tests passed. This is an HFA type. return(ValueTypeShapeCharacteristics.HomogenousFloatAggregate); } return(ValueTypeShapeCharacteristics.None); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { MetadataType type = (MetadataType)defType; // CLI - Partition 1, section 9.5 - Generic types shall not be marked explicitlayout. if (type.HasInstantiation && type.IsExplicitLayout) { throw new TypeLoadException(); } // Count the number of instance fields in advance for convenience int numInstanceFields = 0; foreach (var field in type.GetFields()) if (!field.IsStatic) numInstanceFields++; if (type.IsModuleType) { // This is a global type, it must not have instance fields. if (numInstanceFields > 0) { throw new TypeLoadException(); } // Global types do not do the rest of instance field layout. ComputedInstanceFieldLayout result = new ComputedInstanceFieldLayout(); result.PackValue = type.Context.Target.DefaultPackingSize; result.Offsets = Array.Empty<FieldAndOffset>(); return result; } // CLI - Partition 2, section 22.8 // A type has layout if it is marked SequentialLayout or ExplicitLayout. If any type within an inheritance chain has layout, // then so shall all its base classes, up to the one that descends immediately from System.ValueType (if it exists in the type’s // hierarchy); otherwise, from System.Object // Note: While the CLI isn't clearly worded, the layout needs to be the same for the entire chain. // If the current type isn't ValueType or System.Object and has a layout and the parent type isn't // ValueType or System.Object then the layout type attributes need to match if ((!type.IsValueType && !type.IsObject) && (type.IsSequentialLayout || type.IsExplicitLayout) && (!type.BaseType.IsValueType && !type.BaseType.IsObject)) { MetadataType baseType = type.MetadataBaseType; if (type.IsSequentialLayout != baseType.IsSequentialLayout || type.IsExplicitLayout != baseType.IsExplicitLayout) { throw new TypeLoadException(); } } // Enum types must have a single instance field if (type.IsEnum && numInstanceFields != 1) { throw new TypeLoadException(); } if (type.IsPrimitive) { // Primitive types are special - they may have a single field of the same type // as the type itself. They do not do the rest of instance field layout. if (numInstanceFields > 1) { throw new TypeLoadException(); } SizeAndAlignment instanceByteSizeAndAlignment; var sizeAndAlignment = ComputeInstanceSize( type, type.Context.Target.GetWellKnownTypeSize(type), type.Context.Target.GetWellKnownTypeAlignment(type), out instanceByteSizeAndAlignment ); ComputedInstanceFieldLayout result = new ComputedInstanceFieldLayout { ByteCountUnaligned = instanceByteSizeAndAlignment.Size, ByteCountAlignment = instanceByteSizeAndAlignment.Alignment, FieldAlignment = sizeAndAlignment.Alignment, FieldSize = sizeAndAlignment.Size, PackValue = type.Context.Target.DefaultPackingSize }; if (numInstanceFields > 0) { FieldDesc instanceField = null; foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic) { Debug.Assert(instanceField == null, "Unexpected extra instance field"); instanceField = field; } } Debug.Assert(instanceField != null, "Null instance field"); result.Offsets = new FieldAndOffset[] { new FieldAndOffset(instanceField, 0) }; } else { result.Offsets = Array.Empty<FieldAndOffset>(); } return result; } // Verify that no ByRef types present in this type's fields foreach (var field in type.GetFields()) if (field.FieldType is ByRefType) throw new TypeLoadException(); // If the type has layout, read its packing and size info // If the type has explicit layout, also read the field offset info if (type.IsExplicitLayout || type.IsSequentialLayout) { if (type.IsEnum) { throw new TypeLoadException(); } var layoutMetadata = type.GetClassLayout(); // If packing is out of range or not a power of two, throw that the size is invalid int packing = layoutMetadata.PackingSize; if (packing < 0 || packing > 128 || ((packing & (packing - 1)) != 0)) { throw new TypeLoadException(); } Debug.Assert(layoutMetadata.Offsets == null || layoutMetadata.Offsets.Length == numInstanceFields); } // At this point all special cases are handled and all inputs validated if (type.IsExplicitLayout) { return ComputeExplicitFieldLayout(type, numInstanceFields); } else { // Treat auto layout as sequential for now return ComputeSequentialFieldLayout(type, numInstanceFields); } }
public PInvokeLazyFixupFieldHashtable(DefType owningType) { _owningType = owningType; }
protected abstract void AppendNameForInstantiatedType(StringBuilder sb, DefType type);
public RuntimeDeterminedTypeKey(DefType plainCanonType, GenericParameterDesc detailsType) { _plainCanonType = plainCanonType; _detailsType = detailsType; }
/// <summary> /// Abstraction to allow the type system context to affect the field layout /// algorithm used by types to lay themselves out. /// </summary> public virtual FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type) { // Type system contexts that support computing field layout need to override this. throw new NotSupportedException(); }
public RuntimeDeterminedType GetRuntimeDeterminedType(DefType plainCanonType, GenericParameterDesc detailsType) { return(_runtimeDeterminedTypes.GetOrCreateValue(new RuntimeDeterminedTypeKey(plainCanonType, detailsType))); }
public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth) { TypeDesc returnedType; if (_runtimeTypeHandleResolutionCache.TryGetValue(rtth, out returnedType)) { return(returnedType); } if (rtth.Equals(CanonType.RuntimeTypeHandle)) { returnedType = CanonType; } else if (rtth.Equals(UniversalCanonType.RuntimeTypeHandle)) { returnedType = UniversalCanonType; } else if (RuntimeAugments.IsGenericTypeDefinition(rtth)) { returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth); if (returnedType == null) { unsafe { TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericArgumentCount]; for (int i = 0; i < genericParameters.Length; i++) { genericParameters[i] = GetSignatureVariable(i, false); } returnedType = new NoMetadataType(this, rtth, null, new Instantiation(genericParameters), rtth.GetHashCode()); } } } else if (RuntimeAugments.IsGenericType(rtth)) { RuntimeTypeHandle typeDefRuntimeTypeHandle; RuntimeTypeHandle[] genericArgRuntimeTypeHandles; typeDefRuntimeTypeHandle = RuntimeAugments.GetGenericInstantiation(rtth, out genericArgRuntimeTypeHandles); DefType typeDef = (DefType)ResolveRuntimeTypeHandle(typeDefRuntimeTypeHandle); Instantiation genericArgs = ResolveRuntimeTypeHandles(genericArgRuntimeTypeHandles); returnedType = ResolveGenericInstantiation(typeDef, genericArgs); } else if (RuntimeAugments.IsArrayType(rtth)) { RuntimeTypeHandle elementTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth); TypeDesc elementType = ResolveRuntimeTypeHandle(elementTypeHandle); unsafe { if (rtth.ToEETypePtr()->IsSzArray) { returnedType = GetArrayType(elementType); } else { returnedType = GetArrayType(elementType, rtth.ToEETypePtr()->ArrayRank); } } } else if (RuntimeAugments.IsUnmanagedPointerType(rtth)) { RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth); TypeDesc targetType = ResolveRuntimeTypeHandle(targetTypeHandle); returnedType = GetPointerType(targetType); } else if (RuntimeAugments.IsByRefType(rtth)) { RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth); TypeDesc targetType = ResolveRuntimeTypeHandle(targetTypeHandle); returnedType = GetByRefType(targetType); } else { returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth); if (returnedType == null) { returnedType = new NoMetadataType(this, rtth, null, Instantiation.Empty, rtth.GetHashCode()); } } // We either retrieved an existing DefType that is already registered with the runtime // or one that is not associated with an EEType yet. If it's not associated, associate it. if (returnedType.RuntimeTypeHandle.IsNull()) { TypeBuilderState state = returnedType.GetTypeBuilderStateIfExist(); bool skipStoringRuntimeTypeHandle = false; // If we've already attempted to lookup and failed to retrieve this type handle, we // may have already decided to create a new one. In that case, do not attempt to abort // that creation process as it may have already begun the process of type creation if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle) { skipStoringRuntimeTypeHandle = true; } if (!skipStoringRuntimeTypeHandle) { returnedType.SetRuntimeTypeHandleUnsafe(rtth); } } _runtimeTypeHandleResolutionCache.Add(rtth, returnedType); return(returnedType.WithDebugName()); }
private static MethodDesc FindMatchingVirtualMethodOnTypeByNameAndSig(MethodDesc targetMethod, DefType currentType) { string name = targetMethod.Name; MethodSignature sig = targetMethod.Signature; // TODO: InstantiatedType.GetMethod can't handle this for a situation like // an instantiation of Foo<T>.M(T) because sig is instantiated, but it compares // it to the uninstantiated version //MethodDesc implMethod = currentType.GetMethod(name, sig); MethodDesc implMethod = null; foreach (MethodDesc candidate in currentType.GetAllVirtualMethods()) { if (candidate.Name == name) { if (candidate.Signature.Equals(sig)) { if (implMethod != null) { throw new NotImplementedException("NYI: differentiating between overloads on instantiations when the instantiated signatures match."); } implMethod = candidate; } } } return(implMethod); }
public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { return(ValueTypeShapeCharacteristics.None); }
/// <summary> /// Retrieves the alignment required by a well known type. /// </summary> public LayoutInt GetWellKnownTypeAlignment(DefType type) { // Size == Alignment for all platforms. return(GetWellKnownTypeSize(type)); }
public override bool ComputeContainsGCPointers(DefType type) { // This should never be called throw new NotSupportedException(); }
public RuntimeDeterminedType(DefType rawCanonType, GenericParameterDesc runtimeDeterminedDetailsType) { _rawCanonType = rawCanonType; _runtimeDeterminedDetailsType = runtimeDeterminedDetailsType; }
public void AppendNameForNamespaceTypeWithoutAliases(StringBuilder sb, DefType type) { ModuleDesc owningModule = (type as MetadataType)?.Module; if (owningModule != null && owningModule != _thisModule) { Debug.Assert(owningModule is IAssemblyDesc); string owningModuleName = ((IAssemblyDesc)owningModule).GetName().Name; sb.Append('['); sb.Append(owningModuleName); sb.Append(']'); } string ns = type.Namespace; if (ns.Length > 0) { sb.Append(ns); sb.Append('.'); } sb.Append(type.Name); }
public override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType defType, InstanceLayoutKind layoutKind) { MetadataType type = (MetadataType)defType; if (type.IsGenericDefinition) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // CLI - Partition 1, section 9.5 - Generic types shall not be marked explicitlayout. if (type.HasInstantiation && type.IsExplicitLayout) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadExplicitGeneric, type.GetTypeDefinition()); } // Count the number of instance fields in advance for convenience int numInstanceFields = 0; foreach (var field in type.GetFields()) { if (field.IsStatic) { continue; } TypeDesc fieldType = field.FieldType; // ByRef instance fields are not allowed. if (fieldType.IsByRef) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // ByRef-like instance fields on non-byref-like types are not allowed. if (fieldType.IsByRefLike && !type.IsByRefLike) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } numInstanceFields++; } if (type.IsModuleType) { // This is a global type, it must not have instance fields. if (numInstanceFields > 0) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } // Global types do not do the rest of instance field layout. ComputedInstanceFieldLayout result = new ComputedInstanceFieldLayout(); result.Offsets = Array.Empty <FieldAndOffset>(); return(result); } // CLI - Partition 2, section 22.8 // A type has layout if it is marked SequentialLayout or ExplicitLayout. If any type within an inheritance chain has layout, // then so shall all its base classes, up to the one that descends immediately from System.ValueType (if it exists in the type's // hierarchy); otherwise, from System.Object // Note: While the CLI isn't clearly worded, the layout needs to be the same for the entire chain. // If the current type isn't ValueType or System.Object and has a layout and the parent type isn't // ValueType or System.Object then the layout type attributes need to match if ((!type.IsValueType && !type.IsObject) && (type.IsSequentialLayout || type.IsExplicitLayout) && (!type.BaseType.IsValueType && !type.BaseType.IsObject)) { MetadataType baseType = type.MetadataBaseType; if (type.IsSequentialLayout != baseType.IsSequentialLayout || type.IsExplicitLayout != baseType.IsExplicitLayout) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } } // Enum types must have a single instance field if (type.IsEnum && numInstanceFields != 1) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } if (type.IsPrimitive) { // Primitive types are special - they may have a single field of the same type // as the type itself. They do not do the rest of instance field layout. if (numInstanceFields > 1) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } SizeAndAlignment instanceByteSizeAndAlignment; var sizeAndAlignment = ComputeInstanceSize( type, type.Context.Target.GetWellKnownTypeSize(type), type.Context.Target.GetWellKnownTypeAlignment(type), 0, out instanceByteSizeAndAlignment ); ComputedInstanceFieldLayout result = new ComputedInstanceFieldLayout { ByteCountUnaligned = instanceByteSizeAndAlignment.Size, ByteCountAlignment = instanceByteSizeAndAlignment.Alignment, FieldAlignment = sizeAndAlignment.Alignment, FieldSize = sizeAndAlignment.Size, LayoutAbiStable = true }; if (numInstanceFields > 0) { FieldDesc instanceField = null; foreach (FieldDesc field in type.GetFields()) { if (!field.IsStatic) { Debug.Assert(instanceField == null, "Unexpected extra instance field"); instanceField = field; } } Debug.Assert(instanceField != null, "Null instance field"); result.Offsets = new FieldAndOffset[] { new FieldAndOffset(instanceField, LayoutInt.Zero) }; } else { result.Offsets = Array.Empty <FieldAndOffset>(); } return(result); } // If the type has layout, read its packing and size info // If the type has explicit layout, also read the field offset info if (type.IsExplicitLayout || type.IsSequentialLayout) { if (type.IsEnum) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } var layoutMetadata = type.GetClassLayout(); // If packing is out of range or not a power of two, throw that the size is invalid int packing = layoutMetadata.PackingSize; if (packing < 0 || packing > 128 || ((packing & (packing - 1)) != 0)) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type); } Debug.Assert(layoutMetadata.Offsets == null || layoutMetadata.Offsets.Length == numInstanceFields); } // At this point all special cases are handled and all inputs validated return(ComputeInstanceFieldLayout(type, numInstanceFields)); }
protected override void AppendNameForInstantiatedType(StringBuilder sb, DefType type) { AppendName(sb, type.GetTypeDefinition()); sb.Append('<'); for (int i = 0; i < type.Instantiation.Length; i++) { if (i > 0) sb.Append(", "); AppendName(sb, type.Instantiation[i]); } sb.Append('>'); }
public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind) { MetadataType type = (MetadataType)defType; int numStaticFields = 0; foreach (var field in type.GetFields()) { if (!field.IsStatic || field.HasRva || field.IsLiteral) { continue; } numStaticFields++; } ComputedStaticFieldLayout result; result.GcStatics = new StaticsBlock(); result.NonGcStatics = new StaticsBlock(); result.ThreadGcStatics = new StaticsBlock(); result.ThreadNonGcStatics = new StaticsBlock(); if (numStaticFields == 0) { result.Offsets = Array.Empty <FieldAndOffset>(); return(result); } result.Offsets = new FieldAndOffset[numStaticFields]; TypeSystemContext context = type.Context; PrepareRuntimeSpecificStaticFieldLayout(context, ref result); int index = 0; foreach (var field in type.GetFields()) { // Nonstatic fields, literal fields, and RVA mapped fields don't participate in layout if (!field.IsStatic || field.HasRva || field.IsLiteral) { continue; } TypeDesc fieldType = field.FieldType; if (fieldType.IsByRef || (fieldType.IsValueType && ((DefType)fieldType).IsByRefLike)) { ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } ref StaticsBlock block = ref GetStaticsBlockForField(ref result, field); SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(fieldType, context.Target.DefaultPackingSize, out bool _); block.Size = LayoutInt.AlignUp(block.Size, sizeAndAlignment.Alignment, context.Target); result.Offsets[index] = new FieldAndOffset(field, block.Size); block.Size = block.Size + sizeAndAlignment.Size; block.LargestAlignment = LayoutInt.Max(block.LargestAlignment, sizeAndAlignment.Alignment); index++; }
protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) { // NOTE: We're ignoring the containing type for compatiblity with SigFormat.cpp sb.Append(nestedType.Name); }
protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType) { // NOTE: We're ignoring the containing type for compatiblity with SigFormat.cpp sb.Append(GetTypeName(nestedType)); }
/// <summary> /// Retrieves the alignment required by a well known type. /// </summary> public int GetWellKnownTypeAlignment(DefType type) { // Size == Alignment for all platforms. return GetWellKnownTypeSize(type); }
private static void FromInstanceLayoutHelper(ref GCPointerMapBuilder builder, DefType type) { if (!type.IsValueType && type.HasBaseType) { DefType baseType = type.BaseType; GCPointerMapBuilder baseLayoutBuilder = builder.GetInnerBuilder(0, baseType.InstanceByteCount.AsInt); FromInstanceLayoutHelper(ref baseLayoutBuilder, baseType); } foreach (FieldDesc field in type.GetFields()) { if (field.IsStatic) { continue; } TypeDesc fieldType = field.FieldType; if (fieldType.IsGCPointer) { builder.MarkGCPointer(field.Offset.AsInt); } else if (fieldType.IsValueType) { var fieldDefType = (DefType)fieldType; if (fieldDefType.ContainsGCPointers) { GCPointerMapBuilder innerBuilder = builder.GetInnerBuilder(field.Offset.AsInt, fieldDefType.InstanceByteCount.AsInt); FromInstanceLayoutHelper(ref innerBuilder, fieldDefType); } } } }
public unsafe override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType defType, StaticLayoutKind layoutKind) { MetadataType type = (MetadataType)defType; int numStaticFields = 0; foreach (var field in type.GetFields()) { if (!field.IsStatic || field.HasRva || field.IsLiteral) continue; numStaticFields++; } ComputedStaticFieldLayout result; result.GcStatics = new StaticsBlock(); result.NonGcStatics = new StaticsBlock(); result.ThreadStatics = new StaticsBlock(); if (numStaticFields == 0) { result.Offsets = Array.Empty<FieldAndOffset>(); return result; } result.Offsets = new FieldAndOffset[numStaticFields]; PrepareRuntimeSpecificStaticFieldLayout(type.Context, ref result); int index = 0; foreach (var field in type.GetFields()) { // Nonstatic fields, literal fields, and RVA mapped fields don't participate in layout if (!field.IsStatic || field.HasRva || field.IsLiteral) continue; StaticsBlock* block = field.IsThreadStatic ? &result.ThreadStatics : field.HasGCStaticBase ? &result.GcStatics : &result.NonGcStatics; SizeAndAlignment sizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, type.Context.Target.DefaultPackingSize); block->Size = AlignmentHelper.AlignUp(block->Size, sizeAndAlignment.Alignment); result.Offsets[index] = new FieldAndOffset(field, block->Size); block->Size = checked(block->Size + sizeAndAlignment.Size); block->LargestAlignment = Math.Max(block->LargestAlignment, sizeAndAlignment.Alignment); index++; } FinalizeRuntimeSpecificStaticFieldLayout(type.Context, ref result); return result; }
/// <summary> /// Determine if the type implements <code>IDynamicInterfaceCastable</code> /// </summary> protected internal abstract bool IsIDynamicInterfaceCastableInterface(DefType type);
private static int ComputeBytesUsedInParentType(DefType type) { int cumulativeInstanceFieldPos = 0; if (!type.IsValueType && type.HasBaseType) { cumulativeInstanceFieldPos = type.BaseType.InstanceByteCountUnaligned; } return cumulativeInstanceFieldPos; }
/// <summary> /// Abstraction to allow the type system context to control the interfaces /// algorithm used by types. /// </summary> protected virtual RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForDefType(DefType type) { // Type system contexts that support computing runtime interfaces need to override this. throw new NotSupportedException(); }
/// <summary> /// Retrieves the namespace qualified name of a <see cref="DefType"/>. /// </summary> public static string GetFullName(this DefType metadataType) { string ns = metadataType.Namespace; return(ns.Length > 0 ? String.Concat(ns, ".", metadataType.Name) : metadataType.Name); }
private static MethodDesc FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(MethodDesc method, DefType currentType) { MethodDesc foundMethod = FindMatchingVirtualMethodOnTypeByNameAndSig(method, currentType); if (foundMethod != null) { if (VerifyMethodsHaveTheSameVirtualSlot(foundMethod, method)) { return(foundMethod); } } return(null); }