Description
Asyncify
Because native Web assembly does not yet support pausing and resuming, folks have invented Asyncify to transform wasm code to allow stack unwinding and rewinding. Most people use Asyncify with emscripten, but as far as I can tell, Asyncify is completely implemented through binaryen.
It can be used without emscripten through wasm-opt
(taken from asyncify-wasm
package's GitHub):
wasm-opt --asyncify [-O] [--pass-arg=asyncify-imports@module1.func1,...] in.wasm -o out.wasm
Then on the JavaScript side, you can use exports.asyncify_start_rewind(...)
and the like to use asyncify.
The package asyncify-wasm
makes this simpler and allows "just" using async functions (promises) in the implementation of imported functions (example also taken from README.md):
let { instance } = await Asyncify.instantiateStreaming(fetch('./out.wasm'), {
get_resource_text: async url => {
let response = await fetch(readWasmString(instance, url));
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return passStringToWasm(instance, await response.text());
}
});
await instance.exports._start();
Relevance for project
This could allow using literally the same code for native and web without any modifications (no GameFrame
) to the examples at the cost of an extra build step (wasm-opt
) and some performance (instrumentation from asyncify).
One could implement WindowShouldClose
as a promise that resolved on the next frame:
{
async WindowShouldClose() {
return new Promise((resolve) => {
/* ... */
requestAnimationFrame(() => resolve(/* ... */)):
});
}
}