Beispiel #1
0
 private void OutputComponentSize(ref ObjectDataBuilder objData)
 {
     if (_type.IsArray)
     {
         TypeDesc elementType = ((ArrayType)_type).ElementType;
         if (elementType == elementType.Context.UniversalCanonType)
         {
             objData.EmitShort(0);
         }
         else
         {
             int elementSize = elementType.GetElementSize().AsInt;
             // We validated that this will fit the short when the node was constructed. No need for nice messages.
             objData.EmitShort((short)checked ((ushort)elementSize));
         }
     }
     else if (_type.IsString)
     {
         objData.EmitShort(StringComponentSize.Value);
     }
     else
     {
         objData.EmitShort(0);
     }
 }
Beispiel #2
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            dataBuilder.EmitZeroPointer(); // Sync block

            DefType systemStringType = factory.TypeSystemContext.GetWellKnownType(WellKnownType.String);

            //
            // The GC requires a direct reference to frozen objects' EETypes. If System.String will be compiled into a separate
            // binary, it must be cloned into this one.
            //
            if (factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(systemStringType))
            {
                dataBuilder.EmitPointerReloc(factory.ConstructedClonedTypeSymbol(systemStringType));
            }
            else
            {
                dataBuilder.EmitPointerReloc(factory.ConstructedTypeSymbol(systemStringType));
            }

            dataBuilder.EmitInt(_data.Length);

            foreach (char c in _data)
            {
                dataBuilder.EmitShort((short)c);
            }

            // Null-terminate for friendliness with interop
            dataBuilder.EmitShort(0);

        }
Beispiel #3
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);

            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            short flags = (short)EETypeKind.GenericTypeDefEEType;

            if (_type.IsValueType)
            {
                flags |= (short)EETypeFlags.ValueTypeFlag;
            }
            if (_type.IsInterface)
            {
                flags |= (short)EETypeFlags.IsInterfaceFlag;
            }

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            dataBuilder.EmitPointerReloc(factory.ModuleManagerIndirection);

            return(dataBuilder.ToObjectData());
        }
Beispiel #4
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (!_constructed)
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
                return;
            }

            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type;

            while (currentTypeSlice != null)
            {
                List <MethodDesc> virtualSlots;
                factory.VirtualSlots.TryGetValue(currentTypeSlice, out virtualSlots);
                if (virtualSlots != null)
                {
                    virtualSlotCount += virtualSlots.Count;
                }

                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));
            objData.EmitShort(checked ((short)_type.RuntimeInterfaces.Length));
        }
Beispiel #5
0
        void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            var entryCountReservation = builder.ReserveInt();
            int entryCount            = 0;

            for (int interfaceIndex = 0; interfaceIndex < _type.RuntimeInterfaces.Length; interfaceIndex++)
            {
                var interfaceType = _type.RuntimeInterfaces[interfaceIndex];
                Debug.Assert(interfaceType.IsInterface);

                IReadOnlyList <MethodDesc> virtualSlots = factory.VTable(interfaceType).Slots;

                for (int interfaceMethodSlot = 0; interfaceMethodSlot < virtualSlots.Count; interfaceMethodSlot++)
                {
                    MethodDesc declMethod = virtualSlots[interfaceMethodSlot];
                    var        implMethod = _type.GetClosestDefType().ResolveInterfaceMethodToVirtualMethodOnType(declMethod);

                    // Interface methods first implemented by a base type in the hierarchy will return null for the implMethod (runtime interface
                    // dispatch will walk the inheritance chain).
                    if (implMethod != null)
                    {
                        builder.EmitShort(checked ((short)interfaceIndex));
                        builder.EmitShort(checked ((short)interfaceMethodSlot));
                        builder.EmitShort(checked ((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod)));
                        entryCount++;
                    }
                }
            }

            builder.EmitInt(entryCountReservation, entryCount);
        }
Beispiel #6
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            dataBuilder.EmitZeroPointer(); // Sync block

            DefType systemStringType = factory.TypeSystemContext.GetWellKnownType(WellKnownType.String);

            //
            // The GC requires a direct reference to frozen objects' EETypes. If System.String will be compiled into a separate
            // binary, it must be cloned into this one.
            //
            if (factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(systemStringType))
            {
                dataBuilder.EmitPointerReloc(factory.ConstructedClonedTypeSymbol(systemStringType));
            }
            else
            {
                dataBuilder.EmitPointerReloc(factory.ConstructedTypeSymbol(systemStringType));
            }

            dataBuilder.EmitInt(_data.Length);

            foreach (char c in _data)
            {
                dataBuilder.EmitShort((short)c);
            }

            // Null-terminate for friendliness with interop
            dataBuilder.EmitShort(0);
        }
Beispiel #7
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);

            ComputeOptionalEETypeFields(factory, relocsOnly);

            OutputGCDesc(ref objData);
            OutputComponentSize(ref objData);
            OutputFlags(factory, ref objData);
            OutputBaseSize(ref objData);
            OutputRelatedType(factory, ref objData);

            // Number of vtable slots will be only known later. Reseve the bytes for it.
            var vtableSlotCountReservation = objData.ReserveShort();

            // Number of interfaces will only be known later. Reserve the bytes for it.
            var interfaceCountReservation = objData.ReserveShort();

            objData.EmitInt(_type.GetHashCode());
            objData.EmitPointerReloc(factory.TypeManagerIndirection);

            if (EmitVirtualSlotsAndInterfaces)
            {
                // Emit VTable
                Debug.Assert(objData.CountBytes - ((ISymbolDefinitionNode)this).Offset == GetVTableOffset(objData.TargetPointerSize));
                SlotCounter virtualSlotCounter = SlotCounter.BeginCounting(ref /* readonly */ objData);
                OutputVirtualSlots(factory, ref objData, _type, _type, relocsOnly);

                // Update slot count
                int numberOfVtableSlots = virtualSlotCounter.CountSlots(ref /* readonly */ objData);
                objData.EmitShort(vtableSlotCountReservation, checked ((short)numberOfVtableSlots));

                // Emit interface map
                SlotCounter interfaceSlotCounter = SlotCounter.BeginCounting(ref /* readonly */ objData);
                OutputInterfaceMap(factory, ref objData);

                // Update slot count
                int numberOfInterfaceSlots = interfaceSlotCounter.CountSlots(ref /* readonly */ objData);
                objData.EmitShort(interfaceCountReservation, checked ((short)numberOfInterfaceSlots));
            }
            else
            {
                // If we're not emitting any slots, the number of slots is zero.
                objData.EmitShort(vtableSlotCountReservation, 0);
                objData.EmitShort(interfaceCountReservation, 0);
            }

            OutputFinalizerMethod(factory, ref objData);
            OutputOptionalFields(factory, ref objData);
            OutputNullableTypeParameter(factory, ref objData);
            OutputGenericInstantiationDetails(factory, ref objData);

            return(objData.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory, relocsOnly);

            dataBuilder.RequireInitialPointerAlignment();
            dataBuilder.AddSymbol(this);
            EETypeRareFlags rareFlags = 0;

            short flags = (short)EETypeKind.GenericTypeDefEEType;

            if (_type.IsValueType)
            {
                flags |= (short)EETypeFlags.ValueTypeFlag;
            }
            if (_type.IsInterface)
            {
                flags |= (short)EETypeFlags.IsInterfaceFlag;
            }
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                rareFlags = rareFlags | EETypeRareFlags.HasCctorFlag;
            }
            if (_type.IsByRefLike)
            {
                rareFlags |= EETypeRareFlags.IsByRefLikeFlag;
            }

            if (rareFlags != 0)
            {
                _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, (uint)rareFlags);
            }

            if (HasOptionalFields)
            {
                flags |= (short)EETypeFlags.OptionalFieldsFlag;
            }

            if (_type.IsEnum)
            {
                flags |= (short)EETypeBuilderHelpers.ComputeElementTypeFlags(_type);
            }

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            dataBuilder.EmitPointerReloc(factory.TypeManagerIndirection);
            if (HasOptionalFields)
            {
                dataBuilder.EmitPointerReloc(_optionalFieldsNode);
            }

            return(dataBuilder.ToObjectData());
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);

            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            bool hasPointers = NumSeries > 0;

            if (hasPointers)
            {
                for (int i = ((_runLengths.Length / 2) * 2) - 1; i >= 0; i--)
                {
                    if (_targetPointerSize == 4)
                    {
                        dataBuilder.EmitInt(_runLengths[i]);
                    }
                    else
                    {
                        dataBuilder.EmitLong(_runLengths[i]);
                    }
                }
                if (_targetPointerSize == 4)
                {
                    dataBuilder.EmitInt(NumSeries);
                }
                else
                {
                    dataBuilder.EmitLong(NumSeries);
                }
            }

            int totalSize = 0;

            foreach (int run in _runLengths)
            {
                totalSize += run * _targetPointerSize;
            }

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            if (hasPointers)
            {
                dataBuilder.EmitShort(0x20); // TypeFlags.HasPointers
            }
            else
            {
                dataBuilder.EmitShort(0x00);
            }

            totalSize = Math.Max(totalSize, _targetPointerSize * 3); // minimum GC eetype size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            return(dataBuilder.ToObjectData());
        }
Beispiel #10
0
        void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            var entryCountReservation = builder.ReserveInt();
            int entryCount            = 0;

            TypeDesc declType = _type.GetClosestDefType();

            // Catch any runtime interface collapsing. We shouldn't have any
            Debug.Assert(declType.RuntimeInterfaces.Length == declType.GetTypeDefinition().RuntimeInterfaces.Length);

            for (int interfaceIndex = 0; interfaceIndex < declType.RuntimeInterfaces.Length; interfaceIndex++)
            {
                var interfaceType           = declType.RuntimeInterfaces[interfaceIndex];
                var interfaceDefinitionType = declType.GetTypeDefinition().RuntimeInterfaces[interfaceIndex];
                Debug.Assert(interfaceType.IsInterface);

                IReadOnlyList <MethodDesc> virtualSlots = factory.VTable(interfaceType).Slots;

                for (int interfaceMethodSlot = 0; interfaceMethodSlot < virtualSlots.Count; interfaceMethodSlot++)
                {
                    MethodDesc declMethod = virtualSlots[interfaceMethodSlot];
                    if (!interfaceType.IsTypeDefinition)
                    {
                        declMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(declMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceDefinitionType);
                    }

                    var implMethod = declType.GetTypeDefinition().ResolveInterfaceMethodToVirtualMethodOnType(declMethod);

                    // Interface methods first implemented by a base type in the hierarchy will return null for the implMethod (runtime interface
                    // dispatch will walk the inheritance chain).
                    if (implMethod != null)
                    {
                        TypeDesc implType = declType;
                        while (!implType.HasSameTypeDefinition(implMethod.OwningType))
                        {
                            implType = implType.BaseType;
                        }

                        MethodDesc targetMethod = implMethod;
                        if (!implType.IsTypeDefinition)
                        {
                            targetMethod = factory.TypeSystemContext.GetMethodForInstantiatedType(implMethod.GetTypicalMethodDefinition(), (InstantiatedType)implType);
                        }

                        builder.EmitShort(checked ((short)interfaceIndex));
                        builder.EmitShort(checked ((short)(interfaceMethodSlot + (interfaceType.HasGenericDictionarySlot() ? 1 : 0))));
                        builder.EmitShort(checked ((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, targetMethod, declType)));
                        entryCount++;
                    }
                }
            }

            builder.EmitInt(entryCountReservation, entryCount);
        }
Beispiel #11
0
        protected override void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type.GetClosestDefType();

            while (currentTypeSlice != null)
            {
                virtualSlotCount += factory.VTable(currentTypeSlice).Slots.Count;
                currentTypeSlice  = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));
            objData.EmitShort(checked ((short)_type.RuntimeInterfaces.Length));
        }
Beispiel #12
0
 private void OutputComponentSize(ref ObjectDataBuilder objData)
 {
     if (_type.IsArray)
     {
         objData.EmitShort((short)((ArrayType)_type).ElementType.GetElementSize());
     }
     else if (_type.IsString)
     {
         objData.EmitShort(2);
     }
     else
     {
         objData.EmitShort(0);
     }
 }
Beispiel #13
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            ISymbolNode relatedTypeNode = GetRelatedTypeNode(factory);

            // If the related type (base type / array element type / pointee type) is not part of this compilation group, and
            // the output binaries will be multi-file (not multiple object files linked together), indicate to the runtime
            // that it should indirect through the import address table
            if (relatedTypeNode != null && relatedTypeNode.RepresentsIndirectionCell)
            {
                flags |= (UInt16)EETypeFlags.RelatedTypeViaIATFlag;
            }

            // Todo: Generic Type Definition EETypes

            if (HasOptionalFields)
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }
Beispiel #14
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            dataBuilder.EmitZeroPointer(); // Sync block

            dataBuilder.EmitPointerReloc(GetEETypeNode(factory));

            dataBuilder.EmitInt(_data.Length);

            foreach (char c in _data)
            {
                dataBuilder.EmitShort((short)c);
            }

            // Null-terminate for friendliness with interop
            dataBuilder.EmitShort(0);
        }
Beispiel #15
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            if (factory.TypeSystemContext.IsGenericArrayInterfaceType(_type))
            {
                // Runtime casting logic relies on all interface types implemented on arrays
                // to have the variant flag set (even if all the arguments are non-variant).
                // This supports e.g. casting uint[] to ICollection<int>
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            ISymbolNode relatedTypeNode = GetRelatedTypeNode(factory);

            // If the related type (base type / array element type / pointee type) is not part of this compilation group, and
            // the output binaries will be multi-file (not multiple object files linked together), indicate to the runtime
            // that it should indirect through the import address table
            if (relatedTypeNode != null && relatedTypeNode.RepresentsIndirectionCell)
            {
                flags |= (UInt16)EETypeFlags.RelatedTypeViaIATFlag;
            }

            if (HasOptionalFields)
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }
Beispiel #16
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

            objData.RequireInitialPointerAlignment();
            objData.AddSymbol(this);

            ComputeOptionalEETypeFields(factory, relocsOnly);

            OutputGCDesc(ref objData);
            OutputComponentSize(ref objData);
            OutputFlags(factory, ref objData);
            OutputBaseSize(ref objData);
            OutputRelatedType(factory, ref objData);

            // Avoid consulting VTable slots until they're guaranteed complete during final data emission
            if (EmitVirtualSlotsAndInterfaces && !relocsOnly)
            {
                OutputVirtualSlotAndInterfaceCount(factory, ref objData);
            }
            else
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
            }

            objData.EmitInt(_type.GetHashCode());
            objData.EmitPointerReloc(factory.TypeManagerIndirection);

            if (EmitVirtualSlotsAndInterfaces)
            {
                // Avoid consulting VTable slots until they're guaranteed complete during final data emission
                if (!relocsOnly)
                {
                    OutputVirtualSlots(factory, ref objData, _type, _type);
                }

                OutputInterfaceMap(factory, ref objData);
            }

            OutputFinalizerMethod(factory, ref objData);
            OutputOptionalFields(factory, ref objData);
            OutputNullableTypeParameter(factory, ref objData);
            OutputGenericInstantiationDetails(factory, ref objData);

            return(objData.ToObjectData());
        }
Beispiel #17
0
 private void OutputComponentSize(ref ObjectDataBuilder objData)
 {
     if (_type.IsArray)
     {
         int elementSize = ((ArrayType)_type).ElementType.GetElementSize();
         // We validated that this will fit the short when the node was constructed. No need for nice messages.
         objData.EmitShort((short)checked ((ushort)elementSize));
     }
     else if (_type.IsString)
     {
         objData.EmitShort(2);
     }
     else
     {
         objData.EmitShort(0);
     }
 }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory, relocsOnly);

            dataBuilder.RequireInitialPointerAlignment();
            dataBuilder.AddSymbol(this);

            // +1 for SyncBlock (static size already includes MethodTable)
            Debug.Assert(factory.Target.Abi == TargetAbi.NativeAot || factory.Target.Abi == TargetAbi.CppCodegen);
            int totalSize = (_gcMap.Size + 1) * _target.PointerSize;

            // We only need to check for containsPointers because ThreadStatics are always allocated
            // on the GC heap (no matter what "HasGCStaticBase" says).
            // If that ever changes, we can assume "true" and switch this to an assert.

            bool containsPointers = _gcMap.NumSeries > 0;

            if (containsPointers)
            {
                GCDescEncoder.EncodeStandardGCDesc(ref dataBuilder, _gcMap, totalSize, 0);
            }

            Debug.Assert(dataBuilder.CountBytes == ((ISymbolDefinitionNode)this).Offset);

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            short flags = 0;

            if (containsPointers)
            {
                flags |= (short)EETypeFlags.HasPointersFlag;
            }

            dataBuilder.EmitShort(flags);

            totalSize = Math.Max(totalSize, _target.PointerSize * 3); // minimum GC MethodTable size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            // Related type: System.Object. This allows storing an instance of this type in an array of objects.
            dataBuilder.EmitPointerReloc(factory.NecessaryTypeSymbol(factory.TypeSystemContext.GetWellKnownType(WellKnownType.Object)));

            return(dataBuilder.ToObjectData());
        }
Beispiel #19
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);

            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            // +2 for SyncBlock and EETypePtr field
            int totalSize = (_gcMap.Size + 2) * _target.PointerSize;

            // We only need to check for containsPointers because ThreadStatics are always allocated
            // on the GC heap (no matter what "HasGCStaticBase" says).
            // If that ever changes, we can assume "true" and switch this to an assert.

            bool containsPointers = _gcMap.NumSeries > 0;

            if (containsPointers)
            {
                GCDescEncoder.EncodeStandardGCDesc(ref dataBuilder, _gcMap, totalSize, 0);
            }

            Debug.Assert(dataBuilder.CountBytes == Offset);

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            short flags = 0;

            if (containsPointers)
            {
                flags |= (short)EETypeFlags.HasPointersFlag;
            }

            dataBuilder.EmitShort(flags);

            totalSize = Math.Max(totalSize, _target.PointerSize * 3); // minimum GC eetype size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            // This is just so that EEType::Validate doesn't blow up at runtime
            dataBuilder.EmitPointerReloc(this); // Related type: itself

            return(dataBuilder.ToObjectData());
        }
Beispiel #20
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory, relocsOnly);

            dataBuilder.RequireInitialPointerAlignment();
            dataBuilder.AddSymbol(this);
            EETypeRareFlags rareFlags = 0;

            ushort flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (factory.PreinitializationManager.HasLazyStaticConstructor(_type))
            {
                rareFlags = rareFlags | EETypeRareFlags.HasCctorFlag;
            }
            if (_type.IsByRefLike)
            {
                rareFlags |= EETypeRareFlags.IsByRefLikeFlag;
            }

            if (rareFlags != 0)
            {
                _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, (uint)rareFlags);
            }

            if (HasOptionalFields)
            {
                flags |= (ushort)EETypeFlags.OptionalFieldsFlag;
            }

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitUShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            OutputTypeManagerIndirection(factory, ref dataBuilder);
            OutputWritableData(factory, ref dataBuilder);
            OutputOptionalFields(factory, ref dataBuilder);

            return(dataBuilder.ToObjectData());
        }
Beispiel #21
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

            objData.Alignment = 16;
            objData.DefinedSymbols.Add(this);

            if (!relocsOnly)
            {
                var entries = BuildDispatchMap(factory);
                objData.EmitInt(entries.Length);
                foreach (var entry in entries)
                {
                    objData.EmitShort(entry.InterfaceIndex);
                    objData.EmitShort(entry.InterfaceMethodSlot);
                    objData.EmitShort(entry.ImplementationMethodSlot);
                }
            }

            return(objData.ToObjectData());
        }
Beispiel #22
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (!_constructed)
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
                return;
            }

            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type.GetClosestMetadataType();

            while (currentTypeSlice != null)
            {
                virtualSlotCount += factory.VTable(currentTypeSlice).Slots.Count;
                currentTypeSlice  = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));
            objData.EmitShort(checked ((short)_type.RuntimeInterfaces.Length));
        }
Beispiel #23
0
        protected virtual void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            Debug.Assert(EmitVirtualSlotsAndInterfaces);

            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type.GetClosestDefType();

            while (currentTypeSlice != null)
            {
                if (currentTypeSlice.HasGenericDictionarySlot())
                {
                    virtualSlotCount++;
                }

                virtualSlotCount += factory.VTable(currentTypeSlice).Slots.Count;
                currentTypeSlice  = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));
            objData.EmitShort(checked ((short)_type.RuntimeInterfaces.Length));
        }
Beispiel #24
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            int      virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type;

            while (currentTypeSlice != null)
            {
                List <MethodDesc> virtualSlots;
                factory.VirtualSlots.TryGetValue(currentTypeSlice, out virtualSlots);
                if (virtualSlots != null)
                {
                    virtualSlotCount += virtualSlots.Count;
                }

                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked ((short)virtualSlotCount));

            // Todo: Number of slots of EEInterfaceInfo when we add interface support
            objData.EmitShort(0);
        }
Beispiel #25
0
        private void OutputComponentSize(ref ObjectDataBuilder objData)
        {
            if (_type.IsArray)
            {
                int elementSize = ((ArrayType)_type).ElementType.GetElementSize();
                if (elementSize >= 64 * 1024)
                {
                    // TODO: Array of type 'X' cannot be created because base value type is too large.
                    throw new TypeLoadException();
                }

                objData.EmitShort((short)elementSize);
            }
            else if (_type.IsString)
            {
                objData.EmitShort(2);
            }
            else
            {
                objData.EmitShort(0);
            }
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            short flags = (short)EETypeKind.GenericTypeDefEEType;
            if (_type.IsValueType)
                flags |= (short)EETypeFlags.ValueTypeFlag;
            if (_type.IsInterface)
                flags |= (short)EETypeFlags.IsInterfaceFlag;

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            dataBuilder.EmitPointerReloc(factory.ModuleManagerIndirection);
            
            return dataBuilder.ToObjectData();
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);

            dataBuilder.Alignment = dataBuilder.TargetPointerSize;
            dataBuilder.DefinedSymbols.Add(this);
            EETypeRareFlags rareFlags = 0;

            short flags = (short)EETypeKind.GenericTypeDefEEType;
            if (_type.IsValueType)
                flags |= (short)EETypeFlags.ValueTypeFlag;
            if (_type.IsInterface)
                flags |= (short)EETypeFlags.IsInterfaceFlag;
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
                rareFlags = rareFlags | EETypeRareFlags.HasCctorFlag;

            if (rareFlags != 0)
                _optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, (uint)rareFlags);

            if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
                flags |= (short)EETypeFlags.OptionalFieldsFlag;

            dataBuilder.EmitShort((short)_type.Instantiation.Length);
            dataBuilder.EmitShort(flags);
            dataBuilder.EmitInt(0);         // Base size is always 0
            dataBuilder.EmitZeroPointer();  // No related type
            dataBuilder.EmitShort(0);       // No VTable
            dataBuilder.EmitShort(0);       // No interface map
            dataBuilder.EmitInt(_type.GetHashCode());
            dataBuilder.EmitPointerReloc(factory.ModuleManagerIndirection);
            if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
            {
                dataBuilder.EmitPointerReloc(factory.EETypeOptionalFields(_optionalFieldsBuilder));
            }

            return dataBuilder.ToObjectData();
        }
Beispiel #28
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            // Todo: RelatedTypeViaIATFlag when we support cross-module EETypes
            // Todo: GenericVarianceFlag when we support variance
            // Todo: Generic Type Definition EETypes

            if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }
Beispiel #29
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            bool hasVariance = false;

            foreach (var argVariance in _details.Variance)
            {
                if (argVariance != 0)
                {
                    hasVariance = true;
                    break;
                }
            }

            var builder = new ObjectDataBuilder(factory);

            builder.DefinedSymbols.Add(this);

            builder.RequirePointerAlignment();

            builder.EmitShort((short)checked ((UInt16)_details.Instantiation.Length));

            builder.EmitByte((byte)(hasVariance ? 1 : 0));

            // TODO: general purpose padding
            builder.EmitByte(0);
            if (factory.Target.PointerSize == 8)
            {
                builder.EmitInt(0);
            }

            foreach (var typeArg in _details.Instantiation)
            {
                builder.EmitPointerReloc(factory.NecessaryTypeSymbol(typeArg));
            }

            if (hasVariance)
            {
                foreach (var argVariance in _details.Variance)
                {
                    builder.EmitByte(checked ((byte)argVariance));
                }
            }

            return(builder.ToObjectData());
        }
Beispiel #30
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            // Todo: RelatedTypeViaIATFlag when we support cross-module EETypes
            // Todo: Generic Type Definition EETypes

            if (HasOptionalFields)
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }
Beispiel #31
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            TypeDesc relatedType = null;

            if (_type.IsArray || _type.IsPointer || _type.IsByRef)
            {
                relatedType = ((ParameterizedType)_type).ParameterType;
            }
            else
            {
                relatedType = _type.BaseType;
            }

            // If the related type (base type / array element type / pointee type) is not part of this compilation group, and
            // the output binaries will be multi-file (not multiple object files linked together), indicate to the runtime
            // that it should indirect through the import address table
            if (relatedType != null && factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(relatedType))
            {
                flags |= (UInt16)EETypeFlags.RelatedTypeViaIATFlag;
            }

            // Todo: Generic Type Definition EETypes

            if (HasOptionalFields)
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }
Beispiel #32
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            // +2 for SyncBlock and EETypePtr field
            int totalSize = (_gcMap.Size + 2) * _target.PointerSize;

            // We only need to check for containsPointers because ThreadStatics are always allocated
            // on the GC heap (no matter what "HasGCStaticBase" says).
            // If that ever changes, we can assume "true" and switch this to an assert.

            bool containsPointers = _gcMap.NumSeries > 0;
            if (containsPointers)
            {
                GCDescEncoder.EncodeStandardGCDesc(ref dataBuilder, _gcMap, totalSize, 0);
            }

            Debug.Assert(dataBuilder.CountBytes == Offset);

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            short flags = 0;
            if (containsPointers)
                flags |= (short)EETypeFlags.HasPointersFlag;

            dataBuilder.EmitShort(flags);

            totalSize = Math.Max(totalSize, _target.PointerSize * 3); // minimum GC eetype size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            // Related type: System.Object. This allows storing an instance of this type in an array of objects.
            dataBuilder.EmitPointerReloc(factory.NecessaryTypeSymbol(factory.TypeSystemContext.GetWellKnownType(WellKnownType.Object)));

            return dataBuilder.ToObjectData();
        }
Beispiel #33
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            bool hasPointers = NumSeries > 0;
            if (hasPointers)
            {
                for (int i = ((_runLengths.Length / 2) * 2) - 1; i >= 0; i--)
                {
                    if (_targetPointerSize == 4)
                    {
                        dataBuilder.EmitInt(_runLengths[i]);
                    }
                    else
                    {
                        dataBuilder.EmitLong(_runLengths[i]);
                    }
                }
                if (_targetPointerSize == 4)
                {
                    dataBuilder.EmitInt(NumSeries);
                }
                else
                {
                    dataBuilder.EmitLong(NumSeries);
                }
            }

            int totalSize = 0;
            foreach (int run in _runLengths)
            {
                totalSize += run * _targetPointerSize;
            }

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            if (hasPointers)
                dataBuilder.EmitShort(0x20); // TypeFlags.HasPointers
            else
                dataBuilder.EmitShort(0x00);

            totalSize = Math.Max(totalSize, _targetPointerSize * 3); // minimum GC eetype size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            return dataBuilder.ToObjectData();
        }
Beispiel #34
0
 private void OutputComponentSize(ref ObjectDataBuilder objData)
 {
     if (_type.IsArray)
     {
         objData.EmitShort((short)((ArrayType)_type).ElementType.GetElementSize());
     }
     else if (_type.IsString)
     {
         objData.EmitShort(2);
     }
     else
     {
         objData.EmitShort(0);
     }
 }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.Alignment = 16;
            objData.DefinedSymbols.Add(this);

            if (!relocsOnly)
            {
                var entries = BuildDispatchMap(factory);
                objData.EmitInt(entries.Length);
                foreach (var entry in entries)
                {
                    objData.EmitShort(entry.InterfaceIndex);
                    objData.EmitShort(entry.InterfaceMethodSlot);
                    objData.EmitShort(entry.ImplementationMethodSlot);
                }
            }

            return objData.ToObjectData();
        }
        void EmitDispatchMap(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            var entryCountReservation = builder.ReserveInt();
            int entryCount = 0;
            
            for (int interfaceIndex = 0; interfaceIndex < _type.RuntimeInterfaces.Length; interfaceIndex++)
            {
                var interfaceType = _type.RuntimeInterfaces[interfaceIndex];
                Debug.Assert(interfaceType.IsInterface);

                IReadOnlyList<MethodDesc> virtualSlots = factory.VTable(interfaceType).Slots;
                
                for (int interfaceMethodSlot = 0; interfaceMethodSlot < virtualSlots.Count; interfaceMethodSlot++)
                {
                    MethodDesc declMethod = virtualSlots[interfaceMethodSlot];
                    var implMethod = _type.GetClosestDefType().ResolveInterfaceMethodToVirtualMethodOnType(declMethod);

                    // Interface methods first implemented by a base type in the hierarchy will return null for the implMethod (runtime interface
                    // dispatch will walk the inheritance chain).
                    if (implMethod != null)
                    {
                        builder.EmitShort(checked((short)interfaceIndex));
                        builder.EmitShort(checked((short)interfaceMethodSlot));
                        builder.EmitShort(checked((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod)));
                        entryCount++;
                    }
                }
            }

            builder.EmitInt(entryCountReservation, entryCount);
        }
Beispiel #37
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (!_constructed)
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
                return;
            }

            Debug.Assert(!_type.IsGenericDefinition);

            int virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type.GetClosestMetadataType();

            while (currentTypeSlice != null)
            {
                virtualSlotCount += factory.VTable(currentTypeSlice).Slots.Count;
                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked((short)virtualSlotCount));
            objData.EmitShort(checked((short)_type.RuntimeInterfaces.Length));
        }
Beispiel #38
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (!_constructed)
            {
                objData.EmitShort(0);
                objData.EmitShort(0);
                return;
            }

            int virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type;

            while (currentTypeSlice != null)
            {
                List<MethodDesc> virtualSlots;
                factory.VirtualSlots.TryGetValue(currentTypeSlice, out virtualSlots);
                if (virtualSlots != null)
                {
                    virtualSlotCount += virtualSlots.Count;
                }

                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked((short)virtualSlotCount));
            objData.EmitShort(checked((short)_type.RuntimeInterfaces.Length));
        }
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder dataBuilder = new ObjectDataBuilder(factory);
            dataBuilder.Alignment = 16;
            dataBuilder.DefinedSymbols.Add(this);

            // +2 for SyncBlock and EETypePtr field
            int totalSize = (_gcMap.Size + 2) * _target.PointerSize;

            // We only need to check for containsPointers because ThreadStatics are always allocated
            // on the GC heap (no matter what "HasGCStaticBase" says).
            // If that ever changes, we can assume "true" and switch this to an assert.

            bool containsPointers = _gcMap.NumSeries > 0;
            if (containsPointers)
            {
                GCDescEncoder.EncodeStandardGCDesc(ref dataBuilder, _gcMap, totalSize, 0);
            }

            Debug.Assert(dataBuilder.CountBytes == ((ISymbolNode)this).Offset);

            dataBuilder.EmitShort(0); // ComponentSize is always 0

            short flags = 0;
            if (containsPointers)
                flags |= (short)EETypeFlags.HasPointersFlag;

            dataBuilder.EmitShort(flags);

            totalSize = Math.Max(totalSize, _target.PointerSize * 3); // minimum GC eetype size is 3 pointers
            dataBuilder.EmitInt(totalSize);

            // This is just so that EEType::Validate doesn't blow up at runtime
            dataBuilder.EmitPointerReloc(this); // Related type: itself

            return dataBuilder.ToObjectData();
        }
Beispiel #40
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.Alignment = factory.Target.PointerSize;
            builder.DefinedSymbols.Add(this);

            // Don't bother sorting if we're not emitting the contents
            if (!relocsOnly)
            {
                _items.Sort((x, y) => Comparer <int> .Default.Compare((int)x.Id, (int)y.Id));
            }

            // ReadyToRunHeader.Magic
            builder.EmitInt((int)(ReadyToRunHeaderConstants.Signature));

            // ReadyToRunHeader.MajorVersion
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMajorVersion));
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMinorVersion));

            // ReadyToRunHeader.Flags
            builder.EmitInt(0);

            // ReadyToRunHeader.NumberOfSections
            var sectionCountReservation = builder.ReserveShort();

            // ReadyToRunHeader.EntrySize
            builder.EmitByte((byte)(8 + 2 * factory.Target.PointerSize));

            // ReadyToRunHeader.EntryType
            builder.EmitByte(1);

            int count = 0;

            foreach (var item in _items)
            {
                // Skip empty entries
                if (item.Node.ShouldSkipEmittingObjectNode(factory))
                {
                    continue;
                }

                builder.EmitInt((int)item.Id);

                ModuleInfoFlags flags = 0;
                if (item.EndSymbol != null)
                {
                    flags |= ModuleInfoFlags.HasEndPointer;
                }
                builder.EmitInt((int)flags);

                builder.EmitPointerReloc(item.StartSymbol);

                if (item.EndSymbol != null)
                {
                    builder.EmitPointerReloc(item.EndSymbol);
                }
                else
                {
                    builder.EmitZeroPointer();
                }

                count++;
            }
            builder.EmitShort(sectionCountReservation, checked ((short)count));

            return(builder.ToObjectData());
        }
Beispiel #41
0
        protected override void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            int virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type.GetClosestDefType();

            while (currentTypeSlice != null)
            {
                if (currentTypeSlice.HasGenericDictionarySlot())
                    virtualSlotCount++;

                virtualSlotCount += factory.VTable(currentTypeSlice).Slots.Count;
                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked((short)virtualSlotCount));
            objData.EmitShort(checked((short)_type.RuntimeInterfaces.Length));
        }
Beispiel #42
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.Alignment = factory.Target.PointerSize;
            builder.DefinedSymbols.Add(this);

            // Don't bother sorting if we're not emitting the contents
            if (!relocsOnly)
                _items.Sort((x, y) => Comparer<int>.Default.Compare((int)x.Id, (int)y.Id));

            // ReadyToRunHeader.Magic
            builder.EmitInt((int)(ReadyToRunHeaderConstants.Signature));

            // ReadyToRunHeader.MajorVersion
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMajorVersion));
            builder.EmitShort((short)(ReadyToRunHeaderConstants.CurrentMinorVersion));

            // ReadyToRunHeader.Flags
            builder.EmitInt(0);

            // ReadyToRunHeader.NumberOfSections
            var sectionCountReservation = builder.ReserveShort();

            // ReadyToRunHeader.EntrySize
            builder.EmitByte((byte)(8 + 2 * factory.Target.PointerSize));

            // ReadyToRunHeader.EntryType
            builder.EmitByte(1);

            int count = 0;
            foreach (var item in _items)
            {
                // Skip empty entries
                if (item.Node.ShouldSkipEmittingObjectNode(factory))
                    continue;

                builder.EmitInt((int)item.Id);

                ModuleInfoFlags flags = 0;
                if (item.EndSymbol != null)
                {
                    flags |= ModuleInfoFlags.HasEndPointer;
                }
                builder.EmitInt((int)flags);

                builder.EmitPointerReloc(item.StartSymbol);

                if (item.EndSymbol != null)
                {
                    builder.EmitPointerReloc(item.EndSymbol);
                }
                else
                {
                    builder.EmitZeroPointer();
                }

                count++;
            }
            builder.EmitShort(sectionCountReservation, checked((short)count));

            return builder.ToObjectData();
        }
Beispiel #43
0
 protected virtual void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     objData.EmitShort(0);
     objData.EmitShort(0);
 }
Beispiel #44
0
        private void OutputComponentSize(ref ObjectDataBuilder objData)
        {
            if (_type.IsArray)
            {
                int elementSize = ((ArrayType)_type).ElementType.GetElementSize();
                if (elementSize >= 64 * 1024)
                {
                    // TODO: Array of type 'X' cannot be created because base value type is too large.
                    throw new TypeLoadException();
                }

                objData.EmitShort((short)elementSize);
            }
            else if (_type.IsString)
            {
                objData.EmitShort(2);
            }
            else
            {
                objData.EmitShort(0);
            }
        }
Beispiel #45
0
        private void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            int virtualSlotCount = 0;
            TypeDesc currentTypeSlice = _type;

            while (currentTypeSlice != null)
            {
                List<MethodDesc> virtualSlots;
                factory.VirtualSlots.TryGetValue(currentTypeSlice, out virtualSlots);
                if (virtualSlots != null)
                {
                    virtualSlotCount += virtualSlots.Count;
                }

                currentTypeSlice = currentTypeSlice.BaseType;
            }

            objData.EmitShort(checked((short)virtualSlotCount));

            // Todo: Number of slots of EEInterfaceInfo when we add interface support
            objData.EmitShort(0);
        }
Beispiel #46
0
 protected virtual void OutputVirtualSlotAndInterfaceCount(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     objData.EmitShort(0);
     objData.EmitShort(0);
 }
Beispiel #47
0
 private void OutputComponentSize(ref ObjectDataBuilder objData)
 {
     if (_type.IsArray)
     {
         int elementSize = ((ArrayType)_type).ElementType.GetElementSize();
         // We validated that this will fit the short when the node was constructed. No need for nice messages.
         objData.EmitShort((short)checked((ushort)elementSize));
     }
     else if (_type.IsString)
     {
         objData.EmitShort(2);
     }
     else
     {
         objData.EmitShort(0);
     }
 }
Beispiel #48
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.Alignment = 16;
            objData.DefinedSymbols.Add(this);
            if (_type.IsArray)
            {
                objData.EmitShort((short)((ArrayType)_type).ElementType.GetElementSize()); // m_ComponentSize
                objData.EmitShort(0x4);                           // m_flags: IsArray(0x4)
            }
            else if (_type.IsString)
            {
                objData.EmitShort(2); // m_ComponentSize
                objData.EmitShort(0); // m_flags: 0
            }
            else
            {
                objData.EmitShort(0); // m_ComponentSize
                objData.EmitShort(0); // m_flags: 0
            }

            int pointerSize = _type.Context.Target.PointerSize;
            int minimumObjectSize = pointerSize * 3;
            int objectSize;
            if (_type is MetadataType)
            {
                objectSize = pointerSize +
                    ((MetadataType)_type).InstanceByteCount; // +pointerSize for SyncBlock
            }
            else if (_type is ArrayType)
            {
                objectSize = 3 * pointerSize; // SyncBlock + EETypePtr + Length
                int rank = ((ArrayType)_type).Rank;
                if (rank > 1)
                    objectSize +=
                        2 * _type.Context.GetWellKnownType(WellKnownType.Int32).GetElementSize() * rank;
            }
            else
                throw new NotImplementedException();

            objectSize = AlignmentHelper.AlignUp(objectSize, pointerSize);
            objectSize = Math.Max(minimumObjectSize, objectSize);

            if (_type.IsString)
            {
                // If this is a string, throw away objectSize we computed so far. Strings are special.
                // SyncBlock + EETypePtr + length + firstChar
                objectSize = 2 * pointerSize +
                    _type.Context.GetWellKnownType(WellKnownType.Int32).GetElementSize() +
                    _type.Context.GetWellKnownType(WellKnownType.Char).GetElementSize();
            }

            objData.EmitInt(objectSize);

            if (Type.BaseType != null)
            {
                if (_constructed)
                {
                    objData.EmitPointerReloc(factory.ConstructedTypeSymbol(Type.BaseType));
                }
                else
                {
                    objData.EmitPointerReloc(factory.NecessaryTypeSymbol(Type.BaseType));
                }
            }
            else
            {
                objData.EmitZeroPointer();
            }

            if (_constructed)
            {
                OutputVirtualSlots(ref objData, _type, _type, factory);
            }

            return objData.ToObjectData();
        }
Beispiel #49
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            // Todo: RelatedTypeViaIATFlag when we support cross-module EETypes
            // Todo: GenericVarianceFlag when we support variance
            // Todo: Generic Type Definition EETypes

            if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }
Beispiel #50
0
        private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            UInt16 flags = EETypeBuilderHelpers.ComputeFlags(_type);

            if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
            {
                // Generic array enumerators use special variance rules recognized by the runtime
                flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
            }

            // Todo: RelatedTypeViaIATFlag when we support cross-module EETypes
            // Todo: Generic Type Definition EETypes

            if (HasOptionalFields)
            {
                flags |= (UInt16)EETypeFlags.OptionalFieldsFlag;
            }

            objData.EmitShort((short)flags);
        }