2018-10-20 15:40:23 +02:00

5.5 KiB

AS loader

A convenient loader for AssemblyScript modules. Demangles module exports to a friendly object structure compatible with WebIDL and TypeScript definitions and provides some useful utility to read/write data from/to memory.

Usage

const loader = require("@assemblyscript/loader");
...

API

  • instantiate<T>(module: WebAssembly.Module, imports?: WasmImports): ASUtil & T
    Instantiates an AssemblyScript module using the specified imports.

  • instantiateBuffer<T>(buffer: Uint8Array, imports?: WasmImports): ASUtil & T
    Instantiates an AssemblyScript module from a buffer using the specified imports.

  • instantiateStreaming<T>(response: Response, imports?: WasmImports): Promise<ASUtil & T>
    Instantiates an AssemblyScript module from a response using the specified imports.

  • demangle<T>(exports: WasmExports): T
    Demangles an AssemblyScript module's exports to a friendly object structure. You usually don't have to call this manually as instantiation does this implicitly.

Note: T above can either be omitted if the structure of the module is unknown, or can reference a .d.ts (i.e. typeof MyModule) as produced by the compiler with the -d option.

Instances are automatically populated with useful utility:

  • I8: Int8Array
    An 8-bit signed integer view on the memory.

  • U8: Uint8Array
    An 8-bit unsigned integer view on the memory.

  • I16: Int16Array
    A 16-bit signed integer view on the memory.

  • U16: Uint16Array
    A 16-bit unsigned integer view on the memory.

  • I32: Int32Array
    A 32-bit signed integer view on the memory.

  • U32: Uint32Array
    A 32-bit unsigned integer view on the memory.

  • I64: BigInt64Array
    A 64-bit signed integer view on the memory1.

  • U64: BigUint64Array
    A 64-bit unsigned integer view on the memory1.

  • F32: Float32Array
    A 32-bit float view on the memory.

  • F64: Float64Array
    A 64-bit float view on the memory.

  • newString(str: string): number
    Allocates a new string in the module's memory and returns its pointer. Requires memory.allocate to be exported from your module's entry file, i.e.:

    import "allocator/tlsf";
    export { memory };
    
  • getString(ptr: number): string
    Gets a string from the module's memory by its pointer.

  • newArray(view: TypedArray, length?: number, unsafe?: boolean): number
    Copies a typed array into the module's memory and returns its pointer.

  • newArray(ctor: TypedArrayConstructor, length: number, unsafe?: boolean): number
    Creates a typed array in the module's memory and returns its pointer.

  • getArray(ctor: TypedArrayConstructor, ptr: number): TypedArray
    Gets a view on a typed array in the module's memory by its pointer.

  • freeArray(ptr: number): void
    Frees a typed array in the module's memory. Must not be accessed anymore afterwards.

  • getFunction(ptr: number): function
    Gets a function by its pointer.

  • newFunction(fn: function): number
    Creates a new function in the module's table and returns its pointer. Note that only actual WebAssembly functions, i.e. as exported by the module, are supported.

1 This feature has not yet landed in any VM as of this writing.

Examples

Instantiating a module

// From a module provided as a buffer, i.e. as returned by fs.readFileSync
const myModule = loader.instantiateBuffer(fs.readFileSync("myModule.wasm"), myImports);

// From a response object, i.e. as returned by window.fetch
const myModule = await loader.instantiateStreaming(fetch("myModule.wasm"), myImports);

Reading/writing basic values to/from memory

var ptrToInt8 = ...;
var value = myModule.I8[ptrToInt8]; // alignment of log2(1)=0

var ptrToInt16 = ...;
var value = myModule.I16[ptrToInt16 >>> 1]; // alignment of log2(2)=1

var ptrToInt32 = ...;
var value = myModule.I32[ptrToInt32 >>> 2]; // alignment of log2(4)=2

var ptrToInt64 = ...;
var value = myModule.I64[ptrToInt64 >>> 3]; // alignment of log2(8)=3

var ptrToFloat32 = ...;
var value = myModule.F32[ptrToFloat32 >>> 2]; // alignment of log2(4)=2

var ptrToFloat64 = ...;
var value = myModule.F64[ptrToFloat64 >>> 3]; // alignment of log2(8)=3

// Likewise, for writing
myModule.I8[ptrToInt8] = newValue;
myModule.I16[ptrToInt16 >>> 1] = newValue;
myModule.I32[ptrToInt32 >>> 2] = newValue;
myModule.I64[ptrToInt64 >>> 3] = newValue;
myModule.F32[ptrToFloat32 >>> 2] = newValue;
myModule.F64[ptrToFloat64 >>> 3] = newValue;

Note: Make sure to reference the views as shown above as these will automatically be updated when the module's memory grows.

Allocating/obtaining strings to/from memory

// Allocating a string, i.e. to be passed to an export expecting one
var str = "Hello world!";
var ptr = module.newString(str);

// Disposing a string that is no longer needed (requires memory.free to be exported)
module.memory.free(ptr);

// Obtaining a string, i.e. as returned by an export
var ptrToString = ...;
var str = module.getString(ptrToString);

Usage with TypeScript definitions produced by the compiler

import MyModule from "myModule"; // pointing at the d.ts

const myModule = loader.instatiateBuffer<typeof MyModule>(fs.readFileSync("myModule.wasm"), myImports);