From what I understand, WASM is basically the same idea (ish) as the JRE/JDK, a virtual machine that multiple languages can compile down to and talk to each other. What then, are the main differences?
There are many kinds of differences, but from a practical standpoint the two biggest are probably language support and browser support.
The Java VM doesn't support C like languages that don't use a GC, while wasm initially only supported those languages well. It has GC support too since recently, but using it is not mandatory the way it is with the Java VM. Java has also given up on attempting to support sandboxing, while wasm has a big focus on sandboxing as that is needed for safe usage of wasm in the browser.
in addition to linear memory vs. GC object model, there are significant differences in the complexity of the underlying VM. The JVM has a class loader mechanism, virtual method dispatch, interfaces, and all of that baked into the VM; the idea was to build a VM close to the semantic level of the source language. Wasm on the other hand has memory load/store and indirect call, and expects the guest to build everything from those; the idea was to build a VM close to the semantic level of machine code. (The one key departure is in first-class functions / a "protected stack", as @Dan Gohman likes to say, which has a bunch of implications for things like coroutines and exceptions.) The key corollaries from that are:
It's easier to build and secure an implementation of a low-level VM than a high-level VM. We see this in the fact that there are many independent Wasm implementations (and a motivated person can write a basic interpreter for Wasm in maybe a few days), but historically only a few practical JVMs, and really basically one today (OpenJDK). And, as others touched on above, Wasm's sandboxing has become a relatively validated trust boundary, used in practice in browsers and other untrusted-code scenarios (like function-as-a-service server-side code or like plugin systems), whereas no one relies on JVM-based security; the JVM is always stuffed in a container or machine VM.
It's a much more universal compilation target. Because it has one linear address space, it works perfectly fine without any tricks for C/C++/Rust/Zig/...; any systems language works just fine. First-class functions also give the Wasm environment a nailed-down C ABI, so interop between these systems languages is pretty easy. As others noted above, one can emulate a single address space on the JVM but aside from the emulation overhead, it will be very difficult to FFI to JVM-native languages in that design.
One more thing that actually has real value: the spec is tiny, and has a formal semantics; from this, we have formally verified interpreters and semantics we can use in other places to do formal verification. This has actually been used in practice to prove pieces of Wasm implementations correct, and the formally verified interpreter is used as a differential fuzz oracle.
Last updated: Dec 23 2024 at 13:07 UTC