4
votes

At present, Webassembly only supports a handful of parameter types, namely fixed sized integers and floating point numbers. This means that I can only define and export functions from my C/Rust modules that accept and return numeric values.

However, according to the Mozilla Developer Network, I can manipulate the module's memory from the host Javascript:

[M]emory created by JavaScript or in WebAssembly code will be accessible and mutable from both JavaScript and WebAssembly.

This sounds very promising--it indicates that I could designate part of the memory as a byte buffer in which to shuttle more complex data back and forth across the language barrier. Functions in my module could accept and return pointers (which are themselves i32, fixed size integers), thereby working within the current constraints.

Unfortunately, it is not clear how I should go about managing this memory. If I need to pass data to the Wasm process from JS, I need to write to the Memory object directly but won't know which regions in the Memory are free.

What's the safest strategy? Should I export a pair of malloc-and-free-style functions that give the JS a way to request memory before calls into Wasm? Or is there an established best practice?

1

1 Answers

3
votes

I think the easiest thing is to use Emscripten, and use its built-in malloc / free. Then export a function which, in C++, allocates the memory requested through that malloc / free, and returns the pointer. That way JavaScript can call into WebAssembly to get a usable memory region which isn't already used.

I've detailed how to share strings to / from JS / wasm in this answer, which has details on some of the above.

Note that pointers in WebAssembly aren't really a thing. C++ simply maps them to the Memory, which starts at 0. So when you index the ArrayBuffer you just need the pointer from C++, no extra mapping required.