Description
Previous ID | SR-15188 |
Radar | rdar://problem/83154000 |
Original Reporter | @kateinoigakukun |
Type | Improvement |
Additional Detail from JIRA
Votes | 1 |
Component/s | Compiler |
Labels | Improvement |
Assignee | @kateinoigakukun |
Priority | Medium |
md5: a717f3fd621f1634ebd1eeb736ab0650
Issue Description:
The current Swift implementation has 3 types of calling-convention mismatch in runtime, stdlib, and code emitted by the compiler.
These violations are one of the blockers of porting to WebAssembly because swiftcc and C-cc are not compatible on WebAssembly.
In our SwiftWasm fork, we applied a hacky patch to use the same calling convention for each function. However, it may break ABI on Darwin, so I want to ask compiler folks before submitting patches to the upstream.
The violations can be categorized into 4 types:
1. Defined as a C-cc in runtime but published as a Swift-cc public API in stdlib.
For example, `swift_retainCount` is declared and defined in runtime without explicit cc, so it's defined as a C-cc function. But it's published as a Swift-cc public API here in stdlib.
This means some external users can call the function assuming Swift-cc, but the actual implementation in runtime uses C-cc.
-
The decl of the function in runtime: https://github.com/apple/swift/blob/6e3548797503b4a2bbabcebf7ffd156bc1cac245/stdlib/public/SwiftShims/HeapObject.h#L89-L90
-
The definition in runtime: https://github.com/apple/swift/blob/6e3548797503b4a2bbabcebf7ffd156bc1cac245/stdlib/public/runtime/HeapObject.cpp#L442-L446
- The decl of the public API in stdlib: https://github.com/apple/swift/blob/6e3548797503b4a2bbabcebf7ffd156bc1cac245/stdlib/public/core/DebuggerSupport.swift#L268-L269
The other violating functions in the same way are:
- swift_retainCount, swift_unownedRetainCount, swift_weakRetainCount, _swift_getObjectRuntimeFunctionCounters, _swift_getGlobalRuntimeFunctionCounters, and other RuntimeInvocationsTracking things
2. Emitted as a C-cc from user code, but called as a Swift-cc by stdlib indirectly.
For example, `keypath_get_arg_layout` are emitted as a C-cc function by the compiler, but it's called as a Swift-cc function in the stdlib.
-
Compiler emits the function here: https://github.com/apple/swift/blob/6e3548797503b4a2bbabcebf7ffd156bc1cac245/lib/IRGen/GenKeyPath.cpp#L281-L283
-
stdlib calls the function here: https://github.com/apple/swift/blob/6e3548797503b4a2bbabcebf7ffd156bc1cac245/stdlib/public/core/KeyPath.swift#L863-L864
Other same cases:
- keypath_get_arg_layout, keypath_destroy, keypath_copy, keypath_arg_init
3. Defined as a C-cc in runtime, but called as a Swift-cc in stdlib
For example, `_isClassType` is mainly called by compiler-emitted code and defined as a C-cc function. But it's also called by stdlib.
The call-site of stdlib uses @_silgen_name to link the function, so it's called through swiftcc.
Fortunately, the API is not exposed from Swift stdlib, so no external user calls it as a Swift-cc.
4. Defined as a C-cc in runtime, but called as a Swift-cc by test binary
`swift_demangle` is defined as a C-cc function in runtime, but called as a Swift-cc function from test case.