@@ -172,6 +172,17 @@ internal struct _StringObject {
172172 _internalInvariant ( !isSmall)
173173 return CountAndFlags ( rawUnchecked: _countAndFlagsBits)
174174 }
175+
176+ // FIXME: This ought to be the setter for property `_countAndFlags`.
177+ @_alwaysEmitIntoClient
178+ internal mutating func _setCountAndFlags( to value: CountAndFlags ) {
179+ #if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
180+ self . _count = value. count
181+ self . _flags = value. flags
182+ #else
183+ self . _countAndFlagsBits = value. _storage
184+ #endif
185+ }
175186}
176187
177188// Raw
@@ -894,6 +905,13 @@ extension _StringObject {
894905 discriminatedObjectRawBits & Nibbles . largeAddressMask)
895906 }
896907
908+ @inline ( __always)
909+ @_alwaysEmitIntoClient
910+ internal var largeAddress : UnsafeRawPointer {
911+ UnsafeRawPointer ( bitPattern: largeAddressBits)
912+ . _unsafelyUnwrappedUnchecked
913+ }
914+
897915 @inlinable @inline ( __always)
898916 internal var nativeUTF8Start : UnsafePointer < UInt8 > {
899917 _internalInvariant ( largeFastIsTailAllocated)
@@ -915,11 +933,12 @@ extension _StringObject {
915933 _internalInvariant ( largeFastIsShared)
916934#if _runtime(_ObjC)
917935 if largeIsCocoa {
918- return stableCocoaUTF8Pointer ( cocoaObject) . _unsafelyUnwrappedUnchecked
936+ return withCocoaObject {
937+ stableCocoaUTF8Pointer ( $0) . _unsafelyUnwrappedUnchecked
938+ }
919939 }
920940#endif
921-
922- return sharedStorage. start
941+ return withSharedStorage { $0. start }
923942 }
924943
925944 @usableFromInline
@@ -940,7 +959,24 @@ extension _StringObject {
940959 return _unsafeUncheckedDowncast ( storage, to: __StringStorage. self)
941960#else
942961 _internalInvariant ( hasNativeStorage)
943- return Builtin . reinterpretCast ( largeAddressBits)
962+ let unmanaged = Unmanaged< __StringStorage> . fromOpaque( largeAddress)
963+ return unmanaged. takeUnretainedValue ( )
964+ #endif
965+ }
966+
967+ /// Call `body` with the native storage object of `self`, without retaining
968+ /// it.
969+ @inline ( __always)
970+ internal func withNativeStorage< R> (
971+ _ body: ( __StringStorage ) -> R
972+ ) -> R {
973+ #if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
974+ // FIXME: Do this properly.
975+ return body ( nativeStorage)
976+ #else
977+ _internalInvariant ( hasNativeStorage)
978+ let unmanaged = Unmanaged< __StringStorage> . fromOpaque( largeAddress)
979+ return unmanaged. _withUnsafeGuaranteedRef { body ( $0) }
944980#endif
945981 }
946982
@@ -954,7 +990,23 @@ extension _StringObject {
954990#else
955991 _internalInvariant ( largeFastIsShared && !largeIsCocoa)
956992 _internalInvariant ( hasSharedStorage)
957- return Builtin . reinterpretCast ( largeAddressBits)
993+ let unmanaged = Unmanaged< __SharedStringStorage> . fromOpaque( largeAddress)
994+ return unmanaged. takeUnretainedValue ( )
995+ #endif
996+ }
997+
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) }
9581010#endif
9591011 }
9601012
@@ -967,7 +1019,24 @@ extension _StringObject {
9671019 return object
9681020#else
9691021 _internalInvariant ( largeIsCocoa && !isImmortal)
970- return Builtin . reinterpretCast ( largeAddressBits)
1022+ let unmanaged = Unmanaged< AnyObject> . fromOpaque( largeAddress)
1023+ return unmanaged. takeUnretainedValue ( )
1024+ #endif
1025+ }
1026+
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) }
9711040#endif
9721041 }
9731042
@@ -976,7 +1045,8 @@ extension _StringObject {
9761045 @inline ( __always)
9771046 internal var owner : AnyObject ? {
9781047 guard self . isMortal else { return nil }
979- return Builtin . reinterpretCast ( largeAddressBits)
1048+ let unmanaged = Unmanaged< AnyObject> . fromOpaque( largeAddress)
1049+ return unmanaged. takeUnretainedValue ( )
9801050 }
9811051}
9821052
@@ -1055,7 +1125,8 @@ extension _StringObject {
10551125 @inline ( __always)
10561126 internal var objCBridgeableObject : AnyObject {
10571127 _internalInvariant ( hasObjCBridgeableObject)
1058- return Builtin . reinterpretCast ( largeAddressBits)
1128+ let unmanaged = Unmanaged< AnyObject> . fromOpaque( largeAddress)
1129+ return unmanaged. takeUnretainedValue ( )
10591130 }
10601131
10611132 // Whether the object provides fast UTF-8 contents that are nul-terminated
@@ -1219,7 +1290,8 @@ extension _StringObject {
12191290 }
12201291 }
12211292 if _countAndFlags. isNativelyStored {
1222- let anyObj = Builtin . reinterpretCast ( largeAddressBits) as AnyObject
1293+ let unmanaged = Unmanaged< AnyObject> . fromOpaque( largeAddress)
1294+ let anyObj = unmanaged. takeUnretainedValue ( )
12231295 _internalInvariant ( anyObj is __StringStorage )
12241296 }
12251297 }
0 commit comments