WebAssembly Support for OCaml: Introducing Wasm_of_Ocamlby Isabella Leandersson on Nov 1st, 2023
OCaml is constantly evolving. Developers collaborate to bring support for new features, improve workflows, and resolve pain points. To this end, the OCaml-Wasm GitHub organisation was recently established. Its goal is to bring WebAssembly support to OCaml.
WebAssembly, more commonly known as Wasm, is a low-level virtual machine that is both language- and platform-independent. In essence, Wasm is a binary format designed as a portable compilation target for programming languages. It enables deployment on a variety of platforms like web browsers, cloud, blockchain, and mobile.
Wasm makes no assumptions about language features or operations. As a result, Wasm is technically compatible with any programming language since its code can be interpreted as virtual hardware.
You might be wondering why you should care about Wasm support in OCaml. Well, Wasm has several advantages that make it popular with developers and organisations all over the world. Briefly, they are:
- Security: Wasm has a fully formalised type system and semantics. Wasm engines validate (type check) code and execute it in a memory-safe, isolated environment known as a sandbox. Wasm code performs predictably, with no crashes or unexpected actions, and within restrictions that limit access to the user's local resources.
- Speed: Wasm can take advantage of language implementation techniques like just-in-time (JIT) and ahead-of-time (AOT) compilation, alongside other capabilities common to contemporary hardware. It allows Wasm code to perform at near-native code levels of performance.
- Openness: Wasm is an open standard, meaning that it and all its documentation are openly and freely accessible to developers. Anyone can influence the evolution of Wasm by participating in the W3C Community Group.
- Language Neutrality: As previously mentioned Wasm works by abstracting hardware and doesn't make any assumptions about language features. It makes Wasm language-neutral, meaning it does not privilege any language, programming, or object model above another.
- Platform Independence: Wasm can be built and deployed on different platforms regardless of the OS, hardware, or programming language as long as the Wasm virtual machine is supported.
- Browser Support: Wasm is supported by all major browsers including Chrome, Mozilla Firefox, and Safari.
Currently, several companies and organisations use Wasm. For example, the cross-platform game engine Unity is using Wasm to reduce code size, manage memory, and improve load times. Fastly also uses Wasm. Fastly is a company that offers numerous Network Services for their Compute@Edge platform. Figma, an online collaborative design platform, also uses Wasm to cut their loading times. These are just a few examples of how Wasm is being used to great effect, illustrating the potential and desirability of Wasm.
That is all about to change as there are multiple proposals to bring new features to Wasm. The most relevant to OCaml is the Garbage Collection proposal which will provide heap-allocated data structures that are garbage collected and can directly contain references to foreign values. It is being implemented together with the typed function references proposal. They are expected to ship in November on both Chrome and Firefox. Another proposal includes support for tail calls. These forward-looking features will make Wasm applicable for an even wider range of uses.
There are two main prongs of the effort at the moment. One is
wasocaml, an experimental compiler backend that targets Wasm using the Flambda intermediate representation of the OCaml compiler. Engineers at OCamlPro are behind this approach and you can check out the repo here.
It is relevant to mention two other methods created to run OCaml programs using Wasm runtimes. These methods are appropriate for use cases where the speed of generated code is less of a concern, and differ from
wasm_of_ocaml by being mainly intended for server-side applications. Both
wasicaml are ports of the OCaml bytecode interpreter to Wasm. Wasicaml also has a compiler mode that parses bytecode executable and translates it to Wasm in a similar way to
wasm_of_ocaml, but simpler.
wasm_of_ocaml was and continues to be developed mainly by Tarides engineers, this article will focus on this tool. To get more information about
wasocaml, visit OCamlPro's blog.
As previously mentioned,
wasm_of_ocaml is designed to use OCaml bytecode as its input to emit Wasm code. It uses the same approach as the popular
wasm_of_ocaml also aims to make it possible to compile programs made for
wasm_of_ocaml with minimal changes. Both
wasm_of_ocaml are the brainchildren of Jérôme Vouillon, currently a principal software engineer at Tarides.
Recently, there have been significant strides towards implementing runtime bindings in
wasm_of_ocaml. The toolchain can now compile
ocamlc into Wasm and run the Bonsai tests and examples. The first benchmarks are encouraging, with compiled programs typically running an average of 30% faster than their
With a large part of the OCaml runtime already implemented, there are several additional PRs in the works to get Wasm supported in
Brr. On the whole,
wasm_of_ocaml is getting impressively close to completion thanks to the sustained efforts of Jérôme.
The process is not entirely without challenges, and some adaptations have had to be made for OCaml and Wasm to be compatible. For example, although
wasm_of_ocaml builds on the
wasm_of_ocaml adds a closure conversion phase to eliminate closures and instead target Wasm's closed functions.
There is also the need to consider support for effects, a feature new to OCaml since the OCaml 5 release. Algebraic effects, which permit non-local control flow in a program and are useful for implementing concurrency, are supported in
js_of_ocaml through a static analysis guided selective Continuation-Passing Style (CPS) transformation.
Wasm_of_ocaml supports effect handlers in two ways, one of which is via a CPS transformation like in
It is incredibly helpful for the team to get feedback from people who try
wasm_of_ocaml. You can contribute to the effort on the repo, which also has instructions for how to install and use the toolchain.
Don't hesitate to contact us if you have any questions or comments. The Discuss Forum is another great place to ask questions or share your thoughts. We look forward to seeing you around the OCaml community!