| //===--- Metadata.h - Swift Language ABI Metadata Support -------*- C++ -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Swift runtime support for generating and uniquing metadata. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_RUNTIME_METADATA_H |
| #define SWIFT_RUNTIME_METADATA_H |
| |
| #include "swift/ABI/Metadata.h" |
| #include "swift/Reflection/Records.h" |
| #include "swift/Runtime/Once.h" |
| |
| namespace swift { |
| |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wreturn-type-c-linkage" |
| |
| // Tags used to denote different kinds of allocations made with the metadata |
| // allocator. This is encoded in a header on each allocation when metadata |
| // iteration is enabled, and allows tools to know where each allocation came |
| // from. |
| enum MetadataAllocatorTags : uint16_t { |
| #define TAG(name, value) name##Tag = value, |
| #include "../../../stdlib/public/runtime/MetadataAllocatorTags.def" |
| }; |
| |
| template <typename Runtime> struct MetadataAllocationBacktraceHeader { |
| TargetPointer<Runtime, const void> Next; |
| TargetPointer<Runtime, void> Allocation; |
| uint32_t Count; |
| // Count backtrace pointers immediately follow. |
| }; |
| |
| /// The buffer used by a yield-once coroutine (such as the generalized |
| /// accessors `read` and `modify`). |
| struct YieldOnceBuffer { |
| void *Data[NumWords_YieldOnceBuffer]; |
| }; |
| using YieldOnceContinuation = |
| SWIFT_CC(swift) void (YieldOnceBuffer *buffer, bool forUnwind); |
| |
| /// The return type of a call to a yield-once coroutine. The function |
| /// must be declared with the swiftcall calling convention. |
| template <class ResultTy> |
| struct YieldOnceResult { |
| YieldOnceContinuation *Continuation; |
| ResultTy YieldValue; |
| }; |
| |
| template <class FnTy> |
| struct YieldOnceCoroutine; |
| |
| /// A template which generates the type of the ramp function of a |
| /// yield-once coroutine. |
| template <class ResultTy, class... ArgTys> |
| struct YieldOnceCoroutine<ResultTy(ArgTys...)> { |
| using type = |
| SWIFT_CC(swift) YieldOnceResult<ResultTy> (YieldOnceBuffer *buffer, |
| ArgTys...); |
| }; |
| |
| #if SWIFT_OBJC_INTEROP |
| |
| // Const cast shorthands for ObjC types. |
| |
| /// Cast to id, discarding const if necessary. |
| template <typename T> |
| static inline id id_const_cast(const T* value) { |
| return reinterpret_cast<id>(const_cast<T*>(value)); |
| } |
| |
| /// Cast to Class, discarding const if necessary. |
| template <typename T> |
| static inline Class class_const_cast(const T* value) { |
| return reinterpret_cast<Class>(const_cast<T*>(value)); |
| } |
| |
| /// Cast to Protocol*, discarding const if necessary. |
| template <typename T> |
| static inline Protocol* protocol_const_cast(const T* value) { |
| return reinterpret_cast<Protocol *>(const_cast<T*>(value)); |
| } |
| |
| /// Cast from a CF type, discarding const if necessary. |
| template <typename T> |
| static inline T cf_const_cast(const void* value) { |
| return reinterpret_cast<T>(const_cast<void *>(value)); |
| } |
| |
| #endif |
| |
| /// A standard routine, suitable for placement in the value witness |
| /// table, for copying an opaque POD object. |
| SWIFT_RUNTIME_EXPORT |
| OpaqueValue *swift_copyPOD(OpaqueValue *dest, |
| OpaqueValue *src, |
| const Metadata *self); |
| |
| /// A value-witness table with enum entry points. |
| /// These entry points are available only if the HasEnumWitnesses flag bit is |
| /// set in the 'flags' field. |
| struct EnumValueWitnessTable : ValueWitnessTable { |
| #define WANT_ONLY_ENUM_VALUE_WITNESSES |
| #define VALUE_WITNESS(LOWER_ID, UPPER_ID) \ |
| ValueWitnessTypes::LOWER_ID LOWER_ID; |
| #define FUNCTION_VALUE_WITNESS(LOWER_ID, UPPER_ID, RET, PARAMS) \ |
| ValueWitnessTypes::LOWER_ID LOWER_ID; |
| |
| #include "swift/ABI/ValueWitness.def" |
| |
| constexpr EnumValueWitnessTable() |
| : ValueWitnessTable{}, |
| getEnumTag(nullptr), |
| destructiveProjectEnumData(nullptr), |
| destructiveInjectEnumTag(nullptr) {} |
| constexpr EnumValueWitnessTable( |
| const ValueWitnessTable &base, |
| ValueWitnessTypes::getEnumTagUnsigned getEnumTag, |
| ValueWitnessTypes::destructiveProjectEnumDataUnsigned |
| destructiveProjectEnumData, |
| ValueWitnessTypes::destructiveInjectEnumTagUnsigned |
| destructiveInjectEnumTag) |
| : ValueWitnessTable(base), |
| getEnumTag(getEnumTag), |
| destructiveProjectEnumData(destructiveProjectEnumData), |
| destructiveInjectEnumTag(destructiveInjectEnumTag) {} |
| |
| static bool classof(const ValueWitnessTable *table) { |
| return table->flags.hasEnumWitnesses(); |
| } |
| }; |
| |
| /// A type layout record. This is the subset of the value witness table that is |
| /// necessary to perform dependent layout of generic value types. It excludes |
| /// the value witness functions and includes only the size, alignment, |
| /// extra inhabitants, and miscellaneous flags about the type. |
| struct TypeLayout { |
| ValueWitnessTypes::size size; |
| ValueWitnessTypes::stride stride; |
| ValueWitnessTypes::flags flags; |
| ValueWitnessTypes::extraInhabitantCount extraInhabitantCount; |
| |
| private: |
| void _static_assert_layout(); |
| public: |
| TypeLayout() = default; |
| constexpr TypeLayout(ValueWitnessTypes::size size, |
| ValueWitnessTypes::stride stride, |
| ValueWitnessTypes::flags flags, |
| ValueWitnessTypes::extraInhabitantCount xiCount) |
| : size(size), stride(stride), flags(flags), extraInhabitantCount(xiCount) {} |
| |
| const TypeLayout *getTypeLayout() const { return this; } |
| |
| /// The number of extra inhabitants, that is, bit patterns that do not form |
| /// valid values of the type, in this type's binary representation. |
| unsigned getNumExtraInhabitants() const { |
| return extraInhabitantCount; |
| } |
| |
| bool hasExtraInhabitants() const { |
| return extraInhabitantCount != 0; |
| } |
| }; |
| |
| inline void TypeLayout::_static_assert_layout() { |
| #define CHECK_TYPE_LAYOUT_OFFSET(FIELD) \ |
| static_assert(offsetof(ValueWitnessTable, FIELD) \ |
| - offsetof(ValueWitnessTable, size) \ |
| == offsetof(TypeLayout, FIELD), \ |
| "layout of " #FIELD " in TypeLayout doesn't match " \ |
| "value witness table") |
| CHECK_TYPE_LAYOUT_OFFSET(size); |
| CHECK_TYPE_LAYOUT_OFFSET(flags); |
| CHECK_TYPE_LAYOUT_OFFSET(extraInhabitantCount); |
| CHECK_TYPE_LAYOUT_OFFSET(stride); |
| |
| #undef CHECK_TYPE_LAYOUT_OFFSET |
| } |
| |
| template <> |
| inline void ValueWitnessTable::publishLayout(const TypeLayout &layout) { |
| size = layout.size; |
| stride = layout.stride; |
| extraInhabitantCount = layout.extraInhabitantCount; |
| |
| // Currently there is nothing in the runtime or ABI which tries to |
| // asynchronously check completion, so we can just do a normal store here. |
| // |
| // If we decide to start allowing that (to speed up checkMetadataState, |
| // maybe), we'll have to: |
| // - turn this into an store-release, |
| // - turn the load in checkIsComplete() into a load-acquire, and |
| // - do something about getMutableVWTableForInit. |
| flags = layout.flags; |
| } |
| |
| template <> inline bool ValueWitnessTable::checkIsComplete() const { |
| return !flags.isIncomplete(); |
| } |
| |
| template <> |
| inline const EnumValueWitnessTable *ValueWitnessTable::_asEVWT() const { |
| assert(EnumValueWitnessTable::classof(this)); |
| return static_cast<const EnumValueWitnessTable *>(this); |
| } |
| |
| // Standard value-witness tables. |
| |
| #define BUILTIN_TYPE(Symbol, _) \ |
| SWIFT_RUNTIME_EXPORT const ValueWitnessTable VALUE_WITNESS_SYM(Symbol); |
| #define BUILTIN_POINTER_TYPE(Symbol, _) \ |
| SWIFT_RUNTIME_EXPORT const ValueWitnessTable VALUE_WITNESS_SYM(Symbol); |
| #include "swift/Runtime/BuiltinTypes.def" |
| |
| // The () -> () table can be used for arbitrary function types. |
| SWIFT_RUNTIME_EXPORT |
| const ValueWitnessTable |
| VALUE_WITNESS_SYM(FUNCTION_MANGLING); // () -> () |
| |
| // The @escaping () -> () table can be used for arbitrary escaping function types. |
| SWIFT_RUNTIME_EXPORT |
| const ValueWitnessTable |
| VALUE_WITNESS_SYM(NOESCAPE_FUNCTION_MANGLING); // @noescape () -> () |
| |
| // The @convention(thin) () -> () table can be used for arbitrary thin function types. |
| SWIFT_RUNTIME_EXPORT |
| const ValueWitnessTable |
| VALUE_WITNESS_SYM(THIN_FUNCTION_MANGLING); // @convention(thin) () -> () |
| |
| // The () table can be used for arbitrary empty types. |
| SWIFT_RUNTIME_EXPORT |
| const ValueWitnessTable VALUE_WITNESS_SYM(EMPTY_TUPLE_MANGLING); // () |
| |
| // The table for aligned-pointer-to-pointer types. |
| SWIFT_RUNTIME_EXPORT |
| const ValueWitnessTable METATYPE_VALUE_WITNESS_SYM(Bo); // Builtin.NativeObject.Type |
| |
| /// Return the value witnesses for unmanaged pointers. |
| static inline const ValueWitnessTable &getUnmanagedPointerValueWitnesses() { |
| #if __POINTER_WIDTH__ == 64 |
| return VALUE_WITNESS_SYM(Bi64_); |
| #else |
| return VALUE_WITNESS_SYM(Bi32_); |
| #endif |
| } |
| |
| /// Return value witnesses for a pointer-aligned pointer type. |
| static inline |
| const ValueWitnessTable & |
| getUnmanagedPointerPointerValueWitnesses() { |
| return METATYPE_VALUE_WITNESS_SYM(Bo); |
| } |
| |
| using OpaqueMetadata = TargetOpaqueMetadata<InProcess>; |
| |
| // Standard POD opaque metadata. |
| // The "Int" metadata are used for arbitrary POD data with the |
| // matching characteristics. |
| using FullOpaqueMetadata = FullMetadata<OpaqueMetadata>; |
| #define BUILTIN_TYPE(Symbol, Name) \ |
| SWIFT_RUNTIME_EXPORT \ |
| const FullOpaqueMetadata METADATA_SYM(Symbol); |
| #include "swift/Runtime/BuiltinTypes.def" |
| |
| /// The standard metadata for the empty tuple type. |
| SWIFT_RUNTIME_EXPORT |
| const |
| FullMetadata<TupleTypeMetadata> METADATA_SYM(EMPTY_TUPLE_MANGLING); |
| |
| /// The standard metadata for the empty protocol composition type, Any. |
| SWIFT_RUNTIME_EXPORT |
| const |
| FullMetadata<ExistentialTypeMetadata> METADATA_SYM(ANY_MANGLING); |
| |
| /// The standard metadata for the empty class-constrained protocol composition |
| /// type, AnyObject. |
| SWIFT_RUNTIME_EXPORT |
| const |
| FullMetadata<ExistentialTypeMetadata> METADATA_SYM(ANYOBJECT_MANGLING); |
| |
| |
| /// True if two context descriptors in the currently running program describe |
| /// the same context. |
| bool equalContexts(const ContextDescriptor *a, const ContextDescriptor *b); |
| |
| /// Determines whether two type context descriptors describe the same type |
| /// context. |
| /// |
| /// Runtime availability: Swift 5.4. |
| /// |
| /// \param lhs The first type context descriptor to compare. |
| /// \param rhs The second type context descriptor to compare. |
| /// |
| /// \returns true if both describe the same type context, false otherwise. |
| SWIFT_RUNTIME_EXPORT |
| SWIFT_CC(swift) |
| bool swift_compareTypeContextDescriptors(const TypeContextDescriptor *lhs, |
| const TypeContextDescriptor *rhs); |
| |
| /// Compute the bounds of class metadata with a resilient superclass. |
| ClassMetadataBounds getResilientMetadataBounds( |
| const ClassDescriptor *descriptor); |
| int32_t getResilientImmediateMembersOffset(const ClassDescriptor *descriptor); |
| |
| /// Fetch a uniqued metadata object for a nominal type which requires |
| /// singleton metadata initialization. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse |
| swift_getSingletonMetadata(MetadataRequest request, |
| const TypeContextDescriptor *description); |
| |
| /// Fetch a uniqued metadata object for the generic nominal type described by |
| /// the provided candidate metadata, using that candidate metadata if there is |
| /// not already a canonical metadata. |
| /// |
| /// Runtime availability: Swift 5.4 |
| /// |
| /// \param candidate A prespecialized metadata record for a type which is not |
| /// statically made to be canonical which will be canonicalized |
| /// if no other canonical metadata exists for the type. |
| /// \param cache A pointer to a cache which will be set to the canonical |
| /// metadata record for the type described by the candidate |
| /// metadata record. If the cache has already been populated, its |
| /// contents will be returned. |
| /// \returns The canonical metadata for the specialized generic type described |
| /// by the provided candidate metadata. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) MetadataResponse |
| swift_getCanonicalSpecializedMetadata(MetadataRequest request, |
| const Metadata *candidate, |
| const Metadata **cache); |
| |
| /// Fetch a uniqued metadata object for the generic nominal type described by |
| /// the provided description and arguments, adding the canonical |
| /// prespecializations attached to the type descriptor to the metadata cache on |
| /// first run. |
| /// |
| /// In contrast to swift_getGenericMetadata, this function is for use by |
| /// metadata accessors for which canonical generic metadata has been specialized |
| /// at compile time. |
| /// |
| /// Runtime availability: Swift 5.4 |
| /// |
| /// \param request A specification of the metadata to be returned. |
| /// \param arguments The generic arguments--metadata and witness tables--which |
| /// the returned metadata is to have been instantiated with. |
| /// \param description The type descriptor for the generic type whose |
| /// generic metadata is to have been instantiated. |
| /// \param token The token that ensures that prespecialized records are added to |
| /// the metadata cache only once. |
| /// \returns The canonical metadata for the specialized generic type described |
| /// by the provided candidate metadata. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) MetadataResponse |
| swift_getCanonicalPrespecializedGenericMetadata( |
| MetadataRequest request, const void *const *arguments, |
| const TypeContextDescriptor *description, swift_once_t *token); |
| |
| /// Fetch a uniqued metadata object for a generic nominal type. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse |
| swift_getGenericMetadata(MetadataRequest request, |
| const void * const *arguments, |
| const TypeContextDescriptor *description); |
| |
| /// Allocate a generic class metadata object. This is intended to be |
| /// called by the metadata instantiation function of a generic class. |
| /// |
| /// This function: |
| /// - computes the required size of the metadata object based on the |
| /// class hierarchy; |
| /// - allocates memory for the metadata object based on the computed |
| /// size and the additional requirements imposed by the pattern; |
| /// - copies information from the pattern into the allocated metadata; and |
| /// - fully initializes the ClassMetadata header, except that the |
| /// superclass pointer will be null (or SwiftObject under ObjC interop |
| /// if there is no formal superclass). |
| /// |
| /// The instantiation function is responsible for completing the |
| /// initialization, including: |
| /// - setting the superclass pointer; |
| /// - copying class data from the superclass; |
| /// - installing the generic arguments; |
| /// - installing new v-table entries and overrides; and |
| /// - registering the class with the runtime under ObjC interop. |
| /// Most of this work can be achieved by calling swift_initClassMetadata. |
| SWIFT_RUNTIME_EXPORT |
| ClassMetadata * |
| swift_allocateGenericClassMetadata(const ClassDescriptor *description, |
| const void *arguments, |
| const GenericClassMetadataPattern *pattern); |
| |
| /// Allocate a generic value metadata object. This is intended to be |
| /// called by the metadata instantiation function of a generic struct or |
| /// enum. |
| SWIFT_RUNTIME_EXPORT |
| ValueMetadata * |
| swift_allocateGenericValueMetadata(const ValueTypeDescriptor *description, |
| const void *arguments, |
| const GenericValueMetadataPattern *pattern, |
| size_t extraDataSize); |
| |
| /// Check that the given metadata has the right state. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse swift_checkMetadataState(MetadataRequest request, |
| const Metadata *type); |
| |
| /// Retrieve a witness table based on a given conformance. |
| /// |
| /// \param conformance - The protocol conformance descriptor, which |
| /// contains any information required to form the witness table. |
| /// |
| /// \param type - The conforming type, used to form a uniquing key |
| /// for the conformance. |
| /// |
| /// \param instantiationArgs - An opaque pointer that's forwarded to |
| /// the instantiation function, used for conditional conformances. |
| /// This API implicitly embeds an assumption that these arguments |
| /// never form part of the uniquing key for the conformance, which |
| /// is ultimately a statement about the user model of overlapping |
| /// conformances. |
| SWIFT_RUNTIME_EXPORT |
| const WitnessTable * |
| swift_getWitnessTable(const ProtocolConformanceDescriptor *conformance, |
| const Metadata *type, |
| const void * const *instantiationArgs); |
| |
| /// Retrieve an associated type witness from the given witness table. |
| /// |
| /// \param wtable The witness table. |
| /// \param conformingType Metadata for the conforming type. |
| /// \param reqBase "Base" requirement used to compute the witness index |
| /// \param assocType Associated type descriptor. |
| /// |
| /// \returns metadata for the associated type witness. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse swift_getAssociatedTypeWitness( |
| MetadataRequest request, |
| WitnessTable *wtable, |
| const Metadata *conformingType, |
| const ProtocolRequirement *reqBase, |
| const ProtocolRequirement *assocType); |
| |
| /// Retrieve an associated conformance witness table from the given witness |
| /// table. |
| /// |
| /// \param wtable The witness table. |
| /// \param conformingType Metadata for the conforming type. |
| /// \param assocType Metadata for the associated type. |
| /// \param reqBase "Base" requirement used to compute the witness index |
| /// \param assocConformance Associated conformance descriptor. |
| /// |
| /// \returns corresponding witness table. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| const WitnessTable *swift_getAssociatedConformanceWitness( |
| WitnessTable *wtable, |
| const Metadata *conformingType, |
| const Metadata *assocType, |
| const ProtocolRequirement *reqBase, |
| const ProtocolRequirement *assocConformance); |
| |
| /// Determine whether two protocol conformance descriptors describe the same |
| /// conformance of a type to a protocol. |
| /// |
| /// Runtime availability: Swift 5.4 |
| /// |
| /// \param lhs The first protocol conformance descriptor to compare. |
| /// \param rhs The second protocol conformance descriptor to compare. |
| /// |
| /// \returns true if both describe the same conformance, false otherwise. |
| SWIFT_RUNTIME_EXPORT |
| SWIFT_CC(swift) |
| bool swift_compareProtocolConformanceDescriptors( |
| const ProtocolConformanceDescriptor *lhs, |
| const ProtocolConformanceDescriptor *rhs); |
| |
| /// Fetch a uniqued metadata for a function type. |
| SWIFT_RUNTIME_EXPORT |
| const FunctionTypeMetadata * |
| swift_getFunctionTypeMetadata(FunctionTypeFlags flags, |
| const Metadata *const *parameters, |
| const uint32_t *parameterFlags, |
| const Metadata *result); |
| |
| SWIFT_RUNTIME_EXPORT |
| const FunctionTypeMetadata * |
| swift_getFunctionTypeMetadata0(FunctionTypeFlags flags, |
| const Metadata *result); |
| |
| SWIFT_RUNTIME_EXPORT |
| const FunctionTypeMetadata * |
| swift_getFunctionTypeMetadata1(FunctionTypeFlags flags, |
| const Metadata *arg0, |
| const Metadata *result); |
| |
| SWIFT_RUNTIME_EXPORT |
| const FunctionTypeMetadata * |
| swift_getFunctionTypeMetadata2(FunctionTypeFlags flags, |
| const Metadata *arg0, |
| const Metadata *arg1, |
| const Metadata *result); |
| |
| SWIFT_RUNTIME_EXPORT |
| const FunctionTypeMetadata *swift_getFunctionTypeMetadata3( |
| FunctionTypeFlags flags, |
| const Metadata *arg0, |
| const Metadata *arg1, |
| const Metadata *arg2, |
| const Metadata *result); |
| |
| #if SWIFT_OBJC_INTEROP |
| SWIFT_RUNTIME_EXPORT |
| void |
| swift_instantiateObjCClass(const ClassMetadata *theClass); |
| |
| SWIFT_RUNTIME_EXPORT |
| Class |
| swift_getInitializedObjCClass(Class c); |
| |
| /// Fetch a uniqued type metadata for an ObjC class. |
| SWIFT_RUNTIME_EXPORT |
| const Metadata * |
| swift_getObjCClassMetadata(const ClassMetadata *theClass); |
| |
| /// Get the ObjC class object from class type metadata. |
| SWIFT_RUNTIME_EXPORT |
| const ClassMetadata * |
| swift_getObjCClassFromMetadata(const Metadata *theClass); |
| |
| // Get the ObjC class object from class type metadata, |
| // or nullptr if the type isn't an ObjC class. |
| const ClassMetadata * |
| swift_getObjCClassFromMetadataConditional(const Metadata *theClass); |
| |
| SWIFT_RUNTIME_EXPORT |
| const ClassMetadata * |
| swift_getObjCClassFromObject(HeapObject *object); |
| #endif |
| |
| /// Fetch a unique type metadata object for a foreign type. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse |
| swift_getForeignTypeMetadata(MetadataRequest request, |
| ForeignTypeMetadata *nonUnique); |
| |
| /// Fetch a uniqued metadata for a tuple type. |
| /// |
| /// The labels argument is null if and only if there are no element |
| /// labels in the tuple. Otherwise, it is a null-terminated |
| /// concatenation of space-terminated NFC-normalized UTF-8 strings, |
| /// assumed to point to constant global memory. |
| /// |
| /// That is, for the tuple type (a : Int, Int, c : Int), this |
| /// argument should be: |
| /// "a c \0" |
| /// |
| /// This representation allows label strings to be efficiently |
| /// (1) uniqued within a linkage unit and (2) compared with strcmp. |
| /// In other words, it's optimized for code size and uniquing |
| /// efficiency, not for the convenience of actually consuming |
| /// these strings. |
| /// |
| /// \param elements - potentially invalid if numElements is zero; |
| /// otherwise, an array of metadata pointers. |
| /// \param labels - the labels string |
| /// \param proposedWitnesses - an optional proposed set of value witnesses. |
| /// This is useful when working with a non-dependent tuple type |
| /// where the entrypoint is just being used to unique the metadata. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse |
| swift_getTupleTypeMetadata(MetadataRequest request, |
| TupleTypeFlags flags, |
| const Metadata * const *elements, |
| const char *labels, |
| const ValueWitnessTable *proposedWitnesses); |
| |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse |
| swift_getTupleTypeMetadata2(MetadataRequest request, |
| const Metadata *elt0, const Metadata *elt1, |
| const char *labels, |
| const ValueWitnessTable *proposedWitnesses); |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataResponse |
| swift_getTupleTypeMetadata3(MetadataRequest request, |
| const Metadata *elt0, const Metadata *elt1, |
| const Metadata *elt2, const char *labels, |
| const ValueWitnessTable *proposedWitnesses); |
| |
| /// Perform layout as if for a tuple whose elements have the given layouts. |
| /// |
| /// \param tupleLayout - A structure into which to write the tuple layout. |
| /// Must be non-null. |
| /// \param elementOffsets - An array into which to write the offsets of |
| /// the elements. May be null. Must have space for all elements, |
| /// including element 0 (which will always have offset 0). |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| void swift_getTupleTypeLayout(TypeLayout *tupleLayout, |
| uint32_t *elementOffsets, |
| TupleTypeFlags flags, |
| const TypeLayout * const *elements); |
| |
| /// Perform layout as if for a two-element tuple whose elements have |
| /// the given layouts. |
| /// |
| /// \param tupleLayout - A structure into which to write the tuple layout. |
| /// Must be non-null. |
| /// \returns The offset of the second element. |
| /// The first element always has offset 0. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| size_t swift_getTupleTypeLayout2(TypeLayout *tupleLayout, |
| const TypeLayout *elt0, |
| const TypeLayout *elt1); |
| |
| struct OffsetPair { size_t First; size_t Second; }; |
| |
| /// Perform layout as if for a three-element tuple whose elements have |
| /// the given layouts. |
| /// |
| /// \param tupleLayout - A structure into which to write the tuple layout. |
| /// Must be non-null. |
| /// \returns The offsets of the second and third elements. |
| /// The first element always has offset 0. |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| OffsetPair swift_getTupleTypeLayout3(TypeLayout *tupleLayout, |
| const TypeLayout *elt0Layout, |
| const TypeLayout *elt1Layout, |
| const TypeLayout *elt2Layout); |
| |
| /// Initialize the value witness table and struct field offset vector for a |
| /// struct, using the "Universal" layout strategy. |
| SWIFT_RUNTIME_EXPORT |
| void swift_initStructMetadata(StructMetadata *self, |
| StructLayoutFlags flags, |
| size_t numFields, |
| const TypeLayout * const *fieldTypes, |
| uint32_t *fieldOffsets); |
| |
| /// Allocate the metadata for a class and copy fields from the given pattern. |
| /// The final size of the metadata is calculated at runtime from the metadata |
| /// bounds in the class descriptor. |
| /// |
| /// This function is only intended to be called from the relocation function |
| /// of a resilient class pattern. |
| /// |
| /// The metadata completion function must complete the metadata by calling |
| /// swift_initClassMetadata(). |
| SWIFT_RUNTIME_EXPORT |
| ClassMetadata * |
| swift_relocateClassMetadata(const ClassDescriptor *descriptor, |
| const ResilientClassMetadataPattern *pattern); |
| |
| /// Initialize various fields of the class metadata. |
| /// |
| /// Namely: |
| /// - The superclass field is set to \p super. |
| /// - If the class metadata was allocated at runtime, copies the |
| /// vtable entries from the superclass and installs the class's |
| /// own vtable entries and overrides of superclass vtable entries. |
| /// - Copies the field offsets and generic parameters and conformances |
| /// from the superclass. |
| /// - Initializes the field offsets using the runtime type layouts |
| /// passed in \p fieldTypes. |
| /// |
| /// This initialization pattern in the following cases: |
| /// - The class has generic ancestry, or resiliently-sized fields. |
| /// In this case the metadata was emitted statically but is incomplete, |
| /// because, the superclass field, generic parameters and conformances, |
| /// and field offset vector entries require runtime completion. |
| /// |
| /// - The class is not generic, and has resilient ancestry. |
| /// In this case the class metadata was allocated from a resilient |
| /// class metadata pattern by swift_relocateClassMetadata(). |
| /// |
| /// - The class is generic. |
| /// In this case the class metadata was allocated from a generic |
| /// class metadata pattern by swift_allocateGenericClassMetadata(). |
| SWIFT_RUNTIME_EXPORT |
| void swift_initClassMetadata(ClassMetadata *self, |
| ClassLayoutFlags flags, |
| size_t numFields, |
| const TypeLayout * const *fieldTypes, |
| size_t *fieldOffsets); |
| |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataDependency |
| swift_initClassMetadata2(ClassMetadata *self, |
| ClassLayoutFlags flags, |
| size_t numFields, |
| const TypeLayout * const *fieldTypes, |
| size_t *fieldOffsets); |
| |
| #if SWIFT_OBJC_INTEROP |
| /// Initialize various fields of the class metadata. |
| /// |
| /// This is a special function only used to re-initialize metadata of |
| /// classes that are visible to Objective-C and have resilient fields. |
| /// |
| /// This means the class does not have generic or resilient ancestry, |
| /// and is itself not generic. However, it might have fields whose |
| /// size is not known at compile time. |
| SWIFT_RUNTIME_EXPORT |
| void swift_updateClassMetadata(ClassMetadata *self, |
| ClassLayoutFlags flags, |
| size_t numFields, |
| const TypeLayout * const *fieldTypes, |
| size_t *fieldOffsets); |
| |
| SWIFT_RUNTIME_EXPORT SWIFT_CC(swift) |
| MetadataDependency |
| swift_updateClassMetadata2(ClassMetadata *self, |
| ClassLayoutFlags flags, |
| size_t numFields, |
| const TypeLayout * const *fieldTypes, |
| size_t *fieldOffsets); |
| #endif |
| |
| /// Given class metadata, a class descriptor and a method descriptor, look up |
| /// and load the vtable entry from the given metadata. The metadata must be of |
| /// the same class or a subclass of the descriptor. |
| SWIFT_RUNTIME_EXPORT |
| void * |
| swift_lookUpClassMethod(const ClassMetadata *metadata, |
| const MethodDescriptor *method, |
| const ClassDescriptor *description); |
| |
| /// Fetch a uniqued metadata for a metatype type. |
| SWIFT_RUNTIME_EXPORT |
| const MetatypeMetadata * |
| swift_getMetatypeMetadata(const Metadata *instanceType); |
| |
| /// Fetch a uniqued metadata for an existential metatype type. |
| SWIFT_RUNTIME_EXPORT |
| const ExistentialMetatypeMetadata * |
| swift_getExistentialMetatypeMetadata(const Metadata *instanceType); |
| |
| /// Fetch a uniqued metadata for an existential type. The array |
| /// referenced by \c protocols will be sorted in-place. |
| SWIFT_RUNTIME_EXPORT |
| const ExistentialTypeMetadata * |
| swift_getExistentialTypeMetadata(ProtocolClassConstraint classConstraint, |
| const Metadata *superclassConstraint, |
| size_t numProtocols, |
| const ProtocolDescriptorRef *protocols); |
| |
| /// Perform a copy-assignment from one existential container to another. |
| /// Both containers must be of the same existential type representable with the |
| /// same number of witness tables. |
| SWIFT_RUNTIME_EXPORT |
| OpaqueValue *swift_assignExistentialWithCopy(OpaqueValue *dest, |
| const OpaqueValue *src, |
| const Metadata *type); |
| |
| /// Perform a copy-assignment from one existential container to another. |
| /// Both containers must be of the same existential type representable with no |
| /// witness tables. |
| OpaqueValue *swift_assignExistentialWithCopy0(OpaqueValue *dest, |
| const OpaqueValue *src, |
| const Metadata *type); |
| |
| /// Perform a copy-assignment from one existential container to another. |
| /// Both containers must be of the same existential type representable with one |
| /// witness table. |
| OpaqueValue *swift_assignExistentialWithCopy1(OpaqueValue *dest, |
| const OpaqueValue *src, |
| const Metadata *type); |
| |
| /// Calculate the numeric index of an extra inhabitant of a heap object |
| /// pointer in memory. |
| inline int swift_getHeapObjectExtraInhabitantIndex(HeapObject * const* src) { |
| // This must be consistent with the getHeapObjectExtraInhabitantIndex |
| // implementation in IRGen's ExtraInhabitants.cpp. |
| |
| using namespace heap_object_abi; |
| |
| uintptr_t value = reinterpret_cast<uintptr_t>(*src); |
| if (value >= LeastValidPointerValue) |
| return -1; |
| |
| // Check for tagged pointers on appropriate platforms. Knowing that |
| // value < LeastValidPointerValue tells us a lot. |
| #if SWIFT_OBJC_INTEROP |
| if (value & ((uintptr_t(1) << ObjCReservedLowBits) - 1)) |
| return -1; |
| return int(value >> ObjCReservedLowBits); |
| #else |
| return int(value); |
| #endif |
| } |
| |
| /// Store an extra inhabitant of a heap object pointer to memory, |
| /// in the style of a value witness. |
| inline void swift_storeHeapObjectExtraInhabitant(HeapObject **dest, int index) { |
| // This must be consistent with the storeHeapObjectExtraInhabitant |
| // implementation in IRGen's ExtraInhabitants.cpp. |
| |
| #if SWIFT_OBJC_INTEROP |
| auto value = uintptr_t(index) << heap_object_abi::ObjCReservedLowBits; |
| #else |
| auto value = uintptr_t(index); |
| #endif |
| *dest = reinterpret_cast<HeapObject*>(value); |
| } |
| |
| /// Return the number of extra inhabitants in a heap object pointer. |
| inline constexpr unsigned swift_getHeapObjectExtraInhabitantCount() { |
| // This must be consistent with the getHeapObjectExtraInhabitantCount |
| // implementation in IRGen's ExtraInhabitants.cpp. |
| |
| using namespace heap_object_abi; |
| |
| // The runtime needs no more than INT_MAX inhabitants. |
| #if SWIFT_OBJC_INTEROP |
| return (LeastValidPointerValue >> ObjCReservedLowBits) > INT_MAX |
| ? (unsigned)INT_MAX |
| : (unsigned)(LeastValidPointerValue >> ObjCReservedLowBits); |
| #else |
| return (LeastValidPointerValue) > INT_MAX |
| ? unsigned(INT_MAX) |
| : unsigned(LeastValidPointerValue); |
| #endif |
| } |
| |
| /// Calculate the numeric index of an extra inhabitant of a function |
| /// pointer in memory. |
| inline int swift_getFunctionPointerExtraInhabitantIndex(void * const* src) { |
| // This must be consistent with the getFunctionPointerExtraInhabitantIndex |
| // implementation in IRGen's ExtraInhabitants.cpp. |
| uintptr_t value = reinterpret_cast<uintptr_t>(*src); |
| return (value < heap_object_abi::LeastValidPointerValue |
| ? (int) value : -1); |
| } |
| |
| /// Store an extra inhabitant of a function pointer to memory, in the |
| /// style of a value witness. |
| inline void swift_storeFunctionPointerExtraInhabitant(void **dest, int index) { |
| // This must be consistent with the storeFunctionPointerExtraInhabitantIndex |
| // implementation in IRGen's ExtraInhabitants.cpp. |
| *dest = reinterpret_cast<void*>(static_cast<uintptr_t>(index)); |
| } |
| |
| /// Return the number of extra inhabitants in a function pointer. |
| inline constexpr unsigned swift_getFunctionPointerExtraInhabitantCount() { |
| // This must be consistent with the getFunctionPointerExtraInhabitantCount |
| // implementation in IRGen's ExtraInhabitants.cpp. |
| |
| using namespace heap_object_abi; |
| |
| // The runtime needs no more than INT_MAX inhabitants. |
| return (LeastValidPointerValue) > INT_MAX |
| ? (unsigned)INT_MAX |
| : (unsigned)(LeastValidPointerValue); |
| } |
| |
| /// Return the type name for a given type metadata. |
| std::string nameForMetadata(const Metadata *type, |
| bool qualified = true); |
| |
| /// Register a block of protocol records for dynamic lookup. |
| SWIFT_RUNTIME_EXPORT |
| void swift_registerProtocols(const ProtocolRecord *begin, |
| const ProtocolRecord *end); |
| |
| /// Register a block of protocol conformance records for dynamic lookup. |
| SWIFT_RUNTIME_EXPORT |
| void swift_registerProtocolConformances(const ProtocolConformanceRecord *begin, |
| const ProtocolConformanceRecord *end); |
| |
| /// Register a block of type context descriptors for dynamic lookup. |
| SWIFT_RUNTIME_EXPORT |
| void swift_registerTypeMetadataRecords(const TypeMetadataRecord *begin, |
| const TypeMetadataRecord *end); |
| |
| /// Return the superclass, if any. The result is nullptr for root |
| /// classes and class protocol types. |
| SWIFT_CC(swift) |
| SWIFT_RUNTIME_STDLIB_INTERNAL |
| const Metadata *_swift_class_getSuperclass(const Metadata *theClass); |
| |
| SWIFT_CC(swift) |
| SWIFT_RUNTIME_STDLIB_INTERNAL MetadataResponse |
| getSuperclassMetadata(MetadataRequest request, const ClassMetadata *self); |
| |
| #if !NDEBUG |
| /// Verify that the given metadata pointer correctly roundtrips its |
| /// mangled name through the demangler. |
| void verifyMangledNameRoundtrip(const Metadata *metadata); |
| #endif |
| |
| SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API |
| const TypeContextDescriptor *swift_getTypeContextDescriptor(const Metadata *type); |
| |
| // Defined in KeyPath.swift in the standard library. |
| SWIFT_RUNTIME_EXPORT |
| const HeapObject *swift_getKeyPath(const void *pattern, const void *arguments); |
| |
| // For some reason, MSVC doesn't accept these declarations outside of |
| // swiftCore. TODO: figure out a reasonable way to declare them. |
| #if defined(swiftCore_EXPORTS) |
| |
| /// Given a pointer to a borrowed value of type `Root` and a |
| /// `KeyPath<Root, Value>`, project a pointer to a borrowed value of type |
| /// `Value`. |
| SWIFT_RUNTIME_EXPORT |
| YieldOnceCoroutine<const OpaqueValue* (const OpaqueValue *root, |
| void *keyPath)>::type |
| swift_readAtKeyPath; |
| |
| /// Given a pointer to a mutable value of type `Root` and a |
| /// `WritableKeyPath<Root, Value>`, project a pointer to a mutable value |
| /// of type `Value`. |
| SWIFT_RUNTIME_EXPORT |
| YieldOnceCoroutine<OpaqueValue* (OpaqueValue *root, void *keyPath)>::type |
| swift_modifyAtWritableKeyPath; |
| |
| /// Given a pointer to a borrowed value of type `Root` and a |
| /// `ReferenceWritableKeyPath<Root, Value>`, project a pointer to a |
| /// mutable value of type `Value`. |
| SWIFT_RUNTIME_EXPORT |
| YieldOnceCoroutine<OpaqueValue* (const OpaqueValue *root, void *keyPath)>::type |
| swift_modifyAtReferenceWritableKeyPath; |
| |
| #endif // swiftCore_EXPORTS |
| |
| SWIFT_RUNTIME_EXPORT |
| void swift_enableDynamicReplacementScope(const DynamicReplacementScope *scope); |
| |
| SWIFT_RUNTIME_EXPORT |
| void swift_disableDynamicReplacementScope(const DynamicReplacementScope *scope); |
| |
| #pragma clang diagnostic pop |
| |
| } // end namespace swift |
| |
| #endif // SWIFT_RUNTIME_METADATA_H |