Inheritance: Internal.TypeSystem.TypeDesc
示例#1
0
        /// <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;
 }
示例#4
0
        /// <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;
 }
示例#10
0
 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;
            }
        }
示例#14
0
        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);
        }
示例#16
0
        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;
     }
 }
示例#18
0
        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);
        }
示例#19
0
            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);
            }
示例#20
0
 public override DefType ComputeHomogeneousFloatAggregateElementType(DefType type)
 {
     return(null);
 }
示例#21
0
 /// <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));
        }
示例#24
0
        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);
        }
示例#25
0
        /// <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();
        }
示例#26
0
        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);
        }
示例#27
0
        // 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);
        }
示例#28
0
 /// <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));
 }
示例#29
0
        /// <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);
 }
示例#31
0
 protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType)
 {
     AppendName(sb, containingType);
     sb.Append('/');
     sb.Append(nestedType.Name);
 }
示例#32
0
        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);
        }
示例#33
0
 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);
     }
 }
示例#34
0
        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);
            }
        }
示例#36
0
 public PInvokeLazyFixupFieldHashtable(DefType owningType)
 {
     _owningType = owningType;
 }
示例#37
0
 protected abstract void AppendNameForInstantiatedType(StringBuilder sb, DefType type);
示例#38
0
 public RuntimeDeterminedTypeKey(DefType plainCanonType, GenericParameterDesc detailsType)
 {
     _plainCanonType = plainCanonType;
     _detailsType    = detailsType;
 }
示例#39
0
 /// <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();
 }
示例#40
0
 public RuntimeDeterminedType GetRuntimeDeterminedType(DefType plainCanonType, GenericParameterDesc detailsType)
 {
     return(_runtimeDeterminedTypes.GetOrCreateValue(new RuntimeDeterminedTypeKey(plainCanonType, detailsType)));
 }
示例#41
0
        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());
        }
示例#42
0
        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);
        }
示例#43
0
 public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
 {
     return(ValueTypeShapeCharacteristics.None);
 }
示例#44
0
 /// <summary>
 /// Retrieves the alignment required by a well known type.
 /// </summary>
 public LayoutInt GetWellKnownTypeAlignment(DefType type)
 {
     // Size == Alignment for all platforms.
     return(GetWellKnownTypeSize(type));
 }
示例#45
0
 public override bool ComputeContainsGCPointers(DefType type)
 {
     // This should never be called
     throw new NotSupportedException();
 }
 public RuntimeDeterminedType(DefType rawCanonType, GenericParameterDesc runtimeDeterminedDetailsType)
 {
     _rawCanonType = rawCanonType;
     _runtimeDeterminedDetailsType = runtimeDeterminedDetailsType;
 }
示例#47
0
            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);
            }
示例#48
0
        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));
        }
示例#49
0
                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('>');
                }
示例#50
0
        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++;
            }
示例#51
0
 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);
 }
示例#52
0
 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));
 }
示例#53
0
 /// <summary>
 /// Retrieves the alignment required by a well known type.
 /// </summary>
 public int GetWellKnownTypeAlignment(DefType type)
 {
     // Size == Alignment for all platforms.
     return GetWellKnownTypeSize(type);
 }
示例#54
0
        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;
        }
示例#56
0
 /// <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;
        }
示例#58
0
 /// <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();
 }
示例#59
0
        /// <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);
        }
示例#60
0
        private static MethodDesc FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(MethodDesc method, DefType currentType)
        {
            MethodDesc foundMethod = FindMatchingVirtualMethodOnTypeByNameAndSig(method, currentType);

            if (foundMethod != null)
            {
                if (VerifyMethodsHaveTheSameVirtualSlot(foundMethod, method))
                {
                    return(foundMethod);
                }
            }

            return(null);
        }