Stream: cranelift

Topic: How to implement JIT that returns a tuple?


view this post on Zulip Hanif Ariffin (May 04 2025 at 05:41):

Hi, I am new to cranelift and pretty much all this stuff.

I am trying to extend RustPython's JIT compiler to support returning tuple

def hello():
   return 1, 2

This is how its currently being done https://github.com/hbina/RustPython/blob/29d014a0e1343b0a4d2b12a6755c9662ba38d484/jit/src/lib.rs#L154-L162

Is tuple considered a pointer to an anonymous struct?

A Python Interpreter written in Rust. Contribute to hbina/RustPython development by creating an account on GitHub.

view this post on Zulip bjorn3 (May 04 2025 at 09:27):

The easiest method is to pass a pointer argument where the return value can be written. This is also how native ABIs handle this when the return value doesn't fit in return value registers.

view this post on Zulip Hanif Ariffin (May 04 2025 at 15:10):

Oh my god this gets so much more complicated than I thought
Tuples can be arbitrarily deep, so I have to somehow represent (x,y,(x,(x,(x,y)))
The problem is that the type signature is flat, so I have to maintain a mapping to recover back the tuple structure

view this post on Zulip bjorn3 (May 04 2025 at 15:43):

I would recommend not using multiple return values to represent nested or large tuples. Cranelift will lower them to passing a return value pointer anyway and may stop supporting them at all in the future.

view this post on Zulip Hanif Ariffin (May 04 2025 at 15:51):

Do you have an example snippet of such a thing i.e. creating a product type?
I only see a straightforward type in the list here... https://docs.rs/cranelift-codegen/0.119.0/cranelift_codegen/ir/types/struct.Type.html

view this post on Zulip bjorn3 (May 04 2025 at 15:56):

Pointers in Cranelift are represented as pointer sized integers. So for example I64 on a 64bit system. You can use the pointer_type() method of TargetFrontendConfig (obtained using eg module.target_config()) to get this type. Then on the caller side you did create a stack slot with the size of the tuple, use stack_addr to get a pointer to it (the type argument is the pointer type you previously obtained) And then inside the callee you did use store on the passed in pointer with manually calculated field offsets.

view this post on Zulip bjorn3 (May 04 2025 at 15:57):

Cranelift doesn't have any builtin support for non-primitive types. Rather it provides all the building blocks to emulate them yourself like would happen at the machine code level anyway.

view this post on Zulip Hanif Ariffin (May 04 2025 at 16:08):

Hmm, I see, I can see how to implement this now but this is going to take a lot more work than I thought
I think the code needs a bit more structure now so I am gonna have to work on that first
Thanks a lot for the tips!


Last updated: Dec 06 2025 at 07:03 UTC