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..?
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.
@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?
@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
@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.
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.
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!".
This is great, exactly what I was looking for. Thank you very much @Peter Huene
Last updated: Dec 23 2024 at 14:03 UTC