//===--- ValueWitness.def - Value witness x-macros --------------*- 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 // //===----------------------------------------------------------------------===// // // X-macro definition file for value witness tables. // //===----------------------------------------------------------------------===// // This file is "parameterized" in the sense that exactly one of the // following macros *must* be defined: /// WANT_ALL_VALUE_WITNESSES /// Define this to expand all value witnesses, not just the ones from /// a specific category. #if defined(WANT_ALL_VALUE_WITNESSES) #undef WANT_ALL_VALUE_WITNESSES #define WANT_REQUIRED_VALUE_WITNESSES 1 #define WANT_ENUM_VALUE_WITNESSES 1 /// WANT_ONLY_REQUIRED_VALUE_WITNESSES /// Define this to expand only the required value witnesses. #elif defined(WANT_ONLY_REQUIRED_VALUE_WITNESSES) #undef WANT_ONLY_REQUIRED_VALUE_WITNESSES #define WANT_REQUIRED_VALUE_WITNESSES 1 #define WANT_ENUM_VALUE_WITNESSES 0 /// WANT_ONLY_ENUM_VALUE_WITNESSES /// Define this to expand only the enum value witnesses. #elif defined(WANT_ONLY_ENUM_VALUE_WITNESSES) #undef WANT_ONLY_ENUM_VALUE_WITNESSES #define WANT_REQUIRED_VALUE_WITNESSES 0 #define WANT_ENUM_VALUE_WITNESSES 1 /// WANT_REQUIRED_VALUE_WITNESSES /// WANT_ENUM_VALUE_WITNESSES /// Define all of these to control exactly what to expand. #else #if !defined(WANT_REQUIRED_VALUE_WITNESSES) || !defined(WANT_ENUM_VALUE_WITNESSES) #error failed to define a WANT macro; possible typo? #endif #endif /// VALUE_WITNESS(lowerId, upperId) /// A fallback called for value witnesses if either of DATA_VALUE_WITNESS or /// FUNCTION_VALUE_WITNESS is not defined. /// FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypeList) /// A function value witness. Types will be defined in terms of the /// following macros: /// MUTABLE_VALUE_TYPE - a pointer to a mutable opaque value /// IMMUTABLE_VALUE_TYPE - a pointer to an immutable opaque value /// MUTABLE_BUFFER_TYPE - a pointer to a fixed-size value buffer /// IMMUTABLE_BUFFER_TYPE - a pointer to an immutable fixed-size buffer /// TYPE_TYPE - a pointer to type metadata /// SIZE_TYPE - StoredSize /// INT_TYPE - int /// UINT_TYPE - unsigned int /// VOID_TYPE - void /// Defaults to VALUE_WITNESS. /// FIXME: The 'copy' witnesses should be using immutable types but aren't. #ifndef FUNCTION_VALUE_WITNESS #define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \ VALUE_WITNESS(lowerId, upperId) #endif /// DATA_VALUE_WITNESS(lowerId, upperId, type) /// A non-function value witness. Types are specified as for /// FUNCTION_VALUE_WITNESS /// Defaults to VALUE_WITNESS. #ifndef DATA_VALUE_WITNESS #define DATA_VALUE_WITNESS(lowerId, upperId, type) \ VALUE_WITNESS(lowerId, upperId) #endif /// Begin a range of value witnesses. This will be expanded immediately /// after the first value in the range, whose ID will be upperId. /// Range expansions do not interact well with the use of WANT_ONLY_*. #ifndef BEGIN_VALUE_WITNESS_RANGE #define BEGIN_VALUE_WITNESS_RANGE(rangeId, upperId) #endif /// End a range of value witnesses. This will be expanded immediately /// after the last value in the range, whose ID will be upperId. /// Range expansions do not interact well with the use of WANT_ONLY_*. #ifndef END_VALUE_WITNESS_RANGE #define END_VALUE_WITNESS_RANGE(rangeId, upperId) #endif #if WANT_REQUIRED_VALUE_WITNESSES /// T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self); /// Given an invalid buffer, initialize it as a copy of the /// object in the source buffer. FUNCTION_VALUE_WITNESS(initializeBufferWithCopyOfBuffer, InitializeBufferWithCopyOfBuffer, MUTABLE_VALUE_TYPE, (MUTABLE_BUFFER_TYPE, MUTABLE_BUFFER_TYPE, TYPE_TYPE)) BEGIN_VALUE_WITNESS_RANGE(ValueWitness, InitializeBufferWithCopyOfBuffer) BEGIN_VALUE_WITNESS_RANGE(RequiredValueWitness, InitializeBufferWithCopyOfBuffer) BEGIN_VALUE_WITNESS_RANGE(RequiredValueWitnessFunction, InitializeBufferWithCopyOfBuffer) /// void (*destroy)(T *object, witness_t *self); /// /// Given a valid object of this type, destroy it, leaving it as an /// invalid object. This is useful when generically destroying /// an object which has been allocated in-line, such as an array, /// struct, or tuple element. FUNCTION_VALUE_WITNESS(destroy, Destroy, VOID_TYPE, (MUTABLE_VALUE_TYPE, TYPE_TYPE)) /// T *(*initializeWithCopy)(T *dest, T *src, M *self); /// /// Given an invalid object of this type, initialize it as a copy of /// the source object. Returns the dest object. FUNCTION_VALUE_WITNESS(initializeWithCopy, InitializeWithCopy, MUTABLE_VALUE_TYPE, (MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE)) /// T *(*assignWithCopy)(T *dest, T *src, M *self); /// /// Given a valid object of this type, change it to be a copy of the /// source object. Returns the dest object. FUNCTION_VALUE_WITNESS(assignWithCopy, AssignWithCopy, MUTABLE_VALUE_TYPE, (MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE)) /// T *(*initializeWithTake)(T *dest, T *src, M *self); /// /// Given an invalid object of this type, initialize it by taking /// the value of the source object. The source object becomes /// invalid. Returns the dest object. FUNCTION_VALUE_WITNESS(initializeWithTake, InitializeWithTake, MUTABLE_VALUE_TYPE, (MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE)) /// T *(*assignWithTake)(T *dest, T *src, M *self); /// /// Given a valid object of this type, change it to be a copy of the /// source object. The source object becomes invalid. Returns the /// dest object. FUNCTION_VALUE_WITNESS(assignWithTake, AssignWithTake, MUTABLE_VALUE_TYPE, (MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE)) /// unsigned (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases, /// M *self); /// Given an instance of valid single payload enum with a payload of this /// witness table's type (e.g Optional) , get the tag of the enum. FUNCTION_VALUE_WITNESS(getEnumTagSinglePayload, GetEnumTagSinglePayload, UINT_TYPE, (IMMUTABLE_VALUE_TYPE, UINT_TYPE, TYPE_TYPE)) /// void (*storeEnumTagSinglePayload)(T* enum, UINT_TYPE whichCase, /// UINT_TYPE emptyCases, M *self); /// Given uninitialized memory for an instance of a single payload enum with a /// payload of this witness table's type (e.g Optional), store the /// tag. FUNCTION_VALUE_WITNESS(storeEnumTagSinglePayload, StoreEnumTagSinglePayload, VOID_TYPE, (MUTABLE_VALUE_TYPE, UINT_TYPE, UINT_TYPE, TYPE_TYPE)) END_VALUE_WITNESS_RANGE(RequiredValueWitnessFunction, StoreEnumTagSinglePayload) /// SIZE_TYPE size; /// /// The required storage size of a single object of this type. DATA_VALUE_WITNESS(size, Size, SIZE_TYPE) BEGIN_VALUE_WITNESS_RANGE(TypeLayoutWitness, Size) BEGIN_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness, Size) /// SIZE_TYPE stride; /// /// The required size per element of an array of this type. It is at least /// one, even for zero-sized types, like the empty tuple. DATA_VALUE_WITNESS(stride, Stride, SIZE_TYPE) /// UINT_TYPE flags; /// /// The ValueWitnessAlignmentMask bits represent the required /// alignment of the first byte of an object of this type, expressed /// as a mask of the low bits that must not be set in the pointer. /// This representation can be easily converted to the 'alignof' /// result by merely adding 1, but it is more directly useful for /// performing dynamic structure layouts, and it grants an /// additional bit of precision in a compact field without needing /// to switch to an exponent representation. /// /// The ValueWitnessIsNonPOD bit is set if the type is not POD. /// /// The ValueWitnessIsNonInline bit is set if the type cannot be /// represented in a fixed-size buffer or if it is not bitwise takable. /// /// The ExtraInhabitantsMask bits represent the number of "extra inhabitants" /// of the bit representation of the value that do not form valid values of /// the type. /// /// The Enum_HasSpareBits bit is set if the type's binary representation /// has unused bits. /// /// The HasEnumWitnesses bit is set if the type is an enum type. DATA_VALUE_WITNESS(flags, Flags, UINT_TYPE) /// UINT_TYPE extraInhabitantCount; /// /// The number of extra inhabitants in the type. DATA_VALUE_WITNESS(extraInhabitantCount, ExtraInhabitantCount, UINT_TYPE) END_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness, ExtraInhabitantCount) END_VALUE_WITNESS_RANGE(RequiredValueWitness, ExtraInhabitantCount) END_VALUE_WITNESS_RANGE(TypeLayoutWitness, ExtraInhabitantCount) #endif /* WANT_REQUIRED_VALUE_WITNESSES */ #if WANT_ENUM_VALUE_WITNESSES // The following value witnesses are conditionally present if the witnessed // type is an enum. /// unsigned (*getEnumTag)(T *obj, M *self); /// /// Given a valid object of this enum type, extracts the tag value indicating /// which case of the enum is inhabited. Returned values are in the range /// [0..NumElements-1]. FUNCTION_VALUE_WITNESS(getEnumTag, GetEnumTag, UINT_TYPE, (IMMUTABLE_VALUE_TYPE, TYPE_TYPE)) BEGIN_VALUE_WITNESS_RANGE(EnumValueWitness, GetEnumTag) /// void (*destructiveProjectEnumData)(T *obj, M *self); /// Given a valid object of this enum type, destructively extracts the /// associated payload. FUNCTION_VALUE_WITNESS(destructiveProjectEnumData, DestructiveProjectEnumData, VOID_TYPE, (MUTABLE_VALUE_TYPE, TYPE_TYPE)) /// void (*destructiveInjectEnumTag)(T *obj, unsigned tag, M *self); /// Given an enum case tag and a valid object of case's payload type, /// destructively inserts the tag into the payload. The given tag value /// must be in the range [-ElementsWithPayload..ElementsWithNoPayload-1]. FUNCTION_VALUE_WITNESS(destructiveInjectEnumTag, DestructiveInjectEnumTag, VOID_TYPE, (MUTABLE_VALUE_TYPE, UINT_TYPE, TYPE_TYPE)) END_VALUE_WITNESS_RANGE(EnumValueWitness, DestructiveInjectEnumTag) END_VALUE_WITNESS_RANGE(ValueWitness, DestructiveInjectEnumTag) #endif /* WANT_ENUM_VALUE_WITNESSES */ #undef MUTABLE_VALUE_TYPE #undef IMMUTABLE_VALUE_TYPE #undef MUTABLE_BUFFER_TYPE #undef IMMUTABLE_BUFFER_TYPE #undef TYPE_TYPE #undef SIZE_TYPE #undef INT_TYPE #undef VOID_TYPE #undef END_VALUE_WITNESS_RANGE #undef BEGIN_VALUE_WITNESS_RANGE #undef DATA_VALUE_WITNESS #undef FUNCTION_VALUE_WITNESS #undef VALUE_WITNESS #undef ENUM_VALUE_WITNESS #undef NON_REQUIRED_VALUE_WITNESS #undef REQUIRED_VALUE_WITNESS #undef WANT_ENUM_VALUE_WITNESSES #undef WANT_REQUIRED_VALUE_WITNESSES