Stream: cranelift

Topic: returning values to rust


view this post on Zulip PROMETHIA (Jan 14 2023 at 21:54):

Does anyone know more about how rust <-> JIT'd CLIF interop works?
I know it's possible to return values from CLIF to rust, but:

Slightly unrelated question: will excessive Variables from cranelift_frontend be allocated on the stack when necessary?

I may have a lot more questions, I've been trying to answer them myself but it's difficult to get much information in some places.

view this post on Zulip bjorn3 (Jan 15 2023 at 00:24):

  1. This depends on the abi. I would not recommend using multiple return values on an FFI boundary.
  2. You can pass a pointer as argument where the return value should be written. This also what most ABI's internally do.
  3. Each one has different semantics. For the StructReturn one specificially, when applied to a return pointer (like in my answer number 2) it makes it match the C ABI for returning structs.
  4. Yes, but you have to use extern "C" like all interaction with the jitted code. The default rust abi is unstable. You can use the call_indirect clif instruction.

For the last question, the register allocator will spill values to the stack if necessary.

view this post on Zulip PROMETHIA (Jan 15 2023 at 00:35):

Ah, great. That mostly lines up with what I was thinking. I'm still confused about the StructReturn/StructArgument ones though, what do you mean by "matches the C ABI for returning structs"? I thought it's just passing around a pointer, are they somehow passing it around in a more complex way or have some kind of further restrictions on what they can do with the pointer?

view this post on Zulip bjorn3 (Jan 15 2023 at 10:04):

For returning structs, most ABI's pass in a pointer. Some ABI's however don't pass it in a regular argument register, but pass it in one dedicated for this purpose. StructReturn ensures that this register is used on targets that have a dedicated return pointer register.

For passing in structs, ABI's generally either expand it into multiple register values (you have to do this yourself) or if that isn't possible due to for example the size they often pass it on a specific place on the stack. StructArgument copies the value pointed to by the pointer argument to the right place on the stack. (or just passes it as pointer on ABI's that pass using pointers rather than specific stack offsets) On the callee side the StructArgument pointer will point to the stack location where the argument was copied rather than the original pointer that was pass to the call instruction on the callers side.


Last updated: Dec 23 2024 at 12:05 UTC