In what order do I need to return multiple values in order to return this enum in registers? (I know that it is exactly 16 bytes in size when aligned)
#[repr(C, u8)]
enum Trampoline {
Ret(Value) = 0,
Throw(Value),
TailCall,
}
@Adel Prokurov #[repr(C)]
types don't get passed in registers unless the C ABI says so. In your case the C ABI on at least x86_64 says to pass it on the stack so it will be passed on the stack. You could split it into two u64 you pass manually if you really need. Or if the exact abi doesn't matter you can remove the #[repr]
in which case it will be passed in two registers provided that you are using the rust calling convention. (no guarantees, but it just so happens to be the case right now)
By the way do you want this for perf or abi reasons?
bjorn3 said:
By the way do you want this for perf or abi reasons?
I want it for Scheme -> Rust calls that are not in tail position. To do Scheme -> Rust call I first invoke a thunk that checks arity of a procedure and the type of procedure and then actually invokes the code, it is not done in a tail call because my thunk signature is like this:
fn(vm: &mut Vm, proc: Value, argc: usize, tag: &mut u8) -> Value { ... }
proc
actually stores the fn(...) -> Trampoline
pointer. On the return I update tag
ref to trampoline tag and because of this tail call is not done. So it is more of a performance thing
For returning into rust code with multiple return values I did recommend creating a trampoline which writes the values to a location specified as pointer argument. This is also what Wasmtime does for handling multiple return values.
Yea that is what I am doing right now but then thunk written in Rust does not perform tail call, probably I'll stick to it then and just will wait for return_call
support in Cranelift to rewrite thunks in Cranelift IR :D
Last updated: Dec 23 2024 at 12:05 UTC