Skip to content

Commit 7df19b8

Browse files
[stdlib] Fix calling convention mismatch for debugger utility functions (#69352)
This is the 3rd attempt to fix the mismatch, where the actual definition (e.g. `swift_retainCount`) are defined with C calling-convention and the callers wrongly expect Swift calling-convention. The 1st fix broke ABI compatibility by introducing new symbol references from app-side without any availability checks. The 2nd fix broke lldb's retain counting feature due to new x-ref to Clang module in serialized function body by `@_alwaysEmitIntoClient`. This attemps to avoid introducing serialized x-ref to Clang module by using new `@_extern(c)` attribute. Resolves rdar://113910821 Co-authored-by: Karoy Lorentey <[email protected]>
1 parent 877f8a7 commit 7df19b8

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-experimental-concis
300300

301301
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Macros")
302302
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "FreestandingMacros")
303+
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Extern")
303304

304305
set(swift_core_incorporate_object_libraries)
305306
list(APPEND swift_core_incorporate_object_libraries swiftRuntime)

stdlib/public/core/DebuggerSupport.swift

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,38 @@ public func _stringForPrintObject(_ value: Any) -> String {
268268

269269
public func _debuggerTestingCheckExpect(_: String, _: String) { }
270270

271+
@_alwaysEmitIntoClient @_transparent
272+
internal func _withHeapObject<R>(
273+
of object: AnyObject,
274+
_ body: (UnsafeMutableRawPointer) -> R
275+
) -> R {
276+
defer { _fixLifetime(object) }
277+
let unmanaged = Unmanaged.passUnretained(object)
278+
return body(unmanaged.toOpaque())
279+
}
280+
281+
@_extern(c, "swift_retainCount") @usableFromInline
282+
internal func _swift_retainCount(_: UnsafeMutableRawPointer) -> Int
283+
@_extern(c, "swift_unownedRetainCount") @usableFromInline
284+
internal func _swift_unownedRetainCount(_: UnsafeMutableRawPointer) -> Int
285+
@_extern(c, "swift_weakRetainCount") @usableFromInline
286+
internal func _swift_weakRetainCount(_: UnsafeMutableRawPointer) -> Int
287+
271288
// Utilities to get refcount(s) of class objects.
272-
@_silgen_name("swift_retainCount")
273-
public func _getRetainCount(_ Value: AnyObject) -> UInt
274-
@_silgen_name("swift_unownedRetainCount")
275-
public func _getUnownedRetainCount(_ Value: AnyObject) -> UInt
276-
@_silgen_name("swift_weakRetainCount")
277-
public func _getWeakRetainCount(_ Value: AnyObject) -> UInt
289+
@backDeployed(before: SwiftStdlib 5.11)
290+
public func _getRetainCount(_ object: AnyObject) -> UInt {
291+
let count = _withHeapObject(of: object) { _swift_retainCount($0) }
292+
return UInt(bitPattern: count)
293+
}
294+
295+
@backDeployed(before: SwiftStdlib 5.11)
296+
public func _getUnownedRetainCount(_ object: AnyObject) -> UInt {
297+
let count = _withHeapObject(of: object) { _swift_unownedRetainCount($0) }
298+
return UInt(bitPattern: count)
299+
}
300+
301+
@backDeployed(before: SwiftStdlib 5.11)
302+
public func _getWeakRetainCount(_ object: AnyObject) -> UInt {
303+
let count = _withHeapObject(of: object) { _swift_weakRetainCount($0) }
304+
return UInt(bitPattern: count)
305+
}

test/api-digester/stability-stdlib-abi-without-asserts.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ Func _prespecialize() is a new API without @available attribute
5151
Func _stdlib_isOSVersionAtLeastOrVariantVersionAtLeast(_:_:_:_:_:_:) is a new API without @available attribute
5252
Func _diagnoseUnavailableCodeReached() is a new API without @available attribute
5353

54+
// These functions are not actually added to the ABI, but they had been a part of
55+
// the ABI exposed by the runtime library, so this is not breakage.
56+
// They are now referenced by @_extern(c) declarations in the standard library, but
57+
// api-digester cannot match them with the baseline symbols in the baseline runtime
58+
// library, which were not exposed by the baseline stdlib module.
59+
Func _swift_retainCount(_:) is a new API without @available attribute
60+
Func _swift_unownedRetainCount(_:) is a new API without @available attribute
61+
Func _swift_weakRetainCount(_:) is a new API without @available attribute
62+
5463
Func Collection.removingSubranges(_:) has been removed
5564
Func Collection.subranges(of:) has been removed
5665
Func Collection.subranges(where:) has been removed

0 commit comments

Comments
 (0)