Racket binaryen bindings
(require binaryen) | package: racket-binaryen |
This is a wrapper for the Binaryen suite of WebAssembly tools. WebAssembly (or Wasm) is a binary instruction format for a stack-based virtual machine. More information can be found in its webpage.
1 Getting Started
You are interested in Racket and WebAssembly and somehow found this package? However, you have no idea where to start... well, you came to the right place!
There will be times when a binaryen function is not available yet in this package. I add more support on a regular basis but might have not done so for the functions you need. In that case, open an issue and I will prioritize your requirements.
1.1 Reading WebAssembly
Consider the following Wasm module in text format:
(module (func $double (export "wasm_double") (param $x i32) (result i32) (i32.mul (i32.const 2) (local.get $x))) (func $collatz_iteration (export "wasm_col_iter") (param $x i32) (result i32) (i32.add (i32.const 1) (i32.mul (i32.const 3) (local.get $x)))))
This example defines two functions that are exported from the module: double and collatz_iteration. The function double is exported with the name wasm_double and the function collatz_iteration is exported with the name wasm_col_iter.
To parse a module from a string, use the function module-parse.
> (require binaryen racket/port)
> (define wasm-mod '(module (func $double (export "wasm_double") (param $x i32) (result i32) (i32.mul (i32.const 2) (local.get $x))) (func $collatz_iteration (export "wasm_col_iter") (param $x i32) (result i32) (i32.add (i32.const 1) (i32.mul (i32.const 3) (local.get $x))))))
> (define mod (module-parse (with-output-to-string (lambda () (write wasm-mod))))) > (module-valid? mod) #t
We have read the module in, and checked it’s valid. We can perform a number of queries on the module.
> (module-function-count mod) 2
You can see how it is printed to standard output.
> (module-print mod)
(module
(type $i32_=>_i32 (func (param i32) (result i32)))
(export "wasm_double" (func $double))
(export "wasm_col_iter" (func $collatz_iteration))
(func $double (param $x i32) (result i32)
(i32.mul
(i32.const 2)
(local.get $x)
)
)
(func $collatz_iteration (param $x i32) (result i32)
(i32.add
(i32.const 1)
(i32.mul
(i32.const 3)
(local.get $x)
)
)
)
)
1.2 Writing WebAssembly
You can also create WebAssembly on the fly, have it optimized and write it to a file. Lets say that we want to manually create a module that contains a function square, that multiplies a number with itself.
What we want to create is something like this:
(module (func $square (export "square") (param $x i32) (result $i32) (i32.mul (local.get $x) (local.get $x))))
Most functions in this library will receive an optional module to use as last parameter. If not provided, they will the value of current-module which is useful to create WebAssembly code since you tend to work on a module at a time.
The racket code will take this shape:
(require racket/contract binaryen) (define/contract (create-square) (-> module?) (parameterize ([current-module (module-create)]) (module-add-function "square" (list type-int32) (list type-int32) '() (make-mul-int32 (make-localget 0 type-int32) (make-localget 0 type-int32))) (module-export-function "$square" "square") (current-module)))
In this example we create an empty module with (module-create) and set it as the current-module so that we don’t need to pass it around. Then we add a function withe name "square", receiving one 32bit integer, returning one 32bit integer, and without any locals. The body is created in-place and passed into the function. The function module-add-function creates the function and adds it to the current-module.
1.3 Optimization
1.4 A Longer Example
2 API
2.1 Types
Types refer to WebAssembly types such as int32, int64, etc. There are basic types and ways to aggregate a type from these basic types.
2.2 Optimizations
Binaryen can optimize your webassembly program and many functions depends on the global optimization levels set. This API section describes which levels can be tuned and which facilities are provided to change the levels.
2.3 Modules
A module is the representation of a WebAssembly module into which you add functions, etc.
procedure
(module? x) → boolean?
x : any/c
parameter
(current-module module) → void? module : module?
= #false
procedure
(module-create) → void?
procedure
(module-valid? [mod]) → boolean?
mod : module? = (current-module)
procedure
(module-print [mod]) → void?
mod : module? = (current-module)
procedure
(module-optimize! [mod]) → void?
mod : module? = (current-module)
procedure
(module-read in) → module?
in : bytes?
procedure
(module-parse s) → module?
s : string?
procedure
(module-write mod textual? [#:source-map sm]) → bytes?
mod : module? textual? : boolean? sm : (or/c string? #false) = #false
2.4 Features
Features refer to WebAssembly features that are enabled in a module and generally refer to which WebAssembly proposals have been implemented in Binaryen.
procedure
(set-module-features! features [ #:module mod]) → void? features : (listof feature?) mod : module? = (current-module)
2.5 Functions
A function is the representation of a WebAssembly function.
procedure
(module-add-function name arg-types result-types var-types body [ #:module mod]) → function? name : string? arg-types : (listof type?) result-types : (listof type?) var-types : (listof type?) body : expression? mod : module? = (current-module)
procedure
(module-function-count [#:module mod]) → exact-positive-integer?
mod : module? = (current-module)
procedure
(module-function idx [#:module mod]) → function?
idx : exact-nonnegative-integer? mod : module? = (current-module)
procedure
(function-name f) → string?
f : function?
procedure
(function-parameter-types f) → (listof type?)
f : function?
procedure
(function-result-types f) → (listof type?)
f : function?
procedure
(function-variable-count f) → exact-positive-integer?
f : function?
procedure
(function-variable-type f n) → type?
f : function? n : exact-positive-integer?
2.6 Literals
2.7 Exports
An export represent a value that is exported from a WebAssembly module.
procedure
in : string? out : string? mod : module? = (current-module)
2.8 Expressions
An expression is a way to transform Wasm values through computation.
2.8.1 Unary expressions
A unary expression is an expression that operates on one value. Constructors for unary operations will take the form make-<name>-<type>, where <name> is the operation name, and <type> is the type of the value expected by the operation. Value types are not checked at the compile time, therefore it is possible to create invalid WebAssembly modules. Use module-valid? to validate your modules.
2.8.2 Binary Expressions
A binary expression is an expression that operates on two values.
procedure
a : expression? b : expression? mod : module? = (current-module)
procedure
a : expression? b : expression? mod : module? = (current-module)
procedure
a : expression? b : expression? mod : module? = (current-module)
2.8.3 Load expression
A load expression is an expression that loads a value from memory.