Skip to content

Commit 0ea59b4

Browse files
kateinoigakukunlorentey
authored andcommitted
Fix calling convention mismatch for debugger utility functions
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. Co-authored-by: Karoy Lorentey <[email protected]>
1 parent a67b818 commit 0ea59b4

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 9999)
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 9999)
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 9999)
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)