Source code

Revision control

Copy as Markdown

Other Tools

// |jit-test| skip-if: !wasmStackSwitchingEnabled()
// Wasm throw in continuation, caught by catch on main stack; tag value received
{
let { run } = wasmEvalText(`(module
(type $ft (func))
(type $ct (cont $ft))
(tag $exn (param i32))
(func $f (type $ft)
i32.const 42
throw $exn
)
(elem declare func $f)
(func (export "run") (result i32)
try (result i32)
ref.func $f
cont.new $ct
resume $ct
i32.const 0
catch $exn
end
)
)`).exports;
assertEq(run(), 42);
}
// JS import throws from within continuation, caught by try/catch_all around resume
{
let { run } = wasmEvalText(`(module
(import "env" "fn" (func $fn))
(type $ft (func))
(type $ct (cont $ft))
(func $f (type $ft) call $fn)
(elem declare func $f)
(func (export "run") (result i32)
try (result i32)
ref.func $f
cont.new $ct
resume $ct
i32.const 0
catch_all
i32.const 1
end
)
)`, { env: { fn: () => { throw new Error("test"); } } }).exports;
assertEq(run(), 1);
}
// Throw and catch within a continuation; exception does not escape to resume caller
{
let { run, getG } = wasmEvalText(`(module
(type $ft (func))
(type $ct (cont $ft))
(tag $exn (param i32))
(global $g (mut i32) (i32.const 0))
(func $f (type $ft)
try
i32.const 99
throw $exn
catch $exn
global.set $g
end
)
(elem declare func $f)
(func (export "run")
ref.func $f
cont.new $ct
resume $ct
)
(func (export "getG") (result i32) global.get $g)
)`).exports;
run();
assertEq(getG(), 99);
}
// Continuation suspends, resumes, then throws; try/catch around second resume catches it
{
let { init, step1, step2 } = wasmEvalText(`(module
(type $ft (func))
(type $ct (cont $ft))
(tag $tag)
(tag $exn)
(global $k (mut (ref null $ct)) (ref.null $ct))
(func $f (type $ft)
suspend $tag
throw $exn
)
(elem declare func $f)
(func (export "init")
ref.func $f
cont.new $ct
global.set $k
)
(func (export "step1") (result i32)
(block (result (ref $ct))
global.get $k
resume $ct (on $tag 0)
i32.const 0
return
)
global.set $k
i32.const 1
)
(func (export "step2") (result i32)
try (result i32)
global.get $k
resume $ct
i32.const 0
catch $exn
i32.const 2
end
)
)`).exports;
init();
assertEq(step1(), 1);
assertEq(step2(), 2);
}