You can already do this with JNI. How does WASM improve things? In both cases (WASM or native code) you get the overhead of two runtimes and the hassle of converting data types, don't you?
You can already do this with JNI. How does WASM improve things? In both cases (WASM or native code) you get the overhead of two runtimes and the hassle of converting data types, don't you?
It's often the case that people choose languages based on the availability of the libraries written in those languages. The goal of non-browser WASM is to get rid of that and to minimize the friction of inter-language communication, so you don't have to rewrite it in $language. WASM is not tied to any language (like the JNI).
Here's an example where performance wouldn't matter as much:
Let's say I'm the author of a programming language and I want to add a db layer to my standard lib.
Via WASM I can use a working backend while I'm protyping the API for my db layer. If the performance isn't fast enough I can start implementing my own "native" version with feature parity.
I can then use some of the tests from the original library (via WASM) to make sure my implementation has feature parity to the original.
For performance, we ship three compiler backends: LLVM (fast execution, but slowest compilation), cranelift and singlepass (our own compiler, very fast compilation and you can compile untrusted code - but slowest execution). There is a slowdown, but the goal is to keep that at a minimum (proper performance tracking is on the bucket list). We are pre-compiling the python.wasm (which was already pre-optimized when the compilation to WASM happened) with LLVM, so you should get assembly that is very close to the native execution, with the exception of the necessary VM overhead. The goal is to make it so that the interoperability gains are worth the performance hit.
A bit of a rant, but there's nothing specific to WebAssembly about this.
Whether you're using WebAssembly or native code:
- The basic interface you get between caller and callee is a low-level calling convention, where essentially all you have are integers (which can be pointers), and any higher-level data structures need to be built out of that.
- A slightly higher-level interface is the C ABI; many languages support exporting and consuming APIs using the C ABI, but it can be frustratingly low-level.
- To provide an even higher-level interface, there are bindings generators, which could in principle either be designed as direct language-to-language bridges, or as a single common standard that any language can provide and consume APIs for.
The WebAssembly Component Model standard and the wit-bindgen tool are an example of the latter. They happen to be defined specifically for WebAssembly rather than generically for any architecture. If they become ubiquitous at some point in the future like they're supposed to, then WebAssembly will have an advantage when it comes to high-level bindings, not because of any fundamental technical aspect of WebAssembly itself, but just because people building these bindings on top of WebAssembly have more motivation and more consensus. (WebAssembly does have a technical advantage when it comes to sandboxing between components, but this is relatively unimportant for most use cases.)
But for now, wit-bindgen isn't ubiquitous, and most of those languages don't even work in WebAssembly yet…
Sandboxing also goes a long way towards containing the supply chain security issues that every language is susceptible to.
Native code might assume that code it calls won’t misbehave in these ways, but wasm guarantees it, and that allows wasm VMs which run untrusted code to have more efficient implementations.
Small remark: There is nothing like "the C ABI".
https://faultlore.com/blah/c-isnt-a-language/#c-doesnt-actua...
What you're saying is completely impossible right now AFIK…
Why not? You still need operations like "create object", "look up method", "invoke method", "convert type between languages" etc. WASM doesn't have any kind of polyglot layer that does this automatically.
Ironically, Graal/Truffle actually do. There's a whole infrastructure where languages can expose their structures, functions, objects etc via a language-neutral in-process protocol and the compiler understands how to optimize across the transitions, so you can actually load JavaScript into Python and do those sorts of things:
https://www.graalvm.org/latest/reference-manual/polyglot-pro...
The API you use to import code from other languages is standardized, so it doesn't matter what language the other side is using. But WASM doesn't do anything like that.
"with wasm, you just pull in csharp.wasm, python.wasm and java.wasm, so it's just one binding layer, not three"
Are these real files/projects you're talking about here? If so, can you show us these things? Because WASM seems far too low level to define a Truffle-like polyglot layer let alone make it fast.
> Most languages have a way to run on a wasm engine
But it is basically useless for managed languages that as of yet has to bring their runtimes as well.