Search code examples
javascriptwebassemblydynamic-linkingemscripten

How does WebAssembly.Global facilliate dynamic linking?


The following description is the introduction paragraph for WebAssembly.Global on MDN:

A WebAssembly.Global object represents a global variable instance, accessible from both JavaScript and importable/exportable across one or more WebAssembly.Module instances. This allows dynamic linking of multiple modules.

I am trying to understand how WebAssembly.Global facilitates the dynamic linking of multiple modules. Initially, I thought this was related to multi-threading and that WebAssembly.Global allowed multiple Web Workers running the same WebAssembly.Module to coordinate somehow. However, I no longer think this is the case since it turns out that WebAssembly.Global is neither supported by structured clone algorithm nor is transferable, which I believe means it cannot be sent with postMessage.

The unstable ABI for dynamic linking mentions that WebAssembly.Global can be/is used in Emscripten for env.__stack_pointer, env.__memory_base, and env.__table_base, but I am still unsure why these imports have to be WebAssembly.Globals.


Solution

  • In the MVP of WebAssembly it was not possible to import/export a mutable (non-constant) global (WebAssembly.Global). This was changed by the mutable-global proposal (that is already merged into the current version of WebAssembly). The rationale is explained in details in the linked page. In short:

    One could store the stack pointer into the linear memory (say at address #0) in a single-threaded setup, link several modules, and have a working program.

    This cannot be done safely in a multi-threaded setup, because each thread has to have a separate stack pointer. One could simulate that in different ways (that have their costs; also noted in the previously linked page), as for example use different addresses for each thread. However, it is far better, if a thread-local storage is available. There the globals come into play, as they act as a thread-local storage - each global has its own value for each thread.

    One cannot "play around" that by using "just a second unshared memory instance for each thread", because the multiple memories proposal is not (yet) operational.