コード例 #1
0
ファイル: GCStaticsNode.cs プロジェクト: mskvortsov/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            if (factory.Target.Abi == TargetAbi.CoreRT)
            {
                int delta = GCStaticRegionConstants.Uninitialized;

                // Set the flag that indicates next pointer following EEType is the preinit data
                if (_preInitFieldInfos != null)
                {
                    delta |= GCStaticRegionConstants.HasPreInitializedData;
                }

                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

                if (_preInitFieldInfos != null)
                {
                    builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
                }
            }
            else
            {
                builder.RequireInitialAlignment(_type.GCStaticFieldAlignment.AsInt);

                // @TODO - emit the frozen array node reloc
                builder.EmitZeros(_type.GCStaticFieldSize.AsInt);
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
コード例 #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);
        }
コード例 #3
0
ファイル: EETypeNode.cs プロジェクト: karelz/corert
        private void OutputGenericInstantiationDetails(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (_type.HasInstantiation && !_type.IsTypeDefinition)
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type.GetTypeDefinition()));

                GenericCompositionDetails details;
                if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
                {
                    // Generic array enumerators use special variance rules recognized by the runtime
                    details = new GenericCompositionDetails(_type.Instantiation, new[] { GenericVariance.ArrayCovariant });
                }
                else 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>
                    details = new GenericCompositionDetails(_type, forceVarianceInfo: true);
                }
                else
                {
                    details = new GenericCompositionDetails(_type);
                }

                objData.EmitPointerReloc(factory.GenericComposition(details));
            }
        }
コード例 #4
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

            // Address (to be fixed up at runtime)
            builder.EmitZeroPointer();

            // Entry point name
            if (factory.Target.IsWindows && _entryPointName.StartsWith("#", StringComparison.OrdinalIgnoreCase))
            {
                // Windows-specific ordinal import
                // CLR-compatible behavior: Strings that can't be parsed as a signed integer are treated as zero.
                int entrypointOrdinal;
                if (!int.TryParse(_entryPointName.Substring(1), out entrypointOrdinal))
                    entrypointOrdinal = 0;

                // CLR-compatible behavior: Ordinal imports are 16-bit on Windows. Discard rest of the bits.
                builder.EmitNaturalInt((ushort)entrypointOrdinal);
            }
            else
            {
                // Import by name
                builder.EmitPointerReloc(factory.ConstantUtf8String(_entryPointName));
            }

            // Module fixup cell
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName));

            return builder.ToObjectData();
        }
コード例 #5
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory);

            // These need to be aligned the same as methods because they show up in same contexts
            builder.RequireAlignment(factory.Target.MinimumFunctionAlignment);

            builder.DefinedSymbols.Add(this);

            MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific);

            // Pointer to the canonical body of the method
            builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod));

            // Find out what's the context to use
            ISymbolNode contextParameter;
            if (canonMethod.RequiresInstMethodDescArg())
            {
                contextParameter = factory.MethodGenericDictionary(Method);
            }
            else
            {
                Debug.Assert(canonMethod.RequiresInstMethodTableArg());

                // Ask for a constructed type symbol because we need the vtable to get to the dictionary
                contextParameter = factory.ConstructedTypeSymbol(Method.OwningType);
            }

            // The next entry is a pointer to the pointer to the context to be used for the canonical method
            // TODO: in multi-module, this points to the import cell, and is no longer this weird pointer
            builder.EmitPointerReloc(factory.Indirection(contextParameter));
            
            return builder.ToObjectData();
        }
コード例 #6
0
ファイル: GCStaticsNode.cs プロジェクト: Tryll/CoreRT-armel
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.RequireInitialPointerAlignment();

            int delta = GCStaticRegionConstants.Uninitialized;

            // Set the flag that indicates next pointer following EEType is the preinit data
            bool isPreinitialized = _preinitializationInfo != null && _preinitializationInfo.IsPreinitialized;

            if (isPreinitialized)
            {
                delta |= GCStaticRegionConstants.HasPreInitializedData;
            }

            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

            if (isPreinitialized)
            {
                builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
            }

            builder.AddSymbol(this);

            return(builder.ToObjectData());
        }
コード例 #7
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);

        }
コード例 #8
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory);

            // These need to be aligned the same as methods because they show up in same contexts
            builder.RequireAlignment(factory.Target.MinimumFunctionAlignment);

            builder.DefinedSymbols.Add(this);

            MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific);

            // Pointer to the canonical body of the method
            builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod));

            // Find out what's the context to use
            GenericDictionaryNode dictionary;

            if (canonMethod.RequiresInstMethodDescArg())
            {
                dictionary = factory.MethodGenericDictionary(Method);
            }
            else
            {
                Debug.Assert(canonMethod.RequiresInstMethodTableArg());
                dictionary = factory.TypeGenericDictionary(Method.OwningType);
            }

            // The next entry is a pointer to the pointer to the context to be used for the canonical method
            // TODO: in multi-module, this points to the import cell, and is no longer this weird pointer
            builder.EmitPointerReloc(factory.Indirection(dictionary));

            return(builder.ToObjectData());
        }
コード例 #9
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

            builder.AddSymbol(this);

            ISymbolNode nameSymbol       = factory.ConstantUtf8String(_pInvokeModuleData.ModuleName);
            ISymbolNode moduleTypeSymbol = factory.NecessaryTypeSymbol(_pInvokeModuleData.DeclaringModule.GetGlobalModuleType());

            //
            // Emit a ModuleFixupCell struct
            //

            builder.EmitZeroPointer();
            builder.EmitPointerReloc(nameSymbol);
            builder.EmitPointerReloc(moduleTypeSymbol);

            uint dllImportSearchPath = 0;

            if (_pInvokeModuleData.DllImportSearchPath.HasValue)
            {
                dllImportSearchPath = (uint)_pInvokeModuleData.DllImportSearchPath.Value;
                Debug.Assert((dllImportSearchPath & InteropDataConstants.HasDllImportSearchPath) == 0);
                dllImportSearchPath |= InteropDataConstants.HasDllImportSearchPath;
            }
            builder.EmitInt((int)dllImportSearchPath);

            return(builder.ToObjectData());
        }
コード例 #10
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the 
            // synchronization mechanism of the two values in the runtime.
            objData.Alignment = _targetMethod.Context.Target.PointerSize * 2;
            objData.DefinedSymbols.Add(this);
            
            objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch"));
            
            // The second cell field uses the two lower-order bits to communicate the contents.
            // We add 1 to signal IDC_CachePointerIsInterfacePointer. See src\Native\Runtime\inc\rhbinder.h.
            objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), 1);
            
            // End the run of dispatch cells
            objData.EmitZeroPointer();

            // Avoid consulting VTable slots until they're guaranteed complete during final data emission
            if (!relocsOnly)
            {
                int interfaceMethodSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod);
                if (factory.Target.PointerSize == 8)
                {
                    objData.EmitLong(interfaceMethodSlot);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            return objData.ToObjectData();
        }
コード例 #11
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

            // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the
            // synchronization mechanism of the two values in the runtime.
            objData.Alignment = _targetMethod.Context.Target.PointerSize * 2;
            objData.DefinedSymbols.Add(this);

            objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch"));

            // The second cell field uses the two lower-order bits to communicate the contents.
            // We add 1 to signal IDC_CachePointerIsInterfacePointer. See src\Native\Runtime\inc\rhbinder.h.
            objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), 1);

            // End the run of dispatch cells
            objData.EmitZeroPointer();

            int interfaceMethodSlot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod);

            if (factory.Target.PointerSize == 8)
            {
                objData.EmitLong(interfaceMethodSlot);
            }
            else
            {
                throw new NotImplementedException();
            }

            return(objData.ToObjectData());
        }
コード例 #12
0
        public override void EncodeData(ref ObjectDataBuilder objData, NodeFactory factory, bool relocsOnly)
        {
            TargetArchitecture targetArchitecture = factory.Target.Architecture;

            if (targetArchitecture == TargetArchitecture.ARM)
            {
                objData.EmitPointerReloc(factory.InitialInterfaceDispatchStub);
            }
            else
            {
                objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch"));
            }

            IEETypeNode interfaceType = factory.NecessaryTypeSymbol(_targetMethod.OwningType);

            if (interfaceType.RepresentsIndirectionCell)
            {
                objData.EmitReloc(interfaceType, RelocType.IMAGE_REL_BASED_RELPTR32,
                                  (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsIndirectedInterfaceRelativePointer);
            }
            else
            {
                objData.EmitReloc(interfaceType, RelocType.IMAGE_REL_BASED_RELPTR32,
                                  (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer);
            }

            if (objData.TargetPointerSize == 8)
            {
                // IMAGE_REL_BASED_RELPTR is a 32-bit relocation. However, the cell needs a full pointer
                // width there since a pointer to the cache will be written into the cell. Emit additional
                // 32 bits on targets whose pointer size is 64 bit.
                objData.EmitInt(0);
            }
        }
コード例 #13
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory, relocsOnly);

            // These need to be aligned the same as methods because they show up in same contexts
            builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);

            builder.AddSymbol(this);

            MethodDesc canonMethod = Method.GetCanonMethodTarget(CanonicalFormKind.Specific);

            // Pointer to the canonical body of the method
            builder.EmitPointerReloc(factory.MethodEntrypoint(canonMethod, _isUnboxingStub));

            // Find out what's the context to use
            ISymbolNode contextParameter;

            if (canonMethod.RequiresInstMethodDescArg())
            {
                contextParameter = factory.MethodGenericDictionary(Method);
            }
            else
            {
                Debug.Assert(canonMethod.RequiresInstMethodTableArg());

                // Ask for a constructed type symbol because we need the vtable to get to the dictionary
                contextParameter = factory.ConstructedTypeSymbol(Method.OwningType);
            }

            // The next entry is a pointer to the pointer to the context to be used for the canonical method
            // TODO: in multi-module, this points to the import cell, and is no longer this weird pointer
            builder.EmitPointerReloc(factory.Indirection(contextParameter));

            return(builder.ToObjectData());
        }
コード例 #14
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            Debug.Assert(_dynamicInvokeMethodContainerType != null);

            // Ensure the native layout blob has been saved
            factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory);

            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

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

            if (factory.Target.SupportsRelativePointers)
            {
                objData.EmitReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType), RelocType.IMAGE_REL_BASED_RELPTR32);
            }
            else
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_dynamicInvokeMethodContainerType));
            }

            List <KeyValuePair <MethodDesc, int> > sortedList = new List <KeyValuePair <MethodDesc, int> >(_methodToTemplateIndex);

            sortedList.Sort((firstEntry, secondEntry) => firstEntry.Value.CompareTo(secondEntry.Value));

            for (int i = 0; i < sortedList.Count; i++)
            {
                var nameAndSig = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(sortedList[i].Key));

                if (factory.Target.SupportsRelativePointers)
                {
                    objData.EmitInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitReloc(factory.MethodEntrypoint(sortedList[i].Key), RelocType.IMAGE_REL_BASED_RELPTR32);
                }
                else
                {
                    objData.EmitNaturalInt(nameAndSig.SavedVertex.VertexOffset);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(sortedList[i].Key));
                }
            }

            _endSymbol.SetSymbolOffset(objData.CountBytes);
            objData.AddSymbol(_endSymbol);

            // Prevent further adds now we're done writing
#if DEBUG
            if (!relocsOnly)
            {
                _dataEmitted = true;
            }
#endif

            return(objData.ToObjectData());
        }
コード例 #15
0
ファイル: EETypeNode.cs プロジェクト: shchahrykovich/corert
        protected virtual void OutputVirtualSlots(NodeFactory factory, ref ObjectDataBuilder objData, TypeDesc implType, TypeDesc declType, bool relocsOnly)
        {
            Debug.Assert(EmitVirtualSlotsAndInterfaces);

            declType = declType.GetClosestDefType();

            var baseType = declType.BaseType;

            if (baseType != null)
            {
                OutputVirtualSlots(factory, ref objData, implType, baseType, relocsOnly);
            }

            // The generic dictionary pointer occupies the first slot of each type vtable slice
            if (declType.HasGenericDictionarySlot())
            {
                // Note: Canonical type instantiations always have a generic dictionary vtable slot, but it's empty
                // TODO: emit the correction dictionary slot for interfaces (needed when we start supporting static methods on interfaces)
                if (declType.IsInterface || declType.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    objData.EmitZeroPointer();
                }
                else
                {
                    objData.EmitPointerReloc(factory.TypeGenericDictionary(declType));
                }
            }

            // It's only okay to touch the actual list of slots if we're in the final emission phase
            // or the vtable is not built lazily.
            if (relocsOnly && !factory.CompilationModuleGroup.ShouldProduceFullVTable(declType))
            {
                return;
            }

            // Actual vtable slots follow
            IReadOnlyList <MethodDesc> virtualSlots = factory.VTable(declType).Slots;

            for (int i = 0; i < virtualSlots.Count; i++)
            {
                MethodDesc declMethod = virtualSlots[i];

                // No generic virtual methods can appear in the vtable!
                Debug.Assert(!declMethod.HasInstantiation);

                MethodDesc implMethod = implType.GetClosestDefType().FindVirtualFunctionTargetMethodOnObjectType(declMethod);

                if (!implMethod.IsAbstract)
                {
                    MethodDesc canonImplMethod = implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(canonImplMethod, implMethod.OwningType.IsValueType));
                }
                else
                {
                    objData.EmitZeroPointer();
                }
            }
        }
コード例 #16
0
        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());
        }
コード例 #17
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

            // The interface dispatch cell has an alignment requirement of 2 * [Pointer size] as part of the
            // synchronization mechanism of the two values in the runtime.
            objData.RequireInitialAlignment(_targetMethod.Context.Target.PointerSize * 2);
            objData.AddSymbol(this);

            if (factory.Target.Architecture == TargetArchitecture.ARM)
            {
                objData.EmitPointerReloc(factory.InitialInterfaceDispatchStub);
            }
            else
            {
                objData.EmitPointerReloc(factory.ExternSymbol("RhpInitialDynamicInterfaceDispatch"));
            }

            if (factory.Target.Abi == TargetAbi.CoreRT)
            {
                // TODO: Enable Indirect Pointer for Interface Dispatch Cell. See https://github.com/dotnet/corert/issues/2542
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType),
                                         (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfacePointerOrMetadataToken);
            }
            else
            {
                if (factory.CompilationModuleGroup.ContainsType(_targetMethod.OwningType))
                {
                    objData.EmitReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), RelocType.IMAGE_REL_BASED_RELPTR32,
                                      (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer);
                }
                else
                {
                    objData.EmitReloc(factory.NecessaryTypeSymbol(_targetMethod.OwningType), RelocType.IMAGE_REL_BASED_RELPTR32,
                                      (int)InterfaceDispatchCellCachePointerFlags.CachePointerIsIndirectedInterfaceRelativePointer);
                }

                if (objData.TargetPointerSize == 8)
                {
                    // IMAGE_REL_BASED_RELPTR is a 32-bit relocation. However, the cell needs a full pointer
                    // width there since a pointer to the cache will be written into the cell. Emit additional
                    // 32 bits on targets whose pointer size is 64 bit.
                    objData.EmitInt(0);
                }
            }

            // End the run of dispatch cells
            objData.EmitZeroPointer();

            // Avoid consulting VTable slots until they're guaranteed complete during final data emission
            if (!relocsOnly)
            {
                objData.EmitNaturalInt(VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, _targetMethod));
            }

            return(objData.ToObjectData());
        }
コード例 #18
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);

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

            // Emit an aliased symbol named _tls_index for native P/Invoke code that uses TLS. This is required
            // because we do not link against libcmt.lib.
            ObjectAndOffsetSymbolNode aliasedSymbol = new ObjectAndOffsetSymbolNode(this, objData.CountBytes, "_tls_index", false);

            objData.AddSymbol(aliasedSymbol);

            // This is the TLS index field which is a 4-byte integer. Emit an 8-byte interger which includes a
            // 4-byte padding to make an pointer-sized alignment for the subsequent fields for all targets.
            objData.EmitLong(0);

            // Allocate and initialize the IMAGE_TLS_DIRECTORY PE data structure used by the OS loader to determine
            // TLS allocations. The structure is defined by the OS as following:

            /*
             *  struct _IMAGE_TLS_DIRECTORY32
             *  {
             *      DWORD StartAddressOfRawData;
             *      DWORD EndAddressOfRawData;
             *      DWORD AddressOfIndex;
             *      DWORD AddressOfCallBacks;
             *      DWORD SizeOfZeroFill;
             *      DWORD Characteristics;
             *  }
             *
             *  struct _IMAGE_TLS_DIRECTORY64
             *  {
             *      ULONGLONG StartAddressOfRawData;
             *      ULONGLONG EndAddressOfRawData;
             *      ULONGLONG AddressOfIndex;
             *      ULONGLONG AddressOfCallBacks;
             *      DWORD SizeOfZeroFill;
             *      DWORD Characteristics;
             *  }
             */
            // In order to utilize linker support, the struct variable needs to be named _tls_used
            ObjectAndOffsetSymbolNode structSymbol = new ObjectAndOffsetSymbolNode(this, objData.CountBytes, "_tls_used", false);

            objData.AddSymbol(structSymbol);
            objData.EmitPointerReloc(factory.ThreadStaticsRegion.StartSymbol); // start of tls data
            objData.EmitPointerReloc(factory.ThreadStaticsRegion.EndSymbol);   // end of tls data
            objData.EmitPointerReloc(this);                                    // address of tls_index
            objData.EmitZeroPointer();                                         // pointer to call back array
            objData.EmitInt(0);                                                // size of tls zero fill
            objData.EmitInt(0);                                                // characteristics

            return(objData.ToObjectData());
        }
コード例 #19
0
ファイル: GenericLookupResult.cs プロジェクト: ezverev/corert
        public override void EmitDictionaryEntry(ref ObjectDataBuilder builder, NodeFactory factory, Instantiation typeInstantiation, Instantiation methodInstantiation, GenericDictionaryNode dictionary)
        {
            ISymbolNode target = GetTarget(factory, typeInstantiation, methodInstantiation, dictionary);

            if (target is IFatFunctionPointerNode)
            {
                builder.EmitPointerReloc(target, FatFunctionPointerConstants.Offset);
            }
            else
            {
                builder.EmitPointerReloc(target);
            }
        }
コード例 #20
0
        protected virtual void OutputVirtualSlots(NodeFactory factory, ref ObjectDataBuilder objData, TypeDesc implType, TypeDesc declType)
        {
            Debug.Assert(EmitVirtualSlotsAndInterfaces);

            declType = declType.GetClosestDefType();

            var baseType = declType.BaseType;

            if (baseType != null)
            {
                OutputVirtualSlots(factory, ref objData, implType, baseType);
            }

            // The generic dictionary pointer occupies the first slot of each type vtable slice
            if (declType.HasGenericDictionarySlot())
            {
                // Note: Canonical type instantiations always have a generic dictionary vtable slot, but it's empty
                if (declType.IsCanonicalSubtype(CanonicalFormKind.Any))
                {
                    objData.EmitZeroPointer();
                }
                else
                {
                    objData.EmitPointerReloc(factory.TypeGenericDictionary(declType));
                }
            }

            // Actual vtable slots follow
            IReadOnlyList <MethodDesc> virtualSlots = factory.VTable(declType).Slots;

            for (int i = 0; i < virtualSlots.Count; i++)
            {
                MethodDesc declMethod = virtualSlots[i];

                // No generic virtual methods can appear in the vtable!
                Debug.Assert(!declMethod.HasInstantiation);

                MethodDesc implMethod = implType.GetClosestDefType().FindVirtualFunctionTargetMethodOnObjectType(declMethod);

                if (!implMethod.IsAbstract)
                {
                    MethodDesc canonImplMethod = implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(canonImplMethod, implMethod.OwningType.IsValueType));
                }
                else
                {
                    objData.EmitZeroPointer();
                }
            }
        }
コード例 #21
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

            builder.EmitZeroPointer();
            builder.EmitPointerReloc(factory.ConstantUtf8String(_entryPointName));
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName));

            return builder.ToObjectData();
        }
コード例 #22
0
ファイル: GCStaticsNode.cs プロジェクト: zaccharles/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            if (factory.Target.Abi == TargetAbi.CoreRT || factory.Target.Abi == TargetAbi.CppCodegen)
            {
                ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

                builder.RequireInitialPointerAlignment();

                int delta = GCStaticRegionConstants.Uninitialized;

                // Set the flag that indicates next pointer following EEType is the preinit data
                if (_preInitFieldInfos != null)
                {
                    delta |= GCStaticRegionConstants.HasPreInitializedData;
                }

                builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), delta);

                if (_preInitFieldInfos != null)
                {
                    builder.EmitPointerReloc(factory.GCStaticsPreInitDataNode(_type));
                }

                builder.AddSymbol(this);

                return(builder.ToObjectData());
            }
            else
            {
                if (_preInitFieldInfos == null)
                {
                    ObjectDataBuilder builder = new ObjectDataBuilder(factory, relocsOnly);

                    builder.RequireInitialPointerAlignment();

                    builder.EmitZeros(_type.GCStaticFieldSize.AsInt);

                    builder.AddSymbol(this);

                    return(builder.ToObjectData());
                }
                else
                {
                    _preInitFieldInfos.Sort(PreInitFieldInfo.FieldDescCompare);
                    return(GCStaticsPreInitDataNode.GetDataForPreInitDataField(this, _type, _preInitFieldInfos, 0, factory, relocsOnly));
                }
            }
        }
コード例 #23
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
            {
                return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this }));
            }

            // Zero out the dictionary so that we AV if someone tries to insert after we're done.
            _insertedSymbolsDictionary = null;

            var builder = new ObjectDataBuilder(factory, relocsOnly);

            foreach (SymbolAndDelta symbolAndDelta in _insertedSymbols)
            {
                if (factory.Target.SupportsRelativePointers)
                {
                    // TODO: set low bit if the linkage of the symbol is IAT_PVALUE.
                    builder.EmitReloc(symbolAndDelta.Symbol, RelocType.IMAGE_REL_BASED_RELPTR32, symbolAndDelta.Delta);
                }
                else
                {
                    builder.EmitPointerReloc(symbolAndDelta.Symbol, symbolAndDelta.Delta);
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);

            builder.AddSymbol(this);
            builder.AddSymbol(_endSymbol);

            return(builder.ToObjectData());
        }
コード例 #24
0
        protected virtual void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            ISymbolNode relatedTypeNode = null;

            if (_type.IsArray || _type.IsPointer || _type.IsByRef)
            {
                var parameterType = ((ParameterizedType)_type).ParameterType;
                relatedTypeNode = factory.NecessaryTypeSymbol(parameterType);
            }
            else
            {
                TypeDesc baseType = _type.BaseType;
                if (baseType != null)
                {
                    relatedTypeNode = GetBaseTypeNode(factory);
                }
            }

            if (relatedTypeNode != null)
            {
                objData.EmitPointerReloc(relatedTypeNode);
            }
            else
            {
                objData.EmitZeroPointer();
            }
        }
コード例 #25
0
 protected override void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     //
     // Cloned types use the related type field to point via an IAT slot at their true implementation
     //
     objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type));
 }
コード例 #26
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());
        }
コード例 #27
0
 protected override void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     //
     // Cloned types use the related type field to point via an IAT slot at their true implementation
     //
     objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type));
 }
コード例 #28
0
ファイル: ConstructedEETypeNode.cs プロジェクト: svick/corert
 protected override void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     foreach (var itf in _type.RuntimeInterfaces)
     {
         objData.EmitPointerReloc(factory.NecessaryTypeSymbol(itf));
     }
 }
コード例 #29
0
 private void OutputOptionalFields(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     if (HasOptionalFields)
     {
         objData.EmitPointerReloc(_optionalFieldsNode);
     }
 }
コード例 #30
0
        private void OutputVirtualSlots(NodeFactory factory, ref ObjectDataBuilder objData, TypeDesc implType, TypeDesc declType)
        {
            var baseType = declType.BaseType;

            if (baseType != null)
            {
                OutputVirtualSlots(factory, ref objData, implType, baseType);
            }

            List <MethodDesc> virtualSlots;

            factory.VirtualSlots.TryGetValue(declType, out virtualSlots);

            if (virtualSlots != null)
            {
                for (int i = 0; i < virtualSlots.Count; i++)
                {
                    MethodDesc declMethod = virtualSlots[i];
                    MethodDesc implMethod = VirtualFunctionResolution.FindVirtualFunctionTargetMethodOnObjectType(declMethod, implType.GetClosestMetadataType());

                    if (!implMethod.IsAbstract)
                    {
                        objData.EmitPointerReloc(factory.MethodEntrypoint(implMethod));
                    }
                    else
                    {
                        objData.EmitZeroPointer();
                    }
                }
            }
        }
コード例 #31
0
 private void OutputOptionalFields(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     if (_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
     {
         objData.EmitPointerReloc(_optionalFieldsNode);
     }
 }
コード例 #32
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory, relocsOnly);

            objData.RequireInitialAlignment(4);
            objData.AddSymbol(this);

            if (BuildSealedVTableSlots(factory, relocsOnly))
            {
                for (int i = 0; i < _sealedVTableEntries.Count; i++)
                {
                    MethodDesc  canonImplMethod = _sealedVTableEntries[i].GetCanonMethodTarget(CanonicalFormKind.Specific);
                    IMethodNode relocTarget     = factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType);

                    if (factory.Target.SupportsRelativePointers)
                    {
                        objData.EmitReloc(relocTarget, RelocType.IMAGE_REL_BASED_RELPTR32);
                    }
                    else
                    {
                        objData.EmitPointerReloc(relocTarget);
                    }
                }
            }

            return(objData.ToObjectData());
        }
コード例 #33
0
 private void OutputNullableTypeParameter(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     if (_type.IsNullable)
     {
         objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type.Instantiation[0]));
     }
 }
コード例 #34
0
ファイル: NonGCStaticsNode.cs プロジェクト: wffy/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            // If the type has a class constructor, its non-GC statics section is prefixed
            // by System.Runtime.CompilerServices.StaticClassConstructionContext struct.
            if (factory.TypeSystemContext.HasLazyStaticConstructor(_type))
            {
                int alignmentRequired = Math.Max(_type.NonGCStaticFieldAlignment, GetClassConstructorContextAlignment(_type.Context.Target));
                int classConstructorContextStorageSize = GetClassConstructorContextStorageSize(factory.Target, _type);
                builder.RequireAlignment(alignmentRequired);

                Debug.Assert(classConstructorContextStorageSize >= GetClassConstructorContextSize(_type.Context.Target));

                // Add padding before the context if alignment forces us to do so
                builder.EmitZeros(classConstructorContextStorageSize - GetClassConstructorContextSize(_type.Context.Target));

                // Emit the actual StaticClassConstructionContext
                var cctorMethod = _type.GetStaticConstructor();
                builder.EmitPointerReloc(factory.MethodEntrypoint(cctorMethod));
                builder.EmitZeroPointer();
            }
            else
            {
                builder.RequireAlignment(_type.NonGCStaticFieldAlignment);
            }

            builder.EmitZeros(_type.NonGCStaticFieldSize);
            builder.DefinedSymbols.Add(this);

            return(builder.ToObjectData());
        }
コード例 #35
0
        private void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            ISymbolNode relatedTypeNode = null;

            if (_type.IsArray || _type.IsPointer)
            {
                var parameterType = ((ParameterizedType)_type).ParameterType;
                relatedTypeNode = factory.NecessaryTypeSymbol(parameterType);
            }
            else
            {
                TypeDesc baseType = _type.BaseType;
                if (baseType != null)
                {
                    if (_constructed)
                    {
                        relatedTypeNode = factory.ConstructedTypeSymbol(baseType);
                    }
                    else
                    {
                        relatedTypeNode = factory.NecessaryTypeSymbol(baseType);
                    }
                }
            }

            if (relatedTypeNode != null)
            {
                objData.EmitPointerReloc(relatedTypeNode);
            }
            else
            {
                objData.EmitZeroPointer();
            }
        }
コード例 #36
0
ファイル: ThreadStaticsNode.cs プロジェクト: Maximys/runtime
 public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
 {
     // At runtime, an instance of the GCStaticEEType will be created and a GCHandle to it
     // will be written in this location.
     builder.RequireInitialPointerAlignment();
     builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
 }
コード例 #37
0
ファイル: ThreadStaticsNode.cs プロジェクト: noahfalk/corert
        public override void EncodeData(ref ObjectDataBuilder builder, NodeFactory factory, bool relocsOnly)
        {
            builder.RequirePointerAlignment();

            // At runtime, an instance of the GCStaticEEType will be created and a GCHandle to it
            // will be written in this location.
            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory));
        }
コード例 #38
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.RequirePointerAlignment();
            objData.DefinedSymbols.Add(this);
            objData.EmitPointerReloc(factory.ReadyToRunHeader);

            return objData.ToObjectData();
        }
コード例 #39
0
ファイル: IndirectionNode.cs プロジェクト: nattress/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            var builder = new ObjectDataBuilder(factory);
            builder.RequirePointerAlignment();
            builder.DefinedSymbols.Add(this);

            builder.EmitPointerReloc(_indirectedNode);

            return builder.ToObjectData();
        }
コード例 #40
0
ファイル: GCStaticsNode.cs プロジェクト: nattress/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            builder.RequirePointerAlignment();
            builder.EmitPointerReloc(GetGCStaticEETypeNode(factory), 1);
            builder.DefinedSymbols.Add(this);

            return builder.ToObjectData();
        }
コード例 #41
0
        public override void EncodeData(ref ObjectDataBuilder dataBuilder, NodeFactory factory, bool relocsOnly)
        {
            dataBuilder.RequirePointerAlignment();

            StringDataNode stringDataNode = factory.StringData(_data);
            if (!relocsOnly)
                stringDataNode.SetId(base.Offset);

            dataBuilder.EmitPointerReloc(stringDataNode);
        }
コード例 #42
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a MethodFixupCell struct
            //

            builder.EmitZeroPointer();

            int entryPointBytesCount = Encoding.UTF8.GetByteCount(_entryPointName);
            byte[] entryPointNameBytes = new byte[entryPointBytesCount + 1];
            Encoding.UTF8.GetBytes(_entryPointName, 0, _entryPointName.Length, entryPointNameBytes, 0);

            builder.EmitPointerReloc(factory.ReadOnlyDataBlob("__pinvokename_" + _entryPointName, entryPointNameBytes, 1));
            builder.EmitPointerReloc(factory.PInvokeModuleFixup(_moduleName));

            return builder.ToObjectData();
        }
コード例 #43
0
        protected virtual void EmitDataInternal(ref ObjectDataBuilder builder, NodeFactory factory)
        {
            DictionaryLayoutNode layout = GetDictionaryLayout(factory);

            Instantiation typeInst = this.TypeInstantiation;
            Instantiation methodInst = this.MethodInstantiation;

            foreach (var entry in layout.Entries)
            {
                ISymbolNode targetNode = entry.GetTarget(factory, typeInst, methodInst);
                builder.EmitPointerReloc(targetNode);
            }
        }
コード例 #44
0
 public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
 {
     ObjectDataBuilder objData = new ObjectDataBuilder(factory);
     objData.Alignment = factory.Target.PointerSize;
     objData.DefinedSymbols.Add(this);
     
     foreach (var map in _dispatchMaps)
     {
         objData.EmitPointerReloc(map);
     }
     
     return objData.ToObjectData();
 }
コード例 #45
0
        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();
        }
コード例 #46
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            ISymbolNode nameSymbol = factory.Target.IsWindows ?
                factory.ConstantUtf16String(_moduleName) :
                factory.ConstantUtf8String(_moduleName);

            //
            // Emit a ModuleFixupCell struct
            //

            builder.EmitZeroPointer();
            builder.EmitPointerReloc(nameSymbol);

            return builder.ToObjectData();
        }
コード例 #47
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            ObjectDataBuilder builder = new ObjectDataBuilder(factory);
            builder.DefinedSymbols.Add(this);

            //
            // Emit a ModuleFixupCell struct
            //

            builder.EmitZeroPointer();

            Encoding encoding = factory.Target.IsWindows ? Encoding.Unicode : Encoding.UTF8;

            int moduleNameBytesCount = encoding.GetByteCount(_moduleName);
            byte[] moduleNameBytes = new byte[moduleNameBytesCount + 2];
            encoding.GetBytes(_moduleName, 0, _moduleName.Length, moduleNameBytes, 0);
            builder.EmitPointerReloc(factory.ReadOnlyDataBlob("__modulename_" + _moduleName, moduleNameBytes, 2));

            return builder.ToObjectData();
        }
コード例 #48
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();
        }
コード例 #49
0
ファイル: EETypeNode.cs プロジェクト: justinvp/corert
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
        {
            ObjectDataBuilder objData = new ObjectDataBuilder(factory);
            objData.Alignment = objData.TargetPointerSize;
            objData.DefinedSymbols.Add(this);

            ComputeOptionalEETypeFields(factory);

            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 (!relocsOnly)
            {
                OutputVirtualSlotAndInterfaceCount(factory, ref objData);
            }

            objData.EmitInt(_type.GetHashCode());
            objData.EmitPointerReloc(factory.TypeManagerIndirection);
            
            // 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();
        }
コード例 #50
0
ファイル: GCStaticEETypeNode.cs プロジェクト: justinvp/corert
        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();
        }
コード例 #51
0
ファイル: EETypeNode.cs プロジェクト: modulexcite/corert
        private void OutputFinalizerMethod(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            MethodDesc finalizerMethod = _type.GetFinalizer();

            if (finalizerMethod != null)
            {
                objData.EmitPointerReloc(factory.MethodEntrypoint(finalizerMethod));
            }
        }
コード例 #52
0
ファイル: EETypeNode.cs プロジェクト: modulexcite/corert
 private void OutputOptionalFields(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     if(_optionalFieldsBuilder.IsAtLeastOneFieldUsed())
     {
         objData.EmitPointerReloc(factory.EETypeOptionalFields(_optionalFieldsBuilder));
     }
 }
コード例 #53
0
        public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
        {
            // This node does not trigger generation of other nodes.
            if (relocsOnly)
                return new ObjectData(Array.Empty<byte>(), Array.Empty<Relocation>(), 1, new ISymbolNode[] { this });

            ObjectDataBuilder builder = new ObjectDataBuilder(factory);

            foreach (var mappingEntry in factory.MetadataManager.GetTypeDefinitionMapping())
            {
                if (!factory.CompilationModuleGroup.ContainsType(mappingEntry.Entity))
                    continue;

                // We are looking for any EEType - constructed or not, it has to be in the mapping
                // table so that we can map it to metadata.
                EETypeNode node = null;
                
                if (!mappingEntry.Entity.IsGenericDefinition)
                {
                    node = factory.ConstructedTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }
                
                if (node == null || !node.Marked)
                {
                    // This might have been a typeof() expression.
                    node = factory.NecessaryTypeSymbol(mappingEntry.Entity) as EETypeNode;
                }

                if (node.Marked)
                {
                    // TODO: this format got very inefficient due to not being able to use RVAs
                    //       replace with a hash table

                    builder.EmitPointerReloc(node);
                    builder.EmitInt(mappingEntry.MetadataHandle);

                    if (factory.Target.PointerSize == 8)
                        builder.EmitInt(0); // Pad
                }
            }

            _endSymbol.SetSymbolOffset(builder.CountBytes);
            
            builder.DefinedSymbols.Add(this);
            builder.DefinedSymbols.Add(_endSymbol);

            return builder.ToObjectData();
        }
コード例 #54
0
ファイル: ConstructedEETypeNode.cs プロジェクト: hoyMS/corert
 protected override void OutputInterfaceMap(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     foreach (var itf in _type.RuntimeInterfaces)
     {
         objData.EmitPointerReloc(factory.NecessaryTypeSymbol(itf));
     }
 }
コード例 #55
0
ファイル: ConstructedEETypeNode.cs プロジェクト: hoyMS/corert
        protected override void OutputVirtualSlots(NodeFactory factory, ref ObjectDataBuilder objData, TypeDesc implType, TypeDesc declType)
        {
            declType = declType.GetClosestDefType();

            var baseType = declType.BaseType;
            if (baseType != null)
                OutputVirtualSlots(factory, ref objData, implType, baseType);

            // The generic dictionary pointer occupies the first slot of each type vtable slice
            if (declType.HasGenericDictionarySlot())
            {
                objData.EmitPointerReloc(factory.TypeGenericDictionary(declType));
            }

            // Actual vtable slots follow
            IReadOnlyList<MethodDesc> virtualSlots = factory.VTable(declType).Slots;

            for (int i = 0; i < virtualSlots.Count; i++)
            {
                MethodDesc declMethod = virtualSlots[i];
                MethodDesc implMethod = implType.GetClosestDefType().FindVirtualFunctionTargetMethodOnObjectType(declMethod);

                if (declMethod.HasInstantiation)
                {
                    // Generic virtual methods will "compile", but will fail to link. Check for it here.
                    throw new NotImplementedException("VTable for " + _type + " has generic virtual methods.");
                }

                if (!implMethod.IsAbstract)
                {
                    MethodDesc canonImplMethod = implMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    objData.EmitPointerReloc(factory.MethodEntrypoint(canonImplMethod, implMethod.OwningType.IsValueType));
                }
                else
                {
                    objData.EmitZeroPointer();
                }
            }
        }
コード例 #56
0
ファイル: EETypeNode.cs プロジェクト: justinvp/corert
        protected virtual void OutputRelatedType(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            ISymbolNode relatedTypeNode = null;

            if (_type.IsArray || _type.IsPointer || _type.IsByRef)
            {
                var parameterType = ((ParameterizedType)_type).ParameterType;
                relatedTypeNode = factory.NecessaryTypeSymbol(parameterType);
            }
            else
            {
                TypeDesc baseType = _type.BaseType;
                if (baseType != null)
                {
                    relatedTypeNode = GetBaseTypeNode(factory);
                }
            }

            if (relatedTypeNode != null)
            {
                objData.EmitPointerReloc(relatedTypeNode);
            }
            else
            {
                objData.EmitZeroPointer();
            }
        }
コード例 #57
0
ファイル: EETypeNode.cs プロジェクト: justinvp/corert
        private void OutputFinalizerMethod(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            MethodDesc finalizerMethod = _type.GetFinalizer();

            if (finalizerMethod != null)
            {
                MethodDesc canonFinalizerMethod = finalizerMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                objData.EmitPointerReloc(factory.MethodEntrypoint(canonFinalizerMethod));
            }
        }
コード例 #58
0
ファイル: EETypeNode.cs プロジェクト: justinvp/corert
 private void OutputOptionalFields(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     if (HasOptionalFields)
     {
         objData.EmitPointerReloc(_optionalFieldsNode);
     }
 }
コード例 #59
0
ファイル: EETypeNode.cs プロジェクト: justinvp/corert
 private void OutputNullableTypeParameter(NodeFactory factory, ref ObjectDataBuilder objData)
 {
     if (_type.IsNullable)
     {
         objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type.Instantiation[0]));
     }
 }
コード例 #60
0
ファイル: EETypeNode.cs プロジェクト: justinvp/corert
        private void OutputGenericInstantiationDetails(NodeFactory factory, ref ObjectDataBuilder objData)
        {
            if (_type.HasInstantiation && !_type.IsTypeDefinition)
            {
                objData.EmitPointerReloc(factory.NecessaryTypeSymbol(_type.GetTypeDefinition()));

                GenericCompositionDetails details;
                if (_type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType)
                {
                    // Generic array enumerators use special variance rules recognized by the runtime
                    details = new GenericCompositionDetails(_type.Instantiation, new[] { GenericVariance.ArrayCovariant });
                }
                else
                    details = new GenericCompositionDetails(_type);

                objData.EmitPointerReloc(factory.GenericComposition(details));
            }
        }