Stream: wasmtime

Topic: Workaround for *const u8


view this post on Zulip daubaris (Mar 16 2020 at 12:25):

Hello, is there a way to import a function to a module, which accepts pointers (e.g., fn signature(src: *const u8, dst: *const u8)? I know that there are only a few supported types for now, but I thought that there might be some workarounds..?

view this post on Zulip Peter Huene (Mar 16 2020 at 20:04):

Hi @daubaris . A host function cannot (currently) accept pointers for parameter types because a wasm module can't pass a valid pointer directly to the host. A wasm module can't know the physical addresses of its own memory, only offsets from the wasm memories it references. However, a host function can accept an offset and length pair as parameters that can be used, along with the Memory being referenced by the wasm module, to locate the actual physical location of the data and its extent.

view this post on Zulip daubaris (Mar 17 2020 at 10:05):

@Peter Huene Alright, understood. So, another question. I am trying to access the module memory from the host, but it seems that it is only possible with exported memory only. In the examples, I see that the wat modules are defined by hand and there one could specify the export statement. Is there a way to do it by writing a module in rust?

view this post on Zulip Peter Huene (Mar 17 2020 at 18:15):

@daubaris the Rust toolset should be exporting a memory named "memory" (at least until share nothing linking and interface types are implemented). you should be able to call Instance::get_export to get at the exported memory

view this post on Zulip daubaris (Mar 18 2020 at 07:41):

@Peter Huene yeah, missed that point in the docs. But then again, for the memory to contain some data, the module needs to have a data field, is that correct? (e.g., (data (i32.const <offset>) <data>)). Is there a way to specify from a rust module that it should add the data to the memory so that when it gets compiled it is reachable from the host? (It is clear how to do it in a hand written wat file, but not really when writing a rust module.

view this post on Zulip daubaris (Mar 18 2020 at 13:50):

I also tried doing an std::alloc inside a module, but it seems to return some random memory... Not really sure how to approach this.

view this post on Zulip Peter Huene (Mar 18 2020 at 18:22):

The Rust toolset would be the one generating data to initialize the memory with based on your program, so that's not something you would need to worry about.

For example:

extern { fn print(ptr: *const u8, len: i32); }

fn main() {
    let message = "Hello, world!";
    unsafe { print(message.as_ptr(), message.len() as i32); }
}

The toolset will create a data section for the string and the Rust code doesn't particularly care where it is in memory. From the perspective of the Rust program, it's passing the "address" of the string to the host function, but the host function receives an offset into the memory.

The import for the above looks like this:

(import "env" "print" (func $print (param i32 i32)))

In the host, memory.data_unchecked()[offset..offset+len] would be a byte slice of "Hello, world!".

view this post on Zulip daubaris (Mar 19 2020 at 07:11):

This is great, exactly what I was looking for. Thank you very much @Peter Huene


Last updated: Dec 23 2024 at 14:03 UTC