-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
60 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
= 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 | ||
|
||
{{{ | ||
(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 == | ||
|
||
You can import JavaScript primitive using the {{{"js"}}} namespace: | ||
{{{ | ||
(import "js" "add" (func $add (param f64) (param f64) (result f64))) | ||
}}} | ||
|
||
You can use functions defined in `runtime/wasm/jslib.wat` for conversions. |