v8/test/mjsunit/wasm/exceptions-catchall.js
Michael Starzinger 73250d9c88 [wasm] Fix corner cases with catch-all handling.
This fixes handling of two corner cases with catch-all blocks:
1) The catch-all blocks are conceptually outside the corresponding try.
2) Reachability of catch-all is determined by parent reachability.

R=clemensh@chromium.org
TEST=mjsunit/wasm/exceptions-catchall
BUG=v8:8091

Change-Id: Idfd8310bc232f3ce389763023c5a33f1ef90e0b5
Reviewed-on: https://chromium-review.googlesource.com/c/1270816
Reviewed-by: Ben Titzer <titzer@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56486}
2018-10-09 14:15:13 +00:00

101 lines
3.3 KiB
JavaScript

// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-eh
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
// Test that a catch-all block handles all exceptions thrown locally, but is
// applied only after typed catch blocks have been handled.
(function TestCatchAllLocal() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except1 = builder.addException(kSig_v_v);
let except2 = builder.addException(kSig_v_v);
builder.addFunction("catchall_local", kSig_i_i)
.addBody([
kExprTry, kWasmI32,
kExprGetLocal, 0,
kExprI32Const, 1,
kExprI32Eq,
kExprIf, kWasmStmt,
kExprThrow, except1,
kExprEnd,
kExprGetLocal, 0,
kExprI32Const, 2,
kExprI32Eq,
kExprIf, kWasmStmt,
kExprThrow, except2,
kExprEnd,
kExprI32Const, 61,
kExprCatch, except1,
kExprI32Const, 23,
kExprCatchAll,
kExprI32Const, 42,
kExprEnd
]).exportFunc();
let instance = builder.instantiate();
assertEquals(23, instance.exports.catchall_local(1));
assertEquals(42, instance.exports.catchall_local(2));
assertEquals(61, instance.exports.catchall_local(3));
})();
// Test that a catch-all block handles all exceptions thrown externally, even
// those originating from JavaScript instead of WebAssembly.
(function TestCatchAllExternal() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_v);
let fun = builder.addImport("m", "f", sig_index);
let except = builder.addException(kSig_v_v);
builder.addFunction("throw", kSig_v_v)
.addBody([
kExprThrow, except
]).exportFunc();
builder.addFunction("catchall_external", kSig_i_v)
.addBody([
kExprTry, kWasmI32,
kExprCallFunction, fun,
kExprUnreachable,
kExprCatch, except,
kExprI32Const, 23,
kExprCatchAll,
kExprI32Const, 42,
kExprEnd,
]).exportFunc();
let ex_obj = new Error("my exception");
let instance = builder.instantiate({ m: { f: function() { throw ex_obj }}});
assertThrows(() => instance.exports.throw(), WebAssembly.RuntimeError);
assertEquals(42, instance.exports.catchall_external()); // From JavaScript.
try {
instance.exports.throw();
} catch (e) {
ex_obj = e;
}
assertEquals(23, instance.exports.catchall_external()); // From WebAssembly.
})();
// Test that expressions in a catch-all block are considered to be outside of
// the corresponding try block. Exceptions raised in them will percolate up.
(function TestCatchAllThrowing() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except1 = builder.addException(kSig_v_v);
let except2 = builder.addException(kSig_v_v);
builder.addFunction("catchall", kSig_v_v)
.addBody([
kExprTry, kWasmStmt,
kExprThrow, except1,
kExprCatchAll,
kExprThrow, except2,
kExprEnd
]).exportFunc();
let instance = builder.instantiate();
assertThrows(() => instance.exports.catchall(), WebAssembly.RuntimeError);
})();