Skip to content

Commit dc783c0

Browse files
committed
[Foundation] Remove @_silgen thunks and replace them with shims instead
This avoids indirection by making calls directly to the C implementations which prevents potentials of mismatched intent or changes of calling convention of @_silgen. The added benefit is that all of the shims in this case are no longer visible symbols (anyone using them was not authorized out side of the Foundation overlay). Also the callout methods in the headers now all share similar naming shcemes for easier refactoring and searching in the style of __NS<class><action> style. The previous compiled C/Objective-C source files were built with MRR the new headers MUST be ARC by Swift import rules. The one caveat is that certain functions MUST avoid the bridge case (since they are part of the bridging code-paths and that would incur a recursive potential) which have the types erased up to NSObject * via the macro NS_NON_BRIDGED. The remaining @_silgen declarations are either swift functions exposed externally to the rest of Swift’s runtime or are included in NSNumber.gyb which the Foundation team has other plans for removing those @_silgen functions at a later date and Data.swift has one external function left with @_silgen which is blocked by a bug in the compiler which seems to improperly import that particular method as an inline c function.
1 parent 37081f4 commit dc783c0

37 files changed

+579
-580
lines changed

stdlib/public/SDK/Foundation/CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,9 @@ add_swift_library(swiftFoundation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SD
1111
Decimal.swift
1212
ExtraStringAPIs.swift
1313
FileManager.swift
14-
FileManagerThunks.m
1514
Foundation.swift
16-
Hashing.m
17-
Hashing.swift
1815
IndexPath.swift
1916
IndexSet.swift
20-
IndexSetThunks.m
2117
Locale.swift
2218
Measurement.swift
2319
Notification.swift
@@ -44,7 +40,6 @@ add_swift_library(swiftFoundation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SD
4440
PersonNameComponents.swift
4541
ReferenceConvertible.swift
4642
String.swift
47-
Thunks.mm
4843
TimeZone.swift
4944
TypePreservingNSNumber.mm
5045
URL.swift

stdlib/public/SDK/Foundation/Calendar.swift

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
@_exported import Foundation // Clang module
14-
15-
@_silgen_name("__NSCalendarIsAutoupdating")
16-
internal func __NSCalendarIsAutoupdating(_ calendar: NSCalendar) -> Bool
17-
18-
@_silgen_name("__NSCalendarAutoupdating")
19-
internal func __NSCalendarAutoupdating() -> NSCalendar
20-
21-
@_silgen_name("__NSCalendarCurrent")
22-
internal func __NSCalendarCurrent() -> NSCalendar
23-
24-
@_silgen_name("__NSCalendarInit")
25-
internal func __NSCalendarInit(_ identifier : NSString) -> NSCalendar?
14+
import _SwiftFoundationOverlayShims
2615

2716
/**
2817
`Calendar` encapsulates information about systems of reckoning time in which the beginning, length, and divisions of a year are defined. It provides information about the calendar and support for calendrical computations such as determining the range of a given calendrical unit and adding units to a given absolute time.
@@ -90,7 +79,7 @@ public struct Calendar : Hashable, Equatable, ReferenceConvertible, _MutableBoxi
9079
///
9180
/// This calendar does not track changes that the user makes to their preferences.
9281
public static var current : Calendar {
93-
return Calendar(adoptingReference: __NSCalendarCurrent(), autoupdating: false)
82+
return Calendar(adoptingReference: __NSCalendarCurrent() as! NSCalendar, autoupdating: false)
9483
}
9584

9685
/// A Calendar that tracks changes to user's preferred calendar.
@@ -99,7 +88,7 @@ public struct Calendar : Hashable, Equatable, ReferenceConvertible, _MutableBoxi
9988
///
10089
/// - note: The autoupdating Calendar will only compare equal to another autoupdating Calendar.
10190
public static var autoupdatingCurrent : Calendar {
102-
return Calendar(adoptingReference: __NSCalendarAutoupdating(), autoupdating: true)
91+
return Calendar(adoptingReference: __NSCalendarAutoupdating() as! NSCalendar, autoupdating: true)
10392
}
10493

10594
// MARK: -
@@ -109,8 +98,8 @@ public struct Calendar : Hashable, Equatable, ReferenceConvertible, _MutableBoxi
10998
///
11099
/// - parameter identifier: The kind of calendar to use.
111100
public init(identifier: Identifier) {
112-
let result = __NSCalendarInit(Calendar._toNSCalendarIdentifier(identifier).rawValue as NSString)!
113-
_handle = _MutableHandle(adoptingReference: result)
101+
let result = __NSCalendarCreate(Calendar._toNSCalendarIdentifier(identifier))
102+
_handle = _MutableHandle(adoptingReference: result as! NSCalendar)
114103
_autoupdating = false
115104
}
116105

stdlib/public/SDK/Foundation/Data.swift

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,11 @@ internal func __NSDataInvokeDeallocatorFree(_ mem: UnsafeMutableRawPointer, _ le
3131
#else
3232

3333
@_exported import Foundation // Clang module
34+
import _SwiftFoundationOverlayShims
35+
import _SwiftCoreFoundationOverlayShims
3436

35-
@_silgen_name("__NSDataInvokeDeallocatorVM")
36-
internal func __NSDataInvokeDeallocatorVM(_ mem: UnsafeMutableRawPointer, _ length: Int)
37-
38-
@_silgen_name("__NSDataInvokeDeallocatorUnmap")
39-
internal func __NSDataInvokeDeallocatorUnmap(_ mem: UnsafeMutableRawPointer, _ length: Int)
40-
41-
@_silgen_name("__NSDataInvokeDeallocatorFree")
42-
internal func __NSDataInvokeDeallocatorFree(_ mem: UnsafeMutableRawPointer, _ length: Int)
43-
44-
@_silgen_name("_NSWriteDataToFile_Swift")
45-
internal func _NSWriteDataToFile_Swift(url: NSURL, data: NSData, options: UInt, error: NSErrorPointer) -> Bool
37+
@_silgen_name("__NSDataWriteToURL")
38+
internal func __NSDataWriteToURL(_ data: NSData, _ url: NSURL, _ options: UInt, _ error: NSErrorPointer) -> Bool
4639

4740
#endif
4841

@@ -882,11 +875,11 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
882875
#else
883876
switch self {
884877
case .virtualMemory:
885-
return { __NSDataInvokeDeallocatorVM($0, $1) }
878+
return { NSDataDeallocatorVM($0, UInt($1)) }
886879
case .unmap:
887-
return { __NSDataInvokeDeallocatorUnmap($0, $1) }
880+
return { NSDataDeallocatorUnmap($0, UInt($1)) }
888881
case .free:
889-
return { __NSDataInvokeDeallocatorFree($0, $1) }
882+
return { NSDataDeallocatorFree($0, UInt($1)) }
890883
case .none:
891884
return { _, _ in }
892885
case .custom(let b):
@@ -1206,10 +1199,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12061199
try $0.write(to: url, options: WritingOptions(rawValue: options.rawValue))
12071200
#else
12081201
if _shouldUseNonAtomicWriteReimplementation(options: options) {
1209-
var error : NSError?
1210-
if !_NSWriteDataToFile_Swift(url: url._bridgeToObjectiveC(), data: $0, options: options.rawValue, error: &error) {
1211-
throw error!
1212-
}
1202+
var error: NSError? = nil
1203+
guard __NSDataWriteToURL($0, url as NSURL, options.rawValue, &error) else { throw error! }
12131204
} else {
12141205
try $0.write(to: url, options: WritingOptions(rawValue: options.rawValue))
12151206
}

stdlib/public/SDK/Foundation/DataThunks.m

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,6 @@
1515

1616
#include "swift/Runtime/Config.h"
1717

18-
typedef void (^NSDataDeallocator)(void *, NSUInteger);
19-
extern const NSDataDeallocator NSDataDeallocatorVM;
20-
extern const NSDataDeallocator NSDataDeallocatorUnmap;
21-
extern const NSDataDeallocator NSDataDeallocatorFree;
22-
extern const NSDataDeallocator NSDataDeallocatorNone;
23-
24-
SWIFT_CC(swift)
25-
void __NSDataInvokeDeallocatorVM(void *mem, NSUInteger length) {
26-
NSDataDeallocatorVM(mem, length);
27-
}
28-
29-
SWIFT_CC(swift)
30-
void __NSDataInvokeDeallocatorUnmap(void *mem, NSUInteger length) {
31-
NSDataDeallocatorUnmap(mem, length);
32-
}
33-
34-
SWIFT_CC(swift)
35-
void __NSDataInvokeDeallocatorFree(void *mem, NSUInteger length) {
36-
NSDataDeallocatorFree(mem, length);
37-
}
38-
39-
4018
#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
4119
static int __NSFileProtectionClassForOptions(NSUInteger options) {
4220
int result;
@@ -94,11 +72,47 @@ static NSInteger _NSWriteToFileDescriptor(int32_t fd, const void *buffer, NSUInt
9472
return length - numBytesRemaining;
9573
}
9674

97-
extern NSError *_NSErrorWithFilePath(NSInteger code, id pathOrURL);
98-
extern NSError *_NSErrorWithFilePathAndErrno(NSInteger posixErrno, id pathOrURL, BOOL reading);
75+
static NSError *_NSErrorWithFilePath(NSInteger code, id pathOrURL) {
76+
NSString *key = [pathOrURL isKindOfClass:[NSURL self]] ? NSURLErrorKey : NSFilePathErrorKey;
77+
return [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:[NSDictionary dictionaryWithObjectsAndKeys:pathOrURL, key, nil]];
78+
}
79+
80+
static NSError *_NSErrorWithFilePathAndErrno(NSInteger posixErrno, id pathOrURL, BOOL reading) {
81+
NSInteger code;
82+
if (reading) {
83+
switch (posixErrno) {
84+
case EFBIG: code = NSFileReadTooLargeError; break;
85+
case ENOENT: code = NSFileReadNoSuchFileError; break;
86+
case EPERM: // fallthrough
87+
case EACCES: code = NSFileReadNoPermissionError; break;
88+
case ENAMETOOLONG: code = NSFileReadInvalidFileNameError; break;
89+
default: code = NSFileReadUnknownError; break;
90+
}
91+
} else {
92+
switch (posixErrno) {
93+
case ENOENT: code = NSFileNoSuchFileError; break;
94+
case EPERM: // fallthrough
95+
case EACCES: code = NSFileWriteNoPermissionError; break;
96+
case ENAMETOOLONG: code = NSFileWriteInvalidFileNameError; break;
97+
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
98+
case EDQUOT:
99+
#endif
100+
case ENOSPC: code = NSFileWriteOutOfSpaceError; break;
101+
case EROFS: code = NSFileWriteVolumeReadOnlyError; break;
102+
case EEXIST: code = NSFileWriteFileExistsError; break;
103+
default: code = NSFileWriteUnknownError; break;
104+
}
105+
}
106+
107+
NSString *key = [pathOrURL isKindOfClass:[NSURL self]] ? NSURLErrorKey : NSFilePathErrorKey;
108+
NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:pathOrURL, key, [NSError errorWithDomain:NSPOSIXErrorDomain code:posixErrno userInfo:nil], NSUnderlyingErrorKey, nil];
109+
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:userInfo];
110+
[userInfo release];
111+
return error;
112+
}
99113

100114
SWIFT_CC(swift)
101-
BOOL _NSWriteDataToFile_Swift(NSURL * NS_RELEASES_ARGUMENT url, NSData * NS_RELEASES_ARGUMENT data, NSDataWritingOptions writingOptions, NSError **errorPtr) {
115+
BOOL __NSDataWriteToURL(NSData *NS_RELEASES_ARGUMENT data, NSURL *NS_RELEASES_ARGUMENT url, NSDataWritingOptions writingOptions, NSError **_Nullable errorPtr) {
102116
assert((writingOptions & NSDataWritingAtomic) == 0);
103117

104118
NSString *path = url.path;

stdlib/public/SDK/Foundation/Date.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
@_exported import Foundation // Clang module
1414
import CoreFoundation
15+
import _SwiftCoreFoundationOverlayShims
1516

1617
/**
1718
`Date` represents a single point in time.

stdlib/public/SDK/Foundation/DateInterval.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
@_exported import Foundation // Clang module
14+
import _SwiftCoreFoundationOverlayShims
1415

1516
/// DateInterval represents a closed date interval in the form of [startDate, endDate]. It is possible for the start and end dates to be the same with a duration of 0. DateInterval does not support reverse intervals i.e. intervals where the duration is less than 0 and the end date occurs earlier in time than the start date.
1617
@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)

stdlib/public/SDK/Foundation/Decimal.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
@_exported import Foundation // Clang module
14+
import _SwiftCoreFoundationOverlayShims
1415

1516
extension Decimal {
1617
public typealias RoundingMode = NSDecimalNumber.RoundingMode

stdlib/public/SDK/Foundation/FileManager.swift

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
@_exported import Foundation // Clang module
14-
15-
@_silgen_name("NS_Swift_NSFileManager_replaceItemAtURL_withItemAtURL_backupItemName_options")
16-
internal func NS_Swift_NSFileManager_replaceItemAtURL_withItemAtURL_backupItemName_options(
17-
_ self_: AnyObject,
18-
_ originalItemURL: AnyObject,
19-
_ newItemURL: AnyObject,
20-
_ backupItemName: NSString?,
21-
_ options: FileManager.ItemReplacementOptions,
22-
_ error: NSErrorPointer) -> NSURL?
23-
24-
@_silgen_name("NS_Swift_NSFileManager_enumeratorAt_includingPropertiesForKeys_options_errorHandler")
25-
internal func NS_Swift_NSFileManager_enumeratorAt_includingPropertiesForKeys_options_errorHandler(
26-
_ self_ : AnyObject,
27-
_ url: AnyObject,
28-
_ keys: NSArray?,
29-
_ options: FileManager.DirectoryEnumerationOptions,
30-
_ errorHandler: @escaping @convention(block) (NSURL, NSError) -> Bool) -> FileManager.DirectoryEnumerator?
14+
import _SwiftFoundationOverlayShims
3115

3216
extension FileManager {
3317
/*
@@ -37,31 +21,35 @@ extension FileManager {
3721

3822
@available(*, deprecated, renamed:"replaceItemAt(_:withItemAt:backupItemName:options:)")
3923
public func replaceItemAtURL(originalItemURL: NSURL, withItemAtURL newItemURL: NSURL, backupItemName: String? = nil, options: FileManager.ItemReplacementOptions = []) throws -> NSURL? {
40-
var error: NSError?
41-
if let result = NS_Swift_NSFileManager_replaceItemAtURL_withItemAtURL_backupItemName_options(self, originalItemURL, newItemURL, backupItemName as NSString?, options, &error) {
42-
return result
43-
}
44-
throw error!
24+
var error: NSError? = nil
25+
guard let result = __NSFileManagerReplaceItemAtURL(self, originalItemURL as URL, newItemURL as URL, backupItemName, options, &error) else { throw error! }
26+
return result as NSURL
4527
}
4628

29+
@available(swift, obsoleted: 4)
4730
@available(OSX 10.6, iOS 4.0, *)
4831
public func replaceItemAt(_ originalItemURL: URL, withItemAt newItemURL: URL, backupItemName: String? = nil, options: FileManager.ItemReplacementOptions = []) throws -> NSURL? {
4932
var error: NSError?
50-
if let result = NS_Swift_NSFileManager_replaceItemAtURL_withItemAtURL_backupItemName_options(self, originalItemURL as NSURL, newItemURL as NSURL, backupItemName as NSString?, options, &error) {
51-
return result
52-
}
53-
throw error!
33+
guard let result = __NSFileManagerReplaceItemAtURL(self, originalItemURL, newItemURL , backupItemName, options, &error) else { throw error! }
34+
return result as NSURL
5435
}
5536

37+
@available(swift, introduced: 4)
38+
@available(OSX 10.6, iOS 4.0, *)
39+
public func replaceItemAt(_ originalItemURL: URL, withItemAt newItemURL: URL, backupItemName: String? = nil, options: FileManager.ItemReplacementOptions = []) throws -> URL? {
40+
var error: NSError?
41+
guard let result = __NSFileManagerReplaceItemAtURL(self, originalItemURL, newItemURL , backupItemName, options, &error) else { throw error! }
42+
return result
43+
}
44+
5645
@available(OSX 10.6, iOS 4.0, *)
5746
public func enumerator(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions = [], errorHandler handler: ((URL, Error) -> Bool)? = nil) -> FileManager.DirectoryEnumerator? {
58-
return NS_Swift_NSFileManager_enumeratorAt_includingPropertiesForKeys_options_errorHandler(self, url as NSURL, keys as NSArray?, mask, { (url, error) in
47+
return __NSFileManagerEnumeratorAtURL(self, url, keys, mask, { (url, error) in
5948
var errorResult = true
6049
if let h = handler {
6150
errorResult = h(url as URL, error)
6251
}
6352
return errorResult
6453
})
6554
}
66-
6755
}

stdlib/public/SDK/Foundation/FileManagerThunks.m

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)