@@ -933,11 +933,12 @@ extension _StringObject {
933933 _internalInvariant ( largeFastIsShared)
934934#if _runtime(_ObjC)
935935 if largeIsCocoa {
936- return stableCocoaUTF8Pointer ( cocoaObject) . _unsafelyUnwrappedUnchecked
936+ return withCocoaObject {
937+ stableCocoaUTF8Pointer ( $0) . _unsafelyUnwrappedUnchecked
938+ }
937939 }
938940#endif
939-
940- return sharedStorage. start
941+ return withSharedStorage { $0. start }
941942 }
942943
943944 @usableFromInline
@@ -970,6 +971,7 @@ extension _StringObject {
970971 _ body: ( __StringStorage ) -> R
971972 ) -> R {
972973#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
974+ // FIXME: Do this properly.
973975 return body ( nativeStorage)
974976#else
975977 _internalInvariant ( hasNativeStorage)
@@ -993,6 +995,21 @@ extension _StringObject {
993995#endif
994996 }
995997
998+ @inline ( __always)
999+ internal func withSharedStorage< R> (
1000+ _ body: ( __SharedStringStorage ) -> R
1001+ ) -> R {
1002+ #if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
1003+ // FIXME: Do this properly.
1004+ return body ( sharedStorage)
1005+ #else
1006+ _internalInvariant ( largeFastIsShared && !largeIsCocoa)
1007+ _internalInvariant ( hasSharedStorage)
1008+ let unmanaged = Unmanaged< __SharedStringStorage> . fromOpaque( largeAddress)
1009+ return unmanaged. _withUnsafeGuaranteedRef { body ( $0) }
1010+ #endif
1011+ }
1012+
9961013 @inline ( __always)
9971014 internal var cocoaObject : AnyObject {
9981015#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
@@ -1007,6 +1024,22 @@ extension _StringObject {
10071024#endif
10081025 }
10091026
1027+ /// Call `body` with the bridged Cocoa object in `self`, without retaining
1028+ /// it.
1029+ @inline ( __always)
1030+ internal func withCocoaObject< R> (
1031+ _ body: ( AnyObject ) -> R
1032+ ) -> R {
1033+ #if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
1034+ // FIXME: Do this properly.
1035+ return body ( cocoaObject)
1036+ #else
1037+ _internalInvariant ( largeIsCocoa && !isImmortal)
1038+ let unmanaged = Unmanaged< AnyObject> . fromOpaque( largeAddress)
1039+ return unmanaged. _withUnsafeGuaranteedRef { body ( $0) }
1040+ #endif
1041+ }
1042+
10101043 @_alwaysEmitIntoClient
10111044 @inlinable
10121045 @inline ( __always)
0 commit comments