it's implemented as something like fn(clos: c_void, env: &MyStruct) { env->a++; env->a }: that is, the structure is behind a pointer (we optimize away all loads from clos, which is the closed environment).
We want to tell the lifter that the argument is a JitValue::Ref(JitValue::Struct(vec![JitValue::Value, JitValue::Value, JitValue::Value]), mem::size_of<MyStruct>()) - that is, that it's a pointer to a struct made up of some symbolic value members. This would allow us to do partial application and optimization with the struct's members instead of having to emit Cranelift load/stores for everything.
We might want to annotate the struct MyStruct with a #[derive(JitInput)] or something? Dunno.
Related to #2, but on the lifting side: if we have a closure like so:
it's implemented as something like
fn(clos: c_void, env: &MyStruct) { env->a++; env->a }
: that is, the structure is behind a pointer (we optimize away all loads fromclos
, which is the closed environment).We want to tell the lifter that the argument is a
JitValue::Ref(JitValue::Struct(vec![JitValue::Value, JitValue::Value, JitValue::Value]), mem::size_of<MyStruct>())
- that is, that it's a pointer to a struct made up of some symbolic value members. This would allow us to do partial application and optimization with the struct's members instead of having to emit Cranelift load/stores for everything.We might want to annotate the
struct MyStruct
with a#[derive(JitInput)]
or something? Dunno.