pub fn read_bytes(
    memory: &Memory,
    guest_ptr: GuestPtr,
    len: Len
) -> Result<Vec<u8>, WasmError>
Expand description

read a slice of bytes from the guest in a safe-ish way

a naive approach would look like this:

let view: MemoryView<u8> = ctx.memory(0).view();
unsafe {
    std::slice::from_raw_parts::<u8>(
        view.as_ptr().add(guest_ptr as usize) as _,
        len as _
    )
}.to_vec()

this is similar to the naive write_slice approach and has similar problems @see write_slice()

a better approach is to use an immutable deref from a WasmPtr, which checks against memory bounds for the guest, and map over the whole thing to a Vec

this does the inverse of write_bytes to read a vector of arbitrary length given only a single GuestPtr value

it reads the first 4 u8 bytes at the GuestPtr position and interprets them as a single u32 value representing a Len which is the length of the return Vec to read at position GuestPtr + 4

using the example in write_bytes(), if we had written

[ 3_u8, 0_u8, 0_u8, 0_u8, 1_u8, 2_u8, 3_u8 ]

and this returned a GuestPtr to 5678 then we would read it back by taking the first 4 bytes at 5678 which would be [ 3_u8, 0_u8, 0_u8, 0_u8 ] which we interpret as the length 3_u32.

we then read the length 3 bytes from position 5682 (ptr + 4) to get our originally written bytes of [ 1_u8, 2_u8, 3_u8 ].