Properly handle indirect arguments for external C functions #11189
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #9533
From the description of #9533 and linked issues I gather the C ABI argument passing was ported from Rust, which has the concept of indirect argument passing. Reading the ABI specs for ARM64 (see section 5.4.2, B-3) and for Windows 64 x86, and analyzing the LLVM IR code generated by Clang, it's clear that an indirect argument should be passed as a pointer to caller-allocated memory. This is different than passing an argument on the stack, which seems to be the default in Linux and Darwin on x86: this is handled by LLVM when the argument is annotated with
byval
, and the generated assembly code pushes the value on the stack instead of passing it on a register.This PR fixes two problems, one on the caller and one on the callee:
The change in fun.cr is pretty ugly, but I don't currently know what are all the cases it should cover and it's not immediately obvious from the code. The method
create_local_copy_of_arg
is doing way too much already IMHO.