Description
(module
(import "fuzzing-support" "call-ref" (func $call-ref (param funcref)))
(func $return-exnref-but-trap (result exnref)
(unreachable)
)
(func $call-call-ref (export "call-call-ref")
(call $call-ref
(ref.func $return-exnref-but-trap)
)
)
)
The exported function calls JS and gives it a reference to a function that returns an exnref. The JS then tries to call that function reference, so JS calls $return-exnref-but-trap
. That function actually traps, so no exnref is actually returned. V8 treats the function as invalid to call from JS:
$ d8 --wasm-staging scripts/fuzz_shell.js -- a.wasm
[fuzz-exec] calling call-call-ref
exception thrown: TypeError: type incompatibility when transforming from/to JS
That is the same error as if it returned a v128 or another type that has no JS representation, and the exception happens before actually calling the function (so we never reach the unreachable
).
The fuzzer errored on this because it thinks the exnref type is valid on the boundary, so there is a mismatch between it and V8.
I can't seem to find anything about this in the spec but I might be looking in the wrong place. But I am also surprised: we can pass e.g. anyref across the JS boundary, so why would exnref be disallowed?