A May update on wasm_of_ocaml

Spring is over us and several months have passed since we last shared an update on WebAssembly compilation.

Introduction

wasm_of_ocaml is a compiler from OCaml bytecode to WebAssembly, similar to js_of_ocaml from which it was forked. wasm_of_ocaml offers a functional, almost drop-in replacement for js_of_ocaml - with better performance.

For now, the compiler targets a JavaScript-hosted WebAssembly engine. The produced code furthermore requires the following Wasm extensions to run:

Platform support

wasm_of_ocaml news

Since the last update in December

  • Jérôme gave a talk about wasm_of_ocaml at the INRIA Cambium seminar - slides available here
  • Olivier Nicole joined the wasm_of_ocaml effort
  • Jérôme and Olivier visited Jane Street to help them adopt wasm_of_ocaml

Notable features

  • Sourcemap support was added ocaml-wasm/wasm_of_ocaml#27
  • A first implementation of separate compilation was completed ocaml-wasm/wasm_of_ocaml#36
    • One can compile cmo and cma files, producing intermediate archive files
    • Then the files can be linked together: relevant Wasm modules are put in a directory, and JavaScript code is generated to load them and link them together
  • Store long-lived toplevel values into globals ocaml-wasm/wasm_of_ocaml#30
    • The initialization code produced by wasm_of_ocaml can be large and contain a large number of variables. This is challenging to both binaryen tools and the Wasm engines. The problem can be alleviated by storing long-lived toplevel values into global variables. As an side benefit, many closures can be statically allocated (since their free variables are now stored in globals), which again can provide performance improvements in the remaining parts of the code.
  • Tuple syntax changes ocaml-wasm/wasm_of_ocaml#31
    • Prepared the switch to the new version of binaryen, which has small syntax changes
  • Use the JS String Builtins proposal for string conversions when available ocaml-wasm/wasm_of_ocaml#33
  • Improve the WAT (Wasm text format) output to be more readable ocaml-wasm/wasm_of_ocaml#34
    • Name local variables (they were just numbered) and use shorter names (the names used to be systematically suffixed to ensure they were unique).

Other features and fixes

Binaryen fixes

  • PR: wasm-merge: check that the types of imports and exports match. WebAssembly/binaryen#6437
    • Improved binaryen’s linker to check that the types of imports and exports match. Found a type mismatch in the wasm_of_ocaml runtime this way.
  • PR: Fixes regarding explicit names WebAssembly/binaryen#6466
    • The name of some module components were lost during module linking
  • PR: Fix writing of data segment names in name section WebAssembly/binaryen#6462
    • Binaryen could actually generate a malformed name section
12 Likes

Thanks for the slides.

@vouillon, slide 36 came out unintuitive to me. I would have expected js_of_ocaml’s textual encoding of OCaml into JavaScript to take more space than wasm’s binary encoding. Is it due the difference in abstraction levels of the target languages ?

1 Like

I think this is because Wasm is lower level, indeed. In particular, when allocating a closure, one needs to list all its free variables, while this is implicit in JavaScript.

If you think about it, JavaScript is rather compact. Allocating an array is [e1,..., en]; a function call is f(e1,...,en). And the comma is so common that it is likely to take less than one byte once compressed. It seems hard to do better.

4 Likes