Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid emitted binary for unreachable code #1113

Open
kripken opened this issue Jul 27, 2017 · 3 comments
Open

Invalid emitted binary for unreachable code #1113

kripken opened this issue Jul 27, 2017 · 3 comments

Comments

@kripken
Copy link
Member

kripken commented Jul 27, 2017

Testing the new fuzzer's emitted binaries in wasm VMs, I see something odd. This module

(module
  (memory $0 1 1)
  (export "func_0" (func $func_0))
  (func $func_0 (result f32)
    (block $label$2 f32
      (i32.trunc_u/f64
        (unreachable)
      )
    )
  )
)

won't load in sm or v8,

v8: CompileError: WebAssembly.Module(): Compiling WASM function #0: failed:: type error in merge[0] (expected f32, got i32) @+5

sm: CompileError: at offset 70: type mismatch: expression has type i32 but expected f32

It does work in wabt,

$ ./wasmdump -d a.wasm
a.wasm:	file format wasm 0x00000d

Code Disassembly:

00003c func[0]:
 000042: 02 7d                      | block f32
 000044: 00                         |   unreachable
 000045: ab                         |   i32.trunc_u/f64
 000046: 0b                         | end

(I manually changed the version to 0xd since that's what wabt required), and it works in binaryen. Who is wrong here?

It seems like it should be valid, the unreachable sets us into the mode where it's ok to pop anything, so the i32.trunc is ok and the block popping an f32 should be ok? Is this a case of undefined behavior in wasm type checking?

@binji
Copy link
Member

binji commented Jul 27, 2017

Ah, I see the problem. wasmdump is the old name, the new name is wasm-objdump. wast2wasm won't even generate file since it isn't using the new block signature syntax:

test.wast:5:21: error: syntax error, unexpected VALUE_TYPE, expecting )
    (block $label$2 f32
                    ^^^

Fixing that produces the following error:

test.wast:6:8: error: type mismatch in block, expected f32 but got i32.
      (i32.trunc_u/f64
       ^^^^^^^^^^^^^^^

This error is correct; unreachable makes the stack polymorphic, so i32.trunc_u/f64 pops an f64 and pushes an i32. But then block wants an f32, so it is invalid.

We can generate the invalid wasm file with wast2wasm --no-check, then try to read it using wasm-objdump. This works, since wasm-objdump doesn't validate:

000028 func[0]:
 00002a: 02 7d                      | block f32
 00002c: 00                         |   unreachable
 00002d: ab                         |   i32.trunc_u/f64
 00002e: 0b                         | end
 00002f: 0b                         | end

wasm2wast does validate, and produces the same error as above:

test.wasm:000002e: error: type mismatch in block, expected f32 but got i32.

@kripken
Copy link
Member Author

kripken commented Jul 27, 2017

I see, thanks. Ok, then we are indeed emitting bad code in cases of unreachable code like this.

@kripken kripken changed the title Invalid binary generation? Invalid emitted binary for unreachable code Jul 27, 2017
@kripken
Copy link
Member Author

kripken commented Jul 31, 2017

Will be fixed by #1117.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants