Better way to size a byte array at runtime?

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 :confused: Is there a better way??

Wasmtime Memory.read() is documented here - for reference:

How are you creating and passing your Vec?

I was trying to do:

let mut buf = Vec::<u8>::with_capacity(len);
if let Some(m) = memory {
    m.read(&mut store, ptr, &mut buf)?;
}

Does this work?

let mut buf = Vec::<u8>::with_capacity(len);
if let Some(m) = memory {
    m.read(&mut store, ptr, buf.as_mut_slice())?;
}

&mut buf[..] might also do it.

Neither works :confused: I just keep getting empty strings back when it try. They both compile though

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)?;
}
3 Likes

That indeed works - perhaps it's how needs to be? It does look better to create a vector than a string, and it explains why my hack worked :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.