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

see also