binaryen icon indicating copy to clipboard operation
binaryen copied to clipboard

Asyncify does not support unwinding from functions returning non-nullable values

Open redianthus opened this issue 1 year ago • 3 comments

Hi,

While testing some wasm-opt options for Wasocaml, I found the following assertion failure:

$ wasm-opt -O3 --enable-gc --enable-tail-call --enable-reference-types --enable-multivalue --enable-exception-handling a.out.wasm -o a.out.optimised.wasm --asyncify    
wasm-opt: ~/dev/cpp/binaryen/src/ir/literal-utils.h:35: wasm::Expression* wasm::LiteralUtils::makeZero(wasm::Type, wasm::Module&): Assertion `canMakeZero(type)' failed.
zsh: IOT instruction  wasm-opt -O3 --enable-gc --enable-tail-call --enable-reference-types    -o

I'm on a recent version:

$ wasm-opt version 119 (version_119-55-g7e1413902)

It works without --asyncify.

The binary file is attached, I don't have the text version sorry. I uploaded it as a .jpeg otherwise GitHub won't let me do it: bug_asynficy.

Thanks!

redianthus avatar Oct 07 '24 15:10 redianthus

This may be the same issue as #6989, as Asyncify uses Flatten internally. If not, please upload the file as an archive and I can take a look.

kripken avatar Oct 07 '24 19:10 kripken

Here is an archive: asyncify.zip. I'm not sure it's related but it probably is.

redianthus avatar Oct 08 '24 09:10 redianthus

Thanks. This is a real Asyncify issue, it turns out. Reduced testcase:

(module
 (import "a" "b" (func $import))
 
 (func $0 (result (ref i31))
  (call $import)
  (unreachable)
 )
)

The result of the function is non-nullable. Asyncify works by returning twice, that is, when we pause, we flow out of the function from the pause point, and when we resume we flow back to that point and then continue normally. But the first return must return a value, even if the outside will ignore it, and there is no non-nullable value we can emit. makeZero can't make a null for it, and makeUnreachable would just trap.

We should probably document this as a limitation of Asyncify, with the workaround that function returns must be nullable in functions that unwind, unless I'm missing something.

kripken avatar Oct 08 '24 19:10 kripken