Commit 8cc07618 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Initial implementation of catch-all decoding.

This adds basic support for decoding catch-all expressions as part of a
try block. Note that control flow and code generation support is still
missing.

R=clemensh@chromium.org
TEST=unittests/FunctionBodyDecoderTest.TryCatchAll
BUG=v8:8091

Change-Id: I10a1aa3e3e0418e0a04965e8318c94f449a00bb4
Reviewed-on: https://chromium-review.googlesource.com/c/1268059
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56444}
parent 3d32fbc1
......@@ -487,7 +487,8 @@ enum ControlKind : uint8_t {
kControlBlock,
kControlLoop,
kControlTry,
kControlTryCatch
kControlTryCatch,
kControlTryCatchAll
};
enum Reachability : uint8_t {
......@@ -534,9 +535,12 @@ struct ControlBase {
bool is_if_else() const { return kind == kControlIfElse; }
bool is_block() const { return kind == kControlBlock; }
bool is_loop() const { return kind == kControlLoop; }
bool is_try() const { return is_incomplete_try() || is_try_catch(); }
bool is_incomplete_try() const { return kind == kControlTry; }
bool is_try_catch() const { return kind == kControlTryCatch; }
bool is_try_catchall() const { return kind == kControlTryCatchAll; }
bool is_try() const {
return is_incomplete_try() || is_try_catch() || is_try_catchall();
}
inline Merge<Value>* br_merge() {
return is_loop() ? &this->start_merge : &this->end_merge;
......@@ -1530,9 +1534,22 @@ class WasmFullDecoder : public WasmDecoder<validate> {
break;
}
case kExprCatchAll: {
// TODO(kschimpf): Implement.
CHECK_PROTOTYPE_OPCODE(eh);
OPCODE_ERROR(opcode, "not implemented yet");
if (!VALIDATE(!control_.empty())) {
this->error("catch-all does not match any try");
break;
}
Control* c = &control_.back();
if (!VALIDATE(c->is_try())) {
this->error("catch-all does not match any try");
break;
}
if (!VALIDATE(!c->is_try_catchall())) {
this->error("catch-all already present for try");
break;
}
c->kind = kControlTryCatchAll;
// TODO(mstarzinger): Implement control flow for catch-all.
break;
}
case kExprLoop: {
......@@ -1587,7 +1604,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
}
Control* c = &control_.back();
if (!VALIDATE(!c->is_incomplete_try())) {
this->error(this->pc_, "missing catch in try");
this->error(this->pc_, "missing catch or catch-all in try");
break;
}
if (c->is_onearmed_if()) {
......
......@@ -2433,24 +2433,30 @@ TEST_F(FunctionBodyDecoderTest, ThrowUnreachable) {
TEST_F(FunctionBodyDecoderTest, TryCatch) {
WASM_FEATURE_SCOPE(eh);
TestModuleBuilder builder;
module = builder.module();
builder.AddException(sigs.v_v());
builder.AddException(sigs.v_v());
// TODO(kschimpf): Need to fix catch to use declared exception.
EXPECT_VERIFIES(v_v, WASM_TRY_OP, WASM_CATCH(0), kExprEnd);
// Missing catch.
EXPECT_FAILURE(v_v, WASM_TRY_OP, kExprEnd);
byte ex1 = builder.AddException(sigs.v_v());
byte ex2 = builder.AddException(sigs.v_v());
EXPECT_VERIFIES(v_v, WASM_TRY_OP, WASM_CATCH(ex1), kExprEnd);
EXPECT_FAILURE(v_v, WASM_TRY_OP, kExprEnd); // Missing catch.
EXPECT_FAILURE(v_v, WASM_TRY_OP, WASM_CATCH(ex1)); // Missing end.
EXPECT_FAILURE(v_v, WASM_CATCH(ex1), kExprEnd); // Missing try.
// Missing end.
EXPECT_FAILURE(v_i, WASM_TRY_OP, WASM_CATCH(0));
// TODO(mstarzinger): Double catch. Fix this to verify.
EXPECT_FAILURE(v_v, WASM_TRY_OP, WASM_CATCH(ex1), WASM_CATCH(ex2), kExprEnd);
}
// Double catch.
// TODO(kschimpf): Fix this to verify.
EXPECT_FAILURE(v_i, WASM_TRY_OP, WASM_CATCH(0), WASM_CATCH(1), kExprEnd);
TEST_F(FunctionBodyDecoderTest, TryCatchAll) {
WASM_FEATURE_SCOPE(eh);
TestModuleBuilder builder;
module = builder.module();
byte ex1 = builder.AddException(sigs.v_v());
EXPECT_VERIFIES(v_v, WASM_TRY_OP, kExprCatchAll, kExprEnd);
EXPECT_VERIFIES(v_v, WASM_TRY_OP, WASM_CATCH(ex1), kExprCatchAll, kExprEnd);
EXPECT_FAILURE(v_v, WASM_TRY_OP, kExprCatchAll, kExprCatchAll, kExprEnd);
EXPECT_FAILURE(v_v, WASM_TRY_OP, kExprCatchAll, WASM_CATCH(ex1), kExprEnd);
EXPECT_FAILURE(v_v, WASM_TRY_OP, kExprCatchAll); // Missing end.
EXPECT_FAILURE(v_v, kExprCatchAll, kExprEnd); // Missing try.
}
#undef WASM_TRY_OP
......
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