Commit 0db4391f authored by Thibaud Michaud's avatar Thibaud Michaud Committed by V8 LUCI CQ

[wasm][eh] Make try block handler optional

A try block may have no handler. Relevant links:
https://github.com/WebAssembly/exception-handling/issues/131
https://github.com/WebAssembly/exception-handling/pull/157

R=clemensb@chromium.org

Bug: v8:8091
Change-Id: Ia429762714dd87ed6b043f95c3496c65aaa8495f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2949100
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75100}
parent 25c3eda9
......@@ -1287,9 +1287,8 @@ class LiftoffCompiler {
}
DCHECK(!c->is_try_catchall());
if (c->is_try_catch()) {
// Drop the implicit exception ref.
DCHECK_EQ(c->label_state.stack_height() + 1,
__ cache_state()->stack_height());
// Drop the implicit exception ref if any. There may be none if this is a
// catch-less try block.
__ MergeStackWith(c->label_state, c->br_merge()->arity,
LiftoffAssembler::kForwardJump);
} else {
......
......@@ -2718,6 +2718,11 @@ class WasmFullDecoder : public WasmDecoder<validate> {
DECODE(End) {
DCHECK(!control_.empty());
Control* c = &control_.back();
if (c->is_incomplete_try()) {
// Catch-less try, fall through to the implicit catch-all.
c->kind = kControlTryCatch;
current_catch_ = c->previous_catch; // Pop try scope.
}
if (c->is_try_catch()) {
// Emulate catch-all + re-throw.
FallThrough();
......@@ -2730,10 +2735,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
PopControl();
return 1;
}
if (!VALIDATE(!c->is_incomplete_try())) {
this->DecodeError("missing catch or catch-all in try");
return 0;
}
if (c->is_onearmed_if()) {
if (!VALIDATE(TypeCheckOneArmedIf(c))) return 0;
}
......
......@@ -1112,3 +1112,22 @@ d8.file.execute("test/mjsunit/wasm/exceptions-utils.js");
let instance = builder.instantiate();
assertEquals(42, instance.exports.throw_with_local());
})();
(function TestCatchlessTry() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let except = builder.addException(kSig_v_v);
builder.addFunction('catchless_try', kSig_v_i)
.addBody([
kExprTry, kWasmVoid,
kExprLocalGet, 0,
kExprIf, kWasmVoid,
kExprThrow, except,
kExprEnd,
kExprEnd,
]).exportFunc();
let instance = builder.instantiate();
assertDoesNotThrow(() => instance.exports.catchless_try(0));
assertWasmThrows(instance, except, [], () => instance.exports.catchless_try(1));
})();
......@@ -2956,14 +2956,13 @@ TEST_F(FunctionBodyDecoderTest, TryCatch) {
ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprCatch, ex, kExprEnd});
ExpectValidates(sigs.v_v(),
{WASM_TRY_OP, kExprCatch, ex, kExprCatchAll, kExprEnd});
ExpectValidates(sigs.v_v(), {WASM_TRY_OP, kExprEnd}, kAppendEnd);
ExpectFailure(sigs.v_v(),
{WASM_TRY_OP, kExprCatchAll, kExprCatch, ex, kExprEnd},
kAppendEnd, "catch after catch-all for try");
ExpectFailure(sigs.v_v(),
{WASM_TRY_OP, kExprCatchAll, kExprCatchAll, kExprEnd},
kAppendEnd, "catch-all already present for try");
ExpectFailure(sigs.v_v(), {WASM_TRY_OP, kExprEnd}, kAppendEnd,
"missing catch or catch-all in try");
ExpectFailure(sigs.v_v(), {kExprCatch, ex, kExprEnd}, kAppendEnd,
"catch does not match a try");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment