Skip to content

Commit b0b89cc

Browse files
authored
Allocationless constant String -> NSString bridging via a new tagged pointer type (#1232)
* Revert "Revert "rdar://142693100 (Allocationless constant String -> NSString bridging via a new tagged pointer type) (#2798)" (#2843)" This reverts commit c378439322f5b960ecb972b27ab1419a622ad6b2. * Adopt the new entry point for bridging the new tagged pointers * All remaining callsites passed null-terminated strings, so just eliminate the isTerminated bit and simplify further. Also gets us up to 13 bits of length * Address review comments
1 parent 7abeeef commit b0b89cc

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

Sources/FoundationEssentials/String/String+Bridging.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ extension String : _ObjectiveCBridgeable {
6969
return String(unsafeUninitializedCapacity: SMALL_STRING_CAPACITY) {
7070
_NSTaggedPointerStringGetBytes(source, $0.baseAddress!)
7171
}
72+
} else if tag == OBJC_TAG_NSAtom {
73+
var len = UInt16(0)
74+
let contentsPtr = _CFIndirectTaggedPointerStringGetContents(source, &len)
75+
let contents = UnsafeBufferPointer(start: contentsPtr, count: Int(len))
76+
// Will only fail if contents aren't valid UTF8/ASCII
77+
if let result = _SwiftCreateImmortalString_ForFoundation(buffer: contents, isASCII: true) {
78+
return result
79+
}
80+
// Since our contents are invalid, force a real copy of the string and bridge that instead. This should basically never be hit in practice
81+
return source.mutableCopy() as! String
7282
} else if tag.rawValue == 22 /* OBJC_TAG_Foundation_1 */ {
7383
let cStr = source.utf8String!
7484
return String.init(utf8String: cStr)!
@@ -88,6 +98,9 @@ extension String : _ObjectiveCBridgeable {
8898

8999
if constant {
90100
if ascii {
101+
// We would like to use _SwiftCreateImmortalString_ForFoundation here, but we can't because we need to maintain the invariant
102+
// (constantString as String as NSString) === constantString
103+
// and using _SwiftCreateImmortalString_ForFoundation would make an indirect tagged string instead on the way back
91104
return String(_immortalCocoaString: source, count: len, encoding: Unicode.ASCII.self)
92105
} else {
93106
return String(_immortalCocoaString: source, count: len, encoding: Unicode.UTF16.self)

0 commit comments

Comments
 (0)