Can multiple Wasm modules interact with each other and share memory directly via functions?
Asked Answered
B

1

15

Is there a way to instantiate two Wasm modules, a and b such that a can call functions from b and also access the distinct memory from b? For example, let's say that a gets memory by calling an implementation of malloc in b that is exposed to a. This way, all useful memory comes from b. If so, how can it be done? More specifically, can this be done without additional overhead, and without interacting with JavaScript in-between these operations (except for the initialization step when instantiating the modules and setting imports/exports)? What are the performance characteristics of this sort of indirection and memory access, or is there no issue at all? In this case, I want to micro-optimize.

(I've read several pieces of documentation, but I can't find a clear answer. I think that in future versions of Wasm, there are plans for standardized dynamic linking that would help, but we're not there yet.)

Bradeord answered 14/1, 2020 at 3:26 Comment(0)
L
14

Is there a way to instantiate two WASM modules, a and b such that a can call functions from b

Yes, you can instantiate module b exporting one of its functions, then instantiate a importing that function so that the two can interact. However, this is not going to be as fast as one WebAssembly function calling another as the call is going via the host environment.

and also access the distinct memory from b

Yes, once again, this is possible. Linear memory can be shared between a WebAssembly module and its host, and can also be shared between two modules.

can this be done without additional overhead, and without interacting with JavaScript in-between these operations

As iterates above, no, it cannot currently be done without additional overhead.

This will change in the future as the WebAssembly specification is enhanced and matures. One challenge involved in usefully communicating directly between two WebAssembly modules is understanding the API each exposes. WebAssembly is a compilation target, and different source languages (C++, Rust) encode types in different ways — this significantly limits inter-module communication.

An important stepping stone towards this is Interface Types, which encodes the API specification for a module / function. Once this has been implemented, direct communication between WebAssembly modules should be quite possible.

Lying answered 14/1, 2020 at 6:25 Comment(6)
Tell me if I am wrong, but as of MVP each module has only one linear memory. Then how can two modules share the same memory without dangerously running two runtime within the same memory?Surname
Yes, you are correct - which does significantly limit the types of application that can share memory. Certainly if you use linear memory for runtime state, this is going to be problematic. Here's a pretty trivial example that does show this approach working blog.scottlogic.com/2019/07/15/multithreaded-webassembly.htmlLying
Currently only one memory object can be used by an WASM module but that will be changed in future.Borak
That’s too bad. It looks like I’ll need to wait who knows how long until dynamic linking is implemented: github.com/WebAssembly/tool-conventions/blob/master/…Bradeord
Wait, why is there s jump to JavaScript? Couldn’t the modules import/export to each other at init time? —or are those imports/exports still doing an implicit hop?Bradeord
maybe there is a way to bind two wasm modules into a single composite wasm module before loading into the runtime/browser?Vitiligo

© 2022 - 2024 — McMap. All rights reserved.