mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Runtime][IRGen] Sign type context descriptor pointers.
Ensure that context descriptor pointers are signed in the runtime by putting the ptrauth_struct attribute on the types. We use the new __builtin_ptrauth_struct_key/disc to conditionally apply ptrauth_struct to TrailingObjects based on the signing of the base type, so that pointers to TrailingObjects get signed when used with a context descriptor pointer. We add new runtime entrypoints that take signed pointers where appropriate, and have the compiler emit calls to the new entrypoints when targeting a sufficiently new OS. rdar://111480914
This commit is contained in:
@@ -56,12 +56,24 @@ template <typename Runtime> struct TargetOpaqueMetadata;
|
||||
template <typename Runtime> struct TargetValueMetadata;
|
||||
template <typename Runtime> struct TargetForeignClassMetadata;
|
||||
template <typename Runtime> struct TargetForeignReferenceTypeMetadata;
|
||||
template <typename Runtime> struct TargetContextDescriptor;
|
||||
template <typename Runtime> class TargetTypeContextDescriptor;
|
||||
template <typename Runtime> class TargetClassDescriptor;
|
||||
template <typename Runtime> class TargetValueTypeDescriptor;
|
||||
template <typename Runtime> class TargetEnumDescriptor;
|
||||
template <typename Runtime> class TargetStructDescriptor;
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ContextDescriptor)
|
||||
TargetContextDescriptor;
|
||||
template <typename Runtime>
|
||||
class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
|
||||
TargetTypeContextDescriptor;
|
||||
template <typename Runtime>
|
||||
class swift_ptrauth_struct_context_descriptor(ClassDescriptor)
|
||||
TargetClassDescriptor;
|
||||
template <typename Runtime>
|
||||
class swift_ptrauth_struct_context_descriptor(ValueTypeDescriptor)
|
||||
TargetValueTypeDescriptor;
|
||||
template <typename Runtime>
|
||||
class swift_ptrauth_struct_context_descriptor(EnumDescriptor)
|
||||
TargetEnumDescriptor;
|
||||
template <typename Runtime>
|
||||
class swift_ptrauth_struct_context_descriptor(StructDescriptor)
|
||||
TargetStructDescriptor;
|
||||
template <typename Runtime> struct TargetGenericMetadataPattern;
|
||||
template <typename Runtime> struct TargetProtocolConformanceDescriptor;
|
||||
|
||||
@@ -1632,7 +1644,9 @@ TargetTupleTypeMetadata<Runtime>::getOffsetToNumElements() -> StoredSize {
|
||||
return offsetof(TargetTupleTypeMetadata<Runtime>, NumElements);
|
||||
}
|
||||
|
||||
template <typename Runtime> struct TargetProtocolDescriptor;
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
|
||||
TargetProtocolDescriptor;
|
||||
|
||||
/// A protocol requirement descriptor. This describes a single protocol
|
||||
/// requirement in a protocol descriptor. The index of the requirement in
|
||||
@@ -1660,7 +1674,9 @@ struct TargetProtocolRequirement {
|
||||
|
||||
using ProtocolRequirement = TargetProtocolRequirement<InProcess>;
|
||||
|
||||
template<typename Runtime> struct TargetProtocolDescriptor;
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
|
||||
TargetProtocolDescriptor;
|
||||
using ProtocolDescriptor = TargetProtocolDescriptor<InProcess>;
|
||||
|
||||
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
|
||||
@@ -2803,12 +2819,14 @@ using ExternalProtocolConformanceDescriptor = TargetProtocolConformanceDescripto
|
||||
template<template <typename Runtime> class ObjCInteropKind, unsigned PointerSize>
|
||||
using ExternalProtocolConformanceRecord = TargetProtocolConformanceRecord<External<ObjCInteropKind<RuntimeTarget<PointerSize>>>>;
|
||||
|
||||
template<typename Runtime>
|
||||
struct TargetModuleContextDescriptor;
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ModuleContextDescriptor)
|
||||
TargetModuleContextDescriptor;
|
||||
|
||||
/// Base class for all context descriptors.
|
||||
template<typename Runtime>
|
||||
struct TargetContextDescriptor {
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ContextDescriptor)
|
||||
TargetContextDescriptor {
|
||||
/// Flags describing the context, including its kind and format version.
|
||||
ContextDescriptorFlags Flags;
|
||||
|
||||
@@ -2864,8 +2882,9 @@ inline bool isCImportedModuleName(llvm::StringRef name) {
|
||||
}
|
||||
|
||||
/// Descriptor for a module context.
|
||||
template<typename Runtime>
|
||||
struct TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ModuleContextDescriptor)
|
||||
TargetModuleContextDescriptor final : TargetContextDescriptor<Runtime> {
|
||||
/// The module name.
|
||||
RelativeDirectPointer<const char, /*nullable*/ false> Name;
|
||||
|
||||
@@ -2905,8 +2924,9 @@ TargetContextDescriptor<Runtime>::getModuleContext() const {
|
||||
}
|
||||
|
||||
/// Descriptor for an extension context.
|
||||
template<typename Runtime>
|
||||
struct TargetExtensionContextDescriptor final
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ExtensionContextDescriptor)
|
||||
TargetExtensionContextDescriptor final
|
||||
: TargetContextDescriptor<Runtime>,
|
||||
TrailingGenericContextObjects<TargetExtensionContextDescriptor<Runtime>>
|
||||
{
|
||||
@@ -2944,8 +2964,9 @@ struct TargetMangledContextName {
|
||||
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> name;
|
||||
};
|
||||
|
||||
template<typename Runtime>
|
||||
struct TargetAnonymousContextDescriptor final
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(AnonymousContextDescriptor)
|
||||
TargetAnonymousContextDescriptor final
|
||||
: TargetContextDescriptor<Runtime>,
|
||||
TrailingGenericContextObjects<TargetAnonymousContextDescriptor<Runtime>,
|
||||
TargetGenericContextDescriptorHeader,
|
||||
@@ -3025,8 +3046,9 @@ using ExternalAnonymousContextDescriptor = TargetAnonymousContextDescriptor<Exte
|
||||
/// Only Swift protocols are defined by a protocol descriptor, whereas
|
||||
/// Objective-C (including protocols defined in Swift as @objc) use the
|
||||
/// Objective-C protocol layout.
|
||||
template<typename Runtime>
|
||||
struct TargetProtocolDescriptor final
|
||||
template <typename Runtime>
|
||||
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
|
||||
TargetProtocolDescriptor final
|
||||
: TargetContextDescriptor<Runtime>,
|
||||
swift::ABI::TrailingObjects<
|
||||
TargetProtocolDescriptor<Runtime>,
|
||||
@@ -3117,8 +3139,9 @@ public:
|
||||
|
||||
/// The descriptor for an opaque type.
|
||||
template <typename Runtime>
|
||||
struct TargetOpaqueTypeDescriptor final
|
||||
: TargetContextDescriptor<Runtime>,
|
||||
struct swift_ptrauth_struct_context_descriptor(OpaqueTypeDescriptor)
|
||||
TargetOpaqueTypeDescriptor final
|
||||
: TargetContextDescriptor<Runtime>,
|
||||
TrailingGenericContextObjects<TargetOpaqueTypeDescriptor<Runtime>,
|
||||
TargetGenericContextDescriptorHeader,
|
||||
RelativeDirectPointer<const char>>
|
||||
@@ -3694,8 +3717,8 @@ struct TargetCanonicalSpecializedMetadatasCachingOnceToken {
|
||||
};
|
||||
|
||||
template <typename Runtime>
|
||||
class TargetTypeContextDescriptor
|
||||
: public TargetContextDescriptor<Runtime> {
|
||||
class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
|
||||
TargetTypeContextDescriptor : public TargetContextDescriptor<Runtime> {
|
||||
public:
|
||||
/// The name of the type.
|
||||
TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> Name;
|
||||
@@ -3917,7 +3940,8 @@ struct TargetObjCResilientClassStubInfo {
|
||||
};
|
||||
|
||||
template <typename Runtime>
|
||||
class TargetClassDescriptor final
|
||||
class swift_ptrauth_struct_context_descriptor(ClassDescriptor)
|
||||
TargetClassDescriptor final
|
||||
: public TargetTypeContextDescriptor<Runtime>,
|
||||
public TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
|
||||
TargetTypeGenericContextDescriptorHeader,
|
||||
@@ -4307,8 +4331,8 @@ public:
|
||||
using ClassDescriptor = TargetClassDescriptor<InProcess>;
|
||||
|
||||
template <typename Runtime>
|
||||
class TargetValueTypeDescriptor
|
||||
: public TargetTypeContextDescriptor<Runtime> {
|
||||
class swift_ptrauth_struct_context_descriptor(ValueTypeDescriptor)
|
||||
TargetValueTypeDescriptor : public TargetTypeContextDescriptor<Runtime>{
|
||||
public:
|
||||
static bool classof(const TargetContextDescriptor<Runtime> *cd) {
|
||||
return cd->getKind() == ContextDescriptorKind::Struct ||
|
||||
@@ -4318,7 +4342,8 @@ public:
|
||||
using ValueTypeDescriptor = TargetValueTypeDescriptor<InProcess>;
|
||||
|
||||
template <typename Runtime>
|
||||
class TargetStructDescriptor final
|
||||
class swift_ptrauth_struct_context_descriptor(StructDescriptor)
|
||||
TargetStructDescriptor final
|
||||
: public TargetValueTypeDescriptor<Runtime>,
|
||||
public TrailingGenericContextObjects<TargetStructDescriptor<Runtime>,
|
||||
TargetTypeGenericContextDescriptorHeader,
|
||||
@@ -4445,7 +4470,8 @@ public:
|
||||
using StructDescriptor = TargetStructDescriptor<InProcess>;
|
||||
|
||||
template <typename Runtime>
|
||||
class TargetEnumDescriptor final
|
||||
class swift_ptrauth_struct_context_descriptor(EnumDescriptor)
|
||||
TargetEnumDescriptor final
|
||||
: public TargetValueTypeDescriptor<Runtime>,
|
||||
public TrailingGenericContextObjects<TargetEnumDescriptor<Runtime>,
|
||||
TargetTypeGenericContextDescriptorHeader,
|
||||
|
||||
@@ -34,9 +34,11 @@ struct TargetAnyClassMetadataObjCInterop;
|
||||
template <typename Runtime, typename TargetAnyClassMetadataVariant>
|
||||
struct TargetClassMetadata;
|
||||
template <typename Runtime>
|
||||
struct TargetContextDescriptor;
|
||||
struct swift_ptrauth_struct_context_descriptor(ContextDescriptor)
|
||||
TargetContextDescriptor;
|
||||
template <typename Runtime>
|
||||
struct TargetProtocolDescriptor;
|
||||
struct swift_ptrauth_struct_context_descriptor(ProtocolDescriptor)
|
||||
TargetProtocolDescriptor;
|
||||
|
||||
namespace detail {
|
||||
template <typename Runtime, bool ObjCInterop = Runtime::ObjCInterop>
|
||||
|
||||
@@ -1391,6 +1391,12 @@ namespace SpecialPointerAuthDiscriminators {
|
||||
/// Protocol conformance descriptors.
|
||||
const uint16_t ProtocolConformanceDescriptor = 0xc6eb;
|
||||
|
||||
const uint16_t ProtocolDescriptor = 0xe909; // = 59657
|
||||
|
||||
// Type descriptors as arguments.
|
||||
const uint16_t OpaqueTypeDescriptor = 0xbdd1; // = 48593
|
||||
const uint16_t ContextDescriptor = 0xb5e3; // = 46563
|
||||
|
||||
/// Pointer to value witness table stored in type metadata.
|
||||
///
|
||||
/// Computed with ptrauth_string_discriminator("value_witness_table_t").
|
||||
|
||||
@@ -234,7 +234,8 @@ protected:
|
||||
/// See the file comment for details on the usage of the
|
||||
/// TrailingObjects type.
|
||||
template <typename BaseTy, typename... TrailingTys>
|
||||
class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
|
||||
class swift_ptrauth_struct_derived(BaseTy) TrailingObjects
|
||||
: private trailing_objects_internal::TrailingObjectsImpl<
|
||||
trailing_objects_internal::AlignmentCalcHelper<
|
||||
TrailingTys...>::Alignment,
|
||||
BaseTy, TrailingObjects<BaseTy, TrailingTys...>,
|
||||
|
||||
@@ -19,11 +19,14 @@
|
||||
#define SWIFT_ABI_TYPEIDENTITY_H
|
||||
|
||||
#include "swift/Basic/LLVM.h"
|
||||
#include "swift/Runtime/Config.h"
|
||||
#include <llvm/ADT/Optional.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
|
||||
namespace swift {
|
||||
template <class> class TargetTypeContextDescriptor;
|
||||
template <typename Runtime>
|
||||
class swift_ptrauth_struct_context_descriptor(TypeContextDescriptor)
|
||||
TargetTypeContextDescriptor;
|
||||
struct InProcess;
|
||||
using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;
|
||||
|
||||
|
||||
@@ -929,6 +929,14 @@ public:
|
||||
/// variadic generic types.
|
||||
AvailabilityContext getVariadicGenericTypeAvailability();
|
||||
|
||||
/// Get the runtime availability of the conformsToProtocol runtime entrypoint
|
||||
/// that takes a signed protocol descriptor pointer.
|
||||
AvailabilityContext getSignedConformsToProtocolAvailability();
|
||||
|
||||
/// Get the runtime availability of runtime entrypoints that take signed type
|
||||
/// descriptors.
|
||||
AvailabilityContext getSignedDescriptorAvailability();
|
||||
|
||||
/// Get the runtime availability of features introduced in the Swift 5.2
|
||||
/// compiler for the target platform.
|
||||
AvailabilityContext getSwift52Availability();
|
||||
|
||||
@@ -147,6 +147,15 @@ struct PointerAuthOptions : clang::PointerAuthOptions {
|
||||
/// Protocol conformance descriptors when passed as arguments.
|
||||
PointerAuthSchema ProtocolConformanceDescriptorsAsArguments;
|
||||
|
||||
/// Protocol descriptors when passed as arguments.
|
||||
PointerAuthSchema ProtocolDescriptorsAsArguments;
|
||||
|
||||
/// Opaque type descriptors when passed as arguments.
|
||||
PointerAuthSchema OpaqueTypeDescriptorsAsArguments;
|
||||
|
||||
/// Type context descriptors when passed as arguments.
|
||||
PointerAuthSchema ContextDescriptorsAsArguments;
|
||||
|
||||
/// Resumption functions from yield-once coroutines.
|
||||
PointerAuthSchema YieldOnceResumeFunctions;
|
||||
|
||||
|
||||
@@ -239,11 +239,26 @@ const Metadata *swift_getObjectType(HeapObject *object);
|
||||
/// \param type The metadata for the type for which to do the conformance
|
||||
/// check.
|
||||
/// \param protocol The protocol descriptor for the protocol to check
|
||||
/// conformance for.
|
||||
/// conformance for. This pointer does not have ptrauth applied.
|
||||
SWIFT_RUNTIME_EXPORT
|
||||
const WitnessTable *swift_conformsToProtocol(const Metadata *type,
|
||||
const ProtocolDescriptor *protocol);
|
||||
const void *protocol);
|
||||
|
||||
/// Check whether a type conforms to a given native Swift protocol. Identical to
|
||||
/// swift_conformsToProtocol, except that the protocol parameter has a ptrauth
|
||||
/// signature on ARM64e that is signed with a process independent key.
|
||||
SWIFT_RUNTIME_EXPORT
|
||||
const WitnessTable *
|
||||
swift_conformsToProtocol2(const Metadata *type,
|
||||
const ProtocolDescriptor *protocol);
|
||||
|
||||
/// Check whether a type conforms to a given native Swift protocol. Identical to
|
||||
/// swift_conformsToProtocol, except that the protocol parameter has a ptrauth
|
||||
/// signature on ARM64e that is signed with a process dependent key.
|
||||
SWIFT_RUNTIME_EXPORT
|
||||
const WitnessTable *
|
||||
swift_conformsToProtocolCommon(const Metadata *type,
|
||||
const ProtocolDescriptor *protocol);
|
||||
} // end namespace swift
|
||||
|
||||
#endif // SWIFT_RUNTIME_CASTING_H
|
||||
|
||||
@@ -326,6 +326,18 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
|
||||
#define __ptrauth_swift_type_layout_string \
|
||||
__ptrauth(ptrauth_key_process_independent_data, 1, \
|
||||
SpecialPointerAuthDiscriminators::TypeLayoutString)
|
||||
|
||||
#if __has_attribute(ptrauth_struct)
|
||||
#define swift_ptrauth_struct(key, discriminator) \
|
||||
__attribute__((ptrauth_struct(key, discriminator)))
|
||||
#else
|
||||
#define swift_ptrauth_struct(key, discriminator)
|
||||
#endif
|
||||
// Set ptrauth_struct to the same scheme as the ptrauth_struct on `from`, but
|
||||
// with a modified discriminator.
|
||||
#define swift_ptrauth_struct_derived(from) \
|
||||
swift_ptrauth_struct(__builtin_ptrauth_struct_key(from), \
|
||||
__builtin_ptrauth_struct_disc(from) + 1)
|
||||
#else
|
||||
#define SWIFT_PTRAUTH 0
|
||||
#define __ptrauth_swift_function_pointer(__typekey)
|
||||
@@ -354,11 +366,18 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
|
||||
#define swift_ptrauth_sign_opaque_read_resume_function(__fn, __buffer) (__fn)
|
||||
#define swift_ptrauth_sign_opaque_modify_resume_function(__fn, __buffer) (__fn)
|
||||
#define __ptrauth_swift_type_layout_string
|
||||
#define swift_ptrauth_struct(key, discriminator)
|
||||
#define swift_ptrauth_struct_derived(from)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/// Copy an address-discriminated signed pointer from the source to the dest.
|
||||
#define swift_ptrauth_struct_context_descriptor(name) \
|
||||
swift_ptrauth_struct(ptrauth_key_process_dependent_data, \
|
||||
ptrauth_string_discriminator(#name))
|
||||
|
||||
/// Copy an address-discriminated signed code pointer from the source
|
||||
/// to the destination.
|
||||
template <class T>
|
||||
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE static inline void
|
||||
swift_ptrauth_copy(T *dest, const T *src, unsigned extra, bool allowNull) {
|
||||
@@ -462,9 +481,53 @@ template <typename T>
|
||||
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
|
||||
static inline T swift_auth_data_non_address(T value, unsigned extra) {
|
||||
#if SWIFT_PTRAUTH
|
||||
return (T)ptrauth_auth_data((void *)value,
|
||||
ptrauth_key_process_independent_data,
|
||||
extra);
|
||||
// Cast to void* using a union to avoid implicit ptrauth operations when T
|
||||
// points to a type with the ptrauth_struct attribute.
|
||||
union {
|
||||
T value;
|
||||
void *voidValue;
|
||||
} converter;
|
||||
converter.value = value;
|
||||
if (converter.voidValue == nullptr)
|
||||
return nullptr;
|
||||
return (T)ptrauth_auth_data(converter.voidValue,
|
||||
ptrauth_key_process_independent_data, extra);
|
||||
#else
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
|
||||
static inline T swift_sign_data_non_address(T value, unsigned extra) {
|
||||
#if SWIFT_PTRAUTH
|
||||
// Cast from void* using a union to avoid implicit ptrauth operations when T
|
||||
// points to a type with the ptrauth_struct attribute.
|
||||
union {
|
||||
T value;
|
||||
void *voidValue;
|
||||
} converter;
|
||||
converter.voidValue = ptrauth_sign_unauthenticated(
|
||||
(void *)value, ptrauth_key_process_independent_data, extra);
|
||||
return converter.value;
|
||||
#else
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE
|
||||
static inline T swift_strip_data(T value) {
|
||||
#if SWIFT_PTRAUTH
|
||||
// Cast to void* using a union to avoid implicit ptrauth operations when T
|
||||
// points to a type with the ptrauth_struct attribute.
|
||||
union {
|
||||
T value;
|
||||
void *voidValue;
|
||||
} converter;
|
||||
converter.value = value;
|
||||
|
||||
return (T)ptrauth_strip(converter.voidValue, ptrauth_key_process_independent_data);
|
||||
#else
|
||||
return value;
|
||||
#endif
|
||||
|
||||
@@ -847,7 +847,7 @@ FUNCTION(GetCanonicalPrespecializedGenericMetadata,
|
||||
|
||||
// MetadataResponse swift_getOpaqueTypeMetadata(MetadataRequest request,
|
||||
// const void * const *arguments,
|
||||
// const OpaqueTypeDescriptor *descriptor,
|
||||
// const void *descriptor,
|
||||
// uintptr_t index);
|
||||
FUNCTION(GetOpaqueTypeMetadata, swift_getOpaqueTypeMetadata,
|
||||
SwiftCC, OpaqueTypeAvailability,
|
||||
@@ -856,6 +856,17 @@ FUNCTION(GetOpaqueTypeMetadata, swift_getOpaqueTypeMetadata,
|
||||
ATTRS(NoUnwind, ReadOnly),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// MetadataResponse swift_getOpaqueTypeMetadata2(MetadataRequest request,
|
||||
// const void * const *arguments,
|
||||
// const OpaqueTypeDescriptor *descriptor,
|
||||
// uintptr_t index);
|
||||
FUNCTION(GetOpaqueTypeMetadata2, swift_getOpaqueTypeMetadata2,
|
||||
SwiftCC, SignedDescriptorAvailability,
|
||||
RETURNS(TypeMetadataResponseTy),
|
||||
ARGS(SizeTy, Int8PtrTy, OpaqueTypeDescriptorPtrTy, SizeTy),
|
||||
ATTRS(NoUnwind, ReadOnly),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// const WitnessTable *swift_getOpaqueTypeConformance(const void * const *arguments,
|
||||
// const OpaqueTypeDescriptor *descriptor,
|
||||
// uintptr_t index);
|
||||
@@ -866,6 +877,16 @@ FUNCTION(GetOpaqueTypeConformance, swift_getOpaqueTypeConformance,
|
||||
ATTRS(NoUnwind, ReadOnly, WillReturn),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// const WitnessTable *swift_getOpaqueTypeConformance2(const void * const *arguments,
|
||||
// const OpaqueTypeDescriptor *descriptor,
|
||||
// uintptr_t index);
|
||||
FUNCTION(GetOpaqueTypeConformance2, swift_getOpaqueTypeConformance2,
|
||||
SwiftCC, SignedDescriptorAvailability,
|
||||
RETURNS(WitnessTablePtrTy),
|
||||
ARGS(Int8PtrTy, OpaqueTypeDescriptorPtrTy, SizeTy),
|
||||
ATTRS(NoUnwind, ReadOnly, WillReturn),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
|
||||
// const void * const *arguments,
|
||||
// const void *template);
|
||||
@@ -1617,6 +1638,14 @@ FUNCTION(ConformsToProtocol,
|
||||
ATTRS(NoUnwind, ReadNone),
|
||||
EFFECT(Casting))
|
||||
|
||||
// witness_table* swift_conformsToProtocol2(type*, protocol*);
|
||||
FUNCTION(ConformsToProtocol2,
|
||||
swift_conformsToProtocol2, C_CC, SignedConformsToProtocolAvailability,
|
||||
RETURNS(WitnessTablePtrTy),
|
||||
ARGS(TypeMetadataPtrTy, ProtocolDescriptorPtrTy),
|
||||
ATTRS(NoUnwind, ReadNone),
|
||||
EFFECT(Casting))
|
||||
|
||||
// bool swift_isClassType(type*);
|
||||
FUNCTION(IsClassType,
|
||||
swift_isClassType, C_CC, AlwaysAvailable,
|
||||
@@ -1909,7 +1938,7 @@ FUNCTION(IntToFloat64, swift_intToFloat64, SwiftCC, AlwaysAvailable,
|
||||
// const Metadata *swift_getTypeByMangledNameInContext(
|
||||
// const char *typeNameStart,
|
||||
// size_t typeNameLength,
|
||||
// const TargetContextDescriptor<InProcess> *context,
|
||||
// const void *context,
|
||||
// const void * const *genericArgs)
|
||||
FUNCTION(GetTypeByMangledNameInContext, swift_getTypeByMangledNameInContext,
|
||||
SwiftCC, AlwaysAvailable,
|
||||
@@ -1918,11 +1947,23 @@ FUNCTION(GetTypeByMangledNameInContext, swift_getTypeByMangledNameInContext,
|
||||
ATTRS(NoUnwind, ArgMemOnly),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// const Metadata *swift_getTypeByMangledNameInContext2(
|
||||
// const char *typeNameStart,
|
||||
// size_t typeNameLength,
|
||||
// const TargetContextDescriptor<InProcess> *context,
|
||||
// const void * const *genericArgs)
|
||||
FUNCTION(GetTypeByMangledNameInContext2, swift_getTypeByMangledNameInContext2,
|
||||
SwiftCC, SignedDescriptorAvailability,
|
||||
RETURNS(TypeMetadataPtrTy),
|
||||
ARGS(Int8PtrTy, SizeTy, TypeContextDescriptorPtrTy, Int8PtrPtrTy),
|
||||
ATTRS(NoUnwind, ArgMemOnly),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// const Metadata *swift_getTypeByMangledNameInContextInMetadataState(
|
||||
// size_t metadataState,
|
||||
// const char *typeNameStart,
|
||||
// size_t typeNameLength,
|
||||
// const TargetContextDescriptor<InProcess> *context,
|
||||
// const void *context,
|
||||
// const void * const *genericArgs)
|
||||
FUNCTION(GetTypeByMangledNameInContextInMetadataState,
|
||||
swift_getTypeByMangledNameInContextInMetadataState, SwiftCC,
|
||||
@@ -1933,6 +1974,21 @@ FUNCTION(GetTypeByMangledNameInContextInMetadataState,
|
||||
ATTRS(NoUnwind, ArgMemOnly),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// const Metadata *swift_getTypeByMangledNameInContextInMetadataState2(
|
||||
// size_t metadataState,
|
||||
// const char *typeNameStart,
|
||||
// size_t typeNameLength,
|
||||
// const TargetContextDescriptor<InProcess> *context,
|
||||
// const void * const *genericArgs)
|
||||
FUNCTION(GetTypeByMangledNameInContextInMetadataState2,
|
||||
swift_getTypeByMangledNameInContextInMetadataState2, SwiftCC,
|
||||
SignedDescriptorAvailability,
|
||||
RETURNS(TypeMetadataPtrTy),
|
||||
ARGS(SizeTy, Int8PtrTy, SizeTy, TypeContextDescriptorPtrTy,
|
||||
Int8PtrPtrTy),
|
||||
ATTRS(NoUnwind, ArgMemOnly),
|
||||
EFFECT(MetaData))
|
||||
|
||||
// AsyncTask *swift_task_getCurrent();s
|
||||
FUNCTION(GetCurrentTask,
|
||||
swift_task_getCurrent, SwiftCC,
|
||||
|
||||
@@ -530,6 +530,16 @@ ASTContext::getVariadicGenericTypeAvailability() {
|
||||
return getSwift59Availability();
|
||||
}
|
||||
|
||||
AvailabilityContext
|
||||
ASTContext::getSignedConformsToProtocolAvailability() {
|
||||
return getSwift59Availability();
|
||||
}
|
||||
|
||||
AvailabilityContext
|
||||
ASTContext::getSignedDescriptorAvailability() {
|
||||
return getSwift59Availability();
|
||||
}
|
||||
|
||||
AvailabilityContext ASTContext::getSwift52Availability() {
|
||||
auto target = LangOpts.Target;
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "GenHeap.h"
|
||||
#include "GenMeta.h"
|
||||
#include "GenOpaque.h"
|
||||
#include "GenPointerAuth.h"
|
||||
#include "GenPoly.h"
|
||||
#include "GenProto.h"
|
||||
#include "GenType.h"
|
||||
@@ -460,7 +461,13 @@ getAddressOfOpaqueTypeDescriptor(IRGenFunction &IGF,
|
||||
MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
|
||||
CanOpaqueTypeArchetypeType archetype,
|
||||
DynamicMetadataRequest request) {
|
||||
auto accessorFn = IGF.IGM.getGetOpaqueTypeMetadataFunctionPointer();
|
||||
bool signedDescriptor = IGF.IGM.getAvailabilityContext().isContainedIn(
|
||||
IGF.IGM.Context.getSignedDescriptorAvailability());
|
||||
|
||||
auto accessorFn = signedDescriptor ?
|
||||
IGF.IGM.getGetOpaqueTypeMetadata2FunctionPointer() :
|
||||
IGF.IGM.getGetOpaqueTypeMetadataFunctionPointer();
|
||||
|
||||
auto opaqueDecl = archetype->getDecl();
|
||||
auto genericParam = archetype->getInterfaceType()
|
||||
->castTo<GenericTypeParamType>();
|
||||
@@ -468,6 +475,16 @@ MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
|
||||
auto indexValue = llvm::ConstantInt::get(
|
||||
IGF.IGM.SizeTy, genericParam->getIndex());
|
||||
|
||||
// Sign the descriptor.
|
||||
auto schema =
|
||||
IGF.IGM.getOptions().PointerAuth.OpaqueTypeDescriptorsAsArguments;
|
||||
if (schema && signedDescriptor) {
|
||||
auto authInfo = PointerAuthInfo::emit(
|
||||
IGF, schema, nullptr,
|
||||
PointerAuthEntity::Special::OpaqueTypeDescriptorAsArgument);
|
||||
descriptor = emitPointerAuthSign(IGF, descriptor, authInfo);
|
||||
}
|
||||
|
||||
llvm::CallInst *result = nullptr;
|
||||
withOpaqueTypeGenericArgs(IGF, archetype,
|
||||
[&](llvm::Value *genericArgs) {
|
||||
@@ -487,12 +504,27 @@ MetadataResponse irgen::emitOpaqueTypeMetadataRef(IRGenFunction &IGF,
|
||||
llvm::Value *irgen::emitOpaqueTypeWitnessTableRef(IRGenFunction &IGF,
|
||||
CanOpaqueTypeArchetypeType archetype,
|
||||
ProtocolDecl *protocol) {
|
||||
auto accessorFn = IGF.IGM.getGetOpaqueTypeConformanceFunctionPointer();
|
||||
bool signedDescriptor = IGF.IGM.getAvailabilityContext().isContainedIn(
|
||||
IGF.IGM.Context.getSignedDescriptorAvailability());
|
||||
|
||||
auto accessorFn = signedDescriptor ?
|
||||
IGF.IGM.getGetOpaqueTypeConformance2FunctionPointer() :
|
||||
IGF.IGM.getGetOpaqueTypeConformanceFunctionPointer();
|
||||
auto opaqueDecl = archetype->getDecl();
|
||||
assert(archetype->isRoot() && "Can only follow from the root");
|
||||
|
||||
llvm::Value *descriptor = getAddressOfOpaqueTypeDescriptor(IGF, opaqueDecl);
|
||||
|
||||
// Sign the descriptor.
|
||||
auto schema =
|
||||
IGF.IGM.getOptions().PointerAuth.OpaqueTypeDescriptorsAsArguments;
|
||||
if (schema && signedDescriptor) {
|
||||
auto authInfo = PointerAuthInfo::emit(
|
||||
IGF, schema, nullptr,
|
||||
PointerAuthEntity::Special::OpaqueTypeDescriptorAsArgument);
|
||||
descriptor = emitPointerAuthSign(IGF, descriptor, authInfo);
|
||||
}
|
||||
|
||||
// Compute the index at which this witness table resides.
|
||||
unsigned index = opaqueDecl->getOpaqueGenericParams().size();
|
||||
auto opaqueReqs =
|
||||
|
||||
@@ -355,6 +355,12 @@ PointerAuthEntity::getDeclDiscriminator(IRGenModule &IGM) const {
|
||||
case Special::ProtocolConformanceDescriptor:
|
||||
case Special::ProtocolConformanceDescriptorAsArgument:
|
||||
return SpecialPointerAuthDiscriminators::ProtocolConformanceDescriptor;
|
||||
case Special::ProtocolDescriptorAsArgument:
|
||||
return SpecialPointerAuthDiscriminators::ProtocolDescriptor;
|
||||
case Special::OpaqueTypeDescriptorAsArgument:
|
||||
return SpecialPointerAuthDiscriminators::OpaqueTypeDescriptor;
|
||||
case Special::ContextDescriptorAsArgument:
|
||||
return SpecialPointerAuthDiscriminators::ContextDescriptor;
|
||||
case Special::PartialApplyCapture:
|
||||
return PointerAuthDiscriminator_PartialApplyCapture;
|
||||
case Special::KeyPathDestroy:
|
||||
|
||||
@@ -64,6 +64,9 @@ public:
|
||||
DynamicReplacementKey,
|
||||
ProtocolConformanceDescriptor,
|
||||
ProtocolConformanceDescriptorAsArgument,
|
||||
ProtocolDescriptorAsArgument,
|
||||
OpaqueTypeDescriptorAsArgument,
|
||||
ContextDescriptorAsArgument,
|
||||
TypeLayoutString,
|
||||
};
|
||||
|
||||
|
||||
@@ -739,6 +739,21 @@ static void setPointerAuthOptions(PointerAuthOptions &opts,
|
||||
opts.ProtocolConformanceDescriptorsAsArguments =
|
||||
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
|
||||
|
||||
opts.ProtocolDescriptorsAsArguments =
|
||||
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
|
||||
|
||||
opts.OpaqueTypeDescriptorsAsArguments =
|
||||
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
|
||||
|
||||
opts.ContextDescriptorsAsArguments =
|
||||
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
|
||||
|
||||
opts.OpaqueTypeDescriptorsAsArguments =
|
||||
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
|
||||
|
||||
opts.ContextDescriptorsAsArguments =
|
||||
PointerAuthSchema(dataKey, /*address*/ false, Discrimination::Decl);
|
||||
|
||||
// Coroutine resumption functions are never stored globally in the ABI,
|
||||
// so we can do some things that aren't normally okay to do. However,
|
||||
// we can't use ASIB because that would break ARM64 interoperation.
|
||||
|
||||
@@ -888,6 +888,24 @@ namespace RuntimeConstants {
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
}
|
||||
|
||||
RuntimeAvailability SignedConformsToProtocolAvailability(ASTContext &context) {
|
||||
auto featureAvailability =
|
||||
context.getSignedConformsToProtocolAvailability();
|
||||
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
|
||||
return RuntimeAvailability::ConditionallyAvailable;
|
||||
}
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
}
|
||||
|
||||
RuntimeAvailability SignedDescriptorAvailability(ASTContext &context) {
|
||||
auto featureAvailability =
|
||||
context.getSignedDescriptorAvailability();
|
||||
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
|
||||
return RuntimeAvailability::ConditionallyAvailable;
|
||||
}
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
}
|
||||
|
||||
RuntimeAvailability TaskRunInlineAvailability(ASTContext &context) {
|
||||
if (context.LangOpts.isConcurrencyModelTaskToThread()) {
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
|
||||
@@ -3090,8 +3090,19 @@ emitMetadataAccessByMangledName(IRGenFunction &IGF, CanType type,
|
||||
stringAddr = subIGF.Builder.CreateIntToPtr(stringAddr, IGM.Int8PtrTy);
|
||||
|
||||
llvm::CallInst *call;
|
||||
bool signedDescriptor = IGM.getAvailabilityContext().isContainedIn(
|
||||
IGM.Context.getSignedDescriptorAvailability());
|
||||
if (request.isStaticallyAbstract()) {
|
||||
call = subIGF.Builder.CreateCall(
|
||||
call = signedDescriptor ?
|
||||
subIGF.Builder.CreateCall(
|
||||
IGM.getGetTypeByMangledNameInContextInMetadataState2FunctionPointer(),
|
||||
{llvm::ConstantInt::get(IGM.SizeTy, (size_t)MetadataState::Abstract),
|
||||
stringAddr, size,
|
||||
// TODO: Use mangled name lookup in generic
|
||||
// contexts?
|
||||
llvm::ConstantPointerNull::get(IGM.TypeContextDescriptorPtrTy),
|
||||
llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy)}):
|
||||
subIGF.Builder.CreateCall(
|
||||
IGM.getGetTypeByMangledNameInContextInMetadataStateFunctionPointer(),
|
||||
{llvm::ConstantInt::get(IGM.SizeTy, (size_t)MetadataState::Abstract),
|
||||
stringAddr, size,
|
||||
@@ -3100,7 +3111,15 @@ emitMetadataAccessByMangledName(IRGenFunction &IGF, CanType type,
|
||||
llvm::ConstantPointerNull::get(IGM.TypeContextDescriptorPtrTy),
|
||||
llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy)});
|
||||
} else {
|
||||
call = subIGF.Builder.CreateCall(
|
||||
call = signedDescriptor ?
|
||||
subIGF.Builder.CreateCall(
|
||||
IGM.getGetTypeByMangledNameInContext2FunctionPointer(),
|
||||
{stringAddr, size,
|
||||
// TODO: Use mangled name lookup in generic
|
||||
// contexts?
|
||||
llvm::ConstantPointerNull::get(IGM.TypeContextDescriptorPtrTy),
|
||||
llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy)}) :
|
||||
subIGF.Builder.CreateCall(
|
||||
IGM.getGetTypeByMangledNameInContextFunctionPointer(),
|
||||
{stringAddr, size,
|
||||
// TODO: Use mangled name lookup in generic
|
||||
|
||||
@@ -167,6 +167,16 @@ OVERRIDE_FOREIGN(dynamicCastForeignClassMetatypeUnconditional,
|
||||
|
||||
|
||||
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocol, const WitnessTable *, , , swift::,
|
||||
(const Metadata * const type,
|
||||
const void *protocol),
|
||||
(type, protocol))
|
||||
|
||||
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocol2, const WitnessTable *, , , swift::,
|
||||
(const Metadata * const type,
|
||||
const ProtocolDescriptor *protocol),
|
||||
(type, protocol))
|
||||
|
||||
OVERRIDE_PROTOCOLCONFORMANCE(conformsToProtocolCommon, const WitnessTable *, , , swift::,
|
||||
(const Metadata * const type,
|
||||
const ProtocolDescriptor *protocol),
|
||||
(type, protocol))
|
||||
|
||||
@@ -91,7 +91,7 @@ findHashableBaseTypeImpl(const Metadata *type) {
|
||||
}
|
||||
|
||||
auto witnessTable =
|
||||
swift_conformsToProtocol(type, &HashableProtocolDescriptor);
|
||||
swift_conformsToProtocolCommon(type, &HashableProtocolDescriptor);
|
||||
if (!KnownToConformToHashable && !witnessTable) {
|
||||
// Don't cache the negative response because we don't invalidate
|
||||
// this cache when a new conformance is loaded dynamically.
|
||||
@@ -175,7 +175,7 @@ void _swift_makeAnyHashableUpcastingToHashableBaseType(
|
||||
getValueFromSwiftValue(srcSwiftValue);
|
||||
|
||||
if (auto unboxedHashableWT =
|
||||
swift_conformsToProtocol(unboxedType, &HashableProtocolDescriptor)) {
|
||||
swift_conformsToProtocolCommon(unboxedType, &HashableProtocolDescriptor)) {
|
||||
_swift_makeAnyHashableUpcastingToHashableBaseType(
|
||||
const_cast<OpaqueValue *>(unboxedValue), anyHashableResultPointer,
|
||||
unboxedType, unboxedHashableWT);
|
||||
|
||||
@@ -519,7 +519,7 @@ bool swift::_conformsToProtocol(const OpaqueValue *value,
|
||||
const WitnessTable **conformance) {
|
||||
// Look up the witness table for protocols that need them.
|
||||
if (protocol.needsWitnessTable()) {
|
||||
auto witness = swift_conformsToProtocol(type, protocol.getSwiftProtocol());
|
||||
auto witness = swift_conformsToProtocolCommon(type, protocol.getSwiftProtocol());
|
||||
if (!witness)
|
||||
return false;
|
||||
if (conformance)
|
||||
@@ -1349,7 +1349,7 @@ extern "C" const StructDescriptor NOMINAL_TYPE_DESCR_SYM(SS);
|
||||
static const _ObjectiveCBridgeableWitnessTable *
|
||||
swift_conformsToObjectiveCBridgeable(const Metadata *T) {
|
||||
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>
|
||||
(swift_conformsToProtocol(T, &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable)));
|
||||
(swift_conformsToProtocolCommon(T, &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable)));
|
||||
}
|
||||
|
||||
static const _ObjectiveCBridgeableWitnessTable *
|
||||
|
||||
@@ -210,7 +210,7 @@ static const _ObjectiveCBridgeableWitnessTable *
|
||||
findBridgeWitness(const Metadata *T) {
|
||||
static const auto bridgeableProtocol
|
||||
= &PROTOCOL_DESCR_SYM(s21_ObjectiveCBridgeable);
|
||||
auto w = swift_conformsToProtocol(T, bridgeableProtocol);
|
||||
auto w = swift_conformsToProtocolCommon(T, bridgeableProtocol);
|
||||
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>(w);
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ tryCastToAnyHashable(
|
||||
// General case: If it conforms to Hashable, we cast it
|
||||
if (hashableConformance == nullptr) {
|
||||
hashableConformance = reinterpret_cast<const HashableWitnessTable *>(
|
||||
swift_conformsToProtocol(srcType, &HashableProtocolDescriptor)
|
||||
swift_conformsToProtocolCommon(srcType, &HashableProtocolDescriptor)
|
||||
);
|
||||
}
|
||||
if (hashableConformance) {
|
||||
|
||||
@@ -197,7 +197,7 @@ const Metadata *swift::getNSErrorMetadata() {
|
||||
extern "C" const ProtocolDescriptor PROTOCOL_DESCR_SYM(s5Error);
|
||||
|
||||
const WitnessTable *swift::findErrorWitness(const Metadata *srcType) {
|
||||
return swift_conformsToProtocol(srcType, &PROTOCOL_DESCR_SYM(s5Error));
|
||||
return swift_conformsToProtocolCommon(srcType, &PROTOCOL_DESCR_SYM(s5Error));
|
||||
}
|
||||
|
||||
id swift::dynamicCastValueToNSError(OpaqueValue *src,
|
||||
@@ -389,7 +389,7 @@ const HashableWitnessTable *SwiftError::getHashableConformance() const {
|
||||
const HashableWitnessTable *expectedWT = nullptr;
|
||||
const HashableWitnessTable *wt =
|
||||
reinterpret_cast<const HashableWitnessTable *>(
|
||||
swift_conformsToProtocol(type, &HashableProtocolDescriptor));
|
||||
swift_conformsToProtocolCommon(type, &HashableProtocolDescriptor));
|
||||
hashableConformance.compare_exchange_strong(
|
||||
expectedWT, wt ? wt : reinterpret_cast<const HashableWitnessTable *>(1),
|
||||
std::memory_order_acq_rel);
|
||||
@@ -613,7 +613,7 @@ swift::tryDynamicCastNSErrorObjectToValue(HeapObject *object,
|
||||
return false;
|
||||
|
||||
// Is the target type a bridgeable error?
|
||||
auto witness = swift_conformsToProtocol(destType,
|
||||
auto witness = swift_conformsToProtocolCommon(destType,
|
||||
TheObjectiveCBridgeableError);
|
||||
|
||||
if (witness) {
|
||||
|
||||
@@ -2009,7 +2009,7 @@ public:
|
||||
if (!assocType) return BuiltType();
|
||||
|
||||
auto projectDependentMemberType = [&](const Metadata *baseMetadata) -> const Metadata * {
|
||||
auto witnessTable = swift_conformsToProtocol(baseMetadata, swiftProtocol);
|
||||
auto witnessTable = swift_conformsToProtocolCommon(baseMetadata, swiftProtocol);
|
||||
if (!witnessTable)
|
||||
return nullptr;
|
||||
|
||||
@@ -2282,9 +2282,9 @@ swift_getTypeByMangledNameInEnvironmentInMetadataState(
|
||||
return result.getType().getMetadata();
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
static
|
||||
const Metadata * _Nullable
|
||||
swift_getTypeByMangledNameInContext(
|
||||
swift_getTypeByMangledNameInContextImpl(
|
||||
const char *typeNameStart,
|
||||
size_t typeNameLength,
|
||||
const TargetContextDescriptor<InProcess> *context,
|
||||
@@ -2316,7 +2316,38 @@ swift_getTypeByMangledNameInContext(
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
const Metadata * _Nullable
|
||||
swift_getTypeByMangledNameInContextInMetadataState(
|
||||
swift_getTypeByMangledNameInContext2(
|
||||
const char *typeNameStart,
|
||||
size_t typeNameLength,
|
||||
const TargetContextDescriptor<InProcess> *context,
|
||||
const void * const *genericArgs) {
|
||||
context = swift_auth_data_non_address(
|
||||
context, SpecialPointerAuthDiscriminators::ContextDescriptor);
|
||||
return swift_getTypeByMangledNameInContextImpl(typeNameStart, typeNameLength,
|
||||
context, genericArgs);
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
const Metadata * _Nullable
|
||||
swift_getTypeByMangledNameInContext(
|
||||
const char *typeNameStart,
|
||||
size_t typeNameLength,
|
||||
const void *context,
|
||||
const void * const *genericArgs) {
|
||||
// This call takes `context` without a ptrauth signature. We
|
||||
// declare it as `void *` to avoid the implicit ptrauth we get from
|
||||
// the ptrauth_struct attribute. The static_cast implicitly signs the
|
||||
// pointer when we call through to the implementation in
|
||||
// swift_getTypeByMangledNameInContextImpl.
|
||||
return swift_getTypeByMangledNameInContextImpl(
|
||||
typeNameStart, typeNameLength,
|
||||
static_cast<const TargetContextDescriptor<InProcess> *>(context),
|
||||
genericArgs);
|
||||
}
|
||||
|
||||
static
|
||||
const Metadata * _Nullable
|
||||
swift_getTypeByMangledNameInContextInMetadataStateImpl(
|
||||
size_t metadataState,
|
||||
const char *typeNameStart,
|
||||
size_t typeNameLength,
|
||||
@@ -2345,7 +2376,39 @@ swift_getTypeByMangledNameInContextInMetadataState(
|
||||
return nullptr;
|
||||
}
|
||||
return result.getType().getMetadata();
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
const Metadata * _Nullable
|
||||
swift_getTypeByMangledNameInContextInMetadataState2(
|
||||
size_t metadataState,
|
||||
const char *typeNameStart,
|
||||
size_t typeNameLength,
|
||||
const TargetContextDescriptor<InProcess> *context,
|
||||
const void * const *genericArgs) {
|
||||
context = swift_auth_data_non_address(
|
||||
context, SpecialPointerAuthDiscriminators::ContextDescriptor);
|
||||
return swift_getTypeByMangledNameInContextInMetadataStateImpl(
|
||||
metadataState, typeNameStart, typeNameLength, context, genericArgs);
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
const Metadata * _Nullable
|
||||
swift_getTypeByMangledNameInContextInMetadataState(
|
||||
size_t metadataState,
|
||||
const char *typeNameStart,
|
||||
size_t typeNameLength,
|
||||
const void *context,
|
||||
const void * const *genericArgs) {
|
||||
// This call takes `descriptor` without a ptrauth signature. We
|
||||
// declare it as `void *` to avoid the implicit ptrauth we get from
|
||||
// the ptrauth_struct attribute. The static_cast implicitly signs the
|
||||
// pointer when we call through to the implementation in
|
||||
// swift_getTypeByMangledNameInContextInMetadataState2.
|
||||
return swift_getTypeByMangledNameInContextInMetadataStateImpl(
|
||||
metadataState, typeNameStart, typeNameLength,
|
||||
static_cast<const TargetContextDescriptor<InProcess> *>(context),
|
||||
genericArgs);
|
||||
}
|
||||
|
||||
/// Demangle a mangled name, but don't allow symbolic references.
|
||||
@@ -2624,9 +2687,9 @@ swift_distributed_getWitnessTables(GenericEnvironmentDescriptor *genericEnv,
|
||||
|
||||
// ==== End of Function metadata functions ---------------------------------------
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
static
|
||||
MetadataResponse
|
||||
swift_getOpaqueTypeMetadata(MetadataRequest request,
|
||||
swift_getOpaqueTypeMetadataImpl(MetadataRequest request,
|
||||
const void * const *arguments,
|
||||
const OpaqueTypeDescriptor *descriptor,
|
||||
unsigned index) {
|
||||
@@ -2644,15 +2707,64 @@ swift_getOpaqueTypeMetadata(MetadataRequest request,
|
||||
}).getType().getResponse();
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
MetadataResponse
|
||||
swift_getOpaqueTypeMetadata2(MetadataRequest request,
|
||||
const void * const *arguments,
|
||||
const OpaqueTypeDescriptor *descriptor,
|
||||
unsigned index) {
|
||||
descriptor = swift_auth_data_non_address(
|
||||
descriptor, SpecialPointerAuthDiscriminators::OpaqueTypeDescriptor);
|
||||
return swift_getOpaqueTypeMetadataImpl(request, arguments, descriptor, index);
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
MetadataResponse
|
||||
swift_getOpaqueTypeMetadata(MetadataRequest request,
|
||||
const void * const *arguments,
|
||||
const void *descriptor,
|
||||
unsigned index) {
|
||||
// This call takes `descriptor` without a ptrauth signature. We
|
||||
// declare it as `void *` to avoid the implicit ptrauth we get from
|
||||
// the ptrauth_struct attribute. The static_cast implicitly signs the
|
||||
// pointer when we call through to the implementation in
|
||||
// swift_getOpaqueTypeMetadataImpl.
|
||||
return swift_getOpaqueTypeMetadataImpl(
|
||||
request, arguments, static_cast<const OpaqueTypeDescriptor *>(descriptor),
|
||||
index);
|
||||
}
|
||||
|
||||
static const WitnessTable *
|
||||
swift_getOpaqueTypeConformanceImpl(const void *const *arguments,
|
||||
const OpaqueTypeDescriptor *descriptor,
|
||||
unsigned index) {
|
||||
auto response = swift_getOpaqueTypeMetadataImpl(
|
||||
MetadataRequest(MetadataState::Complete), arguments, descriptor, index);
|
||||
return (const WitnessTable *)response.Value;
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
const WitnessTable *
|
||||
swift_getOpaqueTypeConformance(const void * const *arguments,
|
||||
swift_getOpaqueTypeConformance2(const void * const *arguments,
|
||||
const OpaqueTypeDescriptor *descriptor,
|
||||
unsigned index) {
|
||||
auto response = swift_getOpaqueTypeMetadata(
|
||||
MetadataRequest(MetadataState::Complete),
|
||||
arguments, descriptor, index);
|
||||
return (const WitnessTable *)response.Value;
|
||||
descriptor = swift_auth_data_non_address(
|
||||
descriptor, SpecialPointerAuthDiscriminators::OpaqueTypeDescriptor);
|
||||
return swift_getOpaqueTypeConformanceImpl(arguments, descriptor, index);
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
const WitnessTable *
|
||||
swift_getOpaqueTypeConformance(const void * const *arguments,
|
||||
const void *descriptor,
|
||||
unsigned index) {
|
||||
// This call takes `descriptor` without a ptrauth signature. We
|
||||
// declare it as `void *` to avoid the implicit ptrauth we get from
|
||||
// the ptrauth_struct attribute. The static_cast implicitly signs the
|
||||
// pointer when we call through to the implementation in
|
||||
// swift_getOpaqueTypeConformanceImpl.
|
||||
return swift_getOpaqueTypeConformanceImpl(
|
||||
arguments, static_cast<const OpaqueTypeDescriptor *>(descriptor), index);
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
|
||||
@@ -1147,8 +1147,8 @@ swift_conformsToProtocolMaybeInstantiateSuperclasses(
|
||||
}
|
||||
|
||||
static const WitnessTable *
|
||||
swift_conformsToProtocolImpl(const Metadata *const type,
|
||||
const ProtocolDescriptor *protocol) {
|
||||
swift_conformsToProtocolCommonImpl(const Metadata *const type,
|
||||
const ProtocolDescriptor *protocol) {
|
||||
const WitnessTable *table;
|
||||
bool hasUninstantiatedSuperclass;
|
||||
|
||||
@@ -1173,6 +1173,26 @@ swift_conformsToProtocolImpl(const Metadata *const type,
|
||||
return table;
|
||||
}
|
||||
|
||||
static const WitnessTable *
|
||||
swift_conformsToProtocol2Impl(const Metadata *const type,
|
||||
const ProtocolDescriptor *protocol) {
|
||||
protocol = swift_auth_data_non_address(
|
||||
protocol, SpecialPointerAuthDiscriminators::ProtocolDescriptor);
|
||||
return swift_conformsToProtocolCommonImpl(type, protocol);
|
||||
}
|
||||
|
||||
static const WitnessTable *
|
||||
swift_conformsToProtocolImpl(const Metadata *const type,
|
||||
const void *protocol) {
|
||||
// This call takes `protocol` without a ptrauth signature. We declare
|
||||
// it as `void *` to avoid the implicit ptrauth we get from the
|
||||
// ptrauth_struct attribute. The static_cast implicitly signs the
|
||||
// pointer when we call through to the implementation in
|
||||
// swift_conformsToProtocolCommon.
|
||||
return swift_conformsToProtocolCommonImpl(
|
||||
type, static_cast<const ProtocolDescriptor *>(protocol));
|
||||
}
|
||||
|
||||
const ContextDescriptor *
|
||||
swift::_searchConformancesByMangledTypeName(Demangle::NodePointer node) {
|
||||
auto traceState = runtime::trace::protocol_conformance_scan_begin(node);
|
||||
|
||||
@@ -1644,7 +1644,7 @@ const HashableWitnessTable *
|
||||
swift::hashable_support::getNSStringHashableConformance() {
|
||||
return SWIFT_LAZY_CONSTANT(
|
||||
reinterpret_cast<const HashableWitnessTable *>(
|
||||
swift_conformsToProtocol(
|
||||
swift_conformsToProtocolCommon(
|
||||
getNSStringMetadata(),
|
||||
&HashableProtocolDescriptor
|
||||
)
|
||||
|
||||
@@ -117,7 +117,7 @@ SwiftValueHeader::getHashableConformance() const {
|
||||
const HashableWitnessTable *expectedWT = nullptr;
|
||||
const HashableWitnessTable *wt =
|
||||
reinterpret_cast<const HashableWitnessTable *>(
|
||||
swift_conformsToProtocol(type, &HashableProtocolDescriptor));
|
||||
swift_conformsToProtocolCommon(type, &HashableProtocolDescriptor));
|
||||
hashableConformance.compare_exchange_strong(
|
||||
expectedWT, wt ? wt : reinterpret_cast<const HashableWitnessTable *>(1),
|
||||
std::memory_order_acq_rel);
|
||||
|
||||
@@ -192,7 +192,7 @@ public func useFoo(x: String, y: C) {
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @"$s18opaque_result_type6useFoo1x1yySS_AA1CCtF"
|
||||
// CHECK: [[OPAQUE:%.*]] = call {{.*}} @"$s18opaque_result_type3baz1zQrx_tAA1PRzAA1QRzlFQOMg"
|
||||
// CHECK: [[CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance(ptr {{.*}}, ptr [[OPAQUE]], [[WORD:i32|i64]] 1)
|
||||
// CHECK: [[CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance{{2?}}(ptr {{.*}}, ptr [[OPAQUE]], [[WORD:i32|i64]] 1)
|
||||
// CHECK: [[TYPE:%.*]] = call {{.*}} @__swift_instantiateConcreteTypeFromMangledName{{.*}}({{.*}} @"$s18opaque_result_type3baz1zQrx_tAA1PRzAA1QRzlFQOyAA1CCQo_MD")
|
||||
// CHECK: call swiftcc ptr @swift_getAssociatedConformanceWitness(ptr [[CONFORMANCE]], ptr [[TYPE]]
|
||||
|
||||
@@ -210,7 +210,7 @@ public func gimmeBoom() -> Any {
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @"$sSS18opaque_result_type1PAA1AAaBP_AA1OPWT"
|
||||
// CHECK: [[OPAQUE:%.*]] = call {{.*}} @"$sSS18opaque_result_typeE3pooQryFQOMg"
|
||||
// CHECK: call swiftcc ptr @swift_getOpaqueTypeConformance(ptr {{.*}}, ptr [[OPAQUE]], [[WORD]] 1)
|
||||
// CHECK: call swiftcc ptr @swift_getOpaqueTypeConformance{{2?}}(ptr {{.*}}, ptr [[OPAQUE]], [[WORD]] 1)
|
||||
|
||||
// rdar://problem/49585457
|
||||
protocol R {
|
||||
|
||||
@@ -15,7 +15,7 @@ struct Foo<T: Tubb>: P {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{.*}} @"$s030opaque_result_type_associated_C17_conformance_path3FooVyxGAA1PAA1AAaEP_AA4ButtPWT"
|
||||
// CHECK: [[TUBB_CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance({{.*}}, i{{.*}} 1)
|
||||
// CHECK: [[TUBB_CONFORMANCE:%.*]] = call swiftcc ptr @swift_getOpaqueTypeConformance{{2?}}({{.*}}, i{{.*}} 1)
|
||||
// CHECK: [[BUTT_CONFORMANCE_ADDR:%.*]] = getelementptr {{.*}} [[TUBB_CONFORMANCE]], i32 1
|
||||
// CHECK: [[BUTT_CONFORMANCE:%.*]] = load {{.*}} [[BUTT_CONFORMANCE_ADDR]]
|
||||
// CHECK: ret {{.*}} [[BUTT_CONFORMANCE]]
|
||||
|
||||
@@ -178,6 +178,16 @@ TEST_F(CompatibilityOverrideRuntimeTest, test_swift_conformsToProtocol) {
|
||||
ASSERT_EQ(Result, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CompatibilityOverrideRuntimeTest, test_swift_conformsToProtocol2) {
|
||||
auto Result = swift_conformsToProtocol2(nullptr, nullptr);
|
||||
ASSERT_EQ(Result, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CompatibilityOverrideRuntimeTest, test_swift_conformsToProtocolCommon) {
|
||||
auto Result = swift_conformsToProtocolCommon(nullptr, nullptr);
|
||||
ASSERT_EQ(Result, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CompatibilityOverrideRuntimeTest, test_swift_getTypeByMangledNode) {
|
||||
Demangler demangler;
|
||||
auto Result = swift_getTypeByMangledNode(MetadataState::Abstract,
|
||||
|
||||
Reference in New Issue
Block a user