Search code examples
assemblywebassembly

How is WebAssembly cross-platform when Assembly is not?


My understanding

  • WebAssembly is like Assembly, except that
    • it runs cross-platform
    • it runs isolated
    • it runs on browsers
  • But how is WASM fast and cross-platform simultaneously?
    • Does it pack multiple precompiled binary executables for multiple CPU vendors, like Apple's Universal Binary?
    • But then whenever a new type of CPU gets announced, they wouldn't be able to run existing WASMs
  • WebAssembly's runtime environments (RE) are low-level virtual stack machines (akin to JVM or Flash VM)
  • Seems like WASM is closer to intermediate Java Byte Code instead of the genuinely low-level Assembly.
    • But then, why is it faster?
    • JS Interpreter can skip the parsing
    • It can ship in a much more compact file format

Now my questions.

Question

  • Is WASM only creating intermediate bytecodes from existing C/C++/Rust codes, just like Java JVM, not compiling to bare metal?
  • What is the relationship between WebAssembly and Assembly?
  • Does WASM borrow any idea, technology, or philosophy from Assembly?

Solution

  • As an approximation, you can think of WebAssembly as defining its own CPU with its own instructions. It has its own binary encoding, so "0x6A" means "pop two i32's from the top of the stack and add them, push the result on the top of the stack". You can read the full spec: https://webassembly.github.io/spec/core/bikeshed/

    "Why is it faster" is a complex issue, the short answer is that it was "well designed" by people who have a deep understanding of contemporary compiler technology and CPU design. When your browser receives WebAssembly it could interpret it one instruction at a time, but WAsm was designed so that you could compile it into native code quickly and get reasonably fast native CPU code.

    Is WASM only creating intermediate bytecodes from existing C/C++/Rust codes, just like Java JVM, not compiling to bare metal?

    It does not contain precompiled binaries for any particular real CPU.

    What is the relationship between WebAssembly and Assembly?

    A CPU only knows how to run instructions in its own assembly language, the "instruction set architecture". Therefore all other software must be converted to this first (or run through an interpreter which is itself a program that is converted to CPU instructions first). WebAssembly was designed to make the conversion to native assembly on real machines like x86, ARM and RISC-V easy.

    The relationship is that WAsm must be converted to CPU assembly, or run in an interpreter. Also, WebAssembly is enough like a real CPU that compilers which can already emit code for different CPUs could be extended to emit code for WAsm. This is why we can compile C and Rust to WebAssembly. It's reasonable to expect that any new programming language which can be compiled for a real CPU could also be compiled for WAsm.

    Does WASM borrow any idea, technology, or philosophy from Assembly?

    Sure. Assembly is an imperative programming language (instructions run one after the other), and so too with WAsm. Many actual CPUs define a notion of a stack that you can push/pop and WAsm uses a stack. Most CPUs have instructions like "add two 32-bit integers", and so does WAsm. Most CPUs have "branch" instructions, and so does "WAsm". Most CPUs have instructions to read and write memory at given byte addresses, and so does WAsm.