24
24
#import < objc/runtime.h>
25
25
#include " swift/Runtime/Once.h"
26
26
#include < dlfcn.h>
27
+ #include " swift/Runtime/Atomic.h"
27
28
28
29
typedef enum {
29
30
dyld_objc_string_kind
47
48
// version 0 ends here
48
49
} CFBridgingState;
49
50
50
- static CFBridgingState * bridgingState;
51
+ static std::atomic< CFBridgingState const *> bridgingState;
51
52
static swift_once_t initializeBridgingStateOnce;
52
53
54
+ static CFBridgingState const *getBridgingState () {
55
+ return bridgingState.load (SWIFT_MEMORY_ORDER_CONSUME);
56
+ }
57
+
53
58
extern " C" bool _dyld_is_objc_constant (DyldObjCConstantKind kind,
54
59
const void *addr) SWIFT_RUNTIME_WEAK_IMPORT;
55
60
56
- static void _initializeBridgingFunctionsFromCFImpl (void *ctxt) {
57
- bridgingState = (CFBridgingState *)ctxt;
58
- }
59
-
60
61
@class __SwiftNativeNSStringBase, __SwiftNativeNSError, __SwiftNativeNSArrayBase, __SwiftNativeNSMutableArrayBase, __SwiftNativeNSDictionaryBase, __SwiftNativeNSSetBase, __SwiftNativeNSEnumeratorBase;
61
62
62
63
static void _reparentClasses () {
64
+ auto state = getBridgingState ();
63
65
#pragma clang diagnostic push
64
66
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
65
- if (bridgingState ->NSStringClass ) {
66
- [bridgingState ->NSStringClass class ]; // make sure the class is realized
67
- class_setSuperclass ([__SwiftNativeNSStringBase class ], bridgingState ->NSStringClass );
67
+ if (state ->NSStringClass ) {
68
+ [state ->NSStringClass class ]; // make sure the class is realized
69
+ class_setSuperclass ([__SwiftNativeNSStringBase class ], state ->NSStringClass );
68
70
}
69
- if (bridgingState ->NSErrorClass ) {
70
- [bridgingState ->NSErrorClass class ]; // make sure the class is realized
71
- class_setSuperclass ([__SwiftNativeNSError class ], bridgingState ->NSErrorClass );
71
+ if (state ->NSErrorClass ) {
72
+ [state ->NSErrorClass class ]; // make sure the class is realized
73
+ class_setSuperclass ([__SwiftNativeNSError class ], state ->NSErrorClass );
72
74
}
73
- if (bridgingState ->NSArrayClass ) {
74
- [bridgingState ->NSArrayClass class ]; // make sure the class is realized
75
- class_setSuperclass ([__SwiftNativeNSArrayBase class ], bridgingState ->NSArrayClass );
75
+ if (state ->NSArrayClass ) {
76
+ [state ->NSArrayClass class ]; // make sure the class is realized
77
+ class_setSuperclass ([__SwiftNativeNSArrayBase class ], state ->NSArrayClass );
76
78
}
77
- if (bridgingState ->NSMutableArrayClass ) {
78
- [bridgingState ->NSMutableArrayClass class ]; // make sure the class is realized
79
- class_setSuperclass ([__SwiftNativeNSMutableArrayBase class ], bridgingState ->NSMutableArrayClass );
79
+ if (state ->NSMutableArrayClass ) {
80
+ [state ->NSMutableArrayClass class ]; // make sure the class is realized
81
+ class_setSuperclass ([__SwiftNativeNSMutableArrayBase class ], state ->NSMutableArrayClass );
80
82
}
81
- if (bridgingState ->NSDictionaryClass ) {
82
- [bridgingState ->NSDictionaryClass class ]; // make sure the class is realized
83
- class_setSuperclass ([__SwiftNativeNSDictionaryBase class ], bridgingState ->NSDictionaryClass );
83
+ if (state ->NSDictionaryClass ) {
84
+ [state ->NSDictionaryClass class ]; // make sure the class is realized
85
+ class_setSuperclass ([__SwiftNativeNSDictionaryBase class ], state ->NSDictionaryClass );
84
86
}
85
- if (bridgingState ->NSSetClass ) {
86
- [bridgingState ->NSSetClass class ]; // make sure the class is realized
87
- class_setSuperclass ([__SwiftNativeNSSetBase class ], bridgingState ->NSSetClass );
87
+ if (state ->NSSetClass ) {
88
+ [state ->NSSetClass class ]; // make sure the class is realized
89
+ class_setSuperclass ([__SwiftNativeNSSetBase class ], state ->NSSetClass );
88
90
}
89
- if (bridgingState ->NSEnumeratorClass ) {
90
- [bridgingState ->NSEnumeratorClass class ]; // make sure the class is realized
91
- class_setSuperclass ([__SwiftNativeNSEnumeratorBase class ], bridgingState ->NSEnumeratorClass );
91
+ if (state ->NSEnumeratorClass ) {
92
+ [state ->NSEnumeratorClass class ]; // make sure the class is realized
93
+ class_setSuperclass ([__SwiftNativeNSEnumeratorBase class ], state ->NSEnumeratorClass );
92
94
}
93
95
#pragma clang diagnostic pop
94
96
}
95
97
96
- static void _initializeBridgingFunctionsImpl (void *ctxt) {
97
- assert (!bridgingState);
98
- auto getStringTypeID = (CFTypeID (*)(void ))dlsym (RTLD_DEFAULT, " CFStringGetTypeID" );
99
- if (!getStringTypeID) {
100
- return ; // CF not loaded
101
- }
102
- bridgingState = (CFBridgingState *)calloc (1 , sizeof (CFBridgingState));
103
- bridgingState->version = 0 ;
104
- bridgingState->_CFStringTypeID = getStringTypeID ();
105
- bridgingState->_CFGetTypeID = (CFTypeID (*)(CFTypeRef obj))dlsym (RTLD_DEFAULT, " CFGetTypeID" );
106
- bridgingState->_CFStringHashNSString = (CFHashCode (*)(id ))dlsym (RTLD_DEFAULT, " CFStringHashNSString" );
107
- bridgingState->_CFStringHashCString = (CFHashCode (*)(const uint8_t *, CFIndex))dlsym (RTLD_DEFAULT, " CFStringHashCString" );
108
- bridgingState->NSErrorClass = objc_lookUpClass (" NSError" );
109
- bridgingState->NSStringClass = objc_lookUpClass (" NSString" );
110
- bridgingState->NSArrayClass = objc_lookUpClass (" NSArray" );
111
- bridgingState->NSMutableArrayClass = objc_lookUpClass (" NSMutableArray" );
112
- bridgingState->NSSetClass = objc_lookUpClass (" NSSet" );
113
- bridgingState->NSDictionaryClass = objc_lookUpClass (" NSDictionary" );
114
- bridgingState->NSEnumeratorClass = objc_lookUpClass (" NSEnumerator" );
115
- _reparentClasses ();
116
- }
117
-
118
98
static inline bool initializeBridgingFunctions () {
119
- swift_once (&initializeBridgingStateOnce,
120
- _initializeBridgingFunctionsImpl,
121
- nullptr );
122
- return bridgingState && bridgingState->NSStringClass != nullptr ;
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
123
}
124
124
125
125
SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState (CFBridgingState const * const state) {
126
- swift_once (&initializeBridgingStateOnce,
127
- _initializeBridgingFunctionsFromCFImpl,
128
- (void *)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
+ });
129
130
// It's fine if this runs more than once, it's a noop if it's been done before
130
- // and we want to make sure it happens if CF loads late after it failed initially
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);
131
133
_reparentClasses ();
132
134
}
133
135
@@ -137,7 +139,7 @@ SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState(CFBridgingState co
137
139
138
140
Class swift::getNSErrorClass () {
139
141
if (initializeBridgingFunctions ()) {
140
- return bridgingState ->NSErrorClass ;
142
+ return getBridgingState () ->NSErrorClass ;
141
143
}
142
144
return nullptr ;
143
145
}
@@ -151,20 +153,21 @@ SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState(CFBridgingState co
151
153
__swift_uint8_t
152
154
_swift_stdlib_isNSString (id obj) {
153
155
assert (initializeBridgingFunctions ());
154
- return bridgingState->_CFGetTypeID ((CFTypeRef)obj) == bridgingState->_CFStringTypeID ? 1 : 0 ;
156
+ auto state = getBridgingState ();
157
+ return state->_CFGetTypeID ((CFTypeRef)obj) == state->_CFStringTypeID ? 1 : 0 ;
155
158
}
156
159
157
160
_swift_shims_CFHashCode
158
161
_swift_stdlib_CFStringHashNSString (id _Nonnull obj) {
159
162
assert (initializeBridgingFunctions ());
160
- return bridgingState ->_CFStringHashNSString (obj);
163
+ return getBridgingState () ->_CFStringHashNSString (obj);
161
164
}
162
165
163
166
_swift_shims_CFHashCode
164
167
_swift_stdlib_CFStringHashCString (const _swift_shims_UInt8 * _Nonnull bytes,
165
168
_swift_shims_CFIndex length) {
166
169
assert (initializeBridgingFunctions ());
167
- return bridgingState ->_CFStringHashCString (bytes, length);
170
+ return getBridgingState () ->_CFStringHashCString (bytes, length);
168
171
}
169
172
170
173
const __swift_uint8_t *
0 commit comments