OCaml + WASM
This is a port of the OCaml runtime to the WebAssembly platform.
The core distribution includes ocamlrun
(compiled as ocamlrun.wasm
), and stubs for the native libraries str
, unix
, and threads
.
This allows running OCaml bytecode binaries in a WebAssembly container, including in a browser.
They were built using wasi-sdk, and depend on Wasmer-JS and wasi-kernel for POSIX-like headers and runtime.
The current version is compatible with wasi-sdk 11 and wasi-kernel 0.1.1.
To run a compiled bytecode file, create a wasi-kernel ExecCore
and pass the filename as an argument:
import { ExecCore } from 'wasi-kernel';
var core = new ExecCore({tty: true}),
td = new TextDecoder('utf-8');
core.tty.on('data', b => console.log(td.decode(b))); // to see the output
core.wasmFs.fs.writeFileSync('/my_program.bc', bytecode);
core.start('ocamlrun.wasm', ['ocamlrun', '/my_program.bc']);
Native libraries (str
, unix
, threads
, and others that you may have compiled to WASM) need to be pre-loaded prior to invoking start()
.
await core.proc.dyld.preload('dllcamlstr.so', 'dllcamlstr.wasm');
(This is using the low-level dynamic loader API; future versions of wasi-kernel may be able to read the dynamic library dependencies from the WASM binary itself.)
Building from Source
1 Configure a minimal OCaml with clang
.
CC=clang ./configure --disable-native-compiler --disable-ocamldoc --disable-debugger
2 Build bytecode executables ocaml
and ocamlc
, as well as the standard library.
make world
3 Set the path to wasi-sdk on your system (if not set, defaults to /opt/wasi-sdk
).
export WASI_SDK=/opt/wasi-sdk # or any other path
4 Setup wasi-kit
(from wasi-kernel) so that it is in your PATH
.
Either should work:
- Install globally —
npm i -g wasi-kernel@0.1.1-rc2
. - Install in project —
npm i
, then add$PWD/node_modules/.bin
toPATH
.
5 Build WASM runtime; notice that this overrides header files generated by configure
with preconfigured versions for WASM build.
make wasm
The last command also builds stubs for shared libraries str
, unix
, and threads
.
It uses wasi-sdk's version of clang
, but with --target wasm32-unknown-emscripten
,
since shared-library support in WASI is still incomplete.