summaryrefslogtreecommitdiff
path: root/test/binaryen.js
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2021-01-15 18:48:00 +0900
committerGitHub <noreply@github.com>2021-01-15 18:48:00 +0900
commitbeccdf70258cd99ea25f10af13103e14dc243ffa (patch)
tree1081d7d350fbab7f901b917f2f082c8d351c3157 /test/binaryen.js
parentf18c18e01d03d6d293fe3d701408855bbcea58bd (diff)
downloadbinaryen-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.js35
-rw-r--r--test/binaryen.js/exception-handling.js.txt20
-rw-r--r--test/binaryen.js/expressions.js73
-rw-r--r--test/binaryen.js/expressions.js.txt63
-rw-r--r--test/binaryen.js/kitchen-sink.js14
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt26
-rw-r--r--test/binaryen.js/sideffects.js2
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()
)
==