Closed hmelder closed 6 months ago
Same problem with RISC-V:
Additionally, floating-point arguments to variadic functions (except those that are explicitly named in the parameter list) are passed in integer registers.
18.2 RVG Calling Convention: https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf
This is only the case, when we manually call objc_msgSend. The generated code by clang treats objc_msgSend
as a non-variadic function.
It should always be called as non-variadic, you are required to cast it to the right type before calling.
The only time it should be called with the variadic calling convention is when the underlying method is variadic (e.g. arrayWithObjects:. We might need to add a test for that case.
It should always be called as non-variadic, you are required to cast it to the right type before calling.
That makes sense. Clang emits this too, when Objective-C code is rewritten to C++. I have not heard about this before.
It used to be in the language spec, not sure if Apple has kept it up to date. It was really important on platforms like SPARC, where getting the calling convention wrong would land you on a trap instruction. It's also important with Apple's version of the AArch64 ABI (where there's even more divergence between variadic and non-variadic calling conventions).
According to the AAPCS64 (AArch64 Procedure Call Standard):
See: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#:~:text=The%20rules%20here,converted%20to%20int.
Assume we have an
IMP
that takes afloat
as an argument. AsIMP
is a non-variadic function, the argument is passed in s0 (the lower 32-bit of v0), if it were to be called directly.When calling
objc_msgSend
for the Selector that leads to IMP, we pass the float in d0 (64-vit of v0). Theobjc_msgSend
implementation now tail-calls IMP with arguments in d0.