binaryen icon indicating copy to clipboard operation
binaryen copied to clipboard

Parse Exception with Block Type But WABT Successfully Parses It

Open mobsceneZ opened this issue 1 year ago • 10 comments

Hello there, I recently came across a Wasm module which cannot be parsed by Binaryen:

$ wabt/bin/wasm2wat test.wasm
(module
  (type (;0;) (func (result i32)))
  (type (;1;) (func (param i32) (result i32)))
  (func (;0;) (type 0) (result i32)
    i32.const 1
    block (param i32) (result i32)  ;; label = @1
      i32.const 2
      i32.add
    end)
  (export "param" (func 0)))

When using wasm-dis to parse above wasm module, it encountered following errors:

$ wasm-dis test.wasm
[parse exception: Block requires more values than are available (at 0:48)]
Fatal: error parsing wasm (try --debug for more info)

However, when using wasm2wat provided by WABT, it parsed successfully and wasm-interp runs param function without error:

$ wasm-interp test.wasm -r "param"
param() => i32:3

The binaryen version I tested is 16a59938563c93d8459bf36679c83497aeba7cc7, which is currently the newest commit version.

mobsceneZ avatar Sep 18 '23 10:09 mobsceneZ

FYI this is accepted by the reference interpreter and by Owi.

zapashcanon avatar Sep 18 '23 10:09 zapashcanon

The issue is probably the same as in #5950 - Binaryen does not support multivalue input params to control flow structures (here, block (param i32)). Unfortunately it seems we don't have an error on this atm.

kripken avatar Sep 18 '23 20:09 kripken

The issue is probably the same as in #5950 - Binaryen does not support multivalue input params to control flow structures (here, block (param i32)). Unfortunately it seems we don't have an error on this atm.

Thanks for your kind response, kripken. Sorry to bother but I have two more questions that I'm not sure:

  1. Does Binaryen not support table.init, elem.drop, table.copy, table.fill yet? Because I witnessed similar parse errors when dealing with these instructions.
  2. The following wat file works just fine with WABT's wat2wasm and wasm2wat, however, when I convert it into wasm binary form using wat2wasm and later use wasm-dis to parse it, error occurs:
$ cat test.wat
(module
        (type (;0;) (func))
        (func (;0;) (type 0))
        (func (;1;) (type 0))
        (table (;0;) 10 funcref)
        (elem (;53;) declare func)
        (elem (;54;) declare funcref (ref.func 0) (ref.func 0) (ref.null func) (ref.func 1))
        (elem (;55;) declare func)
        (elem (;56;) declare func 0 0 1 1)
        (elem (;57;) declare func)
        (elem (;58;) declare funcref (ref.func 0) (ref.func 0) (ref.null func) (ref.func 1))
        (elem (;59;) declare func)
        (elem (;60;) declare func 0 0 1 1)
)
$ wat2wasm test.wat -o test.wasm
$ wasm-dis test.wasm --debug
<==
getInt8: 208 (at 40)
getInt8: 112 (at 41)
getU32LEB: 14416 ==>
== processExpressions
zz recurse into 1 at 42
getInt8: 11 (at 42)
readExpression seeing 11
zz recurse from 1 at 43
== processExpressions finished
[parse exception: expected to read a single expression (at 0:43)]
Fatal: error parsing wasm. here is what we read up to the error:
(module
 (table $0 10 funcref)
)

It seems there is something wrong with second declarative element and parsing has a error near ref.null func, why?

mobsceneZ avatar Sep 19 '23 11:09 mobsceneZ

Does Binaryen not support table.init, elem.drop, table.copy, table.fill yet? Because I witnessed similar parse errors when dealing with these instructions.

@tlively just implemented table.fill: #5949 Those others might not be implemented yet, but it sounds like you need them?

I'm not sure what's going on with that elem issue, but perhaps that's a recent change to the binary format? cc @tlively

kripken avatar Sep 19 '23 14:09 kripken

Could be that we don't yet implement table initializers: https://github.com/WebAssembly/binaryen/issues/5628

tlively avatar Sep 19 '23 17:09 tlively

Does Binaryen not support table.init, elem.drop, table.copy, table.fill yet? Because I witnessed similar parse errors when dealing with these instructions.

@tlively just implemented table.fill: #5949 Those others might not be implemented yet, but it sounds like you need them?

I'm not sure what's going on with that elem issue, but perhaps that's a recent change to the binary format? cc @tlively

Thanks again, kripken. Actually the above examples are extracted from WebAssembly's Core Specification TestSuites and I just want to use them as the seed corpus for fuzzing. So it's not a big deal if Binaryen currently doesn't support some of the instructions since I can remove related modules. :)

Could be that we don't yet implement table initializers: #5628

Hey tlively, thanks for your response, I'm wondering why it's related to table initializers since the parse error doesn't give me much information, is it convenient for you to explain it again?

mobsceneZ avatar Sep 20 '23 02:09 mobsceneZ

Hmm, I guess you're right that the error isn't related to table initializers since that example doesn't have any table initializers, but it seems that we're similarly missing support for something to do with element segments. Clearly our support is very patchy in this area.

I hope that soon we will be able to run the full upstream spec test suite in Binaryen, which will help uncover this kind of bug.

tlively avatar Sep 20 '23 03:09 tlively

Hmm, I guess you're right that the error isn't related to table initializers since that example doesn't have any table initializers, but it seems that we're similarly missing support for something to do with element segments. Clearly our support is very patchy in this area.

I hope that soon we will be able to run the full upstream spec test suite in Binaryen, which will help uncover this kind of bug.

Thanks for your kind reply and hope Binaryen would get better in the future :)

mobsceneZ avatar Sep 20 '23 05:09 mobsceneZ

Table.copy is added in #6078

kripken avatar Nov 02 '23 23:11 kripken

table.init is added in https://github.com/WebAssembly/binaryen/pull/6827

kripken avatar Aug 08 '24 23:08 kripken