diff options
-rw-r--r-- | src/tools/wasm-dis.cpp | 7 | ||||
-rw-r--r-- | src/tools/wasm-opt.cpp | 7 | ||||
-rw-r--r-- | test/lit/binary/debug-bad-binary.test | 42 | ||||
-rw-r--r-- | test/lit/binary/debug-bad-binary.test.wasm | bin | 0 -> 49 bytes | |||
-rw-r--r-- | test/lit/binary/stacky-eh.test | 126 |
5 files changed, 117 insertions, 65 deletions
diff --git a/src/tools/wasm-dis.cpp b/src/tools/wasm-dis.cpp index e8ca71528..f9f303359 100644 --- a/src/tools/wasm-dis.cpp +++ b/src/tools/wasm-dis.cpp @@ -70,7 +70,12 @@ int main(int argc, const char* argv[]) { } catch (ParseException& p) { p.dump(std::cerr); std::cerr << '\n'; - Fatal() << "error in parsing wasm binary"; + if (options.debug) { + Fatal() << "error parsing wasm. here is what we read up to the error:\n" + << wasm; + } else { + Fatal() << "error parsing wasm (try --debug for more info)"; + } } catch (MapParseException& p) { p.dump(std::cerr); std::cerr << '\n'; diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp index effd085bc..8f958f164 100644 --- a/src/tools/wasm-opt.cpp +++ b/src/tools/wasm-opt.cpp @@ -279,7 +279,12 @@ int main(int argc, const char* argv[]) { } catch (ParseException& p) { p.dump(std::cerr); std::cerr << '\n'; - Fatal() << "error parsing wasm"; + if (options.debug) { + Fatal() << "error parsing wasm. here is what we read up to the error:\n" + << wasm; + } else { + Fatal() << "error parsing wasm (try --debug for more info)"; + } } catch (MapParseException& p) { p.dump(std::cerr); std::cerr << '\n'; diff --git a/test/lit/binary/debug-bad-binary.test b/test/lit/binary/debug-bad-binary.test new file mode 100644 index 000000000..f45b7d494 --- /dev/null +++ b/test/lit/binary/debug-bad-binary.test @@ -0,0 +1,42 @@ +;; Verify --debug mode prints partial results even after an error. +;; +;; debug-bad-binary.test.wasm contains: +;; +;; (module +;; (global $A (mut i32) (i32.const 10)) +;; +;; (func $a +;; (drop +;; (i32.const 10) +;; ) +;; ) +;; +;; (func $b +;; ;; bad opcodes here! +;; ) +;; +;; (func $c +;; (drop +;; (i32.const 30) +;; ) +;; ) +;; ) +;; +;; We will error when we get to the bad opcodes. In --debug mode, this test +;; shows that we at least print what we read so far up to that point, which will +;; include both the global and the first function. +;; + +RUN: not wasm-opt --debug %s.wasm 2>&1 | filecheck %s + +;; CHECK: Fatal: error parsing wasm. here is what we read up to the error: +;; CHECK-NEXT: (module +;; CHECK-NEXT: (type $none_=>_none (func)) +;; CHECK-NEXT: (global $global$0 (mut i32) (i32.const 10)) +;; CHECK-NEXT: (func $0 +;; CHECK-NEXT: (drop +;; CHECK-NEXT: (i32.const 10) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + diff --git a/test/lit/binary/debug-bad-binary.test.wasm b/test/lit/binary/debug-bad-binary.test.wasm Binary files differnew file mode 100644 index 000000000..322e29e05 --- /dev/null +++ b/test/lit/binary/debug-bad-binary.test.wasm diff --git a/test/lit/binary/stacky-eh.test b/test/lit/binary/stacky-eh.test index 09406bfea..0811b28ff 100644 --- a/test/lit/binary/stacky-eh.test +++ b/test/lit/binary/stacky-eh.test @@ -1,66 +1,66 @@ -# Verify stacky EH binary can be parsed correctly. -# -# stacky-eh.test.wasm contains below: -# try -# nop -# catch 0 # tag type i32 -# i32.const 3 -# local.set 1 -# local.set 2 -# -# (This binary was generated by -# 'wasm-opt --optimize-level=3 --generate-stack-ir -optimize-stack-ir') -# -# This code is 'stacky' in Binaryen parlance. In the binary reader, Binaryen has -# a special routine of creating a block and a local.get/local.set to read stacky -# code into Binaryen AST. So if we don't do any post-fixup, the 'catch' block -# becomes: -# (catch $e-i32 -# (local.set 2 -# (block (result i32) -# (local.set $new -# (pop i32) -# ) -# (local.set 1 -# (i32.const 3) -# ) -# (local.get $new) -# ) -# ) -# ) -# Here the 'block' and `local $new' are newly created to read the stacky code. -# But now the 'pop' ends up nested within the 'block', which is invalid. This -# test tests if this invalid code is correctly fixed up in the binary reader. -# The fixup will hoist the 'pop' and create another local to store it right -# after 'catch'. +;; Verify stacky EH binary can be parsed correctly. +;; +;; stacky-eh.test.wasm contains below: +;; try +;; nop +;; catch 0 # tag type i32 +;; i32.const 3 +;; local.set 1 +;; local.set 2 +;; +;; (This binary was generated by +;; 'wasm-opt --optimize-level=3 --generate-stack-ir -optimize-stack-ir') +;; +;; This code is 'stacky' in Binaryen parlance. In the binary reader, Binaryen has +;; a special routine of creating a block and a local.get/local.set to read stacky +;; code into Binaryen AST. So if we don't do any post-fixup, the 'catch' block +;; becomes: +;; (catch $e-i32 +;; (local.set 2 +;; (block (result i32) +;; (local.set $new +;; (pop i32) +;; ) +;; (local.set 1 +;; (i32.const 3) +;; ) +;; (local.get $new) +;; ) +;; ) +;; ) +;; Here the 'block' and `local $new' are newly created to read the stacky code. +;; But now the 'pop' ends up nested within the 'block', which is invalid. This +;; test tests if this invalid code is correctly fixed up in the binary reader. +;; The fixup will hoist the 'pop' and create another local to store it right +;; after 'catch'. RUN: wasm-opt -all %s.wasm --print | filecheck %s -# CHECK: (func $0 -# CHECK-NEXT: (local $0 i32) -# CHECK-NEXT: (local $1 i32) -# CHECK-NEXT: (local $2 i32) -# CHECK-NEXT: (local $3 i32) -# CHECK-NEXT: (local $4 i32) -# CHECK-NEXT: (try $label$3 -# CHECK-NEXT: (do -# CHECK-NEXT: (nop) -# CHECK-NEXT: ) -# CHECK-NEXT: (catch $tag$0 -# CHECK-NEXT: (local.set $4 -# CHECK-NEXT: (pop i32) -# CHECK-NEXT: ) -# CHECK-NEXT: (local.set $2 -# CHECK-NEXT: (block (result i32) -# CHECK-NEXT: (local.set $3 -# CHECK-NEXT: (local.get $4) -# CHECK-NEXT: ) -# CHECK-NEXT: (local.set $1 -# CHECK-NEXT: (i32.const 3) -# CHECK-NEXT: ) -# CHECK-NEXT: (local.get $3) -# CHECK-NEXT: ) -# CHECK-NEXT: ) -# CHECK-NEXT: ) -# CHECK-NEXT: ) -# CHECK-NEXT: ) +;; CHECK: (func $0 +;; CHECK-NEXT: (local $0 i32) +;; CHECK-NEXT: (local $1 i32) +;; CHECK-NEXT: (local $2 i32) +;; CHECK-NEXT: (local $3 i32) +;; CHECK-NEXT: (local $4 i32) +;; CHECK-NEXT: (try $label$3 +;; CHECK-NEXT: (do +;; CHECK-NEXT: (nop) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (catch $tag$0 +;; CHECK-NEXT: (local.set $4 +;; CHECK-NEXT: (pop i32) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (local.set $2 +;; CHECK-NEXT: (block (result i32) +;; CHECK-NEXT: (local.set $3 +;; CHECK-NEXT: (local.get $4) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (local.set $1 +;; CHECK-NEXT: (i32.const 3) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (local.get $3) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) |