|
37 | 37 | #include <objc/message.h>
|
38 | 38 | #include <objc/objc.h>
|
39 | 39 | #include <Foundation/Foundation.h>
|
| 40 | +#include "../SDK/Foundation/NSError.h" |
40 | 41 |
|
41 | 42 | using namespace swift;
|
42 | 43 | using namespace swift::hashable_support;
|
@@ -220,31 +221,40 @@ static Class getSwiftNativeNSErrorClass() {
|
220 | 221 | object_dispose((id)error);
|
221 | 222 | }
|
222 | 223 |
|
| 224 | +/// Get the error bridging info from the Foundation overlay. If it can't |
| 225 | +/// be loaded, return all NULLs. |
| 226 | +static ErrorBridgingInfo getErrorBridgingInfo() { |
| 227 | + auto *info = SWIFT_LAZY_CONSTANT( |
| 228 | + reinterpret_cast<ErrorBridgingInfo *>( |
| 229 | + dlsym(RTLD_DEFAULT, ERROR_BRIDGING_SYMBOL_NAME_STRING))); |
| 230 | + if (!info) { |
| 231 | + ErrorBridgingInfo nulls = {}; |
| 232 | + return nulls; |
| 233 | + } |
| 234 | + return *info; |
| 235 | +} |
| 236 | + |
223 | 237 | static const WitnessTable *getNSErrorConformanceToError() {
|
224 | 238 | // CFError and NSError are toll-free-bridged, so we can use either type's
|
225 | 239 | // witness table interchangeably. CFError's is potentially slightly more
|
226 | 240 | // efficient since it doesn't need to dispatch for an unsubclassed NSCFError.
|
227 |
| - // The witness table lives in the Foundation overlay, but it should be safe |
228 |
| - // to assume that that's been linked in if a user is using NSError in their |
229 |
| - // Swift source. |
| 241 | + // The error bridging info lives in the Foundation overlay, but it should be |
| 242 | + // safe to assume that that's been linked in if a user is using NSError in |
| 243 | + // their Swift source. |
230 | 244 |
|
231 |
| - auto TheWitnessTable = SWIFT_LAZY_CONSTANT(dlsym(RTLD_DEFAULT, |
232 |
| - MANGLE_AS_STRING(MANGLE_SYM(So10CFErrorRefas5Error10FoundationWa)))); |
233 |
| - assert(TheWitnessTable && |
| 245 | + auto getter = getErrorBridgingInfo().GetCFErrorErrorConformance; |
| 246 | + assert(getter && |
234 | 247 | "Foundation overlay not loaded, or 'CFError : Error' conformance "
|
235 | 248 | "not available");
|
236 |
| - |
237 |
| - return reinterpret_cast<const SWIFT_CC(swift) WitnessTable *(*)()>(TheWitnessTable)(); |
| 249 | + return getter(); |
238 | 250 | }
|
239 | 251 |
|
240 | 252 | static const HashableWitnessTable *getNSErrorConformanceToHashable() {
|
241 |
| - auto TheWitnessTable = SWIFT_LAZY_CONSTANT(dlsym(RTLD_DEFAULT, |
242 |
| - MANGLE_AS_STRING(MANGLE_SYM(So8NSObjectCs8Hashable10ObjectiveCWa)))); |
243 |
| - assert(TheWitnessTable && |
| 253 | + auto getter = getErrorBridgingInfo().GetNSObjectHashableConformance; |
| 254 | + assert(getter && |
244 | 255 | "ObjectiveC overlay not loaded, or 'NSObject : Hashable' conformance "
|
245 | 256 | "not available");
|
246 |
| - |
247 |
| - return reinterpret_cast<const SWIFT_CC(swift) HashableWitnessTable *(*)()>(TheWitnessTable)(); |
| 257 | + return getter(); |
248 | 258 | }
|
249 | 259 |
|
250 | 260 | bool SwiftError::isPureNSError() const {
|
@@ -371,16 +381,9 @@ NSInteger getErrorCode(const OpaqueValue *error,
|
371 | 381 | NSDictionary *_swift_stdlib_getErrorDefaultUserInfo(OpaqueValue *error,
|
372 | 382 | const Metadata *T,
|
373 | 383 | const WitnessTable *Error) {
|
374 |
| - typedef SWIFT_CC(swift) |
375 |
| - NSDictionary *GetDefaultFn(const OpaqueValue *error, |
376 |
| - const Metadata *T, |
377 |
| - const WitnessTable *Error); |
378 |
| - |
379 | 384 | // public func Foundation._getErrorDefaultUserInfo<T: Error>(_ error: T)
|
380 | 385 | // -> AnyObject?
|
381 |
| - auto foundationGetDefaultUserInfo = SWIFT_LAZY_CONSTANT( |
382 |
| - reinterpret_cast<GetDefaultFn*> (dlsym(RTLD_DEFAULT, |
383 |
| - MANGLE_AS_STRING(MANGLE_SYM(10Foundation24_getErrorDefaultUserInfoyyXlSgxs0C0RzlF))))); |
| 386 | + auto foundationGetDefaultUserInfo = getErrorBridgingInfo().GetErrorDefaultUserInfo; |
384 | 387 | if (!foundationGetDefaultUserInfo) {
|
385 | 388 | SWIFT_CC_PLUSONE_GUARD(T->vw_destroy(error));
|
386 | 389 | return nullptr;
|
@@ -517,16 +520,9 @@ typedef SWIFT_CC(swift)
|
517 | 520 | // public func Foundation._bridgeNSErrorToError<
|
518 | 521 | // T : _ObjectiveCBridgeableError
|
519 | 522 | // >(error: NSError, out: UnsafeMutablePointer<T>) -> Bool {
|
520 |
| - typedef SWIFT_CC(swift) |
521 |
| - bool BridgeFn(NSError *, OpaqueValue*, const Metadata *, |
522 |
| - const WitnessTable *); |
523 |
| - auto bridgeNSErrorToError = SWIFT_LAZY_CONSTANT( |
524 |
| - reinterpret_cast<BridgeFn*>(dlsym(RTLD_DEFAULT, |
525 |
| - MANGLE_AS_STRING(MANGLE_SYM(10Foundation21_bridgeNSErrorToError_3outSbSo0C0C_SpyxGtAA021_ObjectiveCBridgeableE0RzlF))))); |
| 523 | + auto bridgeNSErrorToError = getErrorBridgingInfo().BridgeErrorToNSError; |
526 | 524 | // protocol _ObjectiveCBridgeableError
|
527 |
| - auto TheObjectiveCBridgeableError = SWIFT_LAZY_CONSTANT( |
528 |
| - reinterpret_cast<const ProtocolDescriptor *>(dlsym(RTLD_DEFAULT, |
529 |
| - MANGLE_AS_STRING(MANGLE_SYM(10Foundation26_ObjectiveCBridgeableErrorMp))))); |
| 525 | + auto TheObjectiveCBridgeableError = getErrorBridgingInfo().ObjectiveCBridgeableError; |
530 | 526 |
|
531 | 527 | // If the Foundation overlay isn't loaded, then arbitrary NSErrors can't be
|
532 | 528 | // bridged.
|
|
0 commit comments