demo · v137
Stack-switching trace
Step through a JSPI call by hand. Two stacks render side-by-side — the JS stack and the suspendable Wasm stack — with a chronological event log of when each frame is entered, suspended (handed back to the JS event loop), and resumed.
Educational simulatorThe trace replays a representative call. Real V8 stack switching has the same shape but more bookkeeping (continuation objects, on-stack replacement). Spec link below.
JS stack
suspendable Wasm stack
scopes below are the chronological events. dark = entered, amber = suspended (yielded), green = resumed.
the call shape
// JS side
const fetchAsync = async (url) => (await fetch(url)).text();
const promising = WebAssembly.promising(instance.exports.run);
// Wasm side calls a "blocking" import that is a Suspending wrapper
// around an async JS function. The wasm stack is suspended on await
// then resumed when the Promise settles.
const importObj = { env: { fetch_text: new WebAssembly.Suspending(fetchAsync) } };
await promising(); // suspends and resumes invisibly