Пример #1
0
        public uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType)
        {
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetClassTypeIndex was called with non def type");
            ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor();

            classTypeDescriptor.IsStruct    = type.IsValueType ? 1 : 0;
            classTypeDescriptor.Name        = defType.Name;
            classTypeDescriptor.UniqueName  = defType.GetFullName();
            classTypeDescriptor.BaseClassId = 0;
            if (type.HasBaseType && !type.IsValueType)
            {
                classTypeDescriptor.BaseClassId = GetVariableTypeIndex(defType.BaseType, false);
            }
            uint typeIndex = _objectWriter.GetClassTypeIndex(classTypeDescriptor);

            _knownTypes[type] = typeIndex;

            List <DataFieldDescriptor> fieldsDescs = new List <DataFieldDescriptor>();

            foreach (var fieldDesc in defType.GetFields())
            {
                if (fieldDesc.HasRva || fieldDesc.IsLiteral)
                {
                    continue;
                }
                DataFieldDescriptor field = new DataFieldDescriptor();
                field.FieldTypeIndex = GetVariableTypeIndex(fieldDesc.FieldType, false);
                field.Offset         = fieldDesc.Offset.AsInt;
                field.Name           = fieldDesc.Name;
                fieldsDescs.Add(field);
            }

            DataFieldDescriptor[] fields = new DataFieldDescriptor[fieldsDescs.Count];
            for (int i = 0; i < fieldsDescs.Count; ++i)
            {
                fields[i] = fieldsDescs[i];
            }
            ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor();

            fieldsDescriptor.FieldsCount = fieldsDescs.Count;
            fieldsDescriptor.Size        = defType.GetElementSize().AsInt;

            uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields);

            _completeKnownTypes[type] = completeTypeIndex;

            if (needsCompleteType)
            {
                return(completeTypeIndex);
            }
            else
            {
                return(typeIndex);
            }
        }
        private void InsertStaticFieldRegionMember(List <DataFieldDescriptor> fieldDescs, DefType defType, List <DataFieldDescriptor> staticFields, string staticFieldForm, string staticFieldFormTypePrefix, bool staticDataInObject)
        {
            if (staticFields != null && (staticFields.Count > 0))
            {
                // Generate struct symbol for type describing individual fields of the statics region
                ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor
                {
                    Size        = (ulong)0,
                    FieldsCount = staticFields.Count
                };

                ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor
                {
                    IsStruct    = !staticDataInObject ? 1 : 0,
                    Name        = staticFieldFormTypePrefix + _objectWriter.GetMangledName(defType),
                    BaseClassId = 0
                };

                if (staticDataInObject)
                {
                    classTypeDescriptor.BaseClassId = GetTypeIndex(defType.Context.GetWellKnownType(WellKnownType.Object), true);
                }

                uint staticFieldRegionTypeIndex       = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, staticFields.ToArray());
                uint staticFieldRegionSymbolTypeIndex = staticFieldRegionTypeIndex;

                // This means that access to this static region is done via a double indirection
                if (staticDataInObject)
                {
                    PointerTypeDescriptor pointerTypeDescriptor = new PointerTypeDescriptor();
                    pointerTypeDescriptor.Is64Bit     = _is64bit ? 1 : 0;
                    pointerTypeDescriptor.IsConst     = 0;
                    pointerTypeDescriptor.IsReference = 0;
                    pointerTypeDescriptor.ElementType = staticFieldRegionTypeIndex;

                    uint intermediatePointerDescriptor = _objectWriter.GetPointerTypeIndex(pointerTypeDescriptor);
                    pointerTypeDescriptor.ElementType = intermediatePointerDescriptor;
                    staticFieldRegionSymbolTypeIndex  = _objectWriter.GetPointerTypeIndex(pointerTypeDescriptor);
                }

                DataFieldDescriptor staticRegionField = new DataFieldDescriptor
                {
                    FieldTypeIndex = staticFieldRegionSymbolTypeIndex,
                    Offset         = 0xFFFFFFFF,
                    Name           = staticFieldForm
                };

                fieldDescs.Add(staticRegionField);
            }
        }
Пример #3
0
        public uint GetCompleteClassTypeIndex(ClassTypeDescriptor classTypeDescriptor, ClassFieldsTypeDescriptor classFieldsTypeDescriptior, DataFieldDescriptor[] fields)
        {
            FieldListInProgress fieldList = default(FieldListInProgress);

            if ((classTypeDescriptor.BaseClassId != 0) || (fields != null && fields.Length > 0) || (classTypeDescriptor.IsStruct == 0))
            {
                fieldList = StartFieldList();
                if (classTypeDescriptor.BaseClassId != 0)
                {
                    EmitBaseClass(ref fieldList, classTypeDescriptor.BaseClassId);
                }

                if (classTypeDescriptor.IsStruct == 0)
                {
                    EmitVFuncTab(ref fieldList);
                }

                if (fields != null)
                {
                    foreach (DataFieldDescriptor field in fields)
                    {
                        EmitDataMember(ref fieldList, field.FieldTypeIndex, (int)field.Offset, new Utf8String(field.Name));
                    }
                }
                FinalizeFieldList(fieldList);
            }

            uint       classTypeIndex = _blob.GetNextTypeIndex();
            Utf8String name           = new Utf8String(classTypeDescriptor.Name);
            uint       recordSize     = 20 + DebugInfoBlob.StringLengthEncoded(name) + TypeRecordsBlob.NumericLeafSize(classFieldsTypeDescriptior.Size) /*size of length */;

            _blob.WriteWORD(checked ((ushort)(_blob.DWORDAlignedSize(recordSize) - 2))); // don't include size of 'length' in 'length'
            _blob.WriteLeafKind(classTypeDescriptor.IsStruct != 0 ? LeafKind.LF_STRUCTURE : LeafKind.LF_CLASS);
            _blob.WriteWORD(fieldList.FieldsCount);
            _blob.WriteLF_CLASS_Properties(LF_CLASS_Properties.None);
            _blob.WriteDWORD(fieldList.TypeIndexOfFieldList);
            _blob.WriteDWORD(0);                 // Derivation list is not filled in here
            _blob.WriteDWORD(_tiVTShapePointer); // No vtable shape
            _blob.WriteNumericLeaf(classFieldsTypeDescriptior.Size);
            _blob.WriteString(name);
            _blob.AlignToDWORD();
            VerifyBlobEligibleToBeBetweenRecords();
            return(classTypeIndex);
        }
        private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType)
        {
            DefType defType = type as DefType;

            System.Diagnostics.Debug.Assert(defType != null, "GetClassTypeIndex was called with non def type");
            ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor
            {
                IsStruct    = type.IsValueType ? 1 : 0,
                Name        = _objectWriter.GetMangledName(type),
                BaseClassId = 0
            };

            uint typeIndex = _objectWriter.GetClassTypeIndex(classTypeDescriptor);

            _knownTypes[type] = typeIndex;

            if (type.HasBaseType && !type.IsValueType)
            {
                classTypeDescriptor.BaseClassId = GetTypeIndex(defType.BaseType, true);
            }

            List <DataFieldDescriptor> fieldsDescs        = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor> nonGcStaticFields  = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor> gcStaticFields     = new List <DataFieldDescriptor>();
            List <DataFieldDescriptor> threadStaticFields = new List <DataFieldDescriptor>();

            bool isCanonical = defType.IsCanonicalSubtype(CanonicalFormKind.Any);

            foreach (var fieldDesc in defType.GetFields())
            {
                if (fieldDesc.HasRva || fieldDesc.IsLiteral)
                {
                    continue;
                }

                if (isCanonical && fieldDesc.IsStatic)
                {
                    continue;
                }

                LayoutInt           fieldOffset     = fieldDesc.Offset;
                int                 fieldOffsetEmit = fieldOffset.IsIndeterminate ? 0xBAAD : fieldOffset.AsInt;
                DataFieldDescriptor field           = new DataFieldDescriptor
                {
                    FieldTypeIndex = GetVariableTypeIndex(fieldDesc.FieldType, false),
                    Offset         = (ulong)fieldOffsetEmit,
                    Name           = fieldDesc.Name
                };

                if (fieldDesc.IsStatic)
                {
                    if (fieldDesc.IsThreadStatic)
                    {
                        threadStaticFields.Add(field);
                    }
                    else if (fieldDesc.HasGCStaticBase)
                    {
                        gcStaticFields.Add(field);
                    }
                    else
                    {
                        nonGcStaticFields.Add(field);
                    }
                }
                else
                {
                    fieldsDescs.Add(field);
                }
            }

            InsertStaticFieldRegionMember(fieldsDescs, defType, nonGcStaticFields, WindowsNodeMangler.NonGCStaticMemberName, "__type_" + WindowsNodeMangler.NonGCStaticMemberName, false);
            InsertStaticFieldRegionMember(fieldsDescs, defType, gcStaticFields, WindowsNodeMangler.GCStaticMemberName, "__type_" + WindowsNodeMangler.GCStaticMemberName, _abi == TargetAbi.CoreRT);
            InsertStaticFieldRegionMember(fieldsDescs, defType, threadStaticFields, WindowsNodeMangler.ThreadStaticMemberName, "__type_" + WindowsNodeMangler.ThreadStaticMemberName, _abi == TargetAbi.CoreRT);

            DataFieldDescriptor[] fields = new DataFieldDescriptor[fieldsDescs.Count];
            for (int i = 0; i < fieldsDescs.Count; ++i)
            {
                fields[i] = fieldsDescs[i];
            }

            LayoutInt elementSize     = defType.GetElementSize();
            int       elementSizeEmit = elementSize.IsIndeterminate ? 0xBAAD : elementSize.AsInt;
            ClassFieldsTypeDescriptor fieldsDescriptor = new ClassFieldsTypeDescriptor
            {
                Size        = (ulong)elementSizeEmit,
                FieldsCount = fieldsDescs.Count
            };

            uint completeTypeIndex = _objectWriter.GetCompleteClassTypeIndex(classTypeDescriptor, fieldsDescriptor, fields);

            _completeKnownTypes[type] = completeTypeIndex;

            if (needsCompleteType)
            {
                return(completeTypeIndex);
            }
            else
            {
                return(typeIndex);
            }
        }