I'm trying to build a runtime that passes callbacks to WASM modules. For example the host may open a connection to a remote API but does not want to pass full control of that API to a module and instead passes a callback that in some way validates the request before sending it.
I'm using wasmtime from Rust and the only example I can find uses Func::wrap
to define a function that can be placed in the store for the module to access. However I'm not sure if this is really a callback in that I'm not sure if it actually passes control back to the host
I really want something like a trap that says "okay, I've put the relevant data in the store, now I want to host to do something". Is this something that wasmtime supports? Or do I need to rethink the control flow by executing a module function to completion, pausing to do host stuff, then executing the next function?
There is no separate "callback" functionality per-se; a function defined via Func::wrap
does indeed call back into the host.
Thanks! I guess my next question is how IntoFunc
works because right now the compiler error doesn't give a lot of info. I tried creating a callback like this:
let api_get = Func::wrap(
&mut store,
|mut caller: Caller<'_, State>, id: u32| {
if validate(id) {
match api.get(id) {
Ok(data) => return Some(data),
_ => {}
};
}
return None
},
);
But this doesn't satisfy IntoFunc
for reasons unknown to me. How do I express that this function should accept parameters and return a value?
I believe the issue is that you're returning Option<_>
. You'll have to find a way to represent the return value as one (or more, if your guests support multi-value) primitive wasm types.
I've been playing with it a bit and I agree that is one of the issues. However what's confusing me is the closure signature. The compiler is not happy with |caller, id|
or |id, caller|
or |caller| |id|
.
Like this doesn't satisfy IntoFunc
:
Func::wrap::<State, u32, u32>(&mut store, |mut caller: Caller<'_, State>, id: u32| {
return 5
});
For that one I believe it would be <State, (u32,), u32>
Ok this works:
Func::wrap::<State, (u32,), u32>(&mut store, |id: u32| {
return 5
});
but then I lose the Caller context. For my purposes I may not need it, though.
Thanks again for your help Lann!
Last updated: Dec 23 2024 at 12:05 UTC