Changes to runtime library to support non-objc targets

Swift SVN r23122
This commit is contained in:
Graham Batty
2014-11-05 23:17:07 +00:00
parent 5aa60308a6
commit d15c24e25b
8 changed files with 197 additions and 54 deletions

View File

@@ -931,7 +931,9 @@ extern "C" const FullOpaqueMetadata _TMdBi64_; // Builtin.Int64
extern "C" const FullOpaqueMetadata _TMdBi128_; // Builtin.Int128
extern "C" const FullOpaqueMetadata _TMdBo; // Builtin.NativeObject
extern "C" const FullOpaqueMetadata _TMdBb; // Builtin.BridgeObject
#if SWIFT_OBJC_INTEROP
extern "C" const FullOpaqueMetadata _TMdBO; // Builtin.UnknownObject
#endif
/// The prefix on a heap metadata.
struct HeapMetadataHeaderPrefix {
@@ -1993,7 +1995,7 @@ public:
/// type.
const void *getWitnessTable(const Metadata *type) const;
#ifndef NDEBUG
#if defined(NDEBUG) && SWIFT_OBJC_INTEROP
void dump() const;
#endif
};
@@ -2193,6 +2195,7 @@ extern "C" const void *
swift_dynamicCastClassUnconditional(const void *object,
const ClassMetadata *targetType);
#if SWIFT_OBJC_INTEROP
/// \brief Checked Objective-C-style dynamic cast to a class type.
///
/// \param object The object to cast, or nil.
@@ -2241,6 +2244,7 @@ extern "C" const void *
swift_dynamicCastForeignClassUnconditional(
const void *object,
const ForeignClassMetadata *targetType);
#endif
/// \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 *targetType);
#if SWIFT_OBJC_INTEROP
extern "C" const Metadata *
swift_dynamicCastMetatype(const Metadata *sourceType,
const Metadata *targetType);
@@ -2315,7 +2320,8 @@ extern "C" const ClassMetadata *
swift_dynamicCastForeignClassMetatypeUnconditional(
const ClassMetadata *sourceType,
const ClassMetadata *targetType);
#endif
/// \brief Return the dynamic type of an opaque value.
///
/// \param value An opaque value.

View File

@@ -45,7 +45,9 @@ add_swift_library(swiftRuntime
HeapObject.cpp
KnownMetadata.cpp
Metadata.cpp
Reflection.cpp
Stubs.cpp
SwiftObject.cpp
Enum.cpp
Once.cpp
Heap.cpp

View File

@@ -25,6 +25,7 @@
#include "Debug.h"
#include "ExistentialMetadataImpl.h"
#include "Private.h"
#include "../shims/RuntimeShims.h"
#include "stddef.h"
#ifdef __APPLE__
@@ -52,6 +53,7 @@ typedef long double swift_max_align_t;
using namespace swift;
using namespace metadataimpl;
#if SWIFT_OBJC_INTEROP
// Objective-C runtime entry points.
extern "C" const char* class_getName(const ClassMetadata*);
@@ -60,6 +62,7 @@ extern "C" const void *swift_dynamicCastObjCProtocolConditional(
const void *object,
size_t numProtocols,
const ProtocolDescriptor * const *protocols);
#endif
// Return a user-comprehensible name for the given type.
// 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");
}
#if SWIFT_OBJC_INTEROP
// Objective-c bridging helpers.
namespace {
struct _ObjectiveCBridgeableWitnessTable;
@@ -161,6 +165,7 @@ static bool _dynamicCastClassToValueViaObjCBridgeable(
const Metadata *targetType,
const _ObjectiveCBridgeableWitnessTable *targetBridgeWitness,
DynamicCastFlags flags);
#endif
/// A convenient method for failing out of a dynamic cast.
static bool _fail(OpaqueValue *srcValue, const Metadata *srcType,
@@ -221,12 +226,14 @@ swift::swift_dynamicCastClassUnconditional(const void *object,
swift_dynamicCastFailure(_swift_getClass(object), targetType);
}
#if SWIFT_OBJC_INTEROP
static bool _unknownClassConformsToObjCProtocol(const OpaqueValue *value,
const ProtocolDescriptor *protocol) {
const void *object
= *reinterpret_cast<const void * const *>(value);
return swift_dynamicCastObjCProtocolConditional(object, 1, &protocol);
}
#endif
/// Check whether a type conforms to a protocol.
///
@@ -278,25 +285,35 @@ static bool _conformsToProtocol(const OpaqueValue *value,
// conforms to the given protocol.
switch (type->getKind()) {
case MetadataKind::Class:
#if SWIFT_OBJC_INTEROP
if (value) {
return _unknownClassConformsToObjCProtocol(value, protocol);
} else {
return _swift_classConformsToObjCProtocol(type, protocol);
}
#endif
return false;
case MetadataKind::ObjCClassWrapper: {
#if SWIFT_OBJC_INTEROP
if (value) {
return _unknownClassConformsToObjCProtocol(value, protocol);
} else {
auto wrapper = cast<ObjCClassWrapperMetadata>(type);
return _swift_classConformsToObjCProtocol(wrapper->Class, protocol);
}
#endif
return false;
}
case MetadataKind::ForeignClass:
#if SWIFT_OBJC_INTEROP
if (value)
return _unknownClassConformsToObjCProtocol(value, protocol);
return false;
#else
_failCorruptType(type);
#endif
case MetadataKind::Existential: // FIXME
case MetadataKind::ExistentialMetatype: // FIXME
@@ -502,6 +519,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
case MetadataKind::Struct:
case MetadataKind::Enum:
#if SWIFT_OBJC_INTEROP
// If the source type is bridged to Objective-C, try to bridge.
if (auto srcBridgeWitness = findBridgeWitness(srcDynamicType)) {
DynamicCastFlags subFlags
@@ -521,7 +539,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
return success;
}
#endif
break;
case MetadataKind::Function:
@@ -589,14 +607,22 @@ swift::swift_dynamicCastUnknownClass(const void *object,
}
case MetadataKind::ObjCClassWrapper: {
#if SWIFT_OBJC_INTEROP
auto targetClassType
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
return swift_dynamicCastObjCClass(object, targetClassType);
#else
_failCorruptType(targetType);
#endif
}
case MetadataKind::ForeignClass: {
#if SWIFT_OBJC_INTEROP
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
return swift_dynamicCastForeignClass(object, targetClassType);
#else
_failCorruptType(targetType);
#endif
}
case MetadataKind::Existential:
@@ -627,14 +653,22 @@ swift::swift_dynamicCastUnknownClassUnconditional(const void *object,
}
case MetadataKind::ObjCClassWrapper: {
#if SWIFT_OBJC_INTEROP
auto targetClassType
= static_cast<const ObjCClassWrapperMetadata *>(targetType)->Class;
return swift_dynamicCastObjCClassUnconditional(object, targetClassType);
#else
_failCorruptType(targetType);
#endif
}
case MetadataKind::ForeignClass: {
#if SWIFT_OBJC_INTEROP
auto targetClassType = static_cast<const ForeignClassMetadata*>(targetType);
return swift_dynamicCastForeignClassUnconditional(object, targetClassType);
#else
_failCorruptType(targetType);
#endif
}
case MetadataKind::Existential:
@@ -653,6 +687,7 @@ swift::swift_dynamicCastUnknownClassUnconditional(const void *object,
_failCorruptType(targetType);
}
#if SWIFT_OBJC_INTEROP
const Metadata *
swift::swift_dynamicCastMetatype(const Metadata *sourceType,
const Metadata *targetType) {
@@ -854,6 +889,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType,
return origSourceType;
}
}
#endif
/// Do a dynamic cast to the target class.
static bool _dynamicCastUnknownClass(OpaqueValue *dest,
@@ -956,6 +992,7 @@ static bool _dynamicCastFromExistential(OpaqueValue *dest,
return result;
}
#if SWIFT_OBJC_INTEROP
/// Perform a dynamic cast of a metatype to a metatype.
///
/// Note that the check is whether 'metatype' is an *instance of*
@@ -1194,6 +1231,7 @@ static bool _dynamicCastToExistentialMetatype(OpaqueValue *dest,
}
_failCorruptType(srcType);
}
#endif
/// Perform a dynamic cast to an arbitrary type.
bool swift::swift_dynamicCast(OpaqueValue *dest,
@@ -1226,6 +1264,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
case MetadataKind::Enum:
case MetadataKind::Struct: {
#if SWIFT_OBJC_INTEROP
// If the source type is bridged to Objective-C, try to bridge.
if (auto srcBridgeWitness = findBridgeWitness(srcType)) {
return _dynamicCastValueToClassViaObjCBridgeable(dest, src, srcType,
@@ -1233,7 +1272,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
srcBridgeWitness,
flags);
}
#endif
return _fail(src, srcType, targetType, flags);
}
@@ -1255,14 +1294,22 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
flags);
case MetadataKind::Metatype:
#if SWIFT_OBJC_INTEROP
return _dynamicCastToMetatype(dest, src, srcType,
cast<MetatypeMetadata>(targetType),
flags);
#else
return _fail(src, srcType, targetType, flags);
#endif
case MetadataKind::ExistentialMetatype:
#if SWIFT_OBJC_INTEROP
return _dynamicCastToExistentialMetatype(dest, src, srcType,
cast<ExistentialMetatypeMetadata>(targetType),
flags);
#else
return _fail(src, srcType, targetType, flags);
#endif
case MetadataKind::Struct:
case MetadataKind::Enum:
@@ -1270,6 +1317,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
case MetadataKind::Class:
case MetadataKind::ObjCClassWrapper:
case MetadataKind::ForeignClass: {
#if SWIFT_OBJC_INTEROP
// If the target type is bridged to Objective-C, try to bridge.
if (auto targetBridgeWitness = findBridgeWitness(targetType)) {
return _dynamicCastClassToValueViaObjCBridgeable(dest, src, srcType,
@@ -1277,7 +1325,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest,
targetBridgeWitness,
flags);
}
#endif
break;
}
@@ -1447,7 +1495,7 @@ swift::swift_dynamicCastIndirectUnconditional(const OpaqueValue *value,
return value;
}
#ifndef NDEBUG
#if defined(NDEBUG) && SWIFT_OBJC_INTEROP
void ProtocolConformanceRecord::dump() const {
auto symbolName = [&](const void *addr) -> const char * {
Dl_info info;
@@ -2059,6 +2107,18 @@ extern "C" OpaqueExistentialContainer swift_stdlib_dynamicCastToExistential1(
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
//===----------------------------------------------------------------------===//
@@ -2281,13 +2341,6 @@ findBridgeWitness(const Metadata *T) {
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.
extern "C" HeapObject *swift_bridgeNonVerbatimToObjectiveC(
OpaqueValue *value, const Metadata *T
@@ -2421,9 +2474,11 @@ extern "C" bool swift_isBridgedNonVerbatimToObjectiveC(
auto bridgeWitness = findBridgeWitness(T);
return bridgeWitness && bridgeWitness->isBridgedToObjectiveC(value, T);
}
#endif
// func isClassOrObjCExistential<T>(x: T.Type) -> Bool
extern "C" bool swift_isClassOrObjCExistential(const Metadata *value,
const Metadata *T) {
return swift_isClassOrObjCExistentialImpl(T);
}

View File

@@ -32,11 +32,6 @@ namespace swift {
extern "C" LLVM_LIBRARY_VISIBILITY
bool _swift_classConformsToObjCProtocol(const void *theClass,
const ProtocolDescriptor *theProtocol);
#else
static inline bool _swift_classConformsToObjCProtocol(const void *theClass,
const ProtocolDescriptor *theProtocol) {
return false;
}
#endif
extern "C" LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_NORETURN

View 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

View File

@@ -13,7 +13,6 @@
#include "swift/Basic/Fallthrough.h"
#include "swift/Runtime/Reflection.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/ObjCBridge.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Basic/Demangle.h"
#include "Debug.h"
@@ -23,13 +22,18 @@
#include <new>
#include <string>
#include <regex>
#include <Foundation/Foundation.h>
#include <dlfcn.h>
#if SWIFT_OBJC_INTEROP
#include "swift/Runtime/ObjCBridge.h"
#include <Foundation/Foundation.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#endif
using namespace swift;
#if SWIFT_OBJC_INTEROP
// Declare the debugQuickLookObject selector.
@interface DeclareSelectors
@@ -37,6 +41,7 @@ using namespace swift;
@end
@class SwiftObject;
#endif
namespace {
@@ -89,11 +94,12 @@ struct String {
swift_stringFromUTF8InRawMemory(this, concatenated, len1 + len2);
free(concatenated);
}
#if SWIFT_OBJC_INTEROP
explicit String(NSString *s)
// FIXME: Use the usual NSString bridging entry point.
: String([s UTF8String])
{}
#endif
};
struct Array {
@@ -258,7 +264,8 @@ const Metadata *swift_MagicMirrorData_valueType(HeapObject *owner,
swift_release(owner);
return r;
}
#if SWIFT_OBJC_INTEROP
extern "C"
Any swift_MagicMirrorData_objcValue(HeapObject *owner,
const OpaqueValue *value,
@@ -272,6 +279,8 @@ Any swift_MagicMirrorData_objcValue(HeapObject *owner,
swift_release(owner);
return result;
}
#endif
extern "C"
void swift_MagicMirrorData_summary(const Metadata *T, String *result) {
switch (T->getKind()) {
@@ -417,19 +426,23 @@ StringMirrorTuple swift_StructMirror_subscript(intptr_t i,
}
// -- Class destructuring.
static bool classHasSuperclass(const ClassMetadata *c) {
#if SWIFT_OBJC_INTEROP
// A class does not have a superclass if its ObjC superclass is the
// "SwiftObject" root class.
return c->SuperClass
&& (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,
HeapObject *owner,
const OpaqueValue *value,
const Metadata *type);
extern "C"
intptr_t swift_ClassMirror_count(HeapObject *owner,
const OpaqueValue *value,
@@ -437,12 +450,12 @@ intptr_t swift_ClassMirror_count(HeapObject *owner,
auto Clas = static_cast<const ClassMetadata*>(type);
swift_release(owner);
auto count = Clas->getDescription()->Class.NumFields;
// If the class has a superclass, the superclass instance is treated as the
// first child.
if (classHasSuperclass(Clas))
count += 1;
return count;
}
@@ -456,7 +469,7 @@ StringMirrorTuple swift_ClassMirror_subscript(intptr_t i,
StringMirrorTuple result;
auto Clas = static_cast<const ClassMetadata*>(type);
if (classHasSuperclass(Clas)) {
// If the class has a superclass, the superclass instance is treated as the
// first child.
@@ -483,9 +496,13 @@ StringMirrorTuple swift_ClassMirror_subscript(intptr_t i,
if (usesNativeSwiftReferenceCounting(Clas)) {
fieldOffset = Clas->getFieldOffsets()[i];
} else {
#if SWIFT_OBJC_INTEROP
Ivar *ivars = class_copyIvarList((Class)Clas, nullptr);
fieldOffset = ivar_getOffset(ivars[i]);
free(ivars);
#else
swift::crash("Object appears to be Objective-C, but no runtime.");
#endif
}
auto bytes = *reinterpret_cast<const char * const*>(value);
@@ -598,7 +615,7 @@ intptr_t swift_ObjCMirror_count(HeapObject *owner,
return 0;
#endif
}
#if SWIFT_OBJC_INTEROP
static Mirror ObjC_getMirrorForSuperclass(Class sup,
HeapObject *owner,
const OpaqueValue *value,
@@ -749,6 +766,7 @@ OptionalQuickLookObject swift_ClassMirror_quickLookObject(HeapObject *owner,
result.optional.isNone = true;
return result;
}
#endif
// -- MagicMirror implementation.
@@ -769,6 +787,7 @@ extern "C" const MirrorWitnessTable _TWPVSs12_ClassMirrorSs10MirrorTypeSs;
extern "C" const FullMetadata<Metadata> _TMdVSs17_ClassSuperMirror;
extern "C" const MirrorWitnessTable _TWPVSs17_ClassSuperMirrorSs10MirrorTypeSs;
#if SWIFT_OBJC_INTEROP
// These type metadata objects are kept in swiftFoundation because they rely
// on string bridging being installed.
static const Metadata *getObjCMirrorMetadata() {
@@ -804,6 +823,7 @@ static const MirrorWitnessTable *getObjCSuperMirrorWitness() {
return witness;
}
#endif
/// \param owner passed at +1, consumed.
/// \param value passed unowned.
@@ -811,11 +831,13 @@ static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
HeapObject *owner,
const OpaqueValue *value,
const Metadata *type) {
#if SWIFT_OBJC_INTEROP
// If the superclass is natively ObjC, cut over to the ObjC mirror
// implementation.
if (!sup->isTypeMetadata())
return ObjC_getMirrorForSuperclass((Class)sup, owner, value, type);
#endif
Mirror resultBuf;
MagicMirror *result = ::new (&resultBuf) MagicMirror;
@@ -828,6 +850,7 @@ static Mirror getMirrorForSuperclass(const ClassMetadata *sup,
return resultBuf;
}
#if SWIFT_OBJC_INTEROP
/// \param owner passed at +1, consumed.
/// \param value passed unowned.
static Mirror ObjC_getMirrorForSuperclass(Class sup,
@@ -844,7 +867,8 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
result->Data.Value = value;
return resultBuf;
}
#endif
// (type being mirrored, mirror type, mirror witness)
using MirrorTriple
= std::tuple<const Metadata *, const Metadata *, const MirrorWitnessTable *>;
@@ -854,13 +878,16 @@ getImplementationForClass(const OpaqueValue *Value) {
// Get the runtime type of the object.
const void *obj = *reinterpret_cast<const void * const *>(Value);
auto isa = _swift_getClass(obj);
#if SWIFT_OBJC_INTEROP
// If this is a pure ObjC class, reflect it using ObjC's runtime facilities.
if (!isa->isTypeMetadata())
return {isa, getObjCMirrorMetadata(), getObjCMirrorWitness()};
#endif
// 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.
@@ -868,10 +895,12 @@ static MirrorTriple
getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
switch (T->getKind()) {
case MetadataKind::Tuple:
return {T, &_TMdVSs12_TupleMirror, &_TWPVSs12_TupleMirrorSs10MirrorTypeSs};
return std::make_tuple(
T, &_TMdVSs12_TupleMirror, &_TWPVSs12_TupleMirrorSs10MirrorTypeSs);
case MetadataKind::Struct:
return {T, &_TMdVSs13_StructMirror, &_TWPVSs13_StructMirrorSs10MirrorTypeSs};
return std::make_tuple(
T, &_TMdVSs13_StructMirror, &_TWPVSs13_StructMirrorSs10MirrorTypeSs);
case MetadataKind::ObjCClassWrapper:
case MetadataKind::ForeignClass:
@@ -880,12 +909,13 @@ getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
}
case MetadataKind::Opaque: {
#if SWIFT_OBJC_INTEROP
// If this is the Builtin.UnknownObject type, use the dynamic type of the
// object reference.
if (T == &_TMdBO.base) {
return getImplementationForClass(Value);
}
#endif
// If this is the Builtin.NativeObject type, and the heap object is a
// class instance, use the dynamic type of the object reference.
if (T == &_TMdBo.base) {
@@ -904,7 +934,8 @@ getImplementationForType(const Metadata *T, const OpaqueValue *Value) {
case MetadataKind::Existential:
case MetadataKind::ExistentialMetatype:
case MetadataKind::Metatype:
return {T, &_TMdVSs13_OpaqueMirror, &_TWPVSs13_OpaqueMirrorSs10MirrorTypeSs};
return std::make_tuple(
T, &_TMdVSs13_OpaqueMirror, &_TWPVSs13_OpaqueMirrorSs10MirrorTypeSs);
// Types can't have these kinds.
case MetadataKind::PolyFunction:
@@ -968,12 +999,11 @@ getReflectableConformance(const Metadata *T, const OpaqueValue *Value) {
unsigned wtOffset = 0;
for (unsigned i = 0; i < existential->Protocols.NumProtocols; ++i) {
if (existential->Protocols[i] == &_TMpSs11Reflectable) {
return {
reinterpret_cast<const ReflectableWitnessTable*>(
existential->getWitnessTable(Value, wtOffset)),
existential->getDynamicType(Value),
existential->projectValue(Value)
};
return std::make_tuple(
reinterpret_cast<const ReflectableWitnessTable*>(
existential->getWitnessTable(Value, wtOffset)),
existential->getDynamicType(Value),
existential->projectValue(Value));
}
if (existential->Protocols[i]->Flags.needsWitnessTable())
++wtOffset;
@@ -997,12 +1027,11 @@ getReflectableConformance(const Metadata *T, const OpaqueValue *Value) {
swift::crash("Swift mirror lookup failure");
}
return {
reinterpret_cast<const ReflectableWitnessTable*>(
swift_conformsToProtocol(T, &_TMpSs11Reflectable)),
T,
Value
};
return std::make_tuple(
reinterpret_cast<const ReflectableWitnessTable*>(
swift_conformsToProtocol(T, &_TMpSs11Reflectable)),
T,
Value);
}
} // end anonymous namespace
@@ -1121,9 +1150,14 @@ static void swift_stdlib_getTypeNameImpl(OpaqueValue *value,
return;
case MetadataKind::ObjCClassWrapper: {
#if SWIFT_OBJC_INTEROP
auto wrapperMetadata =
static_cast<const ObjCClassWrapperMetadata *>(dynamicType);
new (result) String(object_getClassName((id)wrapperMetadata->Class));
#else
assert(false && "Unexpected ObjC Wrapper Object");
new (result) String("");
#endif
return;
}

View 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

View File

@@ -15,6 +15,8 @@
//
//===----------------------------------------------------------------------===//
#include "swift/Runtime/Config.h"
#if SWIFT_OBJC_INTEROP
#include <objc/NSObject.h>
#include <objc/runtime.h>
#include <objc/message.h>
@@ -22,6 +24,7 @@
#include <objc/objc-abi.h>
#include <objc/objc-internal.h>
#endif
#endif
#include "swift/Runtime/Heap.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Metadata.h"
@@ -34,8 +37,11 @@
#include <stdlib.h>
#include <mutex>
#include <unordered_map>
#if SWIFT_OBJC_INTEROP
#import <CoreFoundation/CFBase.h> // for CFTypeID
#endif
#if SWIFT_OBJC_INTEROP
// Redeclare these just we check them.
extern "C" id objc_retain(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" void objc_destroyWeak(id*);
extern "C" id objc_loadWeakRetained(id*);
#endif
using namespace swift;
@@ -70,7 +77,6 @@ const ClassMetadata *swift::_swift_getClass(const void *object) {
return _swift_getClassOfAllocated(object);
return reinterpret_cast<const ClassMetadata*>(object_getClass((id) object));
}
#endif
struct SwiftObject_s {
void *isa __attribute__((unavailable));
@@ -406,20 +412,30 @@ static void objc_rootWeakRelease(id object) {
UnownedRefs.erase(it);
}
}
#endif
/// Decide dynamically whether the given object uses native Swift
/// reference-counting.
bool swift::usesNativeSwiftReferenceCounting(const ClassMetadata *theClass) {
#if SWIFT_OBJC_INTEROP
if (!theClass->isTypeMetadata()) return false;
return (theClass->getFlags() & ClassFlags::UsesSwift1Refcounting);
#else
return true;
#endif
}
// version for SwiftShims
unsigned char
swift::_swift_usesNativeSwiftReferenceCounting_class(const void *theClass) {
#if SWIFT_OBJC_INTEROP
return usesNativeSwiftReferenceCounting((const ClassMetadata *)theClass);
#else
return true;
#endif
}
#if SWIFT_OBJC_INTEROP
static bool usesNativeSwiftReferenceCounting_allocated(const void *object) {
assert(!isObjCTaggedPointerOrNull(object));
return usesNativeSwiftReferenceCounting(_swift_getClassOfAllocated(object));
@@ -438,10 +454,13 @@ void swift::swift_unknownRelease(void *object) {
return swift_release((HeapObject*) object);
return objc_release((id) object);
}
#endif
void *swift::swift_bridgeObjectRetain(void *object) {
#if SWIFT_OBJC_INTEROP
if (isObjCTaggedPointerOrNull(object))
return object;
#endif
// Mask out the spare bits, which may store arbitrary data.
uintptr_t objectRef = uintptr_t(object)
@@ -454,13 +473,15 @@ void *swift::swift_bridgeObjectRetain(void *object) {
return swift_retain((HeapObject*) objectRef);
return objc_retain((id) objectRef);
#else
return swift_retain((HeapOject*) objectRef);
return swift_retain((HeapObject*) objectRef);
#endif
}
void swift::swift_bridgeObjectRelease(void *object) {
#if SWIFT_OBJC_INTEROP
if (isObjCTaggedPointerOrNull(object))
return;
#endif
// Mask out the spare bits, which may store arbitrary data.
uintptr_t objectRef = uintptr_t(object)
@@ -477,6 +498,7 @@ void swift::swift_bridgeObjectRelease(void *object) {
#endif
}
#if SWIFT_OBJC_INTEROP
void swift::swift_unknownRetainUnowned(void *object) {
if (isObjCTaggedPointerOrNull(object)) return;
if (usesNativeSwiftReferenceCounting_allocated(object))
@@ -506,7 +528,11 @@ static void doWeakInit(WeakReference *addr, void *value, bool valueIsNative) {
if (valueIsNative) {
swift_weakInit(addr, (HeapObject*) value);
} else {
#if SWIFT_OBJC_INTEROP
objc_initWeak((id*) &addr->Value, (id) value);
#else
assert(valueIsNative);
#endif
}
}
@@ -514,7 +540,11 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) {
if (valueIsNative) {
swift_weakDestroy(addr);
} else {
objc_destroyWeak((id*) &addr->Value);
#if SWIFT_OBJC_INTEROP
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_unknownWeakTakeInit(dest, src);
}
#endif
/*****************************************************************************/
/******************************* DYNAMIC CASTS *******************************/
/*****************************************************************************/
#if SWIFT_OBJC_INTEROP
const void *
swift::swift_dynamicCastObjCClass(const void *object,
const ClassMetadata *targetType) {
@@ -764,6 +795,7 @@ extern "C" const char *swift_getGenericClassObjCName(const ClassMetadata *clas,
(unsigned long long)clas);
return fullName;
}
#endif
// Given a non-nil object reference, return true iff the object uses
// native swift reference counting.
@@ -846,7 +878,12 @@ unsigned char swift::_swift_isUniquelyReferenced_native_spareBits(
///
/// That function is otherwise unavailable to the core stdlib.
size_t swift::_swift_class_getInstanceSize_class(const void* c) {
#if SWIFT_OBJC_INTEROP
return class_getInstanceSize((Class)c);
#else
auto metaData = static_cast<const ClassMetadata*>(c);
return metaData->getInstanceSize() - metaData->getInstanceAlignMask();
#endif
}
const ClassMetadata *swift::getRootSuperclass() {