Files
swift-mirror/include/swift/Runtime/Metadata.h
Saleem Abdulrasool 5066729677 Runtime: remove keypath functions in the compiler build
The host tools may be built with the host compiler.  cl objects to the
"extern C" function returning a C++ type which the keypath functions do.
However, these declarations are needed only in the runtime, which is
always built with clang.  Preprocess away the declarations during the
build of the compiler.  This allows us to build with cl once more.
2019-02-25 11:21:28 -08:00

843 lines
33 KiB
C++

//===--- 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"
namespace swift {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
/// 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;
#include "swift/ABI/ValueWitness.def"
constexpr EnumValueWitnessTable()
: ValueWitnessTable{},
getEnumTag(nullptr),
destructiveProjectEnumData(nullptr),
destructiveInjectEnumTag(nullptr) {}
constexpr EnumValueWitnessTable(
const ValueWitnessTable &base,
ValueWitnessTypes::getEnumTag getEnumTag,
ValueWitnessTypes::destructiveProjectEnumData destructiveProjectEnumData,
ValueWitnessTypes::destructiveInjectEnumTag 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.
SWIFT_RUNTIME_EXPORT
bool equalContexts(const ContextDescriptor *a, const ContextDescriptor *b);
/// 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 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);
/// 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);
#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);
#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
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