mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Changes to runtime library to support non-objc targets
Swift SVN r23122
This commit is contained in:
@@ -931,7 +931,9 @@ extern "C" const FullOpaqueMetadata _TMdBi64_; // Builtin.Int64
|
|||||||
extern "C" const FullOpaqueMetadata _TMdBi128_; // Builtin.Int128
|
extern "C" const FullOpaqueMetadata _TMdBi128_; // Builtin.Int128
|
||||||
extern "C" const FullOpaqueMetadata _TMdBo; // Builtin.NativeObject
|
extern "C" const FullOpaqueMetadata _TMdBo; // Builtin.NativeObject
|
||||||
extern "C" const FullOpaqueMetadata _TMdBb; // Builtin.BridgeObject
|
extern "C" const FullOpaqueMetadata _TMdBb; // Builtin.BridgeObject
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
extern "C" const FullOpaqueMetadata _TMdBO; // Builtin.UnknownObject
|
extern "C" const FullOpaqueMetadata _TMdBO; // Builtin.UnknownObject
|
||||||
|
#endif
|
||||||
|
|
||||||
/// The prefix on a heap metadata.
|
/// The prefix on a heap metadata.
|
||||||
struct HeapMetadataHeaderPrefix {
|
struct HeapMetadataHeaderPrefix {
|
||||||
@@ -1993,7 +1995,7 @@ public:
|
|||||||
/// type.
|
/// type.
|
||||||
const void *getWitnessTable(const Metadata *type) const;
|
const void *getWitnessTable(const Metadata *type) const;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#if defined(NDEBUG) && SWIFT_OBJC_INTEROP
|
||||||
void dump() const;
|
void dump() const;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -2193,6 +2195,7 @@ extern "C" const void *
|
|||||||
swift_dynamicCastClassUnconditional(const void *object,
|
swift_dynamicCastClassUnconditional(const void *object,
|
||||||
const ClassMetadata *targetType);
|
const ClassMetadata *targetType);
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
/// \brief Checked Objective-C-style dynamic cast to a class type.
|
/// \brief Checked Objective-C-style dynamic cast to a class type.
|
||||||
///
|
///
|
||||||
/// \param object The object to cast, or nil.
|
/// \param object The object to cast, or nil.
|
||||||
@@ -2241,6 +2244,7 @@ extern "C" const void *
|
|||||||
swift_dynamicCastForeignClassUnconditional(
|
swift_dynamicCastForeignClassUnconditional(
|
||||||
const void *object,
|
const void *object,
|
||||||
const ForeignClassMetadata *targetType);
|
const ForeignClassMetadata *targetType);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Checked dynamic cast of a class instance pointer to the given type.
|
/// \brief Checked dynamic cast of a class instance pointer to the given type.
|
||||||
///
|
///
|
||||||
@@ -2295,6 +2299,7 @@ swift_dynamicCastIndirectUnconditional(const OpaqueValue *value,
|
|||||||
const Metadata *sourceType,
|
const Metadata *sourceType,
|
||||||
const Metadata *targetType);
|
const Metadata *targetType);
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
extern "C" const Metadata *
|
extern "C" const Metadata *
|
||||||
swift_dynamicCastMetatype(const Metadata *sourceType,
|
swift_dynamicCastMetatype(const Metadata *sourceType,
|
||||||
const Metadata *targetType);
|
const Metadata *targetType);
|
||||||
@@ -2315,6 +2320,7 @@ extern "C" const ClassMetadata *
|
|||||||
swift_dynamicCastForeignClassMetatypeUnconditional(
|
swift_dynamicCastForeignClassMetatypeUnconditional(
|
||||||
const ClassMetadata *sourceType,
|
const ClassMetadata *sourceType,
|
||||||
const ClassMetadata *targetType);
|
const ClassMetadata *targetType);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Return the dynamic type of an opaque value.
|
/// \brief Return the dynamic type of an opaque value.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ add_swift_library(swiftRuntime
|
|||||||
HeapObject.cpp
|
HeapObject.cpp
|
||||||
KnownMetadata.cpp
|
KnownMetadata.cpp
|
||||||
Metadata.cpp
|
Metadata.cpp
|
||||||
|
Reflection.cpp
|
||||||
Stubs.cpp
|
Stubs.cpp
|
||||||
|
SwiftObject.cpp
|
||||||
Enum.cpp
|
Enum.cpp
|
||||||
Once.cpp
|
Once.cpp
|
||||||
Heap.cpp
|
Heap.cpp
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "ExistentialMetadataImpl.h"
|
#include "ExistentialMetadataImpl.h"
|
||||||
#include "Private.h"
|
#include "Private.h"
|
||||||
|
#include "../shims/RuntimeShims.h"
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@@ -52,6 +53,7 @@ typedef long double swift_max_align_t;
|
|||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace metadataimpl;
|
using namespace metadataimpl;
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// Objective-C runtime entry points.
|
// Objective-C runtime entry points.
|
||||||
extern "C" const char* class_getName(const ClassMetadata*);
|
extern "C" const char* class_getName(const ClassMetadata*);
|
||||||
|
|
||||||
@@ -60,6 +62,7 @@ extern "C" const void *swift_dynamicCastObjCProtocolConditional(
|
|||||||
const void *object,
|
const void *object,
|
||||||
size_t numProtocols,
|
size_t numProtocols,
|
||||||
const ProtocolDescriptor * const *protocols);
|
const ProtocolDescriptor * const *protocols);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Return a user-comprehensible name for the given type.
|
// Return a user-comprehensible name for the given type.
|
||||||
// FIXME: this only works well for Class/Struct/Enum types. rdar://16392852
|
// FIXME: this only works well for Class/Struct/Enum types. rdar://16392852
|
||||||
@@ -131,6 +134,7 @@ static void _failCorruptType(const Metadata *type) {
|
|||||||
swift::crash("Corrupt Swift type object");
|
swift::crash("Corrupt Swift type object");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// Objective-c bridging helpers.
|
// Objective-c bridging helpers.
|
||||||
namespace {
|
namespace {
|
||||||
struct _ObjectiveCBridgeableWitnessTable;
|
struct _ObjectiveCBridgeableWitnessTable;
|
||||||
@@ -161,6 +165,7 @@ static bool _dynamicCastClassToValueViaObjCBridgeable(
|
|||||||
const Metadata *targetType,
|
const Metadata *targetType,
|
||||||
const _ObjectiveCBridgeableWitnessTable *targetBridgeWitness,
|
const _ObjectiveCBridgeableWitnessTable *targetBridgeWitness,
|
||||||
DynamicCastFlags flags);
|
DynamicCastFlags flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// A convenient method for failing out of a dynamic cast.
|
/// A convenient method for failing out of a dynamic cast.
|
||||||
static bool _fail(OpaqueValue *srcValue, const Metadata *srcType,
|
static bool _fail(OpaqueValue *srcValue, const Metadata *srcType,
|
||||||
@@ -221,12 +226,14 @@ swift::swift_dynamicCastClassUnconditional(const void *object,
|
|||||||
swift_dynamicCastFailure(_swift_getClass(object), targetType);
|
swift_dynamicCastFailure(_swift_getClass(object), targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
static bool _unknownClassConformsToObjCProtocol(const OpaqueValue *value,
|
static bool _unknownClassConformsToObjCProtocol(const OpaqueValue *value,
|
||||||
const ProtocolDescriptor *protocol) {
|
const ProtocolDescriptor *protocol) {
|
||||||
const void *object
|
const void *object
|
||||||
= *reinterpret_cast<const void * const *>(value);
|
= *reinterpret_cast<const void * const *>(value);
|
||||||
return swift_dynamicCastObjCProtocolConditional(object, 1, &protocol);
|
return swift_dynamicCastObjCProtocolConditional(object, 1, &protocol);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Check whether a type conforms to a protocol.
|
/// Check whether a type conforms to a protocol.
|
||||||
///
|
///
|
||||||
@@ -278,25 +285,35 @@ static bool _conformsToProtocol(const OpaqueValue *value,
|
|||||||
// conforms to the given protocol.
|
// conforms to the given protocol.
|
||||||
switch (type->getKind()) {
|
switch (type->getKind()) {
|
||||||
case MetadataKind::Class:
|
case MetadataKind::Class:
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
if (value) {
|
if (value) {
|
||||||
return _unknownClassConformsToObjCProtocol(value, protocol);
|
return _unknownClassConformsToObjCProtocol(value, protocol);
|
||||||
} else {
|
} else {
|
||||||
return _swift_classConformsToObjCProtocol(type, protocol);
|
return _swift_classConformsToObjCProtocol(type, protocol);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
|
||||||
case MetadataKind::ObjCClassWrapper: {
|
case MetadataKind::ObjCClassWrapper: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
if (value) {
|
if (value) {
|
||||||
return _unknownClassConformsToObjCProtocol(value, protocol);
|
return _unknownClassConformsToObjCProtocol(value, protocol);
|
||||||
} else {
|
} else {
|
||||||
auto wrapper = cast<ObjCClassWrapperMetadata>(type);
|
auto wrapper = cast<ObjCClassWrapperMetadata>(type);
|
||||||
return _swift_classConformsToObjCProtocol(wrapper->Class, protocol);
|
return _swift_classConformsToObjCProtocol(wrapper->Class, protocol);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::ForeignClass:
|
case MetadataKind::ForeignClass:
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
if (value)
|
if (value)
|
||||||
return _unknownClassConformsToObjCProtocol(value, protocol);
|
return _unknownClassConformsToObjCProtocol(value, protocol);
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
_failCorruptType(type);
|
||||||
|
#endif
|
||||||
|
|
||||||
case MetadataKind::Existential: // FIXME
|
case MetadataKind::Existential: // FIXME
|
||||||
case MetadataKind::ExistentialMetatype: // FIXME
|
case MetadataKind::ExistentialMetatype: // FIXME
|
||||||
@@ -502,6 +519,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
|
|||||||
|
|
||||||
case MetadataKind::Struct:
|
case MetadataKind::Struct:
|
||||||
case MetadataKind::Enum:
|
case MetadataKind::Enum:
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// If the source type is bridged to Objective-C, try to bridge.
|
// If the source type is bridged to Objective-C, try to bridge.
|
||||||
if (auto srcBridgeWitness = findBridgeWitness(srcDynamicType)) {
|
if (auto srcBridgeWitness = findBridgeWitness(srcDynamicType)) {
|
||||||
DynamicCastFlags subFlags
|
DynamicCastFlags subFlags
|
||||||
@@ -521,7 +539,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
|
|||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MetadataKind::Function:
|
case MetadataKind::Function:
|
||||||
@@ -589,14 +607,22 @@ swift::swift_dynamicCastUnknownClass(const void *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::ObjCClassWrapper: {
|
case MetadataKind::ObjCClassWrapper: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
auto targetClassType
|
auto targetClassType
|
||||||
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
|
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
|
||||||
return swift_dynamicCastObjCClass(object, targetClassType);
|
return swift_dynamicCastObjCClass(object, targetClassType);
|
||||||
|
#else
|
||||||
|
_failCorruptType(targetType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::ForeignClass: {
|
case MetadataKind::ForeignClass: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
|
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
|
||||||
return swift_dynamicCastForeignClass(object, targetClassType);
|
return swift_dynamicCastForeignClass(object, targetClassType);
|
||||||
|
#else
|
||||||
|
_failCorruptType(targetType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::Existential:
|
case MetadataKind::Existential:
|
||||||
@@ -627,14 +653,22 @@ swift::swift_dynamicCastUnknownClassUnconditional(const void *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::ObjCClassWrapper: {
|
case MetadataKind::ObjCClassWrapper: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
auto targetClassType
|
auto targetClassType
|
||||||
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
|
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
|
||||||
return swift_dynamicCastObjCClassUnconditional(object, targetClassType);
|
return swift_dynamicCastObjCClassUnconditional(object, targetClassType);
|
||||||
|
#else
|
||||||
|
_failCorruptType(targetType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::ForeignClass: {
|
case MetadataKind::ForeignClass: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
|
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
|
||||||
return swift_dynamicCastForeignClassUnconditional(object, targetClassType);
|
return swift_dynamicCastForeignClassUnconditional(object, targetClassType);
|
||||||
|
#else
|
||||||
|
_failCorruptType(targetType);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::Existential:
|
case MetadataKind::Existential:
|
||||||
@@ -653,6 +687,7 @@ swift::swift_dynamicCastUnknownClassUnconditional(const void *object,
|
|||||||
_failCorruptType(targetType);
|
_failCorruptType(targetType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
const Metadata *
|
const Metadata *
|
||||||
swift::swift_dynamicCastMetatype(const Metadata *sourceType,
|
swift::swift_dynamicCastMetatype(const Metadata *sourceType,
|
||||||
const Metadata *targetType) {
|
const Metadata *targetType) {
|
||||||
@@ -854,6 +889,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
|
|||||||
return origSourceType;
|
return origSourceType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Do a dynamic cast to the target class.
|
/// Do a dynamic cast to the target class.
|
||||||
static bool _dynamicCastUnknownClass(OpaqueValue *dest,
|
static bool _dynamicCastUnknownClass(OpaqueValue *dest,
|
||||||
@@ -956,6 +992,7 @@ static bool _dynamicCastFromExistential(OpaqueValue *dest,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
/// Perform a dynamic cast of a metatype to a metatype.
|
/// Perform a dynamic cast of a metatype to a metatype.
|
||||||
///
|
///
|
||||||
/// Note that the check is whether 'metatype' is an *instance of*
|
/// Note that the check is whether 'metatype' is an *instance of*
|
||||||
@@ -1194,6 +1231,7 @@ static bool _dynamicCastToExistentialMetatype(OpaqueValue *dest,
|
|||||||
}
|
}
|
||||||
_failCorruptType(srcType);
|
_failCorruptType(srcType);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Perform a dynamic cast to an arbitrary type.
|
/// Perform a dynamic cast to an arbitrary type.
|
||||||
bool swift::swift_dynamicCast(OpaqueValue *dest,
|
bool swift::swift_dynamicCast(OpaqueValue *dest,
|
||||||
@@ -1226,6 +1264,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
|
|||||||
|
|
||||||
case MetadataKind::Enum:
|
case MetadataKind::Enum:
|
||||||
case MetadataKind::Struct: {
|
case MetadataKind::Struct: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// If the source type is bridged to Objective-C, try to bridge.
|
// If the source type is bridged to Objective-C, try to bridge.
|
||||||
if (auto srcBridgeWitness = findBridgeWitness(srcType)) {
|
if (auto srcBridgeWitness = findBridgeWitness(srcType)) {
|
||||||
return _dynamicCastValueToClassViaObjCBridgeable(dest, src, srcType,
|
return _dynamicCastValueToClassViaObjCBridgeable(dest, src, srcType,
|
||||||
@@ -1233,7 +1272,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
|
|||||||
srcBridgeWitness,
|
srcBridgeWitness,
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return _fail(src, srcType, targetType, flags);
|
return _fail(src, srcType, targetType, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1255,14 +1294,22 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
|
|||||||
flags);
|
flags);
|
||||||
|
|
||||||
case MetadataKind::Metatype:
|
case MetadataKind::Metatype:
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
return _dynamicCastToMetatype(dest, src, srcType,
|
return _dynamicCastToMetatype(dest, src, srcType,
|
||||||
cast<MetatypeMetadata>(targetType),
|
cast<MetatypeMetadata>(targetType),
|
||||||
flags);
|
flags);
|
||||||
|
#else
|
||||||
|
return _fail(src, srcType, targetType, flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
case MetadataKind::ExistentialMetatype:
|
case MetadataKind::ExistentialMetatype:
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
return _dynamicCastToExistentialMetatype(dest, src, srcType,
|
return _dynamicCastToExistentialMetatype(dest, src, srcType,
|
||||||
cast<ExistentialMetatypeMetadata>(targetType),
|
cast<ExistentialMetatypeMetadata>(targetType),
|
||||||
flags);
|
flags);
|
||||||
|
#else
|
||||||
|
return _fail(src, srcType, targetType, flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
case MetadataKind::Struct:
|
case MetadataKind::Struct:
|
||||||
case MetadataKind::Enum:
|
case MetadataKind::Enum:
|
||||||
@@ -1270,6 +1317,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
|
|||||||
case MetadataKind::Class:
|
case MetadataKind::Class:
|
||||||
case MetadataKind::ObjCClassWrapper:
|
case MetadataKind::ObjCClassWrapper:
|
||||||
case MetadataKind::ForeignClass: {
|
case MetadataKind::ForeignClass: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// If the target type is bridged to Objective-C, try to bridge.
|
// If the target type is bridged to Objective-C, try to bridge.
|
||||||
if (auto targetBridgeWitness = findBridgeWitness(targetType)) {
|
if (auto targetBridgeWitness = findBridgeWitness(targetType)) {
|
||||||
return _dynamicCastClassToValueViaObjCBridgeable(dest, src, srcType,
|
return _dynamicCastClassToValueViaObjCBridgeable(dest, src, srcType,
|
||||||
@@ -1277,7 +1325,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
|
|||||||
targetBridgeWitness,
|
targetBridgeWitness,
|
||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1447,7 +1495,7 @@ swift::swift_dynamicCastIndirectUnconditional(const OpaqueValue *value,
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#if defined(NDEBUG) && SWIFT_OBJC_INTEROP
|
||||||
void ProtocolConformanceRecord::dump() const {
|
void ProtocolConformanceRecord::dump() const {
|
||||||
auto symbolName = [&](const void *addr) -> const char * {
|
auto symbolName = [&](const void *addr) -> const char * {
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
@@ -2059,6 +2107,18 @@ extern "C" OpaqueExistentialContainer swift_stdlib_dynamicCastToExistential1(
|
|||||||
reinterpret_cast<OpaqueValue *>(&outValue), destType);
|
reinterpret_cast<OpaqueValue *>(&outValue), destType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool swift_isClassOrObjCExistentialImpl(const Metadata *T) {
|
||||||
|
auto kind = T->getKind();
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
|
return Metadata::isAnyKindOfClass(kind) ||
|
||||||
|
(kind == MetadataKind::Existential &&
|
||||||
|
static_cast<const ExistentialTypeMetadata *>(T)->isObjC());
|
||||||
|
#else
|
||||||
|
return Metadata::isAnyKindOfClass(kind);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Bridging to and from Objective-C
|
// Bridging to and from Objective-C
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -2281,13 +2341,6 @@ findBridgeWitness(const Metadata *T) {
|
|||||||
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>(w);
|
return reinterpret_cast<const _ObjectiveCBridgeableWitnessTable *>(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool swift_isClassOrObjCExistentialImpl(const Metadata *T) {
|
|
||||||
auto kind = T->getKind();
|
|
||||||
return Metadata::isAnyKindOfClass(kind) ||
|
|
||||||
(kind == MetadataKind::Existential &&
|
|
||||||
static_cast<const ExistentialTypeMetadata *>(T)->isObjC());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \param value passed at +1, consumed.
|
/// \param value passed at +1, consumed.
|
||||||
extern "C" HeapObject *swift_bridgeNonVerbatimToObjectiveC(
|
extern "C" HeapObject *swift_bridgeNonVerbatimToObjectiveC(
|
||||||
OpaqueValue *value, const Metadata *T
|
OpaqueValue *value, const Metadata *T
|
||||||
@@ -2421,9 +2474,11 @@ extern "C" bool swift_isBridgedNonVerbatimToObjectiveC(
|
|||||||
auto bridgeWitness = findBridgeWitness(T);
|
auto bridgeWitness = findBridgeWitness(T);
|
||||||
return bridgeWitness && bridgeWitness->isBridgedToObjectiveC(value, T);
|
return bridgeWitness && bridgeWitness->isBridgedToObjectiveC(value, T);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// func isClassOrObjCExistential<T>(x: T.Type) -> Bool
|
// func isClassOrObjCExistential<T>(x: T.Type) -> Bool
|
||||||
extern "C" bool swift_isClassOrObjCExistential(const Metadata *value,
|
extern "C" bool swift_isClassOrObjCExistential(const Metadata *value,
|
||||||
const Metadata *T) {
|
const Metadata *T) {
|
||||||
return swift_isClassOrObjCExistentialImpl(T);
|
return swift_isClassOrObjCExistentialImpl(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,6 @@ namespace swift {
|
|||||||
extern "C" LLVM_LIBRARY_VISIBILITY
|
extern "C" LLVM_LIBRARY_VISIBILITY
|
||||||
bool _swift_classConformsToObjCProtocol(const void *theClass,
|
bool _swift_classConformsToObjCProtocol(const void *theClass,
|
||||||
const ProtocolDescriptor *theProtocol);
|
const ProtocolDescriptor *theProtocol);
|
||||||
#else
|
|
||||||
static inline bool _swift_classConformsToObjCProtocol(const void *theClass,
|
|
||||||
const ProtocolDescriptor *theProtocol) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_NORETURN
|
extern "C" LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_NORETURN
|
||||||
|
|||||||
7
stdlib/runtime/Reflection.cpp
Normal file
7
stdlib/runtime/Reflection.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// This file is here only to bring in the parts of Reflection.mm that apply
|
||||||
|
// when not using an objc runtime.
|
||||||
|
#include "swift/Runtime/Config.h"
|
||||||
|
|
||||||
|
#if !SWIFT_OBJC_INTEROP
|
||||||
|
#include "Reflection.mm"
|
||||||
|
#endif
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "swift/Basic/Fallthrough.h"
|
#include "swift/Basic/Fallthrough.h"
|
||||||
#include "swift/Runtime/Reflection.h"
|
#include "swift/Runtime/Reflection.h"
|
||||||
#include "swift/Runtime/HeapObject.h"
|
#include "swift/Runtime/HeapObject.h"
|
||||||
#include "swift/Runtime/ObjCBridge.h"
|
|
||||||
#include "swift/Runtime/Metadata.h"
|
#include "swift/Runtime/Metadata.h"
|
||||||
#include "swift/Basic/Demangle.h"
|
#include "swift/Basic/Demangle.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
@@ -23,13 +22,18 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
|
#include "swift/Runtime/ObjCBridge.h"
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
#include <objc/objc.h>
|
#include <objc/objc.h>
|
||||||
#include <objc/runtime.h>
|
#include <objc/runtime.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// Declare the debugQuickLookObject selector.
|
// Declare the debugQuickLookObject selector.
|
||||||
@interface DeclareSelectors
|
@interface DeclareSelectors
|
||||||
|
|
||||||
@@ -37,6 +41,7 @@ using namespace swift;
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
@class SwiftObject;
|
@class SwiftObject;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -89,11 +94,12 @@ struct String {
|
|||||||
swift_stringFromUTF8InRawMemory(this, concatenated, len1 + len2);
|
swift_stringFromUTF8InRawMemory(this, concatenated, len1 + len2);
|
||||||
free(concatenated);
|
free(concatenated);
|
||||||
}
|
}
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
explicit String(NSString *s)
|
explicit String(NSString *s)
|
||||||
// FIXME: Use the usual NSString bridging entry point.
|
// FIXME: Use the usual NSString bridging entry point.
|
||||||
: String([s UTF8String])
|
: String([s UTF8String])
|
||||||
{}
|
{}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Array {
|
struct Array {
|
||||||
@@ -259,6 +265,7 @@ const Metadata *swift_MagicMirrorData_valueType(HeapObject *owner,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
extern "C"
|
extern "C"
|
||||||
Any swift_MagicMirrorData_objcValue(HeapObject *owner,
|
Any swift_MagicMirrorData_objcValue(HeapObject *owner,
|
||||||
const OpaqueValue *value,
|
const OpaqueValue *value,
|
||||||
@@ -272,6 +279,8 @@ Any swift_MagicMirrorData_objcValue(HeapObject *owner,
|
|||||||
swift_release(owner);
|
swift_release(owner);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void swift_MagicMirrorData_summary(const Metadata *T, String *result) {
|
void swift_MagicMirrorData_summary(const Metadata *T, String *result) {
|
||||||
switch (T->getKind()) {
|
switch (T->getKind()) {
|
||||||
@@ -417,12 +426,16 @@ StringMirrorTuple swift_StructMirror_subscript(intptr_t i,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -- Class destructuring.
|
// -- Class destructuring.
|
||||||
|
|
||||||
static bool classHasSuperclass(const ClassMetadata *c) {
|
static bool classHasSuperclass(const ClassMetadata *c) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// A class does not have a superclass if its ObjC superclass is the
|
// A class does not have a superclass if its ObjC superclass is the
|
||||||
// "SwiftObject" root class.
|
// "SwiftObject" root class.
|
||||||
return c->SuperClass
|
return c->SuperClass
|
||||||
&& (Class)c->SuperClass != NSClassFromString(@"SwiftObject");
|
&& (Class)c->SuperClass != NSClassFromString(@"SwiftObject");
|
||||||
|
#else
|
||||||
|
// In non-objc mode, the test is just if it has a non-null superclass.
|
||||||
|
return c->SuperClass != nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
|
static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
|
||||||
@@ -483,9 +496,13 @@ StringMirrorTuple swift_ClassMirror_subscript(intptr_t i,
|
|||||||
if (usesNativeSwiftReferenceCounting(Clas)) {
|
if (usesNativeSwiftReferenceCounting(Clas)) {
|
||||||
fieldOffset = Clas->getFieldOffsets()[i];
|
fieldOffset = Clas->getFieldOffsets()[i];
|
||||||
} else {
|
} else {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
Ivar *ivars = class_copyIvarList((Class)Clas, nullptr);
|
Ivar *ivars = class_copyIvarList((Class)Clas, nullptr);
|
||||||
fieldOffset = ivar_getOffset(ivars[i]);
|
fieldOffset = ivar_getOffset(ivars[i]);
|
||||||
free(ivars);
|
free(ivars);
|
||||||
|
#else
|
||||||
|
swift::crash("Object appears to be Objective-C, but no runtime.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bytes = *reinterpret_cast<const char * const*>(value);
|
auto bytes = *reinterpret_cast<const char * const*>(value);
|
||||||
@@ -598,7 +615,7 @@ intptr_t swift_ObjCMirror_count(HeapObject *owner,
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
static Mirror ObjC_getMirrorForSuperclass(Class sup,
|
static Mirror ObjC_getMirrorForSuperclass(Class sup,
|
||||||
HeapObject *owner,
|
HeapObject *owner,
|
||||||
const OpaqueValue *value,
|
const OpaqueValue *value,
|
||||||
@@ -749,6 +766,7 @@ OptionalQuickLookObject swift_ClassMirror_quickLookObject(HeapObject *owner,
|
|||||||
result.optional.isNone = true;
|
result.optional.isNone = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// -- MagicMirror implementation.
|
// -- MagicMirror implementation.
|
||||||
|
|
||||||
@@ -769,6 +787,7 @@ extern "C" const MirrorWitnessTable _TWPVSs12_ClassMirrorSs10MirrorTypeSs;
|
|||||||
extern "C" const FullMetadata<Metadata> _TMdVSs17_ClassSuperMirror;
|
extern "C" const FullMetadata<Metadata> _TMdVSs17_ClassSuperMirror;
|
||||||
extern "C" const MirrorWitnessTable _TWPVSs17_ClassSuperMirrorSs10MirrorTypeSs;
|
extern "C" const MirrorWitnessTable _TWPVSs17_ClassSuperMirrorSs10MirrorTypeSs;
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// These type metadata objects are kept in swiftFoundation because they rely
|
// These type metadata objects are kept in swiftFoundation because they rely
|
||||||
// on string bridging being installed.
|
// on string bridging being installed.
|
||||||
static const Metadata *getObjCMirrorMetadata() {
|
static const Metadata *getObjCMirrorMetadata() {
|
||||||
@@ -804,6 +823,7 @@ static const MirrorWitnessTable *getObjCSuperMirrorWitness() {
|
|||||||
|
|
||||||
return witness;
|
return witness;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \param owner passed at +1, consumed.
|
/// \param owner passed at +1, consumed.
|
||||||
/// \param value passed unowned.
|
/// \param value passed unowned.
|
||||||
@@ -811,10 +831,12 @@ static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
|
|||||||
HeapObject *owner,
|
HeapObject *owner,
|
||||||
const OpaqueValue *value,
|
const OpaqueValue *value,
|
||||||
const Metadata *type) {
|
const Metadata *type) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// If the superclass is natively ObjC, cut over to the ObjC mirror
|
// If the superclass is natively ObjC, cut over to the ObjC mirror
|
||||||
// implementation.
|
// implementation.
|
||||||
if (!sup->isTypeMetadata())
|
if (!sup->isTypeMetadata())
|
||||||
return ObjC_getMirrorForSuperclass((Class)sup, owner, value, type);
|
return ObjC_getMirrorForSuperclass((Class)sup, owner, value, type);
|
||||||
|
#endif
|
||||||
|
|
||||||
Mirror resultBuf;
|
Mirror resultBuf;
|
||||||
MagicMirror *result = ::new (&resultBuf) MagicMirror;
|
MagicMirror *result = ::new (&resultBuf) MagicMirror;
|
||||||
@@ -828,6 +850,7 @@ static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
|
|||||||
return resultBuf;
|
return resultBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
/// \param owner passed at +1, consumed.
|
/// \param owner passed at +1, consumed.
|
||||||
/// \param value passed unowned.
|
/// \param value passed unowned.
|
||||||
static Mirror ObjC_getMirrorForSuperclass(Class sup,
|
static Mirror ObjC_getMirrorForSuperclass(Class sup,
|
||||||
@@ -844,6 +867,7 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
|
|||||||
result->Data.Value = value;
|
result->Data.Value = value;
|
||||||
return resultBuf;
|
return resultBuf;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// (type being mirrored, mirror type, mirror witness)
|
// (type being mirrored, mirror type, mirror witness)
|
||||||
using MirrorTriple
|
using MirrorTriple
|
||||||
@@ -855,12 +879,15 @@ getImplementationForClass(const OpaqueValue *Value) {
|
|||||||
const void *obj = *reinterpret_cast<const void * const *>(Value);
|
const void *obj = *reinterpret_cast<const void * const *>(Value);
|
||||||
auto isa = _swift_getClass(obj);
|
auto isa = _swift_getClass(obj);
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// If this is a pure ObjC class, reflect it using ObjC's runtime facilities.
|
// If this is a pure ObjC class, reflect it using ObjC's runtime facilities.
|
||||||
if (!isa->isTypeMetadata())
|
if (!isa->isTypeMetadata())
|
||||||
return {isa, getObjCMirrorMetadata(), getObjCMirrorWitness()};
|
return {isa, getObjCMirrorMetadata(), getObjCMirrorWitness()};
|
||||||
|
#endif
|
||||||
|
|
||||||
// Otherwise, use the native Swift facilities.
|
// Otherwise, use the native Swift facilities.
|
||||||
return {isa, &_TMdVSs12_ClassMirror, &_TWPVSs12_ClassMirrorSs10MirrorTypeSs};
|
return std::make_tuple(
|
||||||
|
isa, &_TMdVSs12_ClassMirror, &_TWPVSs12_ClassMirrorSs10MirrorTypeSs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the magic mirror witnesses appropriate to a particular type.
|
/// Get the magic mirror witnesses appropriate to a particular type.
|
||||||
@@ -868,10 +895,12 @@ static MirrorTriple
|
|||||||
getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
|
getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
|
||||||
switch (T->getKind()) {
|
switch (T->getKind()) {
|
||||||
case MetadataKind::Tuple:
|
case MetadataKind::Tuple:
|
||||||
return {T, &_TMdVSs12_TupleMirror, &_TWPVSs12_TupleMirrorSs10MirrorTypeSs};
|
return std::make_tuple(
|
||||||
|
T, &_TMdVSs12_TupleMirror, &_TWPVSs12_TupleMirrorSs10MirrorTypeSs);
|
||||||
|
|
||||||
case MetadataKind::Struct:
|
case MetadataKind::Struct:
|
||||||
return {T, &_TMdVSs13_StructMirror, &_TWPVSs13_StructMirrorSs10MirrorTypeSs};
|
return std::make_tuple(
|
||||||
|
T, &_TMdVSs13_StructMirror, &_TWPVSs13_StructMirrorSs10MirrorTypeSs);
|
||||||
|
|
||||||
case MetadataKind::ObjCClassWrapper:
|
case MetadataKind::ObjCClassWrapper:
|
||||||
case MetadataKind::ForeignClass:
|
case MetadataKind::ForeignClass:
|
||||||
@@ -880,12 +909,13 @@ getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case MetadataKind::Opaque: {
|
case MetadataKind::Opaque: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// If this is the Builtin.UnknownObject type, use the dynamic type of the
|
// If this is the Builtin.UnknownObject type, use the dynamic type of the
|
||||||
// object reference.
|
// object reference.
|
||||||
if (T == &_TMdBO.base) {
|
if (T == &_TMdBO.base) {
|
||||||
return getImplementationForClass(Value);
|
return getImplementationForClass(Value);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// If this is the Builtin.NativeObject type, and the heap object is a
|
// If this is the Builtin.NativeObject type, and the heap object is a
|
||||||
// class instance, use the dynamic type of the object reference.
|
// class instance, use the dynamic type of the object reference.
|
||||||
if (T == &_TMdBo.base) {
|
if (T == &_TMdBo.base) {
|
||||||
@@ -904,7 +934,8 @@ getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
|
|||||||
case MetadataKind::Existential:
|
case MetadataKind::Existential:
|
||||||
case MetadataKind::ExistentialMetatype:
|
case MetadataKind::ExistentialMetatype:
|
||||||
case MetadataKind::Metatype:
|
case MetadataKind::Metatype:
|
||||||
return {T, &_TMdVSs13_OpaqueMirror, &_TWPVSs13_OpaqueMirrorSs10MirrorTypeSs};
|
return std::make_tuple(
|
||||||
|
T, &_TMdVSs13_OpaqueMirror, &_TWPVSs13_OpaqueMirrorSs10MirrorTypeSs);
|
||||||
|
|
||||||
// Types can't have these kinds.
|
// Types can't have these kinds.
|
||||||
case MetadataKind::PolyFunction:
|
case MetadataKind::PolyFunction:
|
||||||
@@ -968,12 +999,11 @@ getReflectableConformance(const Metadata *T, const OpaqueValue *Value) {
|
|||||||
unsigned wtOffset = 0;
|
unsigned wtOffset = 0;
|
||||||
for (unsigned i = 0; i < existential->Protocols.NumProtocols; ++i) {
|
for (unsigned i = 0; i < existential->Protocols.NumProtocols; ++i) {
|
||||||
if (existential->Protocols[i] == &_TMpSs11Reflectable) {
|
if (existential->Protocols[i] == &_TMpSs11Reflectable) {
|
||||||
return {
|
return std::make_tuple(
|
||||||
reinterpret_cast<const ReflectableWitnessTable*>(
|
reinterpret_cast<const ReflectableWitnessTable*>(
|
||||||
existential->getWitnessTable(Value, wtOffset)),
|
existential->getWitnessTable(Value, wtOffset)),
|
||||||
existential->getDynamicType(Value),
|
existential->getDynamicType(Value),
|
||||||
existential->projectValue(Value)
|
existential->projectValue(Value));
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if (existential->Protocols[i]->Flags.needsWitnessTable())
|
if (existential->Protocols[i]->Flags.needsWitnessTable())
|
||||||
++wtOffset;
|
++wtOffset;
|
||||||
@@ -997,12 +1027,11 @@ getReflectableConformance(const Metadata *T, const OpaqueValue *Value) {
|
|||||||
swift::crash("Swift mirror lookup failure");
|
swift::crash("Swift mirror lookup failure");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return std::make_tuple(
|
||||||
reinterpret_cast<const ReflectableWitnessTable*>(
|
reinterpret_cast<const ReflectableWitnessTable*>(
|
||||||
swift_conformsToProtocol(T, &_TMpSs11Reflectable)),
|
swift_conformsToProtocol(T, &_TMpSs11Reflectable)),
|
||||||
T,
|
T,
|
||||||
Value
|
Value);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
@@ -1121,9 +1150,14 @@ static void swift_stdlib_getTypeNameImpl(OpaqueValue *value,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case MetadataKind::ObjCClassWrapper: {
|
case MetadataKind::ObjCClassWrapper: {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
auto wrapperMetadata =
|
auto wrapperMetadata =
|
||||||
static_cast<const ObjCClassWrapperMetadata *>(dynamicType);
|
static_cast<const ObjCClassWrapperMetadata *>(dynamicType);
|
||||||
new (result) String(object_getClassName((id)wrapperMetadata->Class));
|
new (result) String(object_getClassName((id)wrapperMetadata->Class));
|
||||||
|
#else
|
||||||
|
assert(false && "Unexpected ObjC Wrapper Object");
|
||||||
|
new (result) String("");
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
stdlib/runtime/SwiftObject.cpp
Normal file
7
stdlib/runtime/SwiftObject.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// This file is here only to bring in the parts of SwiftObject.mm that apply
|
||||||
|
// when not using an objc runtime.
|
||||||
|
#include "swift/Runtime/Config.h"
|
||||||
|
|
||||||
|
#if !SWIFT_OBJC_INTEROP
|
||||||
|
#include "SwiftObject.mm"
|
||||||
|
#endif
|
||||||
@@ -15,6 +15,8 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "swift/Runtime/Config.h"
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
#include <objc/NSObject.h>
|
#include <objc/NSObject.h>
|
||||||
#include <objc/runtime.h>
|
#include <objc/runtime.h>
|
||||||
#include <objc/message.h>
|
#include <objc/message.h>
|
||||||
@@ -22,6 +24,7 @@
|
|||||||
#include <objc/objc-abi.h>
|
#include <objc/objc-abi.h>
|
||||||
#include <objc/objc-internal.h>
|
#include <objc/objc-internal.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#include "swift/Runtime/Heap.h"
|
#include "swift/Runtime/Heap.h"
|
||||||
#include "swift/Runtime/HeapObject.h"
|
#include "swift/Runtime/HeapObject.h"
|
||||||
#include "swift/Runtime/Metadata.h"
|
#include "swift/Runtime/Metadata.h"
|
||||||
@@ -34,8 +37,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
#import <CoreFoundation/CFBase.h> // for CFTypeID
|
#import <CoreFoundation/CFBase.h> // for CFTypeID
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
// Redeclare these just we check them.
|
// Redeclare these just we check them.
|
||||||
extern "C" id objc_retain(id);
|
extern "C" id objc_retain(id);
|
||||||
extern "C" void objc_release(id);
|
extern "C" void objc_release(id);
|
||||||
@@ -46,6 +52,7 @@ extern "C" id objc_initWeak(id*, id);
|
|||||||
extern "C" id objc_storeWeak(id*, id);
|
extern "C" id objc_storeWeak(id*, id);
|
||||||
extern "C" void objc_destroyWeak(id*);
|
extern "C" void objc_destroyWeak(id*);
|
||||||
extern "C" id objc_loadWeakRetained(id*);
|
extern "C" id objc_loadWeakRetained(id*);
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
@@ -70,7 +77,6 @@ const ClassMetadata *swift::_swift_getClass(const void *object) {
|
|||||||
return _swift_getClassOfAllocated(object);
|
return _swift_getClassOfAllocated(object);
|
||||||
return reinterpret_cast<const ClassMetadata*>(object_getClass((id) object));
|
return reinterpret_cast<const ClassMetadata*>(object_getClass((id) object));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
struct SwiftObject_s {
|
struct SwiftObject_s {
|
||||||
void *isa __attribute__((unavailable));
|
void *isa __attribute__((unavailable));
|
||||||
@@ -406,20 +412,30 @@ static void objc_rootWeakRelease(id object) {
|
|||||||
UnownedRefs.erase(it);
|
UnownedRefs.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Decide dynamically whether the given object uses native Swift
|
/// Decide dynamically whether the given object uses native Swift
|
||||||
/// reference-counting.
|
/// reference-counting.
|
||||||
bool swift::usesNativeSwiftReferenceCounting(const ClassMetadata *theClass) {
|
bool swift::usesNativeSwiftReferenceCounting(const ClassMetadata *theClass) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
if (!theClass->isTypeMetadata()) return false;
|
if (!theClass->isTypeMetadata()) return false;
|
||||||
return (theClass->getFlags() & ClassFlags::UsesSwift1Refcounting);
|
return (theClass->getFlags() & ClassFlags::UsesSwift1Refcounting);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// version for SwiftShims
|
// version for SwiftShims
|
||||||
unsigned char
|
unsigned char
|
||||||
swift::_swift_usesNativeSwiftReferenceCounting_class(const void *theClass) {
|
swift::_swift_usesNativeSwiftReferenceCounting_class(const void *theClass) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
return usesNativeSwiftReferenceCounting((const ClassMetadata *)theClass);
|
return usesNativeSwiftReferenceCounting((const ClassMetadata *)theClass);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
static bool usesNativeSwiftReferenceCounting_allocated(const void *object) {
|
static bool usesNativeSwiftReferenceCounting_allocated(const void *object) {
|
||||||
assert(!isObjCTaggedPointerOrNull(object));
|
assert(!isObjCTaggedPointerOrNull(object));
|
||||||
return usesNativeSwiftReferenceCounting(_swift_getClassOfAllocated(object));
|
return usesNativeSwiftReferenceCounting(_swift_getClassOfAllocated(object));
|
||||||
@@ -438,10 +454,13 @@ void swift::swift_unknownRelease(void *object) {
|
|||||||
return swift_release((HeapObject*) object);
|
return swift_release((HeapObject*) object);
|
||||||
return objc_release((id) object);
|
return objc_release((id) object);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void *swift::swift_bridgeObjectRetain(void *object) {
|
void *swift::swift_bridgeObjectRetain(void *object) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
if (isObjCTaggedPointerOrNull(object))
|
if (isObjCTaggedPointerOrNull(object))
|
||||||
return object;
|
return object;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mask out the spare bits, which may store arbitrary data.
|
// Mask out the spare bits, which may store arbitrary data.
|
||||||
uintptr_t objectRef = uintptr_t(object)
|
uintptr_t objectRef = uintptr_t(object)
|
||||||
@@ -454,13 +473,15 @@ void *swift::swift_bridgeObjectRetain(void *object) {
|
|||||||
return swift_retain((HeapObject*) objectRef);
|
return swift_retain((HeapObject*) objectRef);
|
||||||
return objc_retain((id) objectRef);
|
return objc_retain((id) objectRef);
|
||||||
#else
|
#else
|
||||||
return swift_retain((HeapOject*) objectRef);
|
return swift_retain((HeapObject*) objectRef);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void swift::swift_bridgeObjectRelease(void *object) {
|
void swift::swift_bridgeObjectRelease(void *object) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
if (isObjCTaggedPointerOrNull(object))
|
if (isObjCTaggedPointerOrNull(object))
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Mask out the spare bits, which may store arbitrary data.
|
// Mask out the spare bits, which may store arbitrary data.
|
||||||
uintptr_t objectRef = uintptr_t(object)
|
uintptr_t objectRef = uintptr_t(object)
|
||||||
@@ -477,6 +498,7 @@ void swift::swift_bridgeObjectRelease(void *object) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
void swift::swift_unknownRetainUnowned(void *object) {
|
void swift::swift_unknownRetainUnowned(void *object) {
|
||||||
if (isObjCTaggedPointerOrNull(object)) return;
|
if (isObjCTaggedPointerOrNull(object)) return;
|
||||||
if (usesNativeSwiftReferenceCounting_allocated(object))
|
if (usesNativeSwiftReferenceCounting_allocated(object))
|
||||||
@@ -506,7 +528,11 @@ static void doWeakInit(WeakReference *addr, void *value, bool valueIsNative) {
|
|||||||
if (valueIsNative) {
|
if (valueIsNative) {
|
||||||
swift_weakInit(addr, (HeapObject*) value);
|
swift_weakInit(addr, (HeapObject*) value);
|
||||||
} else {
|
} else {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
objc_initWeak((id*) &addr->Value, (id) value);
|
objc_initWeak((id*) &addr->Value, (id) value);
|
||||||
|
#else
|
||||||
|
assert(valueIsNative);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +540,11 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) {
|
|||||||
if (valueIsNative) {
|
if (valueIsNative) {
|
||||||
swift_weakDestroy(addr);
|
swift_weakDestroy(addr);
|
||||||
} else {
|
} else {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
objc_destroyWeak((id*) &addr->Value);
|
objc_destroyWeak((id*) &addr->Value);
|
||||||
|
#else
|
||||||
|
assert(valueIsNative);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,11 +647,12 @@ void swift::swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src)
|
|||||||
swift_unknownWeakDestroy(dest);
|
swift_unknownWeakDestroy(dest);
|
||||||
swift_unknownWeakTakeInit(dest, src);
|
swift_unknownWeakTakeInit(dest, src);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/******************************* DYNAMIC CASTS *******************************/
|
/******************************* DYNAMIC CASTS *******************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
const void *
|
const void *
|
||||||
swift::swift_dynamicCastObjCClass(const void *object,
|
swift::swift_dynamicCastObjCClass(const void *object,
|
||||||
const ClassMetadata *targetType) {
|
const ClassMetadata *targetType) {
|
||||||
@@ -764,6 +795,7 @@ extern "C" const char *swift_getGenericClassObjCName(const ClassMetadata *clas,
|
|||||||
(unsigned long long)clas);
|
(unsigned long long)clas);
|
||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Given a non-nil object reference, return true iff the object uses
|
// Given a non-nil object reference, return true iff the object uses
|
||||||
// native swift reference counting.
|
// native swift reference counting.
|
||||||
@@ -846,7 +878,12 @@ unsigned char swift::_swift_isUniquelyReferenced_native_spareBits(
|
|||||||
///
|
///
|
||||||
/// That function is otherwise unavailable to the core stdlib.
|
/// That function is otherwise unavailable to the core stdlib.
|
||||||
size_t swift::_swift_class_getInstanceSize_class(const void* c) {
|
size_t swift::_swift_class_getInstanceSize_class(const void* c) {
|
||||||
|
#if SWIFT_OBJC_INTEROP
|
||||||
return class_getInstanceSize((Class)c);
|
return class_getInstanceSize((Class)c);
|
||||||
|
#else
|
||||||
|
auto metaData = static_cast<const ClassMetadata*>(c);
|
||||||
|
return metaData->getInstanceSize() - metaData->getInstanceAlignMask();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClassMetadata *swift::getRootSuperclass() {
|
const ClassMetadata *swift::getRootSuperclass() {
|
||||||
|
|||||||
Reference in New Issue
Block a user