Skip to content

Commit 3da2492

Browse files
author
Russ Bishop
committed
SR-1485: Change Unmanaged to use UnsafePointer
1 parent 559829f commit 3da2492

File tree

5 files changed

+63
-27
lines changed

5 files changed

+63
-27
lines changed

stdlib/private/SwiftPrivatePthreadExtras/SwiftPrivatePthreadExtras.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ internal func invokeBlockContext(
5252
_ contextAsVoidPointer: UnsafeMutablePointer<Void>?
5353
) -> UnsafeMutablePointer<Void>! {
5454
// The context is passed in +1; we're responsible for releasing it.
55-
let contextAsOpaque = OpaquePointer(contextAsVoidPointer!)
56-
let context = Unmanaged<PthreadBlockContext>.fromOpaque(contextAsOpaque)
55+
let context = Unmanaged<PthreadBlockContext>
56+
.fromOpaque(contextAsVoidPointer!)
5757
.takeRetainedValue()
5858

5959
return context.run()
@@ -68,8 +68,7 @@ public func _stdlib_pthread_create_block<Argument, Result>(
6868
let context = PthreadBlockContextImpl(block: start_routine, arg: arg)
6969
// We hand ownership off to `invokeBlockContext` through its void context
7070
// argument.
71-
let contextAsOpaque = OpaquePointer(bitPattern: Unmanaged.passRetained(context))
72-
let contextAsVoidPointer = UnsafeMutablePointer<Void>(contextAsOpaque)
71+
let contextAsVoidPointer = Unmanaged.passRetained(context).toOpaque()
7372

7473
var threadID = _make_pthread_t()
7574
let result = pthread_create(&threadID, attr,

stdlib/public/core/CTypes.swift

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,6 @@ public struct OpaquePointer : Equatable, Hashable {
130130
self.init(unwrapped)
131131
}
132132

133-
/// Unsafely convert an unmanaged class reference to an opaque
134-
/// C pointer.
135-
///
136-
/// This operation does not change reference counts.
137-
///
138-
/// let str0: CFString = "boxcar"
139-
/// let bits = OpaquePointer(bitPattern: Unmanaged(withoutRetaining: str0))
140-
/// let str1 = Unmanaged<CFString>(bitPattern: bits).object
141-
@_transparent
142-
public init<T>(bitPattern bits: Unmanaged<T>) {
143-
self = unsafeBitCast(bits._value, to: OpaquePointer.self)
144-
}
145-
146133
/// The hash value.
147134
///
148135
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`.
@@ -212,3 +199,11 @@ func _memcpy(
212199

213200
@available(*, unavailable, renamed: "OpaquePointer")
214201
public struct COpaquePointer {}
202+
203+
extension OpaquePointer {
204+
@available(*, unavailable,
205+
message:"use 'Unmanaged.toOpaque()' instead")
206+
public init<T>(bitPattern bits: Unmanaged<T>) {
207+
Builtin.unreachable()
208+
}
209+
}

stdlib/public/core/Runtime.swift.gyb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ import SwiftShims
2323
@_transparent
2424
public // @testable
2525
func _stdlib_atomicCompareExchangeStrongPtrImpl(
26-
object target: UnsafeMutablePointer<OpaquePointer?>,
27-
expected: UnsafeMutablePointer<OpaquePointer?>,
28-
desired: OpaquePointer?) -> Bool {
26+
object target: UnsafeMutablePointer<UnsafeMutablePointer<Void>?>,
27+
expected: UnsafeMutablePointer<UnsafeMutablePointer<Void>?>,
28+
desired: UnsafeMutablePointer<Void>?) -> Bool {
2929

3030
// We use Builtin.Word here because Builtin.RawPointer can't be nil.
3131
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Word(
3232
target._rawValue,
3333
UInt(bitPattern: expected.pointee)._builtinWordValue,
3434
UInt(bitPattern: desired)._builtinWordValue)
35-
expected.pointee = OpaquePointer(bitPattern: Int(oldValue))
35+
expected.pointee = UnsafeMutablePointer(bitPattern: Int(oldValue))
3636
return Bool(won)
3737
}
3838

@@ -72,7 +72,7 @@ func _stdlib_atomicCompareExchangeStrongPtr<T>(
7272
return _stdlib_atomicCompareExchangeStrongPtrImpl(
7373
object: UnsafeMutablePointer(target),
7474
expected: UnsafeMutablePointer(expected),
75-
desired: OpaquePointer(desired))
75+
desired: UnsafeMutablePointer(desired))
7676
}
7777

7878
@_transparent
@@ -81,8 +81,8 @@ public // @testable
8181
func _stdlib_atomicInitializeARCRef(
8282
object target: UnsafeMutablePointer<AnyObject?>,
8383
desired: AnyObject) -> Bool {
84-
var expected: OpaquePointer? = nil
85-
let desiredPtr = OpaquePointer(bitPattern: Unmanaged.passRetained(desired))
84+
var expected: UnsafeMutablePointer<Void>? = nil
85+
let desiredPtr = Unmanaged.passRetained(desired).toOpaque()
8686
let wonRace = _stdlib_atomicCompareExchangeStrongPtrImpl(
8787
object: UnsafeMutablePointer(target),
8888
expected: &expected,
@@ -243,7 +243,8 @@ func _stdlib_atomicLoadARCRef(
243243
let result = _swift_stdlib_atomicLoadPtrImpl(
244244
object: UnsafeMutablePointer(target))
245245
if let unwrapped = result {
246-
return Unmanaged<AnyObject>.fromOpaque(unwrapped).takeUnretainedValue()
246+
return Unmanaged<AnyObject>.fromOpaque(
247+
UnsafePointer(unwrapped)).takeUnretainedValue()
247248
}
248249
return nil
249250
}

stdlib/public/core/Unmanaged.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,22 @@ public struct Unmanaged<Instance : AnyObject> {
2929
///
3030
/// let str: CFString = Unmanaged.fromOpaque(ptr).takeUnretainedValue()
3131
@_transparent
32-
public static func fromOpaque(_ value: OpaquePointer) -> Unmanaged {
32+
public static func fromOpaque(_ value: UnsafePointer<Void>) -> Unmanaged {
3333
return Unmanaged(_private: unsafeBitCast(value, to: Instance.self))
3434
}
3535

36+
/// Unsafely convert an unmanaged class reference to a pointer
37+
///
38+
/// This operation does not change reference counts.
39+
///
40+
/// let str0: CFString = "boxcar"
41+
/// let bits = Unmanaged.passUnretained(str0)
42+
/// let str1 = Unmanaged<CFString>(bits).object
43+
@_transparent
44+
public func toOpaque() -> UnsafeMutablePointer<Void> {
45+
return unsafeBitCast(_value, to: UnsafeMutablePointer<Void>.self)
46+
}
47+
3648
/// Create an unmanaged reference with an unbalanced retain.
3749
/// The object will leak if nothing eventually balances the retain.
3850
///
@@ -201,3 +213,17 @@ public struct Unmanaged<Instance : AnyObject> {
201213
}
202214
#endif
203215
}
216+
217+
extension Unmanaged {
218+
@available(*, unavailable,
219+
message:"use 'fromOpaque(_: UnsafePointer<Void>)' instead")
220+
public static func fromOpaque(_ value: OpaquePointer) -> Unmanaged {
221+
Builtin.unreachable()
222+
}
223+
224+
@available(*, unavailable,
225+
message:"use 'toOpaque() -> UnsafePointer<Void>' instead")
226+
public func toOpaque() -> OpaquePointer {
227+
Builtin.unreachable()
228+
}
229+
}

test/1_stdlib/Unmanaged.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ UnmanagedTests.test("_withUnsafeGuaranteedRef/return") {
5454
}
5555
}
5656

57+
UnmanagedTests.test("Opaque") {
58+
var ref = Foobar()
59+
let opaquePtr = Unmanaged.passUnretained(ref).toOpaque()
60+
61+
let unknownPtr = Int(bitPattern: opaquePtr)
62+
let voidPtr = UnsafePointer<Void>(bitPattern: unknownPtr)
63+
expectNotEmpty(voidPtr, "toOpaque must not return null pointer")
64+
65+
let unmanaged = Unmanaged<Foobar>.fromOpaque(voidPtr!)
66+
expectEqual(
67+
ref === unmanaged.takeUnretainedValue(),
68+
true,
69+
"fromOpaque must return the same reference")
70+
71+
_fixLifetime(ref)
72+
}
5773

5874
runAllTests()
59-

0 commit comments

Comments
 (0)