I'm trying to understand how I can direct the host to some piece of memory the guest has written some data to (both are implemented in Rust). I understand that a guest can't have direct access to the host memory, and all it knows is the offset of the memory it is assigned, but how can I go from doing something like Vec::with_capacity(10)
, to having an offset integer that I can pass to the host for it to use in a memory.data_unchecked()[offset + len]
call? Basically, I know how to pass len (10), but I don't know how to get the offset u32 after allocating the memory in the guest.
(assuming both sides are written in rust) was Vec::with_capacity(10)
run on the wasm/guest side? if yes, then wasm's v.as_ptr()
shall give you offset
for host
wasm pointer is an int32 and direct offset in host's allocated memory
Ah interesting. Thanks @Yury Delendik. So something like this should work (some psuedo code): https://gist.github.com/rust-play/e790f19505cc19d2b1330f68f2e7321c?
not so fast :) I bet the CString::new("foo")
will be destroyed after run
call
but yeah, you'll get the offset
Hmm, yeah, even with mem::forget
I still get a NulError
because I didn't pass the length. And since I can only return a single value from the guest function, I guess that means the right approach is for the guest to call a host function that takes the offset and length as an argument, right?
there is also mem.data_ptr()
which might be more intuitive in your case
Thanks @Yury Delendik. One more question: how can I add the offset to the ptr from mem.data_ptr()
to get the memory location of the string written by the guest? It seems data_ptr().add(offset as usize)
won't work, as I get an empty string when I print the cstr from that pointer.
.add()
is right, so is .offset()
. I'm skeptical about guest's code. Try: { static HELLO: &[u8] = b"Hello, world!\x00"; HELLO.as_ptr() as i32 }
but normally, you would write something like fn run() -> *const u8 {
in the function signature -- you don't have to cast that to i32
Yep, that worked! I wonder why mem::forget
doesn't work in this case though.
yep, be careful, rust can trick you by moving and dropping your stuff
Returning *const u8
won't work in this case, will it? Since WasmTy
isn't implemented for that type?
on host side... for guest side it is fine
Aha, I see. Thanks again @Yury Delendik, I'm off to playing some more with this. It's definitely a lot of fun to work with.
Quick update for anyone who reads this in the future, mem::forget
does work (and so does ManuallyDrop
), I was erroneously dropping the ptr instead of the value itself.
Last updated: Dec 23 2024 at 13:07 UTC