The best WebAssembly runtime may be no runtime

Compiling WebAssembly modules back into C is presented as a way to run sandboxed, portable native code without a heavyweight runtime, enabling things like safer plugin systems and cross-platform binaries. Commenters compare this approach to earlier technologies such as Google Native Client, discuss how WASM’s constrained, well-specified model and tooling ecosystem make it attractive as a universal intermediate layer, and note Firefox’s existing use of this technique. They also highlight limitations and trade-offs: internal memory bugs in C remain, bounds checking and determinism can add overhead, integration with higher-level languages and the DOM is still awkward, and some see the broader WASM hype as outpacing its real-world language and platform support.

Wasm→C as “VM-less” sandboxing

  • Idea: compile C (or other languages) to WebAssembly, then transpile wasm to C and compile natively, inheriting wasm’s safety guarantees without a heavyweight runtime.
  • Firefox already does a variant (RLBox): wasm as an isolation boundary, then compiled back for speed.
  • w2c2 currently focuses on portability, not sandboxing; wasm2c aims for spec-conforming safety (bounds checks, type-safe indirect calls).

Security, bounds checking, and OS isolation

  • Some argue this is redundant: processes already get MMU-based isolation; classic seccomp-style sandboxes and containers can be as or more secure, with narrower syscall surfaces.
  • Others say embedded wasm is attractive where you can’t spin up processes/containers, and for plugin-like use-cases.
  • Wasm relies on linear memory with enforced bounds; production engines use guard pages + mprotect/fault handlers for near-zero-cost checks.
  • Important limitation: wasm does not fix logic bugs or intra-module memory corruption; untrusted modules are isolated from the host, but internal unsafe C remains unsafe.

NaCl, PNaCl, and how we got wasm

  • Native Client solved similar problems but was CPU-specific; PNaCl’s LLVM-bitcode wire format and glibc entanglement were messy.
  • asm.js emerged as a simpler alternative; wasm was a multi-vendor standardization of those lessons.
  • Some see NaCl’s failure as mostly technical; others emphasize political / ecosystem reasons.

C vs LLVM IR vs other IRs

  • Pro-C: C is stable, widely supported, and works as a portable IR, including on obscure OSes (e.g., Mac OS 9, odd CPUs).
  • Anti-C: C can’t express richer aliasing, sum types, or detailed UB handling; LLVM IR would be more expressive but is a moving target and version-tied.
  • View: wasm as a universal mid-layer (→wasm→C/anything) rather than bolting bounds checks into each C compiler.

Bytecode design and performance debates

  • Some criticize wasm’s stack-based design as adding complexity vs register-based IRs; others defend it as sufficient and battle-tested.
  • Disagreement over how “universal” wasm will remain as it grows (GC, threads, richer features) vs becoming opinionated like JVM/CLR.

Use cases, hype, and skepticism

  • Enthusiasts: wasm is a portable ISA for sandboxed plugins, serverless, embedded, cross-language libraries, and software preservation; network effects outweigh technical warts.
  • Skeptics: hype overstates novelty and security; existing bytecodes and VMs addressed similar goals for decades; wasm does not inherently solve web UI pain (HTML/CSS/JS complexity).
  • Some see wasm outside the browser (WASI, plugin systems, Cosmopolitan-style packaging) as more impactful than browser apps.

GC, high-level languages, and DOM

  • Wasm GC is expected to help managed languages, but concerns exist about mismatch with runtimes like Go/Java and lack of things like efficient stack switching.
  • Wasm cannot directly touch DOM/WebGPU; JS shims are required. Some want fully JS-free web apps; others argue DOM/Web APIs are inherently JS-shaped and the overhead is negligible relative to DOM costs.