@jetblack/wasi-marsheller
v1.0.0
Published
This library provides two things:
Downloads
2
Readme
WASI Marshalling
This library provides two things:
- The minimum WASI implementation required for supporting memory allocation and strings.
- A marshalling framework for calling WebAssembly functions in a wasm module from JavaScript.
The intention is to provide support to "drop in" publically available libraries that can be compiled into a wasm module.
The WASI Layer
Three WASI domains are implemented:
- stout/stderr - many libraries fall back to reporting errors over the standard
output/error. These are redirected to
console.log
andconsole.error
. - string passing with UTF-8 requires a call to
setlocale
which in turn requires a system call to request environment variables. This call is intercepted, and returns a application provided set of the environment variables. - memory management - most libraries make use of
malloc
andfree
to manage memory.
The implementation of the WASI layer is provided through a class of the same name. Here is an example of initialising the library.
import { Wasi } from '@jetblack/wasi-marshalling.develop.js'
// Create the Wasi instance passing in environment variables.
const wasi = new Wasi({})
// Instantiate the wasm module.
WebAssembly.instantiateStreaming(
fetch('example.wasm'), {
wasi_snapshot_preview1: wasi
})
.then(res => {
// Initialise the wasi instance
wasi.init(res.instance)
// Do something interesting ...
})
The Marshalling Framework
Given the following C function call which multiplies two arrays.
#include <stdlib.h>
__attribute__((used)) double* multipleFloat64ArraysReturningPtr (double* array1, double* array2, int length)
{
double* result = (double*) malloc(length * sizeof(double));
if (result == 0)
return 0;
for (int i = 0; i < length; ++i) {
result[i] = array1[i] + array2[i];
}
return result;
}
We can define and call the following function prototype.
import {
ArrayType,
Float64Type,
Int32Type,
FunctionPrototype,
In
} from '@jetblack/wasi-marshalling.develop.js'
const prototype = new FunctionPrototype(
// The arguments
[
new In(new ArrayType(new Float64Type())),
new In(new ArrayType(new Float64Type())),
new In(new Int32Type())
],
// The return type
new ArrayType(new Float64Type(), 4)
)
const result = prototype.invoke(
wasi.memoryManager,
wasi.instance.exports.multipleFloat64ArraysReturningPtr,
[1, 2, 3, 4],
[5, 6, 7, 8],
4)
console.log(result)
The framework will take care of passing the data to the wasm module, unpacking the result and allocating/deallocating the memory.
The framework handles the following types:
- Int8, Int16, Int32, Int64
- Uint8, Uint16, Uint32, Uint64
- Float32, Float64
- String
- Array
- Pointer
Usage
To build the package:
npm install
npm run build
To Run the examples in the client
folder.
# Run a node example
npm run exec:nodejs
# Run a browser which uploads an es6 module
npm run exec:es6
# Run code in a `<script>` tag in the browser
npm run exec:browser