Skip to content

Commit bd3643a

Browse files
authored
Merge pull request swiftlang#26588 from Catfish-Man/shadow-backflip
Re-shim tagged NSString creation
2 parents 075e92b + f559a94 commit bd3643a

File tree

4 files changed

+47
-45
lines changed

4 files changed

+47
-45
lines changed

stdlib/public/Darwin/Foundation/String.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,28 @@ extension Substring : _ObjectiveCBridgeable {
9696
}
9797

9898
extension String: CVarArg {}
99+
100+
/*
101+
This is on NSObject so that the stdlib can call it in StringBridge.swift
102+
without having to synthesize a receiver (e.g. lookup a class or allocate)
103+
104+
In the future (once the Foundation overlay can know about SmallString), we
105+
should move the caller of this method up into the overlay and avoid this
106+
indirection.
107+
*/
108+
private extension NSObject {
109+
// The ObjC selector has to start with "new" to get ARC to not autorelease
110+
@_effects(releasenone)
111+
@objc(newTaggedNSStringWithASCIIBytes_:length_:)
112+
func createTaggedString(bytes: UnsafePointer<UInt8>,
113+
count: Int) -> AnyObject? {
114+
//TODO: update this to use _CFStringCreateTaggedPointerString once we can
115+
return CFStringCreateWithBytes(
116+
kCFAllocatorSystemDefault,
117+
bytes,
118+
count,
119+
CFStringBuiltInEncodings.UTF8.rawValue,
120+
false
121+
) as NSString as NSString? //just "as AnyObject" inserts unwanted bridging
122+
}
123+
}

stdlib/public/SwiftShims/CoreFoundationShims.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,17 @@ namespace swift { extern "C" {
2828

2929
#ifdef __OBJC2__
3030
#if __LLP64__
31-
typedef unsigned long long _swift_shims_CFTypeID;
3231
typedef unsigned long long _swift_shims_CFHashCode;
3332
typedef signed long long _swift_shims_CFIndex;
3433
#else
35-
typedef unsigned long _swift_shims_CFTypeID;
3634
typedef unsigned long _swift_shims_CFHashCode;
3735
typedef signed long _swift_shims_CFIndex;
3836
#endif
3937

40-
typedef id _swift_shims_CFStringRef;
41-
typedef __swift_uint32_t _swift_shims_CFStringEncoding;
42-
4338
// Consider creating SwiftMacTypes.h for these
4439
typedef unsigned char _swift_shims_Boolean;
4540
typedef __swift_uint8_t _swift_shims_UInt8;
46-
47-
SWIFT_RUNTIME_STDLIB_API
48-
__attribute__((ns_returns_retained))
49-
_swift_shims_CFStringRef _Nonnull _swift_stdlib_CFStringCreateWithBytes(
50-
const void * _Nullable unused,
51-
const __swift_uint8_t *_Nonnull bytes, _swift_shims_CFIndex numBytes,
52-
_swift_shims_CFStringEncoding encoding,
53-
_swift_shims_Boolean isExternalRepresentation);
41+
typedef __swift_uint32_t _swift_shims_CFStringEncoding;
5442

5543
SWIFT_RUNTIME_STDLIB_API
5644
__swift_uint8_t _swift_stdlib_isNSString(id _Nonnull obj);

stdlib/public/core/StringBridge.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ internal typealias _CocoaString = AnyObject
5858
options: UInt,
5959
range: _SwiftNSRange,
6060
locale: AnyObject?) -> Int
61+
62+
@objc(newTaggedNSStringWithASCIIBytes_:length_:)
63+
func createTaggedString(bytes: UnsafePointer<UInt8>,
64+
count: Int) -> AnyObject?
6165
}
6266

6367
/*
@@ -410,19 +414,28 @@ extension String {
410414
}
411415
}
412416

417+
@_effects(releasenone)
418+
private func _createNSString(
419+
_ receiver: _StringSelectorHolder,
420+
_ ptr: UnsafePointer<UInt8>,
421+
_ count: Int,
422+
_ encoding: UInt32
423+
) -> AnyObject? {
424+
return receiver.createTaggedString(bytes: ptr, count: count)
425+
}
426+
413427
@_effects(releasenone)
414428
private func _createCFString(
415429
_ ptr: UnsafePointer<UInt8>,
416430
_ count: Int,
417431
_ encoding: UInt32
418-
) -> AnyObject {
419-
return _swift_stdlib_CFStringCreateWithBytes(
420-
nil, //ignored in the shim for perf reasons
432+
) -> AnyObject? {
433+
return _createNSString(
434+
unsafeBitCast(__StringStorage.self as AnyClass, to: _StringSelectorHolder.self),
421435
ptr,
422436
count,
423-
kCFStringEncodingUTF8,
424-
0
425-
) as AnyObject
437+
encoding
438+
)
426439
}
427440

428441
extension String {
@@ -431,13 +444,14 @@ extension String {
431444
func _bridgeToObjectiveCImpl() -> AnyObject {
432445
// Smol ASCII a) may bridge to tagged pointers, b) can't contain a BOM
433446
if _guts.isSmallASCII {
434-
return _guts.asSmall.withUTF8 { bufPtr in
447+
let maybeTagged = _guts.asSmall.withUTF8 { bufPtr in
435448
return _createCFString(
436449
bufPtr.baseAddress._unsafelyUnwrappedUnchecked,
437450
bufPtr.count,
438451
kCFStringEncodingUTF8
439452
)
440453
}
454+
if let tagged = maybeTagged { return tagged }
441455
}
442456
if _guts.isSmall {
443457
// We can't form a tagged pointer String, so grow to a non-small String,

stdlib/public/stubs/FoundationHelpers.mm

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,13 @@
2525

2626
using namespace swift;
2727

28-
template <class FromTy> struct DestType;
29-
30-
#define BRIDGE_TYPE(FROM, TO) \
31-
template <> struct DestType<FROM> { using type = TO; }
32-
33-
BRIDGE_TYPE(_swift_shims_CFStringRef, CFStringRef);
34-
BRIDGE_TYPE(_swift_shims_CFStringEncoding, CFStringEncoding);
35-
BRIDGE_TYPE(CFStringRef, _swift_shims_CFStringRef);
36-
37-
template <class FromTy>
38-
static typename DestType<FromTy>::type cast(FromTy value) {
39-
return (typename DestType<FromTy>::type) value;
40-
}
41-
4228
__swift_uint8_t
4329
swift::_swift_stdlib_isNSString(id obj) {
4430
//TODO: we can likely get a small perf win by using _NSIsNSString on
4531
//sufficiently new OSs
4632
return CFGetTypeID((CFTypeRef)obj) == CFStringGetTypeID() ? 1 : 0;
4733
}
4834

49-
_swift_shims_CFStringRef
50-
swift::_swift_stdlib_CFStringCreateWithBytes(
51-
const void *unused, const uint8_t *bytes,
52-
_swift_shims_CFIndex numBytes, _swift_shims_CFStringEncoding encoding,
53-
_swift_shims_Boolean isExternalRepresentation) {
54-
assert(unused == NULL);
55-
return cast(CFStringCreateWithBytes(kCFAllocatorSystemDefault, bytes, numBytes,
56-
cast(encoding),
57-
isExternalRepresentation));
58-
}
59-
6035
extern "C" CFHashCode CFStringHashCString(const uint8_t *bytes, CFIndex len);
6136
extern "C" CFHashCode CFStringHashNSString(id str);
6237

0 commit comments

Comments
 (0)