Source code
Revision control
Copy as Markdown
Other Tools
// |jit-test| skip-if: !wasmStackSwitchingEnabled(); --setpref=wasm_cont_stack_max_vmem=1
// Tests the cap on the virtual memory used by continuation stacks. A cap of one
// byte is too small for even a single stack, and we always allow one, so exactly
// one continuation may be live at a time.
const { makeA, makeB, clear, recur } = wasmEvalText(`(module
(type $ft (func))
(type $ct (cont $ft))
(func $g (type $ft))
(global $a (mut (ref null $ct)) (ref.null $ct))
(global $b (mut (ref null $ct)) (ref.null $ct))
(elem declare func $g $recur)
(func (export "makeA")
(global.set $a (cont.new $ct (ref.func $g))))
(func (export "makeB")
(global.set $b (cont.new $ct (ref.func $g))))
(func (export "clear")
(global.set $a (ref.null $ct))
(global.set $b (ref.null $ct)))
(func $recur (type $ft)
(resume $ct (cont.new $ct (ref.func $recur))))
(func (export "recur") (call $recur))
)`).exports;
makeA();
assertErrorMessage(() => makeB(), WebAssembly.RuntimeError,
/too many continuation stacks/);
// Dropping the continuation returns its stack, so the next one succeeds.
clear();
gc();
makeB();
// Unbounded `resume (cont.new ...)` recursion traps instead of mapping stacks
clear();
gc();
assertErrorMessage(() => recur(), WebAssembly.RuntimeError,
/too many continuation stacks/);