@@ -97,6 +97,16 @@ static uint64_t readTagBytes(const uint8_t *addr, uint8_t byteCount) {
9797 }
9898}
9999
100+ // This check is used to determine whether or not ObjC references can
101+ // be tagged pointers. If they can't, they have the same spare bits
102+ // as swift references, and we have to mask them out before passing the
103+ // reference to ref counting operations.
104+ static constexpr bool platformSupportsTaggedPointers () {
105+ // Platforms that don't reserve bits for ObjC, don't support tagged
106+ // pointers.
107+ return _swift_abi_ObjCReservedBitsMask != 0 ;
108+ }
109+
100110#if defined(__APPLE__) && defined(__arm64__)
101111
102112#define CONTINUE_WITH_COPY (METADATA, READER, ADDR_OFFSET, DEST, SRC ) \
@@ -281,9 +291,12 @@ static void weakDestroy(const Metadata *metadata, LayoutStringReader1 &reader,
281291static void unknownDestroy (const Metadata *metadata,
282292 LayoutStringReader1 &reader, uintptr_t &addrOffset,
283293 uint8_t *addr) {
284- void * object = *(void * *)(addr + addrOffset);
294+ uintptr_t object = *(uintptr_t *)(addr + addrOffset);
285295 addrOffset += sizeof (void *);
286- swift_unknownObjectRelease (object);
296+ if (!platformSupportsTaggedPointers ()) {
297+ object &= ~_swift_abi_SwiftSpareBitsMask;
298+ }
299+ swift_unknownObjectRelease ((void *)object);
287300}
288301
289302static void unknownUnownedDestroy (const Metadata *metadata,
@@ -769,9 +782,10 @@ multiPayloadEnumGeneric(const Metadata *metadata, LayoutStringReader1 &reader,
769782static void blockDestroy (const Metadata *metadata, LayoutStringReader1 &reader,
770783 uintptr_t &addrOffset, uint8_t *addr) {
771784#if SWIFT_OBJC_INTEROP
772- void * object = (void *)(addr + addrOffset);
785+ uintptr_t object = *(uintptr_t *)(addr + addrOffset);
786+ object &= ~_swift_abi_SwiftSpareBitsMask;
773787 addrOffset += sizeof (void *);
774- _Block_release (object);
788+ _Block_release (( void *) object);
775789#else
776790 swift_unreachable (" Blocks are not available on this platform" );
777791#endif
@@ -783,6 +797,11 @@ static void objcStrongDestroy(const Metadata *metadata,
783797#if SWIFT_OBJC_INTEROP
784798 uintptr_t object = *(uintptr_t *)(addr + addrOffset);
785799 addrOffset += sizeof (objc_object*);
800+
801+ if (!platformSupportsTaggedPointers ()) {
802+ object &= ~_swift_abi_SwiftSpareBitsMask;
803+ }
804+
786805 objc_release ((objc_object *)object);
787806#else
788807 swift_unreachable (" ObjC interop is not available on this platform" );
@@ -959,10 +978,13 @@ static void weakCopyInit(const Metadata *metadata, LayoutStringReader1 &reader,
959978static void unknownRetain (const Metadata *metadata, LayoutStringReader1 &reader,
960979 uintptr_t &addrOffset, uint8_t *dest, uint8_t *src) {
961980 uintptr_t _addrOffset = addrOffset;
962- void * object = *(void * *)(src + _addrOffset);
981+ uintptr_t object = *(uintptr_t *)(src + _addrOffset);
963982 memcpy (dest + _addrOffset, &object, sizeof (void *));
964983 addrOffset = _addrOffset + sizeof (void *);
965- swift_unknownObjectRetain (object);
984+ if (!platformSupportsTaggedPointers ()) {
985+ object &= ~_swift_abi_SwiftSpareBitsMask;
986+ }
987+ swift_unknownObjectRetain ((void *)object);
966988}
967989
968990static void unknownUnownedCopyInit (const Metadata *metadata,
@@ -1000,9 +1022,11 @@ static void blockCopy(const Metadata *metadata, LayoutStringReader1 &reader,
10001022 uintptr_t &addrOffset, uint8_t *dest, uint8_t *src) {
10011023#if SWIFT_OBJC_INTEROP
10021024 uintptr_t _addrOffset = addrOffset;
1003- auto *copy = _Block_copy (*( void ** )(src + _addrOffset) );
1004- memcpy (dest + _addrOffset, © , sizeof (void *));
1025+ uintptr_t object = *( uintptr_t * )(src + _addrOffset);
1026+ memcpy (dest + _addrOffset, &object , sizeof (void *));
10051027 addrOffset = _addrOffset + sizeof (void *);
1028+ object &= ~_swift_abi_SwiftSpareBitsMask;
1029+ _Block_copy ((void *)object);
10061030#else
10071031 swift_unreachable (" Blocks are not available on this platform" );
10081032#endif
@@ -1016,6 +1040,11 @@ static void objcStrongRetain(const Metadata *metadata,
10161040 uintptr_t object = *(uintptr_t *)(src + _addrOffset);
10171041 memcpy (dest + _addrOffset, &object, sizeof (objc_object *));
10181042 addrOffset = _addrOffset + sizeof (objc_object *);
1043+
1044+ if (!platformSupportsTaggedPointers ()) {
1045+ object &= ~_swift_abi_SwiftSpareBitsMask;
1046+ }
1047+
10191048 objc_retain ((objc_object *)object);
10201049#else
10211050 swift_unreachable (" ObjC interop is not available on this platform" );
@@ -1368,12 +1397,16 @@ static void unknownAssignWithCopy(const Metadata *metadata,
13681397 uintptr_t &addrOffset, uint8_t *dest,
13691398 uint8_t *src) {
13701399 uintptr_t _addrOffset = addrOffset;
1371- void * destObject = *(void * *)(dest + _addrOffset);
1372- void * srcObject = *(void * *)(src + _addrOffset);
1400+ uintptr_t destObject = *(uintptr_t *)(dest + _addrOffset);
1401+ uintptr_t srcObject = *(uintptr_t *)(src + _addrOffset);
13731402 memcpy (dest + _addrOffset, &srcObject, sizeof (void *));
13741403 addrOffset = _addrOffset + sizeof (void *);
1375- swift_unknownObjectRelease (destObject);
1376- swift_unknownObjectRetain (srcObject);
1404+ if (!platformSupportsTaggedPointers ()) {
1405+ destObject &= ~_swift_abi_SwiftSpareBitsMask;
1406+ srcObject &= ~_swift_abi_SwiftSpareBitsMask;
1407+ }
1408+ swift_unknownObjectRelease ((void *)destObject);
1409+ swift_unknownObjectRetain ((void *)srcObject);
13771410}
13781411
13791412static void bridgeAssignWithCopy (const Metadata *metadata,
@@ -1431,10 +1464,14 @@ static void blockAssignWithCopy(const Metadata *metadata,
14311464 uint8_t *src) {
14321465#if SWIFT_OBJC_INTEROP
14331466 uintptr_t _addrOffset = addrOffset;
1434- _Block_release (*( void ** )(dest + _addrOffset) );
1435- auto *copy = _Block_copy (*( void ** )(src + _addrOffset) );
1436- memcpy (dest + _addrOffset, © , sizeof (void *));
1467+ uintptr_t destObject = *( uintptr_t * )(dest + _addrOffset);
1468+ uintptr_t srcObject = *( uintptr_t * )(src + _addrOffset);
1469+ memcpy (dest + _addrOffset, &srcObject , sizeof (void *));
14371470 addrOffset = _addrOffset + sizeof (void *);
1471+ destObject &= ~_swift_abi_SwiftSpareBitsMask;
1472+ srcObject &= ~_swift_abi_SwiftSpareBitsMask;
1473+ _Block_release ((void *)destObject);
1474+ _Block_copy ((void *)srcObject);
14381475#else
14391476 swift_unreachable (" Blocks are not available on this platform" );
14401477#endif
@@ -1452,6 +1489,11 @@ static void objcStrongAssignWithCopy(const Metadata *metadata,
14521489 memcpy (dest + _addrOffset, &srcObject, sizeof (objc_object*));
14531490 addrOffset = _addrOffset + sizeof (objc_object*);
14541491
1492+ if (!platformSupportsTaggedPointers ()) {
1493+ destObject &= ~_swift_abi_SwiftSpareBitsMask;
1494+ srcObject &= ~_swift_abi_SwiftSpareBitsMask;
1495+ }
1496+
14551497 objc_release ((objc_object *)destObject);
14561498 objc_retain ((objc_object *)srcObject);
14571499#else
0 commit comments