@@ -327,8 +327,10 @@ class MetadataReader {
327
327
}
328
328
329
329
// / Given a pointer to a known-error existential, attempt to discover the
330
- // / pointer to its metadata address and its value address.
331
- Optional<std::pair<RemoteAddress, RemoteAddress>>
330
+ // / pointer to its metadata address, its value address, and whether this
331
+ // / is a toll-free-bridged NSError or an actual Error existential wrapper
332
+ // / around a native Swift value.
333
+ Optional<std::tuple<RemoteAddress, RemoteAddress, bool >>
332
334
readMetadataAndValueErrorExistential (RemoteAddress ExistentialAddress) {
333
335
// An pointer to an error existential is always an heap object.
334
336
auto MetadataAddress =
@@ -337,13 +339,16 @@ class MetadataReader {
337
339
return None;
338
340
339
341
bool isObjC = false ;
342
+ bool isBridged = false ;
340
343
341
344
// If we can determine the Objective-C class name, this is probably an
342
345
// error existential with NSError-compatible layout.
343
346
std::string ObjCClassName;
344
347
if (readObjCClassName (*MetadataAddress, ObjCClassName)) {
345
348
if (ObjCClassName == " __SwiftNativeNSError" )
346
349
isObjC = true ;
350
+ else
351
+ isBridged = true ;
347
352
} else {
348
353
// Otherwise, we can check to see if this is a class metadata with the
349
354
// kind value's least significant bit set, which indicates a pure
@@ -356,6 +361,14 @@ class MetadataReader {
356
361
isObjC = ClassMeta->isPureObjC ();
357
362
}
358
363
364
+ if (isBridged) {
365
+ // NSError instances don't need to be unwrapped.
366
+ return Optional<std::tuple<RemoteAddress, RemoteAddress, bool >>(
367
+ {RemoteAddress (*MetadataAddress),
368
+ ExistentialAddress,
369
+ isBridged});
370
+ }
371
+
359
372
// In addition to the isa pointer and two 32-bit reference counts, if the
360
373
// error existential is layout-compatible with NSError, we also need to
361
374
// skip over its three word-sized fields: the error code, the domain,
@@ -387,9 +400,10 @@ class MetadataReader {
387
400
auto Offset = (sizeof (HeapObject) + AlignmentMask) & ~AlignmentMask;
388
401
InstanceAddress += Offset;
389
402
390
- return Optional<std::pair <RemoteAddress, RemoteAddress>>(
403
+ return Optional<std::tuple <RemoteAddress, RemoteAddress, bool >>(
391
404
{RemoteAddress (*InstanceMetadataAddress),
392
- RemoteAddress (InstanceAddress)});
405
+ RemoteAddress (InstanceAddress),
406
+ isBridged});
393
407
}
394
408
395
409
// / Given a known-opaque existential, attemp to discover the pointer to its
0 commit comments