Skip to content

Instantly share code, notes, and snippets.

@CraigglesO
Last active August 12, 2022 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CraigglesO/6ef0ae00c3ff169822ae75b45141acd8 to your computer and use it in GitHub Desktop.
Save CraigglesO/6ef0ae00c3ff169822ae75b45141acd8 to your computer and use it in GitHub Desktop.
Zig using async/await in WASM
const fs = require('fs')
const source = fs.readFileSync('./async.wasm')
function u32ToU8 (num) {
const resU32 = new Uint32Array([num])
return new Uint8Array(resU32.buffer)
}
function getMemory (instance) {
return new Uint8Array(instance.exports.memory.buffer)
}
function asyncTimeout () {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, 1_000)
})
}
function rand () {
return Math.floor(Math.random() * 100) + 1
}
const mod = new WebAssembly.Module(source)
const instance = new WebAssembly.Instance(mod, {
env: {
memoryBase: 0,
tableBase: 0,
memory: new WebAssembly.Memory({
initial: 512
}),
printNum: (num) => { console.log(`The num is ${num}`) },
printError: (err) => { console.log(`The error is ${err}`) },
jsAsyncFnCall: async (frame, ptr) => {
console.log(frame, ptr)
await asyncTimeout()
const buf = u32ToU8(rand())
const view = getMemory(instance)
const len = buf.byteLength
view.subarray(ptr, ptr + len).set(buf)
instance.exports.wasmResume(frame)
}
}
})
const { wasmAsync } = instance.exports
wasmAsync()
wasmAsync()
const std = @import("std");
const allocator = std.heap.page_allocator;
extern fn printNum(num: u32) void;
extern fn jsAsyncFnCall(store: *anyopaque, resPtr: *u32) void;
pub fn jsAsync () u32 {
var res: u32 = 0;
suspend {
jsAsyncFnCall(@frame(), &res);
}
return res;
}
pub fn jsAwait () void {
var frame = async jsAsync();
printNum(await frame);
}
export fn wasmResume (frame: *anyopaque) callconv(.C) void {
resume @ptrCast(anyframe, @alignCast(4, frame));
}
export fn wasmAsync () void {
const frame = allocator.create(@Frame(jsAwait)) catch return;
frame.* = async jsAwait();
}
@CraigglesO
Copy link
Author

zig build-lib async.zig -target wasm32-freestanding -dynamic -O ReleaseSmall --strip

then

node async.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment