Skip to content

Commit 3202021

Browse files
authored
Merge pull request #66857 from Catfish-Man/revert-bridge-flip
Revert [Runtime] Let CF provide us with state, avoiding runtime lookup
2 parents c5018f3 + e20be0e commit 3202021

File tree

7 files changed

+65
-148
lines changed

7 files changed

+65
-148
lines changed

stdlib/public/SwiftShims/swift/shims/CoreFoundationShims.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,7 @@ _swift_stdlib_NSStringGetCStringTrampoline(id _Nonnull obj,
7474
SWIFT_RUNTIME_STDLIB_API
7575
__swift_uint8_t
7676
_swift_stdlib_dyld_is_objc_constant_string(const void * _Nonnull addr);
77-
78-
/// Get the NSError Objective-C class.
79-
_Nullable Class getNSErrorClass();
80-
77+
8178
#endif // __OBJC2__
8279

8380
#ifdef __cplusplus

stdlib/public/runtime/ErrorObject.mm

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ - (BOOL)isEqual:(id)other {
185185

186186
@end
187187

188+
Class swift::getNSErrorClass() {
189+
return SWIFT_LAZY_CONSTANT(objc_lookUpClass("NSError"));
190+
}
191+
188192
const Metadata *swift::getNSErrorMetadata() {
189193
return SWIFT_LAZY_CONSTANT(
190194
swift_getObjCClassMetadata((const ClassMetadata *)getNSErrorClass()));
@@ -216,8 +220,16 @@ - (BOOL)isEqual:(id)other {
216220
}
217221

218222
static Class getAndBridgeSwiftNativeNSErrorClass() {
219-
(void)getNSErrorClass(); //make sure the bridge is set up
220-
return [__SwiftNativeNSError class];
223+
Class nsErrorClass = swift::getNSErrorClass();
224+
Class ourClass = [__SwiftNativeNSError class];
225+
// We want "err as AnyObject" to do *something* even without Foundation
226+
if (nsErrorClass) {
227+
#pragma clang diagnostic push
228+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
229+
class_setSuperclass(ourClass, nsErrorClass);
230+
#pragma clang diagnostic pop
231+
}
232+
return ourClass;
221233
}
222234

223235
static Class getSwiftNativeNSErrorClass() {

stdlib/public/runtime/SwiftObject.mm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,6 @@ static bool isObjCForUnownedReference(void *value) {
10861086
/*****************************************************************************/
10871087

10881088
#if SWIFT_OBJC_INTEROP
1089-
10901089
static const void *
10911090
swift_dynamicCastObjCClassImpl(const void *object,
10921091
const ClassMetadata *targetType) {

stdlib/public/stubs/FoundationHelpers.mm

Lines changed: 28 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -24,150 +24,60 @@
2424
#import <objc/runtime.h>
2525
#include "swift/Runtime/Once.h"
2626
#include <dlfcn.h>
27-
#include "swift/Runtime/Atomic.h"
2827

2928
typedef enum {
3029
dyld_objc_string_kind
3130
} DyldObjCConstantKind;
3231

3332
using namespace swift;
3433

35-
typedef struct _CFBridgingState {
36-
long version;
37-
CFHashCode(*_CFStringHashCString)(const uint8_t *bytes, CFIndex len);
38-
CFHashCode(*_CFStringHashNSString)(id str);
39-
CFTypeID(*_CFGetTypeID)(CFTypeRef obj);
40-
CFTypeID _CFStringTypeID = 0;
41-
Class NSErrorClass;
42-
Class NSStringClass;
43-
Class NSArrayClass;
44-
Class NSMutableArrayClass;
45-
Class NSSetClass;
46-
Class NSDictionaryClass;
47-
Class NSEnumeratorClass;
48-
//version 0 ends here
49-
} CFBridgingState;
50-
51-
static std::atomic<CFBridgingState const *> bridgingState;
52-
static swift_once_t initializeBridgingStateOnce;
53-
54-
static CFBridgingState const *getBridgingState() {
55-
return bridgingState.load(SWIFT_MEMORY_ORDER_CONSUME);
56-
}
34+
static CFHashCode(*_CFStringHashCString)(const uint8_t *bytes, CFIndex len);
35+
static CFHashCode(*_CFStringHashNSString)(id str);
36+
static CFTypeID(*_CFGetTypeID)(CFTypeRef obj);
37+
static CFTypeID _CFStringTypeID = 0;
38+
static swift_once_t initializeBridgingFuncsOnce;
5739

5840
extern "C" bool _dyld_is_objc_constant(DyldObjCConstantKind kind,
5941
const void *addr) SWIFT_RUNTIME_WEAK_IMPORT;
6042

61-
@class __SwiftNativeNSStringBase, __SwiftNativeNSError, __SwiftNativeNSArrayBase, __SwiftNativeNSMutableArrayBase, __SwiftNativeNSDictionaryBase, __SwiftNativeNSSetBase, __SwiftNativeNSEnumeratorBase;
62-
63-
static void _reparentClasses() {
64-
auto state = getBridgingState();
65-
#pragma clang diagnostic push
66-
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
67-
if (state->NSStringClass) {
68-
[state->NSStringClass class]; //make sure the class is realized
69-
class_setSuperclass([__SwiftNativeNSStringBase class], state->NSStringClass);
70-
}
71-
if (state->NSErrorClass) {
72-
[state->NSErrorClass class]; //make sure the class is realized
73-
class_setSuperclass([__SwiftNativeNSError class], state->NSErrorClass);
74-
}
75-
if (state->NSArrayClass) {
76-
[state->NSArrayClass class]; //make sure the class is realized
77-
class_setSuperclass([__SwiftNativeNSArrayBase class], state->NSArrayClass);
78-
}
79-
if (state->NSMutableArrayClass) {
80-
[state->NSMutableArrayClass class]; //make sure the class is realized
81-
class_setSuperclass([__SwiftNativeNSMutableArrayBase class], state->NSMutableArrayClass);
82-
}
83-
if (state->NSDictionaryClass) {
84-
[state->NSDictionaryClass class]; //make sure the class is realized
85-
class_setSuperclass([__SwiftNativeNSDictionaryBase class], state->NSDictionaryClass);
86-
}
87-
if (state->NSSetClass) {
88-
[state->NSSetClass class]; //make sure the class is realized
89-
class_setSuperclass([__SwiftNativeNSSetBase class], state->NSSetClass);
90-
}
91-
if (state->NSEnumeratorClass) {
92-
[state->NSEnumeratorClass class]; //make sure the class is realized
93-
class_setSuperclass([__SwiftNativeNSEnumeratorBase class], state->NSEnumeratorClass);
94-
}
95-
#pragma clang diagnostic pop
96-
}
97-
98-
static inline bool initializeBridgingFunctions() {
99-
swift::once(initializeBridgingStateOnce, [](){
100-
assert(!getBridgingState());
101-
auto getStringTypeID = (CFTypeID(*)(void))dlsym(RTLD_DEFAULT, "CFStringGetTypeID");
102-
if (!getStringTypeID) {
103-
return; //CF not loaded
104-
}
105-
auto state = (CFBridgingState *)calloc(1, sizeof(CFBridgingState));
106-
state->version = 0;
107-
state->_CFStringTypeID = getStringTypeID();
108-
state->_CFGetTypeID = (CFTypeID(*)(CFTypeRef obj))dlsym(RTLD_DEFAULT, "CFGetTypeID");
109-
state->_CFStringHashNSString = (CFHashCode(*)(id))dlsym(RTLD_DEFAULT, "CFStringHashNSString");
110-
state->_CFStringHashCString = (CFHashCode(*)(const uint8_t *, CFIndex))dlsym(RTLD_DEFAULT, "CFStringHashCString");
111-
state->NSErrorClass = objc_lookUpClass("NSError");
112-
state->NSStringClass = objc_lookUpClass("NSString");
113-
state->NSArrayClass = objc_lookUpClass("NSArray");
114-
state->NSMutableArrayClass = objc_lookUpClass("NSMutableArray");
115-
state->NSSetClass = objc_lookUpClass("NSSet");
116-
state->NSDictionaryClass = objc_lookUpClass("NSDictionary");
117-
state->NSEnumeratorClass = objc_lookUpClass("NSEnumerator");
118-
bridgingState.store(state, std::memory_order_relaxed);
119-
_reparentClasses();
120-
});
121-
auto state = getBridgingState();
122-
return state && state->NSStringClass != nullptr;
123-
}
124-
125-
SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState(CFBridgingState const * const state) {
126-
//Consume the once token to make sure that the lazy version of this in initializeBridgingFunctions only runs if we didn't hit this
127-
swift::once(initializeBridgingStateOnce, [state](){
128-
bridgingState.store(state, std::memory_order_relaxed);
129-
});
130-
//It's fine if this runs more than once, it's a noop if it's been done before
131-
//and we want to make sure it still happens if CF loads late after it failed initially
132-
bridgingState.store(state, std::memory_order_release);
133-
_reparentClasses();
134-
}
135-
136-
namespace swift {
137-
Class getNSErrorClass();
138-
}
139-
140-
Class swift::getNSErrorClass() {
141-
if (initializeBridgingFunctions()) {
142-
return getBridgingState()->NSErrorClass;
143-
}
144-
return nullptr;
43+
static void _initializeBridgingFunctionsImpl(void *ctxt) {
44+
auto getStringTypeID =
45+
(CFTypeID(*)(void))
46+
dlsym(RTLD_DEFAULT, "CFStringGetTypeID");
47+
assert(getStringTypeID);
48+
_CFStringTypeID = getStringTypeID();
49+
50+
_CFGetTypeID = (CFTypeID(*)(CFTypeRef obj))dlsym(RTLD_DEFAULT, "CFGetTypeID");
51+
_CFStringHashNSString = (CFHashCode(*)(id))dlsym(RTLD_DEFAULT,
52+
"CFStringHashNSString");
53+
_CFStringHashCString = (CFHashCode(*)(const uint8_t *, CFIndex))dlsym(
54+
RTLD_DEFAULT,
55+
"CFStringHashCString");
14556
}
14657

147-
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
148-
bool
149-
swift_stdlib_connectNSBaseClasses() {
150-
return initializeBridgingFunctions();
58+
static inline void initializeBridgingFunctions() {
59+
swift_once(&initializeBridgingFuncsOnce,
60+
_initializeBridgingFunctionsImpl,
61+
nullptr);
15162
}
15263

15364
__swift_uint8_t
15465
_swift_stdlib_isNSString(id obj) {
155-
assert(initializeBridgingFunctions());
156-
auto state = getBridgingState();
157-
return state->_CFGetTypeID((CFTypeRef)obj) == state->_CFStringTypeID ? 1 : 0;
66+
initializeBridgingFunctions();
67+
return _CFGetTypeID((CFTypeRef)obj) == _CFStringTypeID ? 1 : 0;
15868
}
15969

16070
_swift_shims_CFHashCode
16171
_swift_stdlib_CFStringHashNSString(id _Nonnull obj) {
162-
assert(initializeBridgingFunctions());
163-
return getBridgingState()->_CFStringHashNSString(obj);
72+
initializeBridgingFunctions();
73+
return _CFStringHashNSString(obj);
16474
}
16575

16676
_swift_shims_CFHashCode
16777
_swift_stdlib_CFStringHashCString(const _swift_shims_UInt8 * _Nonnull bytes,
16878
_swift_shims_CFIndex length) {
169-
assert(initializeBridgingFunctions());
170-
return getBridgingState()->_CFStringHashCString(bytes, length);
79+
initializeBridgingFunctions();
80+
return _CFStringHashCString(bytes, length);
17181
}
17282

17383
const __swift_uint8_t *

stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,22 @@ swift_stdlib_NSObject_isEqual(id lhs,
8787
return (lhs == rhs) || [lhs isEqual:rhs];
8888
}
8989

90+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
91+
bool
92+
swift_stdlib_connectNSBaseClasses() {
93+
% for Class in ('Array', 'MutableArray', 'Dictionary', 'Set', 'String', 'Enumerator'):
94+
Class NS${Class}Super = objc_lookUpClass("NS${Class}");
95+
if (!NS${Class}Super) return false;
96+
Class NS${Class}OurClass = objc_lookUpClass("__SwiftNativeNS${Class}Base");
97+
if (!NS${Class}OurClass) return false;
98+
#pragma clang diagnostic push
99+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
100+
class_setSuperclass(NS${Class}OurClass, NS${Class}Super);
101+
#pragma clang diagnostic pop
102+
% end
103+
return true;
104+
}
105+
90106
#endif
91107

92108
// ${'Local Variables'}:

unittests/runtime/CMakeLists.txt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
4040

4141
set(PLATFORM_SOURCES)
4242
set(PLATFORM_TARGET_LINK_LIBRARIES)
43-
set(PLATFORM_TARGET_RUNTIME_ARCHIVES)
44-
45-
list(APPEND PLATFORM_TARGET_RUNTIME_ARCHIVES
46-
$<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
47-
$<TARGET_OBJECTS:swiftLLVMSupport${SWIFT_PRIMARY_VARIANT_SUFFIX}>
48-
$<TARGET_OBJECTS:swiftDemangling${SWIFT_PRIMARY_VARIANT_SUFFIX}>
49-
)
50-
5143
if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}")
5244
find_library(FOUNDATION_LIBRARY Foundation)
5345
list(APPEND PLATFORM_SOURCES
@@ -61,9 +53,6 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
6153
swift_Concurrency${SWIFT_PRIMARY_VARIANT_SUFFIX}
6254
swiftStdlibUnittest${SWIFT_PRIMARY_VARIANT_SUFFIX}
6355
)
64-
list(APPEND PLATFORM_TARGET_RUNTIME_ARCHIVES
65-
$<TARGET_OBJECTS:swiftStdlibStubs${SWIFT_PRIMARY_VARIANT_SUFFIX}>
66-
)
6756
elseif(SWIFT_HOST_VARIANT STREQUAL "Linux")
6857
if(SWIFT_HOST_VARIANT_ARCH MATCHES "armv6|armv7|i686")
6958
list(APPEND PLATFORM_TARGET_LINK_LIBRARIES
@@ -127,7 +116,9 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
127116
# The runtime tests link to internal runtime symbols, which aren't exported
128117
# from the swiftCore dylib, so we need to link to both the runtime archive
129118
# and the stdlib.
130-
${PLATFORM_TARGET_RUNTIME_ARCHIVES}
119+
$<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
120+
$<TARGET_OBJECTS:swiftLLVMSupport${SWIFT_PRIMARY_VARIANT_SUFFIX}>
121+
$<TARGET_OBJECTS:swiftDemangling${SWIFT_PRIMARY_VARIANT_SUFFIX}>
131122
)
132123

133124
# The local stdlib implementation provides definitions of the swiftCore

unittests/runtime/LongTests/CMakeLists.txt

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,8 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
33

44
set(PLATFORM_SOURCES)
55
set(PLATFORM_TARGET_LINK_LIBRARIES)
6-
set(PLATFORM_TARGET_RUNTIME_ARCHIVES)
7-
8-
list(APPEND PLATFORM_TARGET_RUNTIME_ARCHIVES
9-
$<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
10-
$<TARGET_OBJECTS:swiftLLVMSupport${SWIFT_PRIMARY_VARIANT_SUFFIX}>
11-
$<TARGET_OBJECTS:swiftDemangling${SWIFT_PRIMARY_VARIANT_SUFFIX}>
12-
)
136

147
if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}")
15-
list(APPEND PLATFORM_TARGET_RUNTIME_ARCHIVES
16-
$<TARGET_OBJECTS:swiftStdlibStubs${SWIFT_PRIMARY_VARIANT_SUFFIX}>
17-
)
188
# Placeholder for Darwin Foundation tests (currently none)
199
# find_library(FOUNDATION_LIBRARY Foundation)
2010
# list(APPEND PLATFORM_SOURCES
@@ -52,7 +42,9 @@ if(("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "${SWIFT_PRIMARY_VARIANT_SDK}") AND
5242
# The runtime tests link to internal runtime symbols, which aren't exported
5343
# from the swiftCore dylib, so we need to link to both the runtime archive
5444
# and the stdlib.
55-
${PLATFORM_TARGET_RUNTIME_ARCHIVES}
45+
$<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
46+
$<TARGET_OBJECTS:swiftLLVMSupport${SWIFT_PRIMARY_VARIANT_SUFFIX}>
47+
$<TARGET_OBJECTS:swiftDemangling${SWIFT_PRIMARY_VARIANT_SUFFIX}>
5648
)
5749

5850
# The local stdlib implementation provides definitions of the swiftCore

0 commit comments

Comments
 (0)