Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
vouillon committed Dec 13, 2024
1 parent 0b995da commit 339a9c1
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README_wasm_of_ocaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ opam install dune.3.17.0 wasm_of_ocaml-compiler
You may want to install additional packages. For instance:

```
opam install js_of_ocaml-ppx js_of_ocaml-lwt
opam install js_of_ocaml js_of_ocaml-ppx js_of_ocaml-lwt
```

## Usage
Expand Down
5 changes: 5 additions & 0 deletions manual/menu.wiki
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
==[[rev-bindings|Export OCaml code to JavaScript]]
==<<a_api subproject="js_of_ocaml" text="API"|index>>

=Wasm_of_ocaml - Reference Manual
==[[wasm_overview|Overview]]
==[[wasm_runtime|Binding a JS library]]
==<<a_api subproject="js_of_ocaml" text="API"|index>>

=Js_of_ocaml_lwt - Reference Manual
==[[lwt|Lwt support]]
==<<a_api subproject="js_of_ocaml-lwt" text="API"|index>>
Expand Down
49 changes: 49 additions & 0 deletions manual/wasm_overview.wiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
= Wasm_of_ocaml =

== Overview ==

Wasm_of_ocaml is a compiler from OCaml bytecode programs to WebAssembly.
It provides an alternative way to run pure OCaml programs in JavaScript environment like browsers and Node.js.

The compiler is provided by the wasm_of_ocaml-package. <<a_manual chapter="overview" |Js_of_ocaml packages>> are compatible with this compiler.

== Installation

The easiest way to install wasm_of_ocaml is to use opam.
{{{opam install wasm_of_ocaml-compiler js_of_ocaml js_of_ocaml-ppx js_of_ocaml-lwt}}}

== Usage ==

Your program must first be compiled using the OCaml bytecode
compiler {{{ocamlc}}}. JavaScript bindings are provided by the
{{{js_of_ocaml}}} package and the syntax extension by the
{{{js_of_ocaml-ppx}}} package
{{{
ocamlfind ocamlc -package js_of_ocaml -package js_of_ocaml-ppx \
-linkpkg -o cubes.byte cubes.ml
}}}
Then, run the {{{wasm_of_ocaml}}} compiler to produce Wasm code:
{{{
wasm_of_ocaml cubes.byte
}}}

This produces a Javascript loading script {{{cube.js}} and a directory
{{{cube.assets}} containing the Wasm code.

=== with dune ===
Dune has native support for wasm_of_ocaml.
It supports both standard and separate compilation. See https://dune.readthedocs.io/en/latest/wasmoo.html
== Supported features ==

Most of the OCaml standard library is supported. However,
* Most of Sys module is not supported.

Extra libraries distributed with Ocaml (such as Thread) are not
supported in general. However,
* Bigarray: bigarray are supported using Typed Arrays
* Str: supported
* Graphics: partially supported using canvas (see also js_of_ocaml-lwt.graphics)
* Unix: time related functions are supported

Effect handlers are fully supported with the {{{--enable=effects}}} flag. This is not the default for now since effects are not widely used at the moment and the generated code can be slower, larger and less readable.
62 changes: 62 additions & 0 deletions manual/wasm_runtime.wiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
= Writing Wasm primitives

User-defined primitives can be implemented by writing Wasm modules.
This modules (".wat" extension for text modules and ".wasm" extension
for binary modules) can be passed on the command-line.

It still makes sense to link JavaScript files to specify the possible
side-effects of some primitives (see <<a_manual chapter="linker" |Link
with JavaScript code>>), or to implement some functionalities in
JavaScript.

== Data representation ==

The type {{{(ref eq)}}} is used for all OCaml values.
Integers, chars, booleans and constant constructors are mapped to
{{{(ref i31)}}}.

We use the following types for blocks, strings (and bytes), floats,
float arrays, and Javascript values. The first field of a block is its
tag, of type {{{(ref i31)}}}.
{{{
(type $block (array (mut (ref eq))))
(type $string (array (mut i8)))
(type $float (struct (field f64)))
(type $float_array (array (mut f64)))
(type $js (struct (ref null any)))
}}}

You can import the following functions to access or allocate integers of type int32, int64, and nativeint.
{{{
(import "env" "Int32_val"
(func $Int32_val (param (ref eq)) (result i32)))
(import "env" "caml_copy_int32"
(func $caml_copy_int32 (param i32) (result (ref eq))))
(import "env" "Nativeint_val"
(func $Nativeint_val (param (ref eq)) (result i32)))
(import "env" "caml_copy_nativeint"
(func $caml_copy_int32 (param i32) (result (ref eq))))
(import "env" "Int64_val"
(func $Int64_val (param (ref eq)) (result i64)))
(import "env" "caml_copy_int64"
(func $caml_copy_int64 (param i64) (result (ref eq))))
}}}

== Implementing primitives

Primitives can be defined as exported Wasm functions with parameters and return value of type {{{(ref eq)}}}.
{{{
(func (export "input") (param $channel (ref eq)) (param $buffer (ref eq)) (param $offset (ref eq)) (param $length (ref eq)) (result (ref eq))
...
)
}}}

== Linking with JavaScript ==

If you need to use JavaScript functions to implement your Wasm primitives, you can import them using the {{{"js"}}} namespace:
{{{
(import "js" "add" (func $add (param f64) (param f64) (result f64)))
}}}
The <<a_manual chapter="linker" |Js_of_ocaml linker>> is used include them in the generated code.

You can use functions defined in `runtime/wasm/jslib.wat` for conversions between JavaScript values and OCaml values.

0 comments on commit 339a9c1

Please sign in to comment.