47
47
// version 0 ends here
48
48
} CFBridgingState;
49
49
50
- static CFBridgingState const * bridgingState;
50
+ static std::atomic< CFBridgingState const *> bridgingState;
51
51
static swift_once_t initializeBridgingStateOnce;
52
52
53
+ static CFBridgingState const *getBridgingState () {
54
+ return bridgingState.load (std::memory_order_acquire);
55
+ }
56
+
53
57
extern " C" bool _dyld_is_objc_constant (DyldObjCConstantKind kind,
54
58
const void *addr) SWIFT_RUNTIME_WEAK_IMPORT;
55
59
56
60
@class __SwiftNativeNSStringBase, __SwiftNativeNSError, __SwiftNativeNSArrayBase, __SwiftNativeNSMutableArrayBase, __SwiftNativeNSDictionaryBase, __SwiftNativeNSSetBase, __SwiftNativeNSEnumeratorBase;
57
61
58
62
static void _reparentClasses () {
63
+ auto state = getBridgingState ();
59
64
#pragma clang diagnostic push
60
65
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
61
- if (bridgingState ->NSStringClass ) {
62
- [bridgingState ->NSStringClass class ]; // make sure the class is realized
63
- class_setSuperclass ([__SwiftNativeNSStringBase class ], bridgingState ->NSStringClass );
66
+ if (state ->NSStringClass ) {
67
+ [state ->NSStringClass class ]; // make sure the class is realized
68
+ class_setSuperclass ([__SwiftNativeNSStringBase class ], state ->NSStringClass );
64
69
}
65
- if (bridgingState ->NSErrorClass ) {
66
- [bridgingState ->NSErrorClass class ]; // make sure the class is realized
67
- class_setSuperclass ([__SwiftNativeNSError class ], bridgingState ->NSErrorClass );
70
+ if (state ->NSErrorClass ) {
71
+ [state ->NSErrorClass class ]; // make sure the class is realized
72
+ class_setSuperclass ([__SwiftNativeNSError class ], state ->NSErrorClass );
68
73
}
69
- if (bridgingState ->NSArrayClass ) {
70
- [bridgingState ->NSArrayClass class ]; // make sure the class is realized
71
- class_setSuperclass ([__SwiftNativeNSArrayBase class ], bridgingState ->NSArrayClass );
74
+ if (state ->NSArrayClass ) {
75
+ [state ->NSArrayClass class ]; // make sure the class is realized
76
+ class_setSuperclass ([__SwiftNativeNSArrayBase class ], state ->NSArrayClass );
72
77
}
73
- if (bridgingState ->NSMutableArrayClass ) {
74
- [bridgingState ->NSMutableArrayClass class ]; // make sure the class is realized
75
- class_setSuperclass ([__SwiftNativeNSMutableArrayBase class ], bridgingState ->NSMutableArrayClass );
78
+ if (state ->NSMutableArrayClass ) {
79
+ [state ->NSMutableArrayClass class ]; // make sure the class is realized
80
+ class_setSuperclass ([__SwiftNativeNSMutableArrayBase class ], state ->NSMutableArrayClass );
76
81
}
77
- if (bridgingState ->NSDictionaryClass ) {
78
- [bridgingState ->NSDictionaryClass class ]; // make sure the class is realized
79
- class_setSuperclass ([__SwiftNativeNSDictionaryBase class ], bridgingState ->NSDictionaryClass );
82
+ if (state ->NSDictionaryClass ) {
83
+ [state ->NSDictionaryClass class ]; // make sure the class is realized
84
+ class_setSuperclass ([__SwiftNativeNSDictionaryBase class ], state ->NSDictionaryClass );
80
85
}
81
- if (bridgingState ->NSSetClass ) {
82
- [bridgingState ->NSSetClass class ]; // make sure the class is realized
83
- class_setSuperclass ([__SwiftNativeNSSetBase class ], bridgingState ->NSSetClass );
86
+ if (state ->NSSetClass ) {
87
+ [state ->NSSetClass class ]; // make sure the class is realized
88
+ class_setSuperclass ([__SwiftNativeNSSetBase class ], state ->NSSetClass );
84
89
}
85
- if (bridgingState ->NSEnumeratorClass ) {
86
- [bridgingState ->NSEnumeratorClass class ]; // make sure the class is realized
87
- class_setSuperclass ([__SwiftNativeNSEnumeratorBase class ], bridgingState ->NSEnumeratorClass );
90
+ if (state ->NSEnumeratorClass ) {
91
+ [state ->NSEnumeratorClass class ]; // make sure the class is realized
92
+ class_setSuperclass ([__SwiftNativeNSEnumeratorBase class ], state ->NSEnumeratorClass );
88
93
}
89
94
#pragma clang diagnostic pop
90
95
}
91
96
92
97
static inline bool initializeBridgingFunctions () {
93
98
swift::once (initializeBridgingStateOnce, [](){
94
- assert (!bridgingState );
99
+ assert (!getBridgingState () );
95
100
auto getStringTypeID = (CFTypeID (*)(void ))dlsym (RTLD_DEFAULT, " CFStringGetTypeID" );
96
101
if (!getStringTypeID) {
97
102
return ; // CF not loaded
@@ -109,21 +114,21 @@ static inline bool initializeBridgingFunctions() {
109
114
state->NSSetClass = objc_lookUpClass (" NSSet" );
110
115
state->NSDictionaryClass = objc_lookUpClass (" NSDictionary" );
111
116
state->NSEnumeratorClass = objc_lookUpClass (" NSEnumerator" );
112
- bridgingState = state;
117
+ bridgingState. store ( state) ;
113
118
_reparentClasses ();
114
119
});
115
- return bridgingState && bridgingState->NSStringClass != nullptr ;
120
+ auto state = getBridgingState ();
121
+ return state && state->NSStringClass != nullptr ;
116
122
}
117
123
118
124
SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState (CFBridgingState const * const state) {
119
125
// Consume the once token to make sure that the lazy version of this in initializeBridgingFunctions only runs if we didn't hit this
120
126
swift::once (initializeBridgingStateOnce, [state](){
121
- bridgingState = state;
127
+ bridgingState. store ( state) ;
122
128
});
123
129
// It's fine if this runs more than once, it's a noop if it's been done before
124
130
// and we want to make sure it still happens if CF loads late after it failed initially
125
- bridgingState = state;
126
- std::atomic_thread_fence (std::memory_order_seq_cst); // This is probably unnecessary, but thinking through why it's unnecessary has given multiple people headaches now, and since this only runs once it's not a big deal to just have the barrier.
131
+ bridgingState.store (state);
127
132
_reparentClasses ();
128
133
}
129
134
@@ -133,7 +138,7 @@ SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState(CFBridgingState co
133
138
134
139
Class swift::getNSErrorClass () {
135
140
if (initializeBridgingFunctions ()) {
136
- return bridgingState ->NSErrorClass ;
141
+ return getBridgingState () ->NSErrorClass ;
137
142
}
138
143
return nullptr ;
139
144
}
@@ -147,20 +152,21 @@ SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState(CFBridgingState co
147
152
__swift_uint8_t
148
153
_swift_stdlib_isNSString (id obj) {
149
154
assert (initializeBridgingFunctions ());
150
- return bridgingState->_CFGetTypeID ((CFTypeRef)obj) == bridgingState->_CFStringTypeID ? 1 : 0 ;
155
+ auto state = getBridgingState ();
156
+ return state->_CFGetTypeID ((CFTypeRef)obj) == state->_CFStringTypeID ? 1 : 0 ;
151
157
}
152
158
153
159
_swift_shims_CFHashCode
154
160
_swift_stdlib_CFStringHashNSString (id _Nonnull obj) {
155
161
assert (initializeBridgingFunctions ());
156
- return bridgingState ->_CFStringHashNSString (obj);
162
+ return getBridgingState () ->_CFStringHashNSString (obj);
157
163
}
158
164
159
165
_swift_shims_CFHashCode
160
166
_swift_stdlib_CFStringHashCString (const _swift_shims_UInt8 * _Nonnull bytes,
161
167
_swift_shims_CFIndex length) {
162
168
assert (initializeBridgingFunctions ());
163
- return bridgingState ->_CFStringHashCString (bytes, length);
169
+ return getBridgingState () ->_CFStringHashCString (bytes, length);
164
170
}
165
171
166
172
const __swift_uint8_t *
0 commit comments