mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Make Objective-C interoperability configurable in the runtime
In order to be able to debug, for example, a Linux process from a macOS host, we
need to be able to initialize a ReflectionContext without Objective-C
interoperability. This patch turns ObjCInterOp into another template trait, so
it's possible to instantiate a non-ObjC MetadataReader on a system built with
ObjC-interop (but not vice versa).
This patch changes the class hierarchy to
TargetMetadata<Runtime>
|
TargetHeapMetadata<Runtime>
|
TargetAnyClassMetadata<Runtime>
/ \
/ TargetAnyClassMetadataObjCInterop<Runtime>
/ \
TargetClassMetadata<Runtime, TargetAnyClassMetadata<Runtime>> \
\
TargetClassMetadata<Runtime, TargetAnyClassMetadataObjCInterop<Runtime>>
TargetAnyClassMetadataObjCInterop inherits from TargetAnyClassMetadata because
most of the implementation is the same. This choice makes TargetClassMetadata a
bit tricky. In this patch I went with templating the parent class.
rdar://87179578
This commit is contained in:
@@ -48,6 +48,24 @@
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
namespace swift {
|
||||
|
||||
template <typename Runtime> struct TargetGenericMetadataInstantiationCache;
|
||||
template <typename Runtime> struct TargetAnyClassMetadata;
|
||||
template <typename Runtime> struct TargetAnyClassMetadataObjCInterop;
|
||||
template <typename Runtime, typename TargetAnyClassMetadataVariant>
|
||||
struct TargetClassMetadata;
|
||||
template <typename Runtime> struct TargetStructMetadata;
|
||||
template <typename Runtime> struct TargetOpaqueMetadata;
|
||||
template <typename Runtime> struct TargetValueMetadata;
|
||||
template <typename Runtime> struct TargetForeignClassMetadata;
|
||||
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 TargetGenericMetadataPattern;
|
||||
|
||||
template <unsigned PointerSize>
|
||||
struct RuntimeTarget;
|
||||
|
||||
@@ -90,6 +108,18 @@ struct InProcess {
|
||||
using StoredSize = size_t;
|
||||
using StoredPointerDifference = ptrdiff_t;
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
static constexpr bool ObjCInterop = true;
|
||||
template <typename T>
|
||||
using TargetAnyClassMetadata = TargetAnyClassMetadataObjCInterop<T>;
|
||||
#else
|
||||
static constexpr bool ObjCInterop = false;
|
||||
template <typename T>
|
||||
using TargetAnyClassMetadata = TargetAnyClassMetadata<T>;
|
||||
#endif
|
||||
template <typename T>
|
||||
using TargetClassMetadata = TargetClassMetadata<T, TargetAnyClassMetadata<T>>;
|
||||
|
||||
static_assert(sizeof(StoredSize) == sizeof(StoredPointerDifference),
|
||||
"target uses differently-sized size_t and ptrdiff_t");
|
||||
|
||||
@@ -120,14 +150,44 @@ struct ExternalPointer {
|
||||
StoredPointer PointerValue;
|
||||
};
|
||||
|
||||
/// An external process's runtime target, which may be a different architecture.
|
||||
template <typename Runtime> struct WithObjCInterop {
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
|
||||
static constexpr size_t PointerSize = Runtime::PointerSize;
|
||||
static constexpr bool ObjCInterop = true;
|
||||
template <typename T>
|
||||
using TargetAnyClassMetadata = TargetAnyClassMetadataObjCInterop<T>;
|
||||
};
|
||||
|
||||
template <typename Runtime> struct NoObjCInterop {
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
|
||||
static constexpr size_t PointerSize = Runtime::PointerSize;
|
||||
static constexpr bool ObjCInterop = false;
|
||||
template <typename T>
|
||||
using TargetAnyClassMetadata = TargetAnyClassMetadata<T>;
|
||||
};
|
||||
|
||||
/// An external process's runtime target, which may be a different architecture,
|
||||
/// and may or may not have Objective-C interoperability.
|
||||
template <typename Runtime>
|
||||
struct External {
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
|
||||
template <typename T>
|
||||
using TargetAnyClassMetadata =
|
||||
typename Runtime::template TargetAnyClassMetadata<T>;
|
||||
template <typename T>
|
||||
using TargetClassMetadata = TargetClassMetadata<T, TargetAnyClassMetadata<T>>;
|
||||
|
||||
static constexpr size_t PointerSize = Runtime::PointerSize;
|
||||
static constexpr bool ObjCInterop = Runtime::ObjCInterop;
|
||||
const StoredPointer PointerValue;
|
||||
|
||||
template <typename T>
|
||||
@@ -478,21 +538,6 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Runtime> struct TargetGenericMetadataInstantiationCache;
|
||||
template <typename Runtime> struct TargetAnyClassMetadata;
|
||||
template <typename Runtime> struct TargetClassMetadata;
|
||||
template <typename Runtime> struct TargetStructMetadata;
|
||||
template <typename Runtime> struct TargetOpaqueMetadata;
|
||||
template <typename Runtime> struct TargetValueMetadata;
|
||||
template <typename Runtime> struct TargetForeignClassMetadata;
|
||||
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 TargetGenericMetadataPattern;
|
||||
|
||||
using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;
|
||||
|
||||
// FIXME: https://bugs.swift.org/browse/SR-1155
|
||||
@@ -540,7 +585,7 @@ struct TargetMetadata {
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
protected:
|
||||
constexpr TargetMetadata(TargetAnyClassMetadata<Runtime> *isa)
|
||||
constexpr TargetMetadata(TargetAnyClassMetadataObjCInterop<Runtime> *isa)
|
||||
: Kind(reinterpret_cast<StoredPointer>(isa)) {}
|
||||
#endif
|
||||
|
||||
@@ -559,7 +604,6 @@ public:
|
||||
Kind = static_cast<StoredPointer>(kind);
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
protected:
|
||||
const TargetAnyClassMetadata<Runtime> *getClassISA() const {
|
||||
return reinterpret_cast<const TargetAnyClassMetadata<Runtime> *>(Kind);
|
||||
@@ -567,7 +611,6 @@ protected:
|
||||
void setClassISA(const TargetAnyClassMetadata<Runtime> *isa) {
|
||||
Kind = reinterpret_cast<StoredPointer>(isa);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
/// Is this a class object--the metadata record for a Swift class (which also
|
||||
@@ -684,12 +727,23 @@ public:
|
||||
getTypeContextDescriptor() const {
|
||||
switch (getKind()) {
|
||||
case MetadataKind::Class: {
|
||||
const auto cls = static_cast<const TargetClassMetadata<Runtime> *>(this);
|
||||
if (!cls->isTypeMetadata())
|
||||
return nullptr;
|
||||
if (cls->isArtificialSubclass())
|
||||
return nullptr;
|
||||
return cls->getDescription();
|
||||
if (Runtime::ObjCInterop) {
|
||||
const auto cls = static_cast<const TargetClassMetadata<
|
||||
Runtime, TargetAnyClassMetadataObjCInterop<Runtime>> *>(this);
|
||||
if (!cls->isTypeMetadata())
|
||||
return nullptr;
|
||||
if (cls->isArtificialSubclass())
|
||||
return nullptr;
|
||||
return cls->getDescription();
|
||||
} else {
|
||||
const auto cls = static_cast<const TargetClassMetadata<
|
||||
Runtime, TargetAnyClassMetadata<Runtime>> *>(this);
|
||||
if (!cls->isTypeMetadata())
|
||||
return nullptr;
|
||||
if (cls->isArtificialSubclass())
|
||||
return nullptr;
|
||||
return cls->getDescription();
|
||||
}
|
||||
}
|
||||
case MetadataKind::Struct:
|
||||
case MetadataKind::Enum:
|
||||
@@ -706,7 +760,8 @@ public:
|
||||
|
||||
/// Get the class object for this type if it has one, or return null if the
|
||||
/// type is not a class (or not a class with a class object).
|
||||
const TargetClassMetadata<Runtime> *getClassObject() const;
|
||||
const typename Runtime::template TargetClassMetadata<Runtime> *
|
||||
getClassObject() const;
|
||||
|
||||
/// Retrieve the generic arguments of this type, if it has any.
|
||||
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> const *
|
||||
@@ -740,8 +795,9 @@ public:
|
||||
typename std::enable_if<std::is_same<R, InProcess>::value, Class>::type
|
||||
getObjCClassObject() const {
|
||||
return reinterpret_cast<Class>(
|
||||
const_cast<TargetClassMetadata<InProcess>*>(
|
||||
getClassObject()));
|
||||
const_cast<TargetClassMetadata<
|
||||
InProcess, TargetAnyClassMetadataObjCInterop<InProcess>> *>(
|
||||
getClassObject()));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -777,7 +833,9 @@ template <typename Runtime>
|
||||
struct TargetHeapMetadataHeaderPrefix {
|
||||
/// Destroy the object, returning the allocated size of the object
|
||||
/// or 0 if the object shouldn't be deallocated.
|
||||
TargetSignedPointer<Runtime, HeapObjectDestroyer *__ptrauth_swift_heap_object_destructor> destroy;
|
||||
TargetSignedPointer<Runtime, HeapObjectDestroyer *
|
||||
__ptrauth_swift_heap_object_destructor>
|
||||
destroy;
|
||||
};
|
||||
using HeapMetadataHeaderPrefix =
|
||||
TargetHeapMetadataHeaderPrefix<InProcess>;
|
||||
@@ -809,10 +867,8 @@ struct TargetHeapMetadata : TargetMetadata<Runtime> {
|
||||
TargetHeapMetadata() = default;
|
||||
constexpr TargetHeapMetadata(MetadataKind kind)
|
||||
: TargetMetadata<Runtime>(kind) {}
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
constexpr TargetHeapMetadata(TargetAnyClassMetadata<Runtime> *isa)
|
||||
constexpr TargetHeapMetadata(TargetAnyClassMetadataObjCInterop<Runtime> *isa)
|
||||
: TargetMetadata<Runtime>(isa) {}
|
||||
#endif
|
||||
};
|
||||
using HeapMetadata = TargetHeapMetadata<InProcess>;
|
||||
|
||||
@@ -949,6 +1005,8 @@ struct TargetClassMetadataBounds : TargetMetadataBounds<Runtime> {
|
||||
|
||||
using TargetMetadataBounds<Runtime>::NegativeSizeInWords;
|
||||
using TargetMetadataBounds<Runtime>::PositiveSizeInWords;
|
||||
using TargetClassMetadata =
|
||||
typename Runtime::template TargetClassMetadata<Runtime>;
|
||||
|
||||
/// The offset from the address point of the metadata to the immediate
|
||||
/// members.
|
||||
@@ -961,10 +1019,13 @@ struct TargetClassMetadataBounds : TargetMetadataBounds<Runtime> {
|
||||
: TargetMetadataBounds<Runtime>{negativeSizeInWords, positiveSizeInWords},
|
||||
ImmediateMembersOffset(immediateMembersOffset) {}
|
||||
|
||||
template <typename T>
|
||||
using TargetClassMetadataT = typename Runtime::template TargetClassMetadata<T>;
|
||||
|
||||
/// Return the basic bounds of all Swift class metadata.
|
||||
/// The immediate members offset will not be meaningful.
|
||||
static constexpr TargetClassMetadataBounds<Runtime> forSwiftRootClass() {
|
||||
using Metadata = FullMetadata<TargetClassMetadata<Runtime>>;
|
||||
using Metadata = FullMetadata<TargetClassMetadataT<Runtime>>;
|
||||
return forAddressPointAndSize(sizeof(typename Metadata::HeaderType),
|
||||
sizeof(Metadata));
|
||||
}
|
||||
@@ -1007,39 +1068,65 @@ template <typename Runtime>
|
||||
struct TargetAnyClassMetadata : public TargetHeapMetadata<Runtime> {
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
using TargetClassMetadata =
|
||||
typename Runtime::template TargetClassMetadata<Runtime>;
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
constexpr TargetAnyClassMetadata(TargetAnyClassMetadata<Runtime> *isa,
|
||||
TargetClassMetadata<Runtime> *superclass)
|
||||
: TargetHeapMetadata<Runtime>(isa),
|
||||
Superclass(superclass),
|
||||
CacheData{nullptr, nullptr},
|
||||
Data(SWIFT_CLASS_IS_SWIFT_MASK) {}
|
||||
#endif
|
||||
|
||||
constexpr TargetAnyClassMetadata(TargetClassMetadata<Runtime> *superclass)
|
||||
: TargetHeapMetadata<Runtime>(MetadataKind::Class),
|
||||
Superclass(superclass)
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
, CacheData{nullptr, nullptr},
|
||||
Data(SWIFT_CLASS_IS_SWIFT_MASK)
|
||||
#endif
|
||||
{}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
// Allow setting the metadata kind to a class ISA on class metadata.
|
||||
using TargetMetadata<Runtime>::getClassISA;
|
||||
using TargetMetadata<Runtime>::setClassISA;
|
||||
#endif
|
||||
protected:
|
||||
constexpr TargetAnyClassMetadata(
|
||||
TargetAnyClassMetadataObjCInterop<Runtime> *isa,
|
||||
TargetClassMetadata *superclass)
|
||||
: TargetHeapMetadata<Runtime>(isa), Superclass(superclass) {}
|
||||
public:
|
||||
constexpr TargetAnyClassMetadata(TargetClassMetadata *superclass)
|
||||
: TargetHeapMetadata<Runtime>(MetadataKind::Class),
|
||||
Superclass(superclass) {}
|
||||
|
||||
// Note that ObjC classes do not have a metadata header.
|
||||
|
||||
/// The metadata for the superclass. This is null for the root class.
|
||||
TargetSignedPointer<Runtime, const TargetClassMetadata<Runtime> *
|
||||
TargetSignedPointer<Runtime, const TargetClassMetadata *
|
||||
__ptrauth_swift_objc_superclass>
|
||||
Superclass;
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
/// Is this object a valid swift type metadata? That is, can it be
|
||||
/// safely downcast to ClassMetadata?
|
||||
bool isTypeMetadata() const {
|
||||
return true;
|
||||
}
|
||||
/// A different perspective on the same bit.
|
||||
bool isPureObjC() const {
|
||||
return !isTypeMetadata();
|
||||
}
|
||||
};
|
||||
|
||||
/// This is the class metadata object for all classes (Swift and ObjC) in a
|
||||
/// runtime that has Objective-C interoperability.
|
||||
template <typename Runtime>
|
||||
struct TargetAnyClassMetadataObjCInterop
|
||||
: public TargetAnyClassMetadata<Runtime> {
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
|
||||
using TargetClassMetadataObjCInterop =
|
||||
TargetClassMetadata<Runtime, TargetAnyClassMetadataObjCInterop<Runtime>>;
|
||||
|
||||
constexpr TargetAnyClassMetadataObjCInterop(
|
||||
TargetAnyClassMetadataObjCInterop<Runtime> *isa,
|
||||
TargetClassMetadataObjCInterop *superclass)
|
||||
: TargetAnyClassMetadata<Runtime>(isa, superclass),
|
||||
CacheData{nullptr, nullptr},
|
||||
Data(SWIFT_CLASS_IS_SWIFT_MASK) {}
|
||||
|
||||
constexpr TargetAnyClassMetadataObjCInterop(
|
||||
TargetClassMetadataObjCInterop *superclass)
|
||||
: TargetAnyClassMetadata<Runtime>(superclass), CacheData{nullptr,
|
||||
nullptr},
|
||||
Data(SWIFT_CLASS_IS_SWIFT_MASK) {}
|
||||
|
||||
// Allow setting the metadata kind to a class ISA on class metadata.
|
||||
using TargetMetadata<Runtime>::getClassISA;
|
||||
using TargetMetadata<Runtime>::setClassISA;
|
||||
|
||||
/// The cache data is used for certain dynamic lookups; it is owned
|
||||
/// by the runtime and generally needs to interoperate with
|
||||
/// Objective-C's use.
|
||||
@@ -1052,26 +1139,25 @@ struct TargetAnyClassMetadata : public TargetHeapMetadata<Runtime> {
|
||||
StoredSize Data;
|
||||
|
||||
static constexpr StoredPointer offsetToData() {
|
||||
return offsetof(TargetAnyClassMetadata, Data);
|
||||
return offsetof(TargetAnyClassMetadataObjCInterop, Data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Is this object a valid swift type metadata? That is, can it be
|
||||
/// safely downcast to ClassMetadata?
|
||||
bool isTypeMetadata() const {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
return (Data & SWIFT_CLASS_IS_SWIFT_MASK);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
/// A different perspective on the same bit
|
||||
bool isPureObjC() const {
|
||||
return !isTypeMetadata();
|
||||
}
|
||||
};
|
||||
using AnyClassMetadata =
|
||||
TargetAnyClassMetadata<InProcess>;
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
using AnyClassMetadata = TargetAnyClassMetadataObjCInterop<InProcess>;
|
||||
#else
|
||||
using AnyClassMetadata = TargetAnyClassMetadata<InProcess>;
|
||||
#endif
|
||||
|
||||
using ClassIVarDestroyer =
|
||||
SWIFT_CC(swift) void(SWIFT_CONTEXT HeapObject *);
|
||||
@@ -1082,23 +1168,28 @@ using ClassIVarDestroyer =
|
||||
///
|
||||
/// Note that the layout of this type is compatible with the layout of
|
||||
/// an Objective-C class.
|
||||
template <typename Runtime>
|
||||
struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> {
|
||||
///
|
||||
/// If the Runtime supports Objective-C interoperability, this class inherits
|
||||
/// from TargetAnyClassMetadataObjCInterop, otherwise it inherits from
|
||||
/// TargetAnyClassMetadata.
|
||||
template <typename Runtime, typename TargetAnyClassMetadataVariant>
|
||||
struct TargetClassMetadata : public TargetAnyClassMetadataVariant {
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
|
||||
TargetClassMetadata() = default;
|
||||
constexpr TargetClassMetadata(const TargetAnyClassMetadata<Runtime> &base,
|
||||
ClassFlags flags,
|
||||
ClassIVarDestroyer *ivarDestroyer,
|
||||
StoredPointer size, StoredPointer addressPoint,
|
||||
StoredPointer alignMask,
|
||||
StoredPointer classSize, StoredPointer classAddressPoint)
|
||||
: TargetAnyClassMetadata<Runtime>(base),
|
||||
Flags(flags), InstanceAddressPoint(addressPoint),
|
||||
InstanceSize(size), InstanceAlignMask(alignMask),
|
||||
Reserved(0), ClassSize(classSize), ClassAddressPoint(classAddressPoint),
|
||||
Description(nullptr), IVarDestroyer(ivarDestroyer) {}
|
||||
constexpr TargetClassMetadata(const TargetAnyClassMetadataVariant &base,
|
||||
ClassFlags flags,
|
||||
ClassIVarDestroyer *ivarDestroyer,
|
||||
StoredPointer size, StoredPointer addressPoint,
|
||||
StoredPointer alignMask,
|
||||
StoredPointer classSize,
|
||||
StoredPointer classAddressPoint)
|
||||
: TargetAnyClassMetadataVariant(base), Flags(flags),
|
||||
InstanceAddressPoint(addressPoint), InstanceSize(size),
|
||||
InstanceAlignMask(alignMask), Reserved(0), ClassSize(classSize),
|
||||
ClassAddressPoint(classAddressPoint), Description(nullptr),
|
||||
IVarDestroyer(ivarDestroyer) {}
|
||||
|
||||
// The remaining fields are valid only when isTypeMetadata().
|
||||
// The Objective-C runtime knows the offsets to some of these fields.
|
||||
@@ -1150,7 +1241,7 @@ public:
|
||||
// - class variables (if we choose to support these)
|
||||
// - "tabulated" virtual methods
|
||||
|
||||
using TargetAnyClassMetadata<Runtime>::isTypeMetadata;
|
||||
using TargetAnyClassMetadataVariant::isTypeMetadata;
|
||||
|
||||
ConstTargetMetadataPointer<Runtime, TargetClassDescriptor>
|
||||
getDescription() const {
|
||||
@@ -1350,7 +1441,18 @@ public:
|
||||
return metadata->getKind() == MetadataKind::Class;
|
||||
}
|
||||
};
|
||||
using ClassMetadata = TargetClassMetadata<InProcess>;
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
using ClassMetadata =
|
||||
TargetClassMetadata<InProcess,
|
||||
TargetAnyClassMetadataObjCInterop<InProcess>>;
|
||||
#else
|
||||
using ClassMetadata =
|
||||
TargetClassMetadata<InProcess, TargetAnyClassMetadata<InProcess>>;
|
||||
#endif
|
||||
|
||||
template <typename Runtime>
|
||||
using TargetClassMetadataObjCInterop =
|
||||
TargetClassMetadata<Runtime, TargetAnyClassMetadataObjCInterop<Runtime>>;
|
||||
|
||||
/// The structure of class metadata that's compatible with dispatch objects.
|
||||
/// This includes Swift heap metadata, followed by the vtable entries that
|
||||
@@ -1398,7 +1500,7 @@ using HeapLocalVariableMetadata
|
||||
/// Swift-compiled.
|
||||
template <typename Runtime>
|
||||
struct TargetObjCClassWrapperMetadata : public TargetMetadata<Runtime> {
|
||||
ConstTargetMetadataPointer<Runtime, TargetClassMetadata> Class;
|
||||
ConstTargetMetadataPointer<Runtime, TargetClassMetadataObjCInterop> Class;
|
||||
|
||||
static bool classof(const TargetMetadata<Runtime> *metadata) {
|
||||
return metadata->getKind() == MetadataKind::ObjCClassWrapper;
|
||||
@@ -1832,7 +1934,6 @@ TargetTupleTypeMetadata<Runtime>::getOffsetToNumElements() -> StoredSize {
|
||||
|
||||
template <typename Runtime> struct TargetProtocolDescriptor;
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
/// Layout of a small prefix of an Objective-C protocol, used only to
|
||||
/// directly extract the name of the protocol.
|
||||
template <typename Runtime>
|
||||
@@ -1843,7 +1944,6 @@ struct TargetObjCProtocolPrefix {
|
||||
/// The mangled name of the protocol.
|
||||
TargetPointer<Runtime, const char> Name;
|
||||
};
|
||||
#endif
|
||||
|
||||
/// A reference to a protocol within the runtime, which may be either
|
||||
/// a Swift protocol or (when Objective-C interoperability is enabled) an
|
||||
@@ -1877,13 +1977,14 @@ public:
|
||||
TargetProtocolDescriptorRef(
|
||||
ProtocolDescriptorPointer protocol,
|
||||
ProtocolDispatchStrategy dispatchStrategy) {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
storage = reinterpret_cast<StoredPointer>(protocol)
|
||||
| (dispatchStrategy == ProtocolDispatchStrategy::ObjC ? IsObjCBit : 0);
|
||||
#else
|
||||
assert(dispatchStrategy == ProtocolDispatchStrategy::Swift);
|
||||
storage = reinterpret_cast<StoredPointer>(protocol);
|
||||
#endif
|
||||
if (Runtime::ObjCInterop) {
|
||||
storage =
|
||||
reinterpret_cast<StoredPointer>(protocol) |
|
||||
(dispatchStrategy == ProtocolDispatchStrategy::ObjC ? IsObjCBit : 0);
|
||||
} else {
|
||||
assert(dispatchStrategy == ProtocolDispatchStrategy::Swift);
|
||||
storage = reinterpret_cast<StoredPointer>(protocol);
|
||||
}
|
||||
}
|
||||
|
||||
const static TargetProtocolDescriptorRef forSwift(
|
||||
@@ -1917,22 +2018,18 @@ public:
|
||||
|
||||
/// Determine what kind of protocol this is, Swift or Objective-C.
|
||||
ProtocolDispatchStrategy getDispatchStrategy() const {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (isObjC()) {
|
||||
return ProtocolDispatchStrategy::ObjC;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ProtocolDispatchStrategy::Swift;
|
||||
}
|
||||
|
||||
/// Determine whether this protocol has a 'class' constraint.
|
||||
ProtocolClassConstraint getClassConstraint() const {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (isObjC()) {
|
||||
return ProtocolClassConstraint::Class;
|
||||
}
|
||||
#endif
|
||||
|
||||
return getSwiftProtocol()->getProtocolContextDescriptorFlags()
|
||||
.getClassConstraint();
|
||||
@@ -1940,21 +2037,17 @@ public:
|
||||
|
||||
/// Determine whether this protocol needs a witness table.
|
||||
bool needsWitnessTable() const {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (isObjC()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SpecialProtocol getSpecialProtocol() const {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (isObjC()) {
|
||||
return SpecialProtocol::None;
|
||||
}
|
||||
#endif
|
||||
|
||||
return getSwiftProtocol()->getProtocolContextDescriptorFlags()
|
||||
.getSpecialProtocol();
|
||||
@@ -1962,9 +2055,7 @@ public:
|
||||
|
||||
/// Retrieve the Swift protocol descriptor.
|
||||
ProtocolDescriptorPointer getSwiftProtocol() const {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
assert(!isObjC());
|
||||
#endif
|
||||
|
||||
// NOTE: we explicitly use a C-style cast here because cl objects to the
|
||||
// reinterpret_cast from a uintptr_t type to an unsigned type which the
|
||||
@@ -1978,12 +2069,15 @@ public:
|
||||
return storage;
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
/// Whether this references an Objective-C protocol.
|
||||
bool isObjC() const {
|
||||
return (storage & IsObjCBit) != 0;
|
||||
if (Runtime::ObjCInterop)
|
||||
return (storage & IsObjCBit) != 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
/// Retrieve the Objective-C protocol.
|
||||
TargetPointer<Runtime, Protocol> getObjCProtocol() const {
|
||||
assert(isObjC());
|
||||
@@ -2460,11 +2554,13 @@ class RelativeTargetProtocolDescriptorPointer {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
bool isObjC() const {
|
||||
return objcPointer.getInt();
|
||||
}
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (Runtime::ObjCInterop)
|
||||
return objcPointer.getInt();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Retrieve a reference to the protocol.
|
||||
@@ -2472,13 +2568,14 @@ public:
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (isObjC()) {
|
||||
return TargetProtocolDescriptorRef<Runtime>::forObjC(
|
||||
const_cast<Protocol*>(objcPointer.getPointer()));
|
||||
const_cast<Protocol *>(objcPointer.getPointer()));
|
||||
}
|
||||
#endif
|
||||
|
||||
return TargetProtocolDescriptorRef<Runtime>::forSwift(
|
||||
reinterpret_cast<ConstTargetMetadataPointer<
|
||||
Runtime, TargetProtocolDescriptor>>(swiftPointer.getPointer()));
|
||||
reinterpret_cast<
|
||||
ConstTargetMetadataPointer<Runtime, TargetProtocolDescriptor>>(
|
||||
swiftPointer.getPointer()));
|
||||
}
|
||||
|
||||
operator TargetProtocolDescriptorRef<Runtime>() const {
|
||||
@@ -2489,6 +2586,9 @@ public:
|
||||
/// A reference to a type.
|
||||
template <typename Runtime>
|
||||
struct TargetTypeReference {
|
||||
template <typename T>
|
||||
using TargetClassMetadata = typename T::template TargetClassMetadata<T>;
|
||||
|
||||
union {
|
||||
/// A direct reference to a TypeContextDescriptor or ProtocolDescriptor.
|
||||
RelativeDirectPointer<TargetContextDescriptor<Runtime>>
|
||||
@@ -2502,7 +2602,7 @@ struct TargetTypeReference {
|
||||
/// An indirect reference to an Objective-C class.
|
||||
RelativeDirectPointer<
|
||||
ConstTargetMetadataPointer<Runtime, TargetClassMetadata>>
|
||||
IndirectObjCClass;
|
||||
IndirectObjCClass;
|
||||
|
||||
/// A direct reference to an Objective-C class name.
|
||||
RelativeDirectPointer<const char>
|
||||
@@ -2526,14 +2626,12 @@ struct TargetTypeReference {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
/// If this type reference is one of the kinds that supports ObjC
|
||||
/// references,
|
||||
const TargetClassMetadata<Runtime> *
|
||||
const TargetClassMetadataObjCInterop<Runtime> *
|
||||
getObjCClass(TypeReferenceKind kind) const;
|
||||
#endif
|
||||
|
||||
const TargetClassMetadata<Runtime> * const *
|
||||
const TargetClassMetadataObjCInterop<Runtime> * const *
|
||||
getIndirectObjCClass(TypeReferenceKind kind) const {
|
||||
assert(kind == TypeReferenceKind::IndirectObjCClass);
|
||||
return IndirectObjCClass.get();
|
||||
@@ -2615,10 +2713,11 @@ public:
|
||||
return TypeRef.getDirectObjCClassName(getTypeKind());
|
||||
}
|
||||
|
||||
const TargetClassMetadata<Runtime> * const *getIndirectObjCClass() const {
|
||||
const TargetClassMetadataObjCInterop<Runtime> *const *
|
||||
getIndirectObjCClass() const {
|
||||
return TypeRef.getIndirectObjCClass(getTypeKind());
|
||||
}
|
||||
|
||||
|
||||
const TargetContextDescriptor<Runtime> *getTypeDescriptor() const {
|
||||
return TypeRef.getTypeDescriptor(getTypeKind());
|
||||
}
|
||||
|
||||
@@ -168,6 +168,8 @@ public:
|
||||
using StoredPointer = typename Runtime::StoredPointer;
|
||||
using StoredSignedPointer = typename Runtime::StoredSignedPointer;
|
||||
using StoredSize = typename Runtime::StoredSize;
|
||||
using TargetClassMetadata =
|
||||
typename Runtime::template TargetClassMetadata<Runtime>;
|
||||
|
||||
private:
|
||||
/// The maximum number of bytes to read when reading metadata. Anything larger
|
||||
@@ -502,7 +504,7 @@ public:
|
||||
if (!meta || meta->getKind() != MetadataKind::Class)
|
||||
return StoredPointer();
|
||||
|
||||
auto classMeta = cast<TargetClassMetadata<Runtime>>(meta);
|
||||
auto classMeta = cast<TargetClassMetadata>(meta);
|
||||
return stripSignedPointer(classMeta->Superclass);
|
||||
}
|
||||
|
||||
@@ -514,39 +516,39 @@ public:
|
||||
if (!meta || meta->getKind() != MetadataKind::Class)
|
||||
return None;
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
// The following algorithm only works on the non-fragile Apple runtime.
|
||||
if (Runtime::ObjCInterop) {
|
||||
// The following algorithm only works on the non-fragile Apple runtime.
|
||||
|
||||
// Grab the RO-data pointer. This part is not ABI.
|
||||
StoredPointer roDataPtr = readObjCRODataPtr(MetadataAddress);
|
||||
if (!roDataPtr)
|
||||
return None;
|
||||
// Grab the RO-data pointer. This part is not ABI.
|
||||
StoredPointer roDataPtr = readObjCRODataPtr(MetadataAddress);
|
||||
if (!roDataPtr)
|
||||
return None;
|
||||
|
||||
// Get the address of the InstanceStart field.
|
||||
auto address = roDataPtr + sizeof(uint32_t) * 1;
|
||||
// Get the address of the InstanceStart field.
|
||||
auto address = roDataPtr + sizeof(uint32_t) * 1;
|
||||
|
||||
unsigned start;
|
||||
if (!Reader->readInteger(RemoteAddress(address), &start))
|
||||
return None;
|
||||
unsigned start;
|
||||
if (!Reader->readInteger(RemoteAddress(address), &start))
|
||||
return None;
|
||||
|
||||
return start;
|
||||
#else
|
||||
// All swift class instances start with an isa pointer,
|
||||
// followed by the retain counts (which are the size of a long long).
|
||||
size_t isaAndRetainCountSize = sizeof(StoredSize) + sizeof(long long);
|
||||
size_t start = isaAndRetainCountSize;
|
||||
return start;
|
||||
} else {
|
||||
// All swift class instances start with an isa pointer,
|
||||
// followed by the retain counts (which are the size of a long long).
|
||||
size_t isaAndRetainCountSize = sizeof(StoredSize) + sizeof(long long);
|
||||
size_t start = isaAndRetainCountSize;
|
||||
|
||||
auto classMeta = cast<TargetClassMetadata<Runtime>>(meta);
|
||||
while (stripSignedPointer(classMeta->Superclass)) {
|
||||
classMeta = cast<TargetClassMetadata<Runtime>>(
|
||||
readMetadata(stripSignedPointer(classMeta->Superclass)));
|
||||
auto classMeta = cast<TargetClassMetadata>(meta);
|
||||
while (stripSignedPointer(classMeta->Superclass)) {
|
||||
classMeta = cast<TargetClassMetadata>(
|
||||
readMetadata(stripSignedPointer(classMeta->Superclass)));
|
||||
|
||||
// Subtract the size contribution of the isa and retain counts from
|
||||
// the super class.
|
||||
start += classMeta->InstanceSize - isaAndRetainCountSize;
|
||||
// Subtract the size contribution of the isa and retain counts from
|
||||
// the super class.
|
||||
start += classMeta->InstanceSize - isaAndRetainCountSize;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
return start;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Given a pointer to the metadata, attempt to read the value
|
||||
@@ -588,7 +590,7 @@ public:
|
||||
if (!Meta)
|
||||
return None;
|
||||
|
||||
if (auto ClassMeta = dyn_cast<TargetClassMetadata<Runtime>>(Meta)) {
|
||||
if (auto ClassMeta = dyn_cast<TargetClassMetadata>(Meta)) {
|
||||
if (ClassMeta->isPureObjC()) {
|
||||
// If we can determine the Objective-C class name, this is probably an
|
||||
// error existential with NSError-compatible layout.
|
||||
@@ -719,34 +721,36 @@ public:
|
||||
Demangler &dem,
|
||||
Resolver resolver) {
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
// Check whether we have an Objective-C protocol.
|
||||
if (ProtocolAddress.isObjC()) {
|
||||
auto Name = readObjCProtocolName(ProtocolAddress.getObjCProtocol());
|
||||
StringRef NameStr(Name);
|
||||
if (Runtime::ObjCInterop) {
|
||||
// Check whether we have an Objective-C protocol.
|
||||
if (ProtocolAddress.isObjC()) {
|
||||
auto Name = readObjCProtocolName(ProtocolAddress.getObjCProtocol());
|
||||
StringRef NameStr(Name);
|
||||
|
||||
// If this is a Swift-defined protocol, demangle it.
|
||||
if (NameStr.startswith("_TtP")) {
|
||||
auto Demangled = dem.demangleSymbol(NameStr);
|
||||
if (!Demangled)
|
||||
return resolver.failure();
|
||||
|
||||
// FIXME: This appears in _swift_buildDemanglingForMetadata().
|
||||
while (Demangled->getKind() == Node::Kind::Global ||
|
||||
Demangled->getKind() == Node::Kind::TypeMangling ||
|
||||
Demangled->getKind() == Node::Kind::Type ||
|
||||
Demangled->getKind() == Node::Kind::ProtocolList ||
|
||||
Demangled->getKind() == Node::Kind::TypeList ||
|
||||
Demangled->getKind() == Node::Kind::Type) {
|
||||
if (Demangled->getNumChildren() != 1)
|
||||
// If this is a Swift-defined protocol, demangle it.
|
||||
if (NameStr.startswith("_TtP")) {
|
||||
auto Demangled = dem.demangleSymbol(NameStr);
|
||||
if (!Demangled)
|
||||
return resolver.failure();
|
||||
Demangled = Demangled->getFirstChild();
|
||||
|
||||
// FIXME: This appears in _swift_buildDemanglingForMetadata().
|
||||
while (Demangled->getKind() == Node::Kind::Global ||
|
||||
Demangled->getKind() == Node::Kind::TypeMangling ||
|
||||
Demangled->getKind() == Node::Kind::Type ||
|
||||
Demangled->getKind() == Node::Kind::ProtocolList ||
|
||||
Demangled->getKind() == Node::Kind::TypeList ||
|
||||
Demangled->getKind() == Node::Kind::Type) {
|
||||
if (Demangled->getNumChildren() != 1)
|
||||
return resolver.failure();
|
||||
Demangled = Demangled->getFirstChild();
|
||||
}
|
||||
|
||||
return resolver.swiftProtocol(Demangled);
|
||||
}
|
||||
|
||||
return resolver.swiftProtocol(Demangled);
|
||||
// Otherwise, this is an imported protocol.
|
||||
return resolver.objcProtocol(NameStr);
|
||||
}
|
||||
|
||||
// Otherwise, this is an imported protocol.
|
||||
return resolver.objcProtocol(NameStr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1419,7 +1423,7 @@ public:
|
||||
return readMetadataBoundsOfSuperclass(superclass);
|
||||
},
|
||||
[&](MetadataRef metadata) -> llvm::Optional<ClassMetadataBounds> {
|
||||
auto cls = dyn_cast<TargetClassMetadata<Runtime>>(metadata);
|
||||
auto cls = dyn_cast<TargetClassMetadata>(metadata);
|
||||
if (!cls)
|
||||
return None;
|
||||
|
||||
@@ -1659,6 +1663,10 @@ protected:
|
||||
return Reader->readString(RemoteAddress(namePtr), className);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
using TargetClassMetadataT =
|
||||
typename Runtime::template TargetClassMetadata<T>;
|
||||
|
||||
MetadataRef readMetadata(StoredPointer address) {
|
||||
auto cached = MetadataCache.find(address);
|
||||
if (cached != MetadataCache.end())
|
||||
@@ -1672,7 +1680,9 @@ protected:
|
||||
|
||||
switch (getEnumeratedMetadataKind(KindValue)) {
|
||||
case MetadataKind::Class:
|
||||
return _readMetadata<TargetClassMetadata>(address);
|
||||
|
||||
return _readMetadata<TargetClassMetadataT>(address);
|
||||
|
||||
case MetadataKind::Enum:
|
||||
return _readMetadata<TargetEnumMetadata>(address);
|
||||
case MetadataKind::ErrorObject:
|
||||
@@ -1779,7 +1789,7 @@ protected:
|
||||
bool skipArtificialSubclasses = false) {
|
||||
switch (metadata->getKind()) {
|
||||
case MetadataKind::Class: {
|
||||
auto classMeta = cast<TargetClassMetadata<Runtime>>(metadata);
|
||||
auto classMeta = cast<TargetClassMetadata>(metadata);
|
||||
while (true) {
|
||||
if (!classMeta->isTypeMetadata())
|
||||
return 0;
|
||||
@@ -1801,7 +1811,7 @@ protected:
|
||||
if (!superMeta)
|
||||
return 0;
|
||||
|
||||
auto superclassMeta = dyn_cast<TargetClassMetadata<Runtime>>(superMeta);
|
||||
auto superclassMeta = dyn_cast<TargetClassMetadata>(superMeta);
|
||||
if (!superclassMeta)
|
||||
return 0;
|
||||
|
||||
@@ -2692,7 +2702,7 @@ private:
|
||||
|
||||
BuiltType readNominalTypeFromClassMetadata(MetadataRef origMetadata,
|
||||
bool skipArtificialSubclasses = false) {
|
||||
auto classMeta = cast<TargetClassMetadata<Runtime>>(origMetadata);
|
||||
auto classMeta = cast<TargetClassMetadata>(origMetadata);
|
||||
if (classMeta->isTypeMetadata())
|
||||
return readNominalTypeFromMetadata(origMetadata, skipArtificialSubclasses);
|
||||
|
||||
@@ -2715,6 +2725,10 @@ private:
|
||||
return BuiltObjCClass;
|
||||
}
|
||||
|
||||
using TargetClassMetadataObjCInterop =
|
||||
swift::TargetClassMetadata<Runtime,
|
||||
TargetAnyClassMetadataObjCInterop<Runtime>>;
|
||||
|
||||
/// Given that the remote process is running the non-fragile Apple runtime,
|
||||
/// grab the ro-data from a class pointer.
|
||||
StoredPointer readObjCRODataPtr(StoredPointer classAddress) {
|
||||
@@ -2723,9 +2737,10 @@ private:
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
StoredPointer dataPtr;
|
||||
if (!Reader->readInteger(RemoteAddress(classAddress +
|
||||
TargetClassMetadata<Runtime>::offsetToData()),
|
||||
&dataPtr))
|
||||
if (!Reader->readInteger(
|
||||
RemoteAddress(classAddress +
|
||||
TargetClassMetadataObjCInterop::offsetToData()),
|
||||
&dataPtr))
|
||||
return StoredPointer();
|
||||
|
||||
// Apply the data-pointer mask.
|
||||
|
||||
@@ -649,13 +649,24 @@ static RemoteASTContextImpl *createImpl(ASTContext &ctx,
|
||||
std::shared_ptr<MemoryReader> &&reader) {
|
||||
auto &target = ctx.LangOpts.Target;
|
||||
assert(target.isArch32Bit() || target.isArch64Bit());
|
||||
bool objcInterop = ctx.LangOpts.EnableObjCInterop;
|
||||
|
||||
if (target.isArch32Bit()) {
|
||||
using Target = External<RuntimeTarget<4>>;
|
||||
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
|
||||
if (objcInterop) {
|
||||
using Target = External<WithObjCInterop<RuntimeTarget<4>>>;
|
||||
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
|
||||
} else {
|
||||
using Target = External<NoObjCInterop<RuntimeTarget<4>>>;
|
||||
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
|
||||
}
|
||||
} else {
|
||||
using Target = External<RuntimeTarget<8>>;
|
||||
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
|
||||
if (objcInterop) {
|
||||
using Target = External<WithObjCInterop<RuntimeTarget<8>>>;
|
||||
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
|
||||
} else {
|
||||
using Target = External<NoObjCInterop<RuntimeTarget<8>>>;
|
||||
return new RemoteASTContextConcreteImpl<Target>(std::move(reader), ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,11 @@ using namespace swift;
|
||||
using namespace swift::reflection;
|
||||
using namespace swift::remote;
|
||||
|
||||
using Runtime = External<RuntimeTarget<sizeof(uintptr_t)>>;
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
using Runtime = External<WithObjCInterop<RuntimeTarget<sizeof(uintptr_t)>>>;
|
||||
#else
|
||||
using Runtime = External<NoObjCInterop<RuntimeTarget<sizeof(uintptr_t)>>>;
|
||||
#endif
|
||||
using NativeReflectionContext = swift::reflection::ReflectionContext<Runtime>;
|
||||
|
||||
struct SwiftReflectionContext {
|
||||
|
||||
@@ -487,19 +487,21 @@ public:
|
||||
return c;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<> inline const ClassMetadata *
|
||||
Metadata::getClassObject() const {
|
||||
|
||||
template <>
|
||||
inline const ClassMetadata *Metadata::getClassObject() const {
|
||||
switch (getKind()) {
|
||||
case MetadataKind::Class: {
|
||||
// Native Swift class metadata is also the class object.
|
||||
return static_cast<const ClassMetadata *>(this);
|
||||
}
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
case MetadataKind::ObjCClassWrapper: {
|
||||
// Objective-C class objects are referenced by their Swift metadata wrapper.
|
||||
auto wrapper = static_cast<const ObjCClassWrapperMetadata *>(this);
|
||||
return wrapper->Class;
|
||||
}
|
||||
#endif
|
||||
// Other kinds of types don't have class objects.
|
||||
default:
|
||||
return nullptr;
|
||||
|
||||
@@ -1111,6 +1111,7 @@ static bool isSubclass(const Metadata *subclass, const Metadata *superclass) {
|
||||
}
|
||||
}
|
||||
const ClassMetadata *swiftSubclass = cast<ClassMetadata>(subclass);
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
if (auto *objcSuperclass = dyn_cast<ObjCClassWrapperMetadata>(superclass)) {
|
||||
// Walk up swiftSubclass's ancestors until we get to an ObjC class, then
|
||||
// kick over to swift_dynamicCastMetatype.
|
||||
@@ -1123,6 +1124,7 @@ static bool isSubclass(const Metadata *subclass, const Metadata *superclass) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if (isa<ForeignClassMetadata>(superclass)) {
|
||||
// superclass is foreign, but subclass is not (if it were, the above
|
||||
// !isa<ClassMetadata> condition would have been entered). Since it is not
|
||||
|
||||
@@ -611,14 +611,25 @@ static ReflectionContextHolder makeReflectionContextForObjectFiles(
|
||||
uint8_t pointerSize;
|
||||
Reader->queryDataLayout(DataLayoutQueryType::DLQ_GetPointerSize,
|
||||
nullptr, &pointerSize);
|
||||
|
||||
switch (pointerSize) {
|
||||
case 4:
|
||||
return makeReflectionContextForMetadataReader<External<RuntimeTarget<4>>>
|
||||
(std::move(Reader));
|
||||
return makeReflectionContextForMetadataReader<
|
||||
// FIXME: This could be configurable.
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
External<WithObjCInterop<RuntimeTarget<4>>>
|
||||
#else
|
||||
External<NoObjCInterop<RuntimeTarget<4>>>
|
||||
#endif
|
||||
>(std::move(Reader));
|
||||
case 8:
|
||||
return makeReflectionContextForMetadataReader<External<RuntimeTarget<8>>>
|
||||
(std::move(Reader));
|
||||
return makeReflectionContextForMetadataReader<
|
||||
// FIXME: This could be configurable.
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
External<WithObjCInterop<RuntimeTarget<8>>>
|
||||
#else
|
||||
External<NoObjCInterop<RuntimeTarget<8>>>
|
||||
#endif
|
||||
>(std::move(Reader));
|
||||
default:
|
||||
fputs("unsupported word size in object file\n", stderr);
|
||||
abort();
|
||||
|
||||
Reference in New Issue
Block a user