How can I include a WebAssembly module from a C++ file?

Viewed 795

WebAssembly is a binary language that intends to, among other goals, break the barriers between programming languages.

Currently, it's easy enough to compile C++ code to WebAsm and include it into JavaScript code. There's even a proposal and a Webpack polyfill to make it as easy as import { foo } from 'bar.wasm'.

Moreover, WebAssembly supports wasm files that list their own dependencies, in the form of import declarations.

Is there some polyfill build tool that allows users to include a webasm module into a C++ compilation unit, in the process of compiling it to wasm? For example, let's say I have a Rust module that I want to use inside a C++ module, both of which I'm compiling to wasm. Is there a way to write code equivalent to this:

#include "node_modules/some_rust_utility/index.wasm"

int someCppFunction(const std::string& data) {
  return some_rust_utility::foobar(data.c_str());
}

and have it compile or not depending on whether foobar is defined with a matching type in some_rust_utility?


Note: I expect the answer to this question may change over time as WebAssembly support marches on. If you see this question years afterwards and the answer has changed, feel free to add an update.

1 Answers

It's currently impossible.

The situation might change at some point (which is why I'm not marking this question as solved), but so far the standard doesn't support wasm-to-wasm interoperability:

Since the WebAssembly spec does not define how import names are interpreted [...] the host environment can interpret the module name as a file path, a URL, a key in a fixed set of builtin modules or the host environment may invoke a user-defined hook to resolve the module name to one of these;

(eg it's implementation-defined)

As far as I know, currently a wasm module cannot directly import from another wasm module, instead it must use JavaScript as an intermediary.

Yes, the module defers this to the embedder (typically JS). As far as the module is concerned, it just knows that something is providing the import, but it doesn't know where it came from.

It's not a design goal for Wasm to guarantee seamless interop between multiple languages, or even multiple compilers of the same language (whether with memory or GC). That is in line with its low-level approach and a very conscious decision: such universal interop has often been promised but never worked out well in practice. Languages are just too different.

If multiple compilers or languages want to be able to interoperate, then they are of course free to define a common ABI on top of Wasm. That would be great! But Wasm itself doesn't need to prescribe it, no more than a CPU architecture does.

Given the above comment, it seems likely that language interoperability will remain a low priority for wasm contributors in the near future.

Related