Using the loader to fetch and instantiate our wasm lets us access some useful utility functions but we need to update our WasmLoader
class to export them.
// js/loader.js
// WasmLoader::wasm()
const instance = await loader.instantiateStreaming(fetch(path), imports);
return instance;
// WasmLoader::wasmFallback()
const instance = await loader.instantiate(bytes, imports);
The instance methods include our exported wasm functions along with AssemblyScript utilities. We're reading a string from memory so we're going to use __getString().
// index.html
const { fizzbuzz, __getString } = instance;
const str = __getString(fizzbuzz(3));
document.write(str);
Let's check out the source code of __getString
// Take a pointer as only argument
function __getString(ptr) {
// Return null if there's no pointer
if (!ptr) return null;
// Get reference to wasm memory
const buffer = memory.buffer;
// Load wasm memory buffer into a 32 bit unsigned integer array
const id = new Uint32Array(buffer)
// The memory location of the string is at pointer + the runtime header offset
// The location is then zero fill right shifted
[ptr + ID_OFFSET >>> 2];
/** Reads a string from the module's memory by its pointer. */
function __getString(ptr) {
if (!ptr) return null;
const buffer = memory.buffer;
const id = new Uint32Array(buffer)[ptr + ID_OFFSET >>> 2];
if (id !== STRING_ID) throw Error(`not a string: ${ptr}`);
return getStringImpl(buffer, ptr);
}