//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #if _runtime(_ObjC) /// A Swift Array or Dictionary of types conforming to /// `_ObjectiveCBridgeable` can be passed to Objective-C as an NSArray or /// NSDictionary, respectively. The elements of the resulting NSArray /// or NSDictionary will be the result of calling `_bridgeToObjectiveC` /// on each element of the source container. public protocol _ObjectiveCBridgeable { associatedtype _ObjectiveCType : AnyObject /// Returns `true` iff instances of `Self` can be converted to /// Objective-C. Even if this method returns `true`, a given /// instance of `Self._ObjectiveCType` may, or may not, convert /// successfully to `Self`; for example, an `NSArray` will only /// convert successfully to `[String]` if it contains only /// `NSString`s. @warn_unused_result static func _isBridgedToObjectiveC() -> Bool // _getObjectiveCType is a workaround: right now protocol witness // tables don't include associated types, so we cannot find // '_ObjectiveCType.self' from them. /// Must return `_ObjectiveCType.self`. @warn_unused_result static func _getObjectiveCType() -> Any.Type /// Convert `self` to Objective-C. @warn_unused_result func _bridgeToObjectiveC() -> _ObjectiveCType /// Bridge from an Objective-C object of the bridged class type to a /// value of the Self type. /// /// This bridging operation is used for forced downcasting (e.g., /// via as), and may defer complete checking until later. For /// example, when bridging from `NSArray` to `Array`, we can defer /// the checking for the individual elements of the array. /// /// - parameter result: The location where the result is written. The optional /// will always contain a value. static func _forceBridgeFromObjectiveC( source: _ObjectiveCType, result: inout Self? ) /// Try to bridge from an Objective-C object of the bridged class /// type to a value of the Self type. /// /// This conditional bridging operation is used for conditional /// downcasting (e.g., via as?) and therefore must perform a /// complete conversion to the value type; it cannot defer checking /// to a later time. /// /// - parameter result: The location where the result is written. /// /// - Returns: `true` if bridging succeeded, `false` otherwise. This redundant /// information is provided for the convenience of the runtime's `dynamic_cast` /// implementation, so that it need not look into the optional representation /// to determine success. static func _conditionallyBridgeFromObjectiveC( source: _ObjectiveCType, result: inout Self? ) -> Bool } //===--- Bridging for metatypes -------------------------------------------===// /// A stand-in for a value of metatype type. /// /// The language and runtime do not yet support protocol conformances for /// structural types like metatypes. However, we can use a struct that contains /// a metatype, make it conform to _ObjectiveCBridgeable, and its witness table /// will be ABI-compatible with one that directly provided conformance to the /// metatype type itself. public struct _BridgeableMetatype: _ObjectiveCBridgeable { internal var value: AnyObject.Type public typealias _ObjectiveCType = AnyObject public static func _isBridgedToObjectiveC() -> Bool { return true } public static func _getObjectiveCType() -> Any.Type { return AnyObject.self } public func _bridgeToObjectiveC() -> AnyObject { return value } public static func _forceBridgeFromObjectiveC( source: AnyObject, result: inout _BridgeableMetatype? ) { result = _BridgeableMetatype(value: source as! AnyObject.Type) } public static func _conditionallyBridgeFromObjectiveC( source: AnyObject, result: inout _BridgeableMetatype? ) -> Bool { if let type = source as? AnyObject.Type { result = _BridgeableMetatype(value: type) return true } result = nil return false } } //===--- Bridging facilities written in Objective-C -----------------------===// // Functions that must discover and possibly use an arbitrary type's // conformance to a given protocol. See ../runtime/Metadata.cpp for // implementations. //===----------------------------------------------------------------------===// /// Attempt to convert `x` to its Objective-C representation. /// /// - If `T` is a class type, it is always bridged verbatim, the function /// returns `x`; /// /// - otherwise, `T` conforms to `_ObjectiveCBridgeable`: /// + if `T._isBridgedToObjectiveC()` returns `false`, then the /// result is empty; /// + otherwise, returns the result of `x._bridgeToObjectiveC()`; /// /// - otherwise, the result is empty. @warn_unused_result public func _bridgeToObjectiveC(x: T) -> AnyObject? { if _fastPath(_isClassOrObjCExistential(T.self)) { return unsafeBitCast(x, to: AnyObject.self) } return _bridgeNonVerbatimToObjectiveC(x) } @warn_unused_result public func _bridgeToObjectiveCUnconditional(x: T) -> AnyObject { let optResult: AnyObject? = _bridgeToObjectiveC(x) _precondition(optResult != nil, "value failed to bridge from Swift type to a Objective-C type") return optResult! } /// Same as `_bridgeToObjectiveCUnconditional`, but autoreleases the /// return value if `T` is bridged non-verbatim. @warn_unused_result func _bridgeToObjectiveCUnconditionalAutorelease(x: T) -> AnyObject { if _fastPath(_isClassOrObjCExistential(T.self)) { return unsafeBitCast(x, to: AnyObject.self) } guard let bridged = _bridgeNonVerbatimToObjectiveC(x) else { _preconditionFailure( "Dictionary key failed to bridge from Swift type to a Objective-C type") } _autorelease(bridged) return bridged } @warn_unused_result @_silgen_name("swift_bridgeNonVerbatimToObjectiveC") func _bridgeNonVerbatimToObjectiveC(x: T) -> AnyObject? /// Convert `x` from its Objective-C representation to its Swift /// representation. /// /// - If `T` is a class type: /// - if the dynamic type of `x` is `T` or a subclass of it, it is bridged /// verbatim, the function returns `x`; /// - otherwise, if `T` conforms to `_ObjectiveCBridgeable`: /// + if the dynamic type of `x` is not `T._getObjectiveCType()` /// or a subclass of it, trap; /// + otherwise, returns the result of `T._forceBridgeFromObjectiveC(x)`; /// - otherwise, trap. @warn_unused_result public func _forceBridgeFromObjectiveC(x: AnyObject, _: T.Type) -> T { if _fastPath(_isClassOrObjCExistential(T.self)) { return x as! T } var result: T? _bridgeNonVerbatimFromObjectiveC(x, T.self, &result) return result! } /// Convert `x` from its Objective-C representation to its Swift /// representation. @warn_unused_result @_silgen_name("_forceBridgeFromObjectiveC_bridgeable") public func _forceBridgeFromObjectiveC_bridgeable(x: T._ObjectiveCType, _: T.Type) -> T { var result: T? T._forceBridgeFromObjectiveC(x, result: &result) return result! } /// Attempt to convert `x` from its Objective-C representation to its Swift /// representation. /// /// - If `T` is a class type: /// - if the dynamic type of `x` is `T` or a subclass of it, it is bridged /// verbatim, the function returns `x`; /// - otherwise, if `T` conforms to `_ObjectiveCBridgeable`: /// + if `T._isBridgedToObjectiveC()` returns `false`, then the result is /// empty; /// + otherwise, if the dynamic type of `x` is not `T._getObjectiveCType()` /// or a subclass of it, the result is empty; /// + otherwise, returns the result of /// `T._conditionallyBridgeFromObjectiveC(x)`; /// - otherwise, the result is empty. @warn_unused_result public func _conditionallyBridgeFromObjectiveC( x: AnyObject, _: T.Type ) -> T? { if _fastPath(_isClassOrObjCExistential(T.self)) { return x as? T } var result: T? _bridgeNonVerbatimFromObjectiveCConditional(x, T.self, &result) return result } /// Attempt to convert `x` from its Objective-C representation to its Swift /// representation. @warn_unused_result @_silgen_name("_conditionallyBridgeFromObjectiveC_bridgeable") public func _conditionallyBridgeFromObjectiveC_bridgeable( x: T._ObjectiveCType, _: T.Type ) -> T? { var result: T? T._conditionallyBridgeFromObjectiveC (x, result: &result) return result } @_silgen_name("swift_bridgeNonVerbatimFromObjectiveC") func _bridgeNonVerbatimFromObjectiveC( x: AnyObject, _ nativeType: T.Type, _ result: inout T? ) /// Runtime optional to conditionally perform a bridge from an object to a value /// type. /// /// - parameter result: Will be set to the resulting value if bridging succeeds, and /// unchanged otherwise. /// /// - Returns: `true` to indicate success, `false` to indicate failure. @_silgen_name("swift_bridgeNonVerbatimFromObjectiveCConditional") func _bridgeNonVerbatimFromObjectiveCConditional( x: AnyObject, _ nativeType: T.Type, _ result: inout T? ) -> Bool /// Determines if values of a given type can be converted to an Objective-C /// representation. /// /// - If `T` is a class type, returns `true`; /// - otherwise, if `T` conforms to `_ObjectiveCBridgeable`, returns /// `T._isBridgedToObjectiveC()`. @warn_unused_result public func _isBridgedToObjectiveC(_: T.Type) -> Bool { if _fastPath(_isClassOrObjCExistential(T.self)) { return true } return _isBridgedNonVerbatimToObjectiveC(T.self) } @warn_unused_result @_silgen_name("swift_isBridgedNonVerbatimToObjectiveC") func _isBridgedNonVerbatimToObjectiveC(_: T.Type) -> Bool /// A type that's bridged "verbatim" does not conform to /// `_ObjectiveCBridgeable`, and can have its bits reinterpreted as an /// `AnyObject`. When this function returns true, the storage of an /// `Array` can be `unsafeBitCast` as an array of `AnyObject`. @warn_unused_result public func _isBridgedVerbatimToObjectiveC(_: T.Type) -> Bool { return _isClassOrObjCExistential(T.self) } /// Retrieve the Objective-C type to which the given type is bridged. @warn_unused_result public func _getBridgedObjectiveCType(_: T.Type) -> Any.Type? { if _fastPath(_isClassOrObjCExistential(T.self)) { return T.self } return _getBridgedNonVerbatimObjectiveCType(T.self) } @warn_unused_result @_silgen_name("swift_getBridgedNonVerbatimObjectiveCType") func _getBridgedNonVerbatimObjectiveCType(_: T.Type) -> Any.Type? // -- Pointer argument bridging @_transparent internal var _nilNativeObject: AnyObject? { return nil } /// A mutable pointer-to-ObjC-pointer argument. /// /// This type has implicit conversions to allow passing any of the following /// to a C or ObjC API: /// /// - `nil`, which gets passed as a null pointer, /// - an inout argument of the referenced type, which gets passed as a pointer /// to a writeback temporary with autoreleasing ownership semantics, /// - an `UnsafeMutablePointer`, which is passed as-is. /// /// Passing pointers to mutable arrays of ObjC class pointers is not /// directly supported. Unlike `UnsafeMutablePointer`, /// `AutoreleasingUnsafeMutablePointer` must reference storage that /// does not own a reference count to the referenced /// value. UnsafeMutablePointer's operations, by contrast, assume that /// the referenced storage owns values loaded from or stored to it. /// /// This type does not carry an owner pointer unlike the other C*Pointer types /// because it only needs to reference the results of inout conversions, which /// already have writeback-scoped lifetime. public struct AutoreleasingUnsafeMutablePointer : Equatable, NilLiteralConvertible, _Pointer { public let _rawValue: Builtin.RawPointer @_transparent public // COMPILER_INTRINSIC init(_ _rawValue: Builtin.RawPointer) { self._rawValue = _rawValue } @_transparent var _isNull : Bool { return UnsafeMutablePointer(self)._isNull } /// Access the `Pointee` instance referenced by `self`. /// /// - Precondition: the pointee has been initialized with an instance of type /// `Pointee`. public var pointee: Pointee { /// Retrieve the value the pointer points to. @_transparent get { _stdlibAssert(!_isNull) // We can do a strong load normally. return UnsafeMutablePointer(self).pointee } /// Set the value the pointer points to, copying over the previous value. /// /// AutoreleasingUnsafeMutablePointers are assumed to reference a /// value with __autoreleasing ownership semantics, like 'NSFoo**' /// in ARC. This autoreleases the argument before trivially /// storing it to the referenced memory. @_transparent nonmutating set { _stdlibAssert(!_isNull) // Autorelease the object reference. typealias OptionalAnyObject = AnyObject? Builtin.retain(unsafeBitCast(newValue, to: OptionalAnyObject.self)) Builtin.autorelease(unsafeBitCast(newValue, to: OptionalAnyObject.self)) // Trivially assign it as an OpaquePointer; the pointer references an // autoreleasing slot, so retains/releases of the original value are // unneeded. let p = UnsafeMutablePointer( UnsafeMutablePointer(self)) p.pointee = unsafeBitCast(newValue, to: OpaquePointer.self) } } /// Access the `i`th element of the raw array pointed to by /// `self`. /// /// - Precondition: `self != nil`. public subscript(i: Int) -> Pointee { @_transparent get { _stdlibAssert(!_isNull) // We can do a strong load normally. return (UnsafePointer(self) + i).pointee } } /// Create an instance initialized with `nil`. @_transparent public init(nilLiteral: ()) { self._rawValue = _nilRawPointer } /// Explicit construction from an UnsafeMutablePointer. /// /// This is inherently unsafe; UnsafeMutablePointer assumes the /// referenced memory has +1 strong ownership semantics, whereas /// AutoreleasingUnsafeMutablePointer implies +0 semantics. @_transparent public init(_ ptr: UnsafeMutablePointer) { self._rawValue = ptr._rawValue } /// Explicit construction from a UnsafePointer. /// /// This is inherently unsafe because UnsafePointers do not imply /// mutability. @_transparent init(_ ptr: UnsafePointer) { self._rawValue = ptr._rawValue } } extension AutoreleasingUnsafeMutablePointer : CustomDebugStringConvertible { /// A textual representation of `self`, suitable for debugging. public var debugDescription: String { return _rawPointerToString(_rawValue) } } @_transparent @warn_unused_result public func == ( lhs: AutoreleasingUnsafeMutablePointer, rhs: AutoreleasingUnsafeMutablePointer ) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue)) } internal struct _CocoaFastEnumerationStackBuf { // Clang uses 16 pointers. So do we. internal var _item0: Builtin.RawPointer internal var _item1: Builtin.RawPointer internal var _item2: Builtin.RawPointer internal var _item3: Builtin.RawPointer internal var _item4: Builtin.RawPointer internal var _item5: Builtin.RawPointer internal var _item6: Builtin.RawPointer internal var _item7: Builtin.RawPointer internal var _item8: Builtin.RawPointer internal var _item9: Builtin.RawPointer internal var _item10: Builtin.RawPointer internal var _item11: Builtin.RawPointer internal var _item12: Builtin.RawPointer internal var _item13: Builtin.RawPointer internal var _item14: Builtin.RawPointer internal var _item15: Builtin.RawPointer @_transparent internal var count: Int { return 16 } internal init() { _item0 = _nilRawPointer _item1 = _item0 _item2 = _item0 _item3 = _item0 _item4 = _item0 _item5 = _item0 _item6 = _item0 _item7 = _item0 _item8 = _item0 _item9 = _item0 _item10 = _item0 _item11 = _item0 _item12 = _item0 _item13 = _item0 _item14 = _item0 _item15 = _item0 _sanityCheck(sizeofValue(self) >= sizeof(Builtin.RawPointer.self) * count) } } extension AutoreleasingUnsafeMutablePointer { @available(*, unavailable, renamed="Pointee") public typealias Memory = Pointee @available(*, unavailable, renamed="pointee") public var memory: Pointee { fatalError("unavailable function can't be called") } @available(*, unavailable, message="Removed in Swift 3. Please use nil literal instead.") public init() { fatalError("unavailable function can't be called") } } #endif