Skip to content

Module hb_beamr.erl

BEAMR: A WAMR wrapper for BEAM.

Description

Beamr is a library that allows you to run WASM modules in BEAM, using the Webassembly Micro Runtime (WAMR) as its engine. Each WASM module is executed using a Linked-In Driver (LID) that is loaded into BEAM. It is designed with a focus on supporting long-running WASM executions that interact with Erlang functions and processes easily.

Because each WASM module runs as an independent async worker, if you plan to run many instances in parallel, you should be sure to configure the BEAM to have enough async worker threads enabled (see erl +A N in the Erlang manuals).

The core API is simple:

       start(WasmBinary) -> {ok, Port, Imports, Exports}
           Where:
               WasmBinary is the WASM binary to load.
               Port is the port to the LID.
               Imports is a list of tuples of the form {Module, Function,
                   Args, Signature}.
               Exports is a list of tuples of the form {Function, Args,
                   Signature}.
       stop(Port) -> ok
       call(Port, FunctionName, Args) -> {ok, Result}
           Where:
               FunctionName is the name of the function to call.
               Args is a list of Erlang terms (converted to WASM values by
                   BEAMR) that match the signature of the function.
               Result is a list of Erlang terms (converted from WASM values).
       call(Port, FunName, Args[, Import, State, Opts]) -> {ok, Res, NewState}
           Where:
               ImportFun is a function that will be called upon each import.
               ImportFun must have an arity of 2: Taking an arbitrary <code>state</code>
               term, and a map containing the <code>port</code>, <code>module</code>, <code>func</code>, <code>args</code>,<code>signature</code>, and the <code>options</code> map of the import.
               It must return a tuple of the form {ok, Response, NewState}.
       serialize(Port) -> {ok, Mem}
           Where:
               Port is the port to the LID.
               Mem is a binary representing the full WASM state.
       deserialize(Port, Mem) -> ok
           Where:
               Port is the port to the LID.
               Mem is a binary output of a previous <code>serialize/1</code> call.

BEAMR was designed for use in the HyperBEAM project, but is suitable for deployment in other Erlang applications that need to run WASM modules. PRs are welcome.

Function Index

benchmark_test/0*
call/3Call a function in the WASM executor (see moduledoc for more details).
call/4
call/5
call/6
deserialize/2Deserialize a WASM state from a binary.
dispatch_response/2*Check the type of an import response and dispatch it to a Beamr port.
driver_loads_test/0*
imported_function_test/0*Test that imported functions can be called from the WASM module.
is_valid_arg_list/1*Check that a list of arguments is valid for a WASM function call.
load_driver/0*Load the driver for the WASM executor.
monitor_call/4*Synchonously monitor the WASM executor for a call result and any imports that need to be handled.
multiclient_test/0*Ensure that processes outside of the initial one can interact with the WASM executor.
serialize/1Serialize the WASM state to a binary.
simple_wasm_test/0*Test standalone hb_beamr correctly after loading a WASM module.
start/1Start a WASM executor context.
start/2
stop/1Stop a WASM executor context.
stub/3Stub import function for the WASM executor.
wasm64_test/0*Test that WASM Memory64 modules load and execute correctly.
wasm_send/2
worker/2*A worker process that is responsible for handling a WASM instance.

Function Details

benchmark_test/0 *

benchmark_test() -> any()

call/3

call(PID, FuncRef, Args) -> any()

Call a function in the WASM executor (see moduledoc for more details).

call/4

call(PID, FuncRef, Args, ImportFun) -> any()

call/5

call(PID, FuncRef, Args, ImportFun, StateMsg) -> any()

call/6

call(PID, FuncRef, Args, ImportFun, StateMsg, Opts) -> any()

deserialize/2

deserialize(WASM, Bin) -> any()

Deserialize a WASM state from a binary.

dispatch_response/2 *

dispatch_response(WASM, Term) -> any()

Check the type of an import response and dispatch it to a Beamr port.

driver_loads_test/0 *

driver_loads_test() -> any()

imported_function_test/0 *

imported_function_test() -> any()

Test that imported functions can be called from the WASM module.

is_valid_arg_list/1 *

is_valid_arg_list(Args) -> any()

Check that a list of arguments is valid for a WASM function call.

load_driver/0 *

load_driver() -> any()

Load the driver for the WASM executor.

monitor_call/4 *

monitor_call(WASM, ImportFun, StateMsg, Opts) -> any()

Synchonously monitor the WASM executor for a call result and any imports that need to be handled.

multiclient_test/0 *

multiclient_test() -> any()

Ensure that processes outside of the initial one can interact with the WASM executor.

serialize/1

serialize(WASM) -> any()

Serialize the WASM state to a binary.

simple_wasm_test/0 *

simple_wasm_test() -> any()

Test standalone hb_beamr correctly after loading a WASM module.

start/1

start(WasmBinary) -> any()

Start a WASM executor context. Yields a port to the LID, and the imports and exports of the WASM module. Optionally, specify a mode (wasm or aot) to indicate the type of WASM module being loaded.

start/2

start(WasmBinary, Mode) -> any()

stop/1

stop(WASM) -> any()

Stop a WASM executor context.

stub/3

stub(Msg1, Msg2, Opts) -> any()

Stub import function for the WASM executor.

wasm64_test/0 *

wasm64_test() -> any()

Test that WASM Memory64 modules load and execute correctly.

wasm_send/2

wasm_send(WASM, Message) -> any()

worker/2 *

worker(Port, Listener) -> any()

A worker process that is responsible for handling a WASM instance. It wraps the WASM port, handling inputs and outputs from the WASM module. The last sender to the port is always the recipient of its messages, so be careful to ensure that there is only one active sender to the port at any time.