Continuing WebAssembly with Effect Handlers

Luna Phipps-Costin, Andreas Rossberg, Arjun Guha, Daan Leijen, Daniel Hillerström, KC Sivaramakrishnan, Matija Pretnar, and Sam Lindley
ACM SIGPLAN Conference on Object Oriented Programming, Systems, Languages and Applications (OOPSLA), 2023

WebAssembly (Wasm) is a low-level portable code format offering near native performance. It is intended as a compilation target for a wide variety of source languages. However, Wasm provides no direct support for non-local control flow features such as async/await, generators/iterators, lightweight threads, first-class continuations, etc. This means that compilers for source languages with such features must ceremoniously transform whole source programs in order to target Wasm.

We present WasmFX, an extension to Wasm which provides a universal target for non-local control features via \emph{effect handlers}, enabling compilers to translate such features directly into Wasm. Our extension is minimal and only adds three main instructions for creating, suspending, and resuming continuations. Moreover, our primitive instructions are type-safe providing typed continuations which are well-aligned with the design principles of Wasm whose stacks are typed.

We present a formal specification of WasmFX and show that the extension is sound. We have implemented WasmFX as an extension to the Wasm reference interpreter and also built a prototype WasmFX extension for Wasmtime, a production-grade Wasm engine, piggybacking on Wasmtime’s existing fibers API. The preliminary performance results for our prototype are encouraging, and we outline future plans to realise a native implementation.


  title = {Continuing {{WebAssembly}} with {{Effect Handlers}}},
  author = {{Phipps-Costin}, Luna and Rossberg, Andreas and Guha, Arjun and Leijen, Daan and Hillerstr{\"o}m, Daniel and Sivaramakrishnan, {\relax KC} and Pretnar, Matija and Lindley, Sam},
  year = {2023},
  journal = {Proceedings of the ACM on Programming Languages (PACMPL)},
  volume = {7},
  number = {OOPSLA}