Exemple #1
0
        private static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType type, int numInstanceFields)
        {
            var offsets = new FieldAndOffset[numInstanceFields];

            // For types inheriting from another type, field offsets continue on from where they left off
            int cumulativeInstanceFieldPos = ComputeBytesUsedInParentType(type);

            int largestAlignmentRequirement = 1;
            int fieldOrdinal = 0;
            int packingSize  = ComputePackingSize(type);

            foreach (var field in type.GetFields())
            {
                if (field.IsStatic)
                {
                    continue;
                }

                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequirement)
                {
                    largestAlignmentRequirement = fieldSizeAndAlignment.Alignment;
                }

                cumulativeInstanceFieldPos = AlignmentHelper.AlignUp(cumulativeInstanceFieldPos, fieldSizeAndAlignment.Alignment);
                offsets[fieldOrdinal]      = new FieldAndOffset(field, cumulativeInstanceFieldPos);
                cumulativeInstanceFieldPos = checked (cumulativeInstanceFieldPos + fieldSizeAndAlignment.Size);

                fieldOrdinal++;
            }

            if (type.IsValueType)
            {
                var layoutMetadata = type.GetClassLayout();
                cumulativeInstanceFieldPos = Math.Max(cumulativeInstanceFieldPos, layoutMetadata.Size);
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, largestAlignmentRequirement, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();

            computedLayout.FieldAlignment     = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize          = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets            = offsets;

            return(computedLayout);
        }
Exemple #2
0
        private static int ComputePackingSize(MetadataType type)
        {
            var layoutMetadata = type.GetClassLayout();

            // If a type contains pointers then the metadata specified packing size is ignored (On desktop this is disqualification from ManagedSequential)
            if (layoutMetadata.PackingSize == 0 || type.ContainsPointers)
            {
                return(type.Context.Target.DefaultPackingSize);
            }
            else
            {
                return(layoutMetadata.PackingSize);
            }
        }
        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,
                };

                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));
        }
Exemple #4
0
 // Properties that are passed through from the type definition
 public override ClassLayoutMetadata GetClassLayout()
 {
     return(_typeDef.GetClassLayout());
 }
        private static int ComputePackingSize(MetadataType type)
        {
            var layoutMetadata = type.GetClassLayout();

            // If a type contains pointers then the metadata specified packing size is ignored (On desktop this is disqualification from ManagedSequential)
            if (layoutMetadata.PackingSize == 0 || type.ContainsPointers)
                return type.Context.Target.DefaultPackingSize;
            else
                return layoutMetadata.PackingSize;
        }
        private static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType type, int numInstanceFields)
        {
            var offsets = new FieldAndOffset[numInstanceFields];

            // For types inheriting from another type, field offsets continue on from where they left off
            int cumulativeInstanceFieldPos = ComputeBytesUsedInParentType(type);

            int largestAlignmentRequirement = 1;
            int fieldOrdinal = 0;
            int packingSize = ComputePackingSize(type);

            foreach (var field in type.GetFields())
            {
                if (field.IsStatic)
                    continue;

                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequirement)
                    largestAlignmentRequirement = fieldSizeAndAlignment.Alignment;

                cumulativeInstanceFieldPos = AlignmentHelper.AlignUp(cumulativeInstanceFieldPos, fieldSizeAndAlignment.Alignment);
                offsets[fieldOrdinal] = new FieldAndOffset(field, cumulativeInstanceFieldPos);
                cumulativeInstanceFieldPos = checked(cumulativeInstanceFieldPos + fieldSizeAndAlignment.Size);

                fieldOrdinal++;
            }

            if (type.IsValueType)
            {
                var layoutMetadata = type.GetClassLayout();
                cumulativeInstanceFieldPos = Math.Max(cumulativeInstanceFieldPos, layoutMetadata.Size);
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, largestAlignmentRequirement, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
            computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets = offsets;

            return computedLayout;
        }
        private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
        {
            // Instance slice size is the total size of instance not including the base type.
            // It is calculated as the field whose offset and size add to the greatest value.
            int cumulativeInstanceFieldPos =
                type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0;
            int instanceSize = cumulativeInstanceFieldPos;

            var layoutMetadata = type.GetClassLayout();

            int packingSize = ComputePackingSize(type);
            int largestAlignmentRequired = 1;

            var offsets = new FieldAndOffset[numInstanceFields];
            int fieldOrdinal = 0;

            foreach (var fieldAndOffset in layoutMetadata.Offsets)
            {
                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired)
                    largestAlignmentRequired = fieldSizeAndAlignment.Alignment;

                if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset)
                    throw new TypeLoadException();

                int computedOffset = checked(fieldAndOffset.Offset + cumulativeInstanceFieldPos);

                switch (fieldAndOffset.Field.FieldType.Category)
                {
                    case TypeFlags.Array:
                    case TypeFlags.Class:
                        {
                            int offsetModulo = computedOffset % type.Context.Target.PointerSize;
                            if (offsetModulo != 0)
                            {
                                // GC pointers MUST be aligned.
                                if (offsetModulo == 4)
                                {
                                    // We must be attempting to compile a 32bit app targeting a 64 bit platform.
                                    throw new TypeLoadException();
                                }
                                else
                                {
                                    // Its just wrong
                                    throw new TypeLoadException();
                                }
                            }
                            break;
                        }
                }

                offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset);

                int fieldExtent = checked(computedOffset + fieldSizeAndAlignment.Size);
                if (fieldExtent > instanceSize)
                {
                    instanceSize = fieldExtent;
                }

                fieldOrdinal++;
            }

            if (type.IsValueType && layoutMetadata.Size > instanceSize)
            {
                instanceSize = layoutMetadata.Size;
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
            computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets = offsets;

            return computedLayout;
        }
Exemple #8
0
        private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record)
        {
            if (entity.ContainingType != null)
            {
                var enclosingType = (TypeDefinition)HandleType(entity.ContainingType);
                record.EnclosingType = enclosingType;
                enclosingType.NestedTypes.Add(record);

                var namespaceDefinition =
                    HandleNamespaceDefinition(entity.ContainingType.Module, entity.ContainingType.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
            }
            else
            {
                var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
                namespaceDefinition.TypeDefinitions.Add(record);
            }

            record.Name = HandleString(entity.Name);

            Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout();
            record.Size        = checked ((uint)layoutMetadata.Size);
            record.PackingSize = checked ((uint)layoutMetadata.PackingSize);
            record.Flags       = GetTypeAttributes(entity);

            if (entity.HasBaseType)
            {
                record.BaseType = HandleType(entity.BaseType);
            }

            if (entity.ExplicitlyImplementedInterfaces.Length > 0)
            {
                record.Interfaces = entity.ExplicitlyImplementedInterfaces
                                    .Where(i => !IsBlocked(i))
                                    .Select(i => HandleType(i)).ToList();
            }

            if (entity.HasInstantiation)
            {
                var genericParams = new List <GenericParameter>(entity.Instantiation.Length);
                foreach (var p in entity.Instantiation)
                {
                    genericParams.Add(HandleGenericParameter((Cts.GenericParameterDesc)p));
                }
                record.GenericParameters = genericParams;
            }

            var fields = new List <Field>();

            foreach (var field in entity.GetFields())
            {
                if (_policy.GeneratesMetadata(field))
                {
                    fields.Add(HandleFieldDefinition(field));
                }
            }
            record.Fields = fields;

            var methods = new List <Method>();

            foreach (var method in entity.GetMethods())
            {
                if (_policy.GeneratesMetadata(method))
                {
                    methods.Add(HandleMethodDefinition(method));
                }
            }
            record.Methods = methods;

            var ecmaEntity = entity as Cts.Ecma.EcmaType;

            if (ecmaEntity != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle);
                foreach (var property in ecmaRecord.GetProperties())
                {
                    Property prop = HandleProperty(ecmaEntity.EcmaModule, property);
                    if (prop != null)
                    {
                        record.Properties.Add(prop);
                    }
                }

                // TODO: Events

                // TODO: CustomAttributes
            }
        }
Exemple #9
0
        private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
        {
            // Instance slice size is the total size of instance not including the base type.
            // It is calculated as the field whose offset and size add to the greatest value.
            int cumulativeInstanceFieldPos =
                type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0;
            int instanceSize = cumulativeInstanceFieldPos;

            var layoutMetadata = type.GetClassLayout();

            int packingSize = ComputePackingSize(type);
            int largestAlignmentRequired = 1;

            var offsets      = new FieldAndOffset[numInstanceFields];
            int fieldOrdinal = 0;

            foreach (var fieldAndOffset in layoutMetadata.Offsets)
            {
                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired)
                {
                    largestAlignmentRequired = fieldSizeAndAlignment.Alignment;
                }

                if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset)
                {
                    throw new TypeLoadException();
                }

                int computedOffset = checked (fieldAndOffset.Offset + cumulativeInstanceFieldPos);

                switch (fieldAndOffset.Field.FieldType.Category)
                {
                case TypeFlags.Array:
                case TypeFlags.Class:
                {
                    int offsetModulo = computedOffset % type.Context.Target.PointerSize;
                    if (offsetModulo != 0)
                    {
                        // GC pointers MUST be aligned.
                        if (offsetModulo == 4)
                        {
                            // We must be attempting to compile a 32bit app targeting a 64 bit platform.
                            throw new TypeLoadException();
                        }
                        else
                        {
                            // Its just wrong
                            throw new TypeLoadException();
                        }
                    }
                    break;
                }
                }

                offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset);

                int fieldExtent = checked (computedOffset + fieldSizeAndAlignment.Size);
                if (fieldExtent > instanceSize)
                {
                    instanceSize = fieldExtent;
                }

                fieldOrdinal++;
            }

            if (type.IsValueType && layoutMetadata.Size > instanceSize)
            {
                instanceSize = layoutMetadata.Size;
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();

            computedLayout.FieldAlignment     = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize          = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets            = offsets;

            return(computedLayout);
        }
Exemple #10
0
        private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record)
        {
            Debug.Assert(entity.IsTypeDefinition);

            Cts.MetadataType containingType = (Cts.MetadataType)entity.ContainingType;
            if (containingType != null)
            {
                var enclosingType = (TypeDefinition)HandleType(containingType);
                record.EnclosingType = enclosingType;
                enclosingType.NestedTypes.Add(record);

                var namespaceDefinition =
                    HandleNamespaceDefinition(containingType.Module, entity.ContainingType.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
            }
            else
            {
                var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace);
                record.NamespaceDefinition = namespaceDefinition;

                if (entity.IsModuleType)
                {
                    // These don't get added to the global namespace.
                    // Instead, they have a dedicated field on the scope record.
                }
                else
                {
                    namespaceDefinition.TypeDefinitions.Add(record);
                }
            }

            record.Name = HandleString(entity.Name);

            Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout();
            record.Size        = checked ((uint)layoutMetadata.Size);
            record.PackingSize = checked ((ushort)layoutMetadata.PackingSize);
            record.Flags       = GetTypeAttributes(entity);

            try
            {
                if (entity.HasBaseType)
                {
                    record.BaseType = HandleType(entity.BaseType);
                }
            }
            catch (Cts.TypeSystemException) when(HasNestedTypes(entity))
            {
                // We might have been forced to generate metadata for a type
                // that wasn't looked at during code generation because it's an owning
                // type of a type we did look at. Allow those to generate incomplete
                // metadata. The ultimate fix is to rewrite metadata generation to be
                // System.Reflection.Metadata-based as opposed to type system based.
                // If there's no nested types, this is a bug and should tear down
                // the compiler at this point.
            }

            try
            {
                record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length;
                foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces)
                {
                    if (IsBlocked(interfaceType))
                    {
                        continue;
                    }
                    record.Interfaces.Add(HandleType(interfaceType));
                }
            }
            catch (Cts.TypeSystemException) when(HasNestedTypes(entity))
            {
                // We might have been forced to generate metadata for a type
                // that wasn't looked at during code generation because it's an owning
                // type of a type we did look at. Allow those to generate incomplete
                // metadata. The ultimate fix is to rewrite metadata generation to be
                // System.Reflection.Metadata-based as opposed to type system based.
                // If there's no nested types, this is a bug and should tear down
                // the compiler at this point.
            }

            if (entity.HasInstantiation)
            {
                record.GenericParameters.Capacity = entity.Instantiation.Length;
                foreach (var p in entity.Instantiation)
                {
                    record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p));
                }
            }

            foreach (var field in entity.GetFields())
            {
                if (_policy.GeneratesMetadata(field))
                {
                    record.Fields.Add(HandleFieldDefinition(field));
                }
            }

            foreach (var method in entity.GetMethods())
            {
                if (_policy.GeneratesMetadata(method))
                {
                    record.Methods.Add(HandleMethodDefinition(method));
                }
            }

            var ecmaEntity = entity as Cts.Ecma.EcmaType;

            if (ecmaEntity != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle);

                foreach (var e in ecmaRecord.GetEvents())
                {
                    Event evt = HandleEvent(ecmaEntity.EcmaModule, e);
                    if (evt != null)
                    {
                        record.Events.Add(evt);
                    }
                }

                foreach (var property in ecmaRecord.GetProperties())
                {
                    Property prop = HandleProperty(ecmaEntity.EcmaModule, property);
                    if (prop != null)
                    {
                        record.Properties.Add(prop);
                    }
                }

                Ecma.CustomAttributeHandleCollection customAttributes = ecmaRecord.GetCustomAttributes();
                if (customAttributes.Count > 0)
                {
                    record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes);
                }

                /* COMPLETENESS
                 * foreach (var miHandle in ecmaRecord.GetMethodImplementations())
                 * {
                 *  Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader;
                 *
                 *  Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle);
                 *
                 *  Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody);
                 *  if (_policy.IsBlocked(methodBody))
                 *      continue;
                 *
                 *  Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration);
                 *  if (_policy.IsBlocked(methodDecl.GetTypicalMethodDefinition()))
                 *      continue;
                 *
                 *  MethodImpl methodImplRecord = new MethodImpl
                 *  {
                 *      MethodBody = HandleQualifiedMethod(methodBody),
                 *      MethodDeclaration = HandleQualifiedMethod(methodDecl)
                 *  };
                 *
                 *  record.MethodImpls.Add(methodImplRecord);
                 * }*/
            }
Exemple #11
0
        private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record)
        {
            Debug.Assert(entity.IsTypeDefinition);

            Cts.MetadataType containingType = (Cts.MetadataType)entity.ContainingType;
            if (containingType != null)
            {
                var enclosingType = (TypeDefinition)HandleType(containingType);
                record.EnclosingType = enclosingType;
                enclosingType.NestedTypes.Add(record);

                var namespaceDefinition =
                    HandleNamespaceDefinition(containingType.Module, entity.ContainingType.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
            }
            else
            {
                var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
                namespaceDefinition.TypeDefinitions.Add(record);
            }

            record.Name = HandleString(entity.Name);

            Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout();
            record.Size        = checked ((uint)layoutMetadata.Size);
            record.PackingSize = checked ((ushort)layoutMetadata.PackingSize);
            record.Flags       = GetTypeAttributes(entity);

            if (entity.HasBaseType)
            {
                record.BaseType = HandleType(entity.BaseType);
            }

            record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length;
            foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces)
            {
                if (IsBlocked(interfaceType))
                {
                    continue;
                }
                record.Interfaces.Add(HandleType(interfaceType));
            }

            if (entity.HasInstantiation)
            {
                record.GenericParameters.Capacity = entity.Instantiation.Length;
                foreach (var p in entity.Instantiation)
                {
                    record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p));
                }
            }

            foreach (var field in entity.GetFields())
            {
                if (_policy.GeneratesMetadata(field))
                {
                    record.Fields.Add(HandleFieldDefinition(field));
                }
            }

            foreach (var method in entity.GetMethods())
            {
                if (_policy.GeneratesMetadata(method))
                {
                    record.Methods.Add(HandleMethodDefinition(method));
                }
            }

            var ecmaEntity = entity as Cts.Ecma.EcmaType;

            if (ecmaEntity != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle);

                foreach (var e in ecmaRecord.GetEvents())
                {
                    Event evt = HandleEvent(ecmaEntity.EcmaModule, e);
                    if (evt != null)
                    {
                        record.Events.Add(evt);
                    }
                }

                foreach (var property in ecmaRecord.GetProperties())
                {
                    Property prop = HandleProperty(ecmaEntity.EcmaModule, property);
                    if (prop != null)
                    {
                        record.Properties.Add(prop);
                    }
                }

                Ecma.CustomAttributeHandleCollection customAttributes = ecmaRecord.GetCustomAttributes();
                if (customAttributes.Count > 0)
                {
                    record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes);
                }

                foreach (var miHandle in ecmaRecord.GetMethodImplementations())
                {
                    Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader;

                    Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle);

                    Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody);
                    if (_policy.IsBlocked(methodBody))
                    {
                        continue;
                    }

                    Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration);
                    if (_policy.IsBlocked(methodDecl.GetTypicalMethodDefinition()))
                    {
                        continue;
                    }

                    MethodImpl methodImplRecord = new MethodImpl
                    {
                        MethodBody        = HandleQualifiedMethod(methodBody),
                        MethodDeclaration = HandleQualifiedMethod(methodDecl)
                    };

                    record.MethodImpls.Add(methodImplRecord);
                }
            }
        }
Exemple #12
0
        private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
        {
            // Instance slice size is the total size of instance not including the base type.
            // It is calculated as the field whose offset and size add to the greatest value.
            LayoutInt cumulativeInstanceFieldPos =
                type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : LayoutInt.Zero;
            LayoutInt instanceSize = cumulativeInstanceFieldPos;

            var layoutMetadata = type.GetClassLayout();

            int       packingSize = ComputePackingSize(type);
            LayoutInt largestAlignmentRequired = LayoutInt.One;

            var offsets      = new FieldAndOffset[numInstanceFields];
            int fieldOrdinal = 0;

            foreach (var fieldAndOffset in layoutMetadata.Offsets)
            {
                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize);

                largestAlignmentRequired = LayoutInt.Max(fieldSizeAndAlignment.Alignment, largestAlignmentRequired);

                if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset)
                {
                    throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadBadFormat, type);
                }

                LayoutInt computedOffset = fieldAndOffset.Offset + cumulativeInstanceFieldPos;

                if (fieldAndOffset.Field.FieldType.IsGCPointer && !computedOffset.IsIndeterminate)
                {
                    int offsetModulo = computedOffset.AsInt % type.Context.Target.PointerSize;
                    if (offsetModulo != 0)
                    {
                        // GC pointers MUST be aligned.
                        throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadExplicitLayout, type, fieldAndOffset.Offset.ToStringInvariant());
                    }
                }

                offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset);

                LayoutInt fieldExtent = computedOffset + fieldSizeAndAlignment.Size;
                instanceSize = LayoutInt.Max(fieldExtent, instanceSize);

                fieldOrdinal++;
            }

            if (type.IsValueType)
            {
                instanceSize = LayoutInt.Max(new LayoutInt(layoutMetadata.Size), instanceSize);
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();

            computedLayout.FieldAlignment     = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize          = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets            = offsets;

            return(computedLayout);
        }
        private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
        {
            // Instance slice size is the total size of instance not including the base type.
            // It is calculated as the field whose offset and size add to the greatest value.
            int cumulativeInstanceFieldPos =
                type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0;
            int instanceSize = cumulativeInstanceFieldPos;

            var layoutMetadata = type.GetClassLayout();

            int packingSize = ComputePackingSize(type);
            int largestAlignmentRequired = 1;

            var offsets = new FieldAndOffset[numInstanceFields];
            int fieldOrdinal = 0;

            foreach (var fieldAndOffset in layoutMetadata.Offsets)
            {
                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired)
                    largestAlignmentRequired = fieldSizeAndAlignment.Alignment;

                if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset)
                    throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadBadFormat, type);

                int computedOffset = checked(fieldAndOffset.Offset + cumulativeInstanceFieldPos);

                if (fieldAndOffset.Field.FieldType.IsGCPointer)
                {
                    int offsetModulo = computedOffset % type.Context.Target.PointerSize;
                    if (offsetModulo != 0)
                    {
                        // GC pointers MUST be aligned.
                        throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadExplicitLayout, type, fieldAndOffset.Offset.ToStringInvariant());
                    }
                }

                offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset);

                int fieldExtent = checked(computedOffset + fieldSizeAndAlignment.Size);
                if (fieldExtent > instanceSize)
                {
                    instanceSize = fieldExtent;
                }

                fieldOrdinal++;
            }

            if (type.IsValueType && layoutMetadata.Size > instanceSize)
            {
                instanceSize = layoutMetadata.Size;
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
            computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets = offsets;

            return computedLayout;
        }