I'm using Wasmtime to execute a WASM module within my rust application.
To access WASM linear memory, I use wasmtime Memory and the function read() to read the results of the WASM module from it's linear memory. Read takes a &mut [u8] buffer to write the bytes to. That works great if I pass a byte array with fixed length like [0u8; 16], but since I don't know the length of the result I wish to define the length of the buffer at runtime (my wasm-module return length to the rust caller prior to reading memory). Passing a Vec<u8> doesnt work - it's simply never filled with any data but just returns empty even though it compiles.
How can I size a byte array at runtime?
I've come up with a hacky workaround that actually does work:
let mut buf = String::from_utf8(vec![b'X'; len])?;
let mut buf = unsafe { buf.as_bytes_mut() };
Using that the buffer length is always correct - but just feels wrong Is there a better way??
Wasmtime Memory.read() is documented here - for reference:
Ah, I see the issue now - Vec::<u8>::with_capacity(len) creates a Vec with the capacity in memory to store len elements, but zero elements actually stored.
When you turn this into a slice to pass to read, you get an empty slice, and so read isn't able to actually write anything into it (bear in mind that a &mut [u8] cannot be resized, you need the Vec to do that).
You need to create a Vec that is already initialized to the length you want to fill:
let mut buf = vec![0; len];
if let Some(m) = memory {
m.read(&mut store, ptr, &mut buf)?;
}