diff options
author | Heejin Ahn <aheejin@gmail.com> | 2021-01-15 18:48:00 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-15 18:48:00 +0900 |
commit | beccdf70258cd99ea25f10af13103e14dc243ffa (patch) | |
tree | 1081d7d350fbab7f901b917f2f082c8d351c3157 /test/binaryen.js | |
parent | f18c18e01d03d6d293fe3d701408855bbcea58bd (diff) | |
download | binaryen-beccdf70258cd99ea25f10af13103e14dc243ffa.tar.gz binaryen-beccdf70258cd99ea25f10af13103e14dc243ffa.tar.bz2 binaryen-beccdf70258cd99ea25f10af13103e14dc243ffa.zip |
Basic EH instrucion support for the new spec (#3487)
This updates `try`-`catch`-`catch_all` and `rethrow` instructions to
match the new spec. `delegate` is not included. Now `Try` contains not a
single `catchBody` expression but a vector of catch
bodies and events.
This updates most existing routines, optimizations, and tests modulo the
interpreter and the CFG traversal. Because the interpreter has not been
updated yet, the EH spec test is temporarily disabled in check.py. Also,
because the CFG traversal for EH is not yet updated, several EH tests in
`rse_all-features.wast`, which uses CFG traversal, are temporarily
commented out.
Also added a few more tests in existing EH test functions in
test/passes. In the previous spec, `catch` was catching all exceptions
so it was assumed that anything `try` body throws is caught by its
`catch`, but now we can assume the same only if there is a `catch_all`.
Newly added tests test cases when there is a `catch_all` and cases there
are only `catch`es separately.
Diffstat (limited to 'test/binaryen.js')
-rw-r--r-- | test/binaryen.js/exception-handling.js | 35 | ||||
-rw-r--r-- | test/binaryen.js/exception-handling.js.txt | 20 | ||||
-rw-r--r-- | test/binaryen.js/expressions.js | 73 | ||||
-rw-r--r-- | test/binaryen.js/expressions.js.txt | 63 | ||||
-rw-r--r-- | test/binaryen.js/kitchen-sink.js | 14 | ||||
-rw-r--r-- | test/binaryen.js/kitchen-sink.js.txt | 26 | ||||
-rw-r--r-- | test/binaryen.js/sideffects.js | 2 |
7 files changed, 142 insertions, 91 deletions
diff --git a/test/binaryen.js/exception-handling.js b/test/binaryen.js/exception-handling.js index 3f5f6de74..e6cadcf88 100644 --- a/test/binaryen.js/exception-handling.js +++ b/test/binaryen.js/exception-handling.js @@ -1,7 +1,9 @@ function cleanInfo(info) { var ret = {}; for (var x in info) { - if (x == 'id' || x == 'type' || x == 'name' || x == 'event') { + // Filter out address pointers and only print meaningful info + if (x == 'id' || x == 'type' || x == 'name' || x == 'event' || + x == 'depth' || x == 'hasCatchAll') { ret[x] = info[x]; } } @@ -23,36 +25,31 @@ var event_ = module.addEvent("e", 0, binaryen.i32, binaryen.none); // (throw $e (i32.const 0)) // ) // (catch -// ;; We don't support multi-value yet. Use locals instead. -// (local.set 0 (exnref.pop)) -// (drop -// (block $l (result i32) -// (rethrow -// (br_on_exn $l $e (local.get 0)) -// ) -// ) -// ) +// (drop (pop i32)) +// (rethrow 0) // ) // ) var throw_ = module.throw("e", [module.i32.const(0)]); -var br_on_exn = module.br_on_exn("l", "e", module.local.get(0, binaryen.exnref)); -var rethrow = module.rethrow(br_on_exn); +var rethrow = module.rethrow(0); var try_ = module.try( throw_, - module.block(null, [ - module.local.set(0, module.exnref.pop()), - module.drop( - module.block("l", [rethrow], binaryen.i32) + ["e"], + [ + module.block(null, + [ + module.drop(module.i32.pop()), + rethrow + ], + binaryen.none ) ] - ) ); -var func = module.addFunction("test", binaryen.none, binaryen.none, [binaryen.exnref], try_); + +var func = module.addFunction("test", binaryen.none, binaryen.none, [], try_); console.log(module.emitText()); assert(module.validate()); console.log("getExpressionInfo(throw) = " + stringify(throw_)); -console.log("getExpressionInfo(br_on_exn) = " + stringify(br_on_exn)); console.log("getExpressionInfo(rethrow) = " + stringify(rethrow)); console.log("getExpressionInfo(try) = " + stringify(try_)); diff --git a/test/binaryen.js/exception-handling.js.txt b/test/binaryen.js/exception-handling.js.txt index 19861dd21..e7c72e6a7 100644 --- a/test/binaryen.js/exception-handling.js.txt +++ b/test/binaryen.js/exception-handling.js.txt @@ -3,32 +3,22 @@ (type $i32_=>_none (func (param i32))) (event $e (attr 0) (param i32)) (func $test - (local $0 exnref) (try (do (throw $e (i32.const 0) ) ) - (catch - (local.set $0 - (pop exnref) - ) + (catch $e (drop - (block $l (result i32) - (rethrow - (br_on_exn $l $e - (local.get $0) - ) - ) - ) + (pop i32) ) + (rethrow 0) ) ) ) ) getExpressionInfo(throw) = {"id":47,"type":1,"event":"e"} -getExpressionInfo(br_on_exn) = {"id":49,"type":9,"name":"l","event":"e"} -getExpressionInfo(rethrow) = {"id":48,"type":1} -getExpressionInfo(try) = {"id":46,"type":0} +getExpressionInfo(rethrow) = {"id":48,"type":1,"depth":0} +getExpressionInfo(try) = {"id":46,"type":1,"hasCatchAll":0} diff --git a/test/binaryen.js/expressions.js b/test/binaryen.js/expressions.js index 61fc0a3ef..757d88b1b 100644 --- a/test/binaryen.js/expressions.js +++ b/test/binaryen.js/expressions.js @@ -1435,31 +1435,69 @@ console.log("# RefEq"); console.log("# Try"); (function testTry() { const module = new binaryen.Module(); + module.addEvent("event1", 0, binaryen.none, binaryen.none); + module.addEvent("event2", 0, binaryen.none, binaryen.none); + module.addEvent("event3", 0, binaryen.none, binaryen.none); var body = module.i32.const(1); - var catchBody = module.i32.const(2); - const theTry = binaryen.Try(module.try(body, catchBody)); + var catchBodies = [ + module.i32.const(2), + module.i32.const(3) + ]; + const theTry = binaryen.Try(module.try(body, ["event1"], catchBodies)); assert(theTry instanceof binaryen.Try); assert(theTry instanceof binaryen.Expression); assert(theTry.body === body); - assert(theTry.catchBody === catchBody); + assertDeepEqual(theTry.catchBodies, catchBodies); assert(theTry.type === binaryen.i32); + assert(theTry.getNumCatchEvents() == 1); + assert(theTry.getNumCatchBodies() == 2); + assert(theTry.hasCatchAll() == 1); + console.log(theTry.toText()); - theTry.body = body = module.i32.const(3); + theTry.body = body = module.i32.const(4); assert(theTry.body === body); - theTry.catchBody = catchBody = module.i32.const(4); - assert(theTry.catchBody === catchBody); + catchBodies = [ + module.i32.const(5) // set + //remove + ]; + theTry.setCatchBodies(catchBodies); + assertDeepEqual(theTry.catchBodies, catchBodies); + assertDeepEqual(theTry.getCatchBodies(), catchBodies); + console.log(theTry.toText()); + + theTry.insertCatchEventAt(1, "event2"); + theTry.insertCatchBodyAt(0, module.i32.const(6)); + assert(theTry.getNumCatchEvents() == 2); + assert(theTry.getNumCatchBodies() == 2); + assert(theTry.hasCatchAll() == 0); + console.log(theTry.toText()); + + assert(theTry.removeCatchEventAt(1) == "event2"); + theTry.removeCatchBodyAt(1); + assert(theTry.getNumCatchEvents() == 1); + assert(theTry.getNumCatchBodies() == 1); + console.log(theTry.toText()); + + theTry.appendCatchEvent("event3"); + theTry.appendCatchBody(module.drop(module.i32.const(7))); + assert(theTry.getCatchEventAt(0) == "event1"); + assert(theTry.getCatchEventAt(1) == "event3"); + theTry.setCatchEvents(["event2", "event3"]); + assertDeepEqual(theTry.getCatchEvents(), ["event2", "event3"]); + theTry.setCatchBodies([module.i32.const(8), module.i32.const(9)]); + assert(theTry.getCatchEventAt(0) == "event2"); + assert(theTry.getCatchEventAt(1) == "event3"); + theTry.setCatchEventAt(1, "event1"); + theTry.setCatchBodyAt(1, module.i32.const(10)); + assert(theTry.getCatchEventAt(1) == "event1"); + console.log(theTry.toText()); + theTry.type = binaryen.f64; theTry.finalize(); assert(theTry.type === binaryen.i32); console.log(theTry.toText()); - assert( - theTry.toText() - == - "(try (result i32)\n (do\n (i32.const 3)\n )\n (catch\n (i32.const 4)\n )\n)\n" - ); - module.dispose(); })(); @@ -1512,15 +1550,14 @@ console.log("# Rethrow"); (function testRethrow() { const module = new binaryen.Module(); - var exnref = module.local.get(1, binaryen.exnref); - const theRethrow = binaryen.Rethrow(module.rethrow(exnref)); + const theRethrow = binaryen.Rethrow(module.rethrow(0)); assert(theRethrow instanceof binaryen.Rethrow); assert(theRethrow instanceof binaryen.Expression); - assert(theRethrow.exnref === exnref); + assert(theRethrow.depth === 0); assert(theRethrow.type === binaryen.unreachable); - theRethrow.exnref = exnref = module.local.get(2, binaryen.exnref); - assert(theRethrow.exnref === exnref); + theRethrow.depth = 1 + assert(theRethrow.depth === 1); theRethrow.type = binaryen.f64; theRethrow.finalize(); assert(theRethrow.type === binaryen.unreachable); @@ -1529,7 +1566,7 @@ console.log("# Rethrow"); assert( theRethrow.toText() == - "(rethrow\n (local.get $2)\n)\n" + "(rethrow 1)\n" ); module.dispose(); diff --git a/test/binaryen.js/expressions.js.txt b/test/binaryen.js/expressions.js.txt index ba946b296..d6c090d18 100644 --- a/test/binaryen.js/expressions.js.txt +++ b/test/binaryen.js/expressions.js.txt @@ -219,11 +219,68 @@ # Try (try (result i32) (do + (i32.const 1) + ) + (catch $event1 + (i32.const 2) + ) + (catch_all (i32.const 3) ) - (catch +) + +(try (result i32) + (do (i32.const 4) ) + (catch $event1 + (i32.const 5) + ) +) + +(try (result i32) + (do + (i32.const 4) + ) + (catch $event1 + (i32.const 6) + ) + (catch $event2 + (i32.const 5) + ) +) + +(try (result i32) + (do + (i32.const 4) + ) + (catch $event1 + (i32.const 6) + ) +) + +(try (result i32) + (do + (i32.const 4) + ) + (catch $event2 + (i32.const 8) + ) + (catch $event1 + (i32.const 10) + ) +) + +(try (result i32) + (do + (i32.const 4) + ) + (catch $event2 + (i32.const 8) + ) + (catch $event1 + (i32.const 10) + ) ) # Throw @@ -233,9 +290,7 @@ ) # Rethrow -(rethrow - (local.get $2) -) +(rethrow 1) # BrOnExn (br_on_exn $bar $event2 diff --git a/test/binaryen.js/kitchen-sink.js b/test/binaryen.js/kitchen-sink.js index 146335130..8e7e81f26 100644 --- a/test/binaryen.js/kitchen-sink.js +++ b/test/binaryen.js/kitchen-sink.js @@ -547,18 +547,8 @@ function test_core() { // Exception handling module.try( module.throw("a-event", [module.i32.const(0)]), - module.block(null, [ - module.local.set(5, module.exnref.pop()), - module.drop( - module.block("try-block", [ - module.rethrow( - module.br_on_exn("try-block", "a-event", - module.local.get(5, binaryen.exnref)), - ) - ], binaryen.i32) - ) - ] - ) + ["a-event"], + [module.drop(module.i32.pop())] ), // Atomics diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt index 907d490fe..ef15d8a00 100644 --- a/test/binaryen.js/kitchen-sink.js.txt +++ b/test/binaryen.js/kitchen-sink.js.txt @@ -1865,18 +1865,9 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (i32.const 0) ) ) - (catch - (local.set $5 - (pop exnref) - ) + (catch $a-event (drop - (block $try-block (result i32) - (rethrow - (br_on_exn $try-block $a-event - (local.get $5) - ) - ) - ) + (pop i32) ) ) ) @@ -3737,18 +3728,9 @@ getExpressionInfo(tuple[3])={"id":14,"type":5,"value":3.7} (i32.const 0) ) ) - (catch - (local.set $5 - (pop exnref) - ) + (catch $a-event (drop - (block $try-block (result i32) - (rethrow - (br_on_exn $try-block $a-event - (local.get $5) - ) - ) - ) + (pop i32) ) ) ) diff --git a/test/binaryen.js/sideffects.js b/test/binaryen.js/sideffects.js index bfb5404c2..cb0e8ac7f 100644 --- a/test/binaryen.js/sideffects.js +++ b/test/binaryen.js/sideffects.js @@ -108,7 +108,7 @@ assert( assert( binaryen.getSideEffects( - module.drop(module.exnref.pop()), + module.drop(module.i32.pop()), module.getFeatures() ) == |