Skip to content

[stdlib] Unexport shadow protocols #20509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 15, 2018
Merged
4 changes: 1 addition & 3 deletions stdlib/public/SDK/Foundation/NSArray.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ extension Array : _ObjectiveCBridgeable {
//
// The bug is fixed in: OS X 10.11.0, iOS 9.0, all versions of tvOS
// and watchOS.
self = Array(
_immutableCocoaArray:
unsafeBitCast(_cocoaArray.copy() as AnyObject, to: _NSArrayCore.self))
self = Array(_immutableCocoaArray: _cocoaArray.copy() as AnyObject)
}

@_semantics("convertToObjectiveC")
Expand Down
9 changes: 3 additions & 6 deletions stdlib/public/SDK/Foundation/NSDictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extension Dictionary {
///
/// The provided `NSDictionary` will be copied to ensure that the copy can
/// not be mutated by other code.
fileprivate init(_cocoaDictionary: __shared _NSDictionary) {
fileprivate init(_cocoaDictionary: __shared AnyObject) {
assert(
_isBridgedVerbatimToObjectiveC(Key.self) &&
_isBridgedVerbatimToObjectiveC(Value.self),
Expand All @@ -49,9 +49,7 @@ extension Dictionary {
// The bug is fixed in: OS X 10.11.0, iOS 9.0, all versions of tvOS
// and watchOS.
self = Dictionary(
_immutableCocoaDictionary:
unsafeBitCast(_cocoaDictionary.copy(with: nil) as AnyObject,
to: _NSDictionary.self))
_immutableCocoaDictionary: _cocoaDictionary.copy(with: nil) as AnyObject)
}
}

Expand All @@ -75,8 +73,7 @@ extension Dictionary : _ObjectiveCBridgeable {

if _isBridgedVerbatimToObjectiveC(Key.self) &&
_isBridgedVerbatimToObjectiveC(Value.self) {
result = [Key : Value](
_cocoaDictionary: unsafeBitCast(d as AnyObject, to: _NSDictionary.self))
result = [Key : Value](_cocoaDictionary: d)
return
}

Expand Down
8 changes: 3 additions & 5 deletions stdlib/public/SDK/Foundation/NSSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extension Set {
///
/// The provided `NSSet` will be copied to ensure that the copy can
/// not be mutated by other code.
fileprivate init(_cocoaSet: __shared _NSSet) {
fileprivate init(_cocoaSet: __shared AnyObject) {
assert(_isBridgedVerbatimToObjectiveC(Element.self),
"Set can be backed by NSSet _variantStorage only when the member type can be bridged verbatim to Objective-C")
// FIXME: We would like to call CFSetCreateCopy() to avoid doing an
Expand All @@ -29,9 +29,7 @@ extension Set {
//
// The bug is fixed in: OS X 10.11.0, iOS 9.0, all versions of tvOS
// and watchOS.
self = Set(
_immutableCocoaSet:
unsafeBitCast(_cocoaSet.copy(with: nil) as AnyObject, to: _NSSet.self))
self = Set(_immutableCocoaSet: _cocoaSet.copy(with: nil) as AnyObject)
}
}

Expand Down Expand Up @@ -69,7 +67,7 @@ extension Set : _ObjectiveCBridgeable {
}

if _isBridgedVerbatimToObjectiveC(Element.self) {
result = Set<Element>(_cocoaSet: unsafeBitCast(s, to: _NSSet.self))
result = Set<Element>(_cocoaSet: s)
return
}

Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/core/Array.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1728,7 +1728,7 @@ extension Array {
// to do the bridging in an ABI safe way. Even though this looks useless,
// DO NOT DELETE!
@usableFromInline internal
func _bridgeCocoaArray<T>(_ _immutableCocoaArray: _NSArrayCore) -> Array<T> {
func _bridgeCocoaArray<T>(_ _immutableCocoaArray: AnyObject) -> Array<T> {
return Array(_buffer: _ArrayBuffer(nsArray: _immutableCocoaArray))
}

Expand Down Expand Up @@ -1764,7 +1764,7 @@ extension Array {
/// * `Element` is bridged verbatim to Objective-C (i.e.,
/// is a reference type).
@inlinable
public init(_immutableCocoaArray: _NSArrayCore) {
public init(_immutableCocoaArray: AnyObject) {
self = _bridgeCocoaArray(_immutableCocoaArray)
}
}
Expand Down
87 changes: 19 additions & 68 deletions stdlib/public/core/ArrayBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import SwiftShims

@usableFromInline
internal typealias _ArrayBridgeStorage
= _BridgeStorage<__ContiguousArrayStorageBase, _NSArrayCore>
= _BridgeStorage<__ContiguousArrayStorageBase>

@usableFromInline
@_fixed_layout
Expand All @@ -33,7 +33,7 @@ internal struct _ArrayBuffer<Element> : _ArrayBufferProtocol {
}

@inlinable
internal init(nsArray: _NSArrayCore) {
internal init(nsArray: AnyObject) {
_sanityCheck(_isClassOrObjCExistential(Element.self))
_storage = _ArrayBridgeStorage(objC: nsArray)
}
Expand Down Expand Up @@ -121,8 +121,8 @@ extension _ArrayBuffer {
///
/// O(1) if the element type is bridged verbatim, O(*n*) otherwise.
@inlinable
internal func _asCocoaArray() -> _NSArrayCore {
return _fastPath(_isNative) ? _native._asCocoaArray() : _nonNative
internal func _asCocoaArray() -> AnyObject {
return _fastPath(_isNative) ? _native._asCocoaArray() : _nonNative.buffer
}

/// If this buffer is backed by a uniquely-referenced mutable
Expand Down Expand Up @@ -175,8 +175,7 @@ extension _ArrayBuffer {
)
}
else {
let ns = _nonNative
let element = ns.objectAt(index)
let element = _nonNative[index]
precondition(
element is Element,
"""
Expand Down Expand Up @@ -216,26 +215,12 @@ extension _ArrayBuffer {
if _fastPath(_isNative) {
return _native._copyContents(subRange: bounds, initializing: target)
}

let nonNative = _nonNative

let nsSubRange = SwiftShims._SwiftNSRange(
location: bounds.lowerBound,
length: bounds.upperBound - bounds.lowerBound)

let buffer = UnsafeMutableRawPointer(target).assumingMemoryBound(
to: AnyObject.self)

// Copies the references out of the NSArray without retaining them
nonNative.getObjects(buffer, range: nsSubRange)

// Make another pass to retain the copied objects
var result = target
for _ in bounds {
result.initialize(to: result.pointee)
result += 1
}
return result
let buffer = UnsafeMutableRawPointer(target)
.assumingMemoryBound(to: AnyObject.self)
let result = _nonNative._copyContents(
subRange: bounds,
initializing: buffer)
return UnsafeMutableRawPointer(result).assumingMemoryBound(to: Element.self)
}

/// Returns a `_SliceBuffer` containing the given sub-range of elements in
Expand All @@ -244,45 +229,10 @@ extension _ArrayBuffer {
internal subscript(bounds: Range<Int>) -> _SliceBuffer<Element> {
get {
_typeCheck(bounds)

if _fastPath(_isNative) {
return _native[bounds]
}

let boundsCount = bounds.count
if boundsCount == 0 {
return _SliceBuffer(
_buffer: _ContiguousArrayBuffer<Element>(),
shiftedToStartIndex: bounds.lowerBound)
}

// Look for contiguous storage in the NSArray
let nonNative = self._nonNative
let cocoa = _CocoaArrayWrapper(nonNative)
let cocoaStorageBaseAddress = cocoa.contiguousStorage(self.indices)

if let cocoaStorageBaseAddress = cocoaStorageBaseAddress {
let basePtr = UnsafeMutableRawPointer(cocoaStorageBaseAddress)
.assumingMemoryBound(to: Element.self)
return _SliceBuffer(
owner: nonNative,
subscriptBaseAddress: basePtr,
indices: bounds,
hasNativeBuffer: false)
}

// No contiguous storage found; we must allocate
let result = _ContiguousArrayBuffer<Element>(
_uninitializedCount: boundsCount, minimumCapacity: 0)

// Tell Cocoa to copy the objects into our storage
cocoa.buffer.getObjects(
UnsafeMutableRawPointer(result.firstElementAddress)
.assumingMemoryBound(to: AnyObject.self),
range: _SwiftNSRange(location: bounds.lowerBound, length: boundsCount))

return _SliceBuffer(
_buffer: result, shiftedToStartIndex: bounds.lowerBound)
return _nonNative[bounds].unsafeCastElements(to: Element.self)
}
set {
fatalError("not implemented")
Expand Down Expand Up @@ -315,7 +265,7 @@ extension _ArrayBuffer {
_native.count = newValue
}
}

/// Traps if an inout violation is detected or if the buffer is
/// native and the subscript is out of range.
///
Expand Down Expand Up @@ -392,7 +342,7 @@ extension _ArrayBuffer {
)
} else {
// ObjC arrays do their own subscript checking.
element = _nonNative.objectAt(i)
element = _nonNative[i]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: This was probably written this way because -objectAtIndexedSubscript: is just going to call -objectAtIndex:, and you might as well save that one objc_msgSend.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not call -objectAtIndexedSubscript:: _nonNative now returns a _CocoaArrayWrapper, which is a Swift struct. Its opaque subscript calls objectAt(_:), which is the shadow protocol's pet name for -objectAtIndex: a.k.a. object(at:)

This does add an extra static function call compared to the original, but those are pretty cheap, and this is on a slow path anyway, so it shouldn't matter much.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, my bad for not taking the whole patch at once. Thanks for the explanation.

precondition(
element is Element,
"""
Expand Down Expand Up @@ -460,7 +410,7 @@ extension _ArrayBuffer {
/// An object that keeps the elements stored in this buffer alive.
@inlinable
internal var owner: AnyObject {
return _fastPath(_isNative) ? _native._storage : _nonNative
return _fastPath(_isNative) ? _native._storage : _nonNative.buffer
}

/// An object that keeps the elements stored in this buffer alive.
Expand All @@ -481,7 +431,8 @@ extension _ArrayBuffer {
return _native.identity
}
else {
return UnsafeRawPointer(Unmanaged.passUnretained(_nonNative).toOpaque())
return UnsafeRawPointer(
Unmanaged.passUnretained(_nonNative.buffer).toOpaque())
}
}

Expand Down Expand Up @@ -550,11 +501,11 @@ extension _ArrayBuffer {
}

@inlinable
internal var _nonNative: _NSArrayCore {
internal var _nonNative: _CocoaArrayWrapper {
@inline(__always)
get {
_sanityCheck(_isClassOrObjCExistential(Element.self))
return _storage.objCInstance
return _CocoaArrayWrapper(_storage.objCInstance)
}
}
}
Expand Down
9 changes: 3 additions & 6 deletions stdlib/public/core/BridgeStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// Types that are bridged to Objective-C need to manage an object
// that may be either some native class or the @objc Cocoa
// equivalent. _BridgeStorage discriminates between these two
// possibilities and stores a few extra bits when the stored type is
// possibilities and stores a single extra bit when the stored type is
// native. It is assumed that the @objc class instance may in fact
// be a tagged pointer, and thus no extra bits may be available.
//
Expand All @@ -22,15 +22,12 @@ import SwiftShims

@_fixed_layout
@usableFromInline
internal struct _BridgeStorage<
NativeClass: AnyObject,
ObjCClass: AnyObject
> {
internal struct _BridgeStorage<NativeClass: AnyObject> {
@usableFromInline
internal typealias Native = NativeClass

@usableFromInline
internal typealias ObjC = ObjCClass
internal typealias ObjC = AnyObject

// rawValue is passed inout to _isUnique. Although its value
// is unchanged, it must appear mutable to the optimizer.
Expand Down
Loading