Commit b2b40134 authored by jpp's avatar jpp Committed by Commit bot

[WASM] Exception handling prototype.

------------------------------------------------------------------------

This CL adds support for decoding eh-related wasm opcodes:
* Throw: used for raising an exception; the thrown value lives on top of
         the evaluation stack;
* TryCatch: used to start a try block that has a catch clause;
* TryFinally: used to start a try block that has a finally clause;
* TryCatchFinally: used to start a try block that has both catch and
                   finally clauses;
* Catch <local>: used to start the catch block of a
                 TryCatch/TryCatchFinally block; the thrown value is
                 stored in local <local>; and
* Finally: used to start a finally block of TryFinally/TryCatchFinally.

Three different opcodes are used to start a try block to simplify the
AST construction during bytecode parsing.

BUG=

Review-Url: https://codereview.chromium.org/2222193004
Cr-Commit-Position: refs/heads/master@{#38579}
parent b8f47504
......@@ -529,6 +529,8 @@ DEFINE_INT(typed_array_max_size_in_heap, 64,
DEFINE_BOOL(wasm_simd_prototype, false,
"enable prototype simd opcodes for wasm")
DEFINE_BOOL(wasm_eh_prototype, false,
"enable prototype exception handling opcodes for wasm")
// Profiler flags.
DEFINE_INT(frame_count, 1, "number of stack frames inspected by the profiler")
......
This diff is collapsed.
......@@ -55,6 +55,12 @@ const WasmCodePosition kNoCodePosition = -1;
V(BrTable, 0x08, _) \
V(Return, 0x09, _) \
V(Unreachable, 0x0a, _) \
V(Throw, 0xfa, _) \
V(TryCatch, 0xfb, _) \
V(TryCatchFinally, 0xfc, _) \
V(TryFinally, 0xfd, _) \
V(Catch, 0xfe, _) \
V(Finally, 0xff, _) \
V(End, 0x0F, _)
// Constants, locals, globals, and calls.
......
......@@ -1829,6 +1829,91 @@ TEST_F(AstDecoderTest, Select_TypeCheck) {
WASM_SELECT(WASM_F32(9.9), WASM_GET_LOCAL(0), WASM_I64V_1(0)));
}
TEST_F(AstDecoderTest, Throw) {
FLAG_wasm_eh_prototype = true;
EXPECT_VERIFIES_INLINE(sigs.v_i(), WASM_GET_LOCAL(0), kExprThrow);
// TODO(jpp): can't throw d, f, or l.
EXPECT_VERIFIES_INLINE(sigs.i_d(), WASM_GET_LOCAL(0), kExprThrow,
WASM_I32V(0));
EXPECT_VERIFIES_INLINE(sigs.i_f(), WASM_GET_LOCAL(0), kExprThrow,
WASM_I32V(0));
EXPECT_VERIFIES_INLINE(sigs.l_l(), WASM_GET_LOCAL(0), kExprThrow,
WASM_I64V(0));
}
#define WASM_CATCH(local) kExprCatch, static_cast<byte>(local)
TEST_F(AstDecoderTest, TryCatch) {
FLAG_wasm_eh_prototype = true;
EXPECT_VERIFIES_INLINE(sigs.v_i(), kExprTryCatch, WASM_CATCH(0), kExprEnd);
// Missing catch.
EXPECT_FAILURE_INLINE(sigs.v_v(), kExprTryCatch, kExprEnd);
// Missing end.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatch, WASM_CATCH(0));
// Double catch.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatch, WASM_CATCH(0), WASM_CATCH(0),
kExprEnd);
// Unexpected finally.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatch, WASM_CATCH(0), kExprFinally,
kExprEnd);
}
TEST_F(AstDecoderTest, TryFinally) {
FLAG_wasm_eh_prototype = true;
EXPECT_VERIFIES_INLINE(sigs.v_v(), kExprTryFinally, kExprFinally, kExprEnd);
// Mising finally.
EXPECT_FAILURE_INLINE(sigs.v_v(), kExprTryFinally, kExprEnd);
// Missing end.
EXPECT_FAILURE_INLINE(sigs.v_v(), kExprTryFinally, kExprFinally);
// Double finally.
EXPECT_FAILURE_INLINE(sigs.v_v(), kExprTryFinally, kExprFinally, kExprFinally,
kExprEnd);
// Unexpected catch.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatch, WASM_CATCH(0), kExprFinally,
kExprEnd);
}
TEST_F(AstDecoderTest, TryCatchFinally) {
FLAG_wasm_eh_prototype = true;
EXPECT_VERIFIES_INLINE(sigs.v_i(), kExprTryCatchFinally, WASM_CATCH(0),
kExprFinally, kExprEnd);
// Missing catch.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, kExprFinally,
kExprEnd);
// Double catch.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, WASM_CATCH(0),
WASM_CATCH(0), kExprFinally, kExprEnd);
// Missing finally.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, WASM_CATCH(0),
kExprEnd);
// Double finally.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, WASM_CATCH(0),
kExprFinally, kExprFinally, kExprEnd);
// Finally before catch.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, kExprFinally,
WASM_CATCH(0), kExprEnd);
// Missing both try and finally.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, kExprEnd);
// Missing end.
EXPECT_FAILURE_INLINE(sigs.v_i(), kExprTryCatchFinally, WASM_CATCH(0),
kExprFinally);
}
class WasmOpcodeLengthTest : public TestWithZone {
public:
WasmOpcodeLengthTest() : TestWithZone() {}
......@@ -1856,6 +1941,12 @@ TEST_F(WasmOpcodeLengthTest, Statements) {
EXPECT_LENGTH(1, kExprSelect);
EXPECT_LENGTH(3, kExprBr);
EXPECT_LENGTH(3, kExprBrIf);
EXPECT_LENGTH(1, kExprThrow);
EXPECT_LENGTH(1, kExprTryCatch);
EXPECT_LENGTH(1, kExprTryFinally);
EXPECT_LENGTH(1, kExprTryCatchFinally);
EXPECT_LENGTH(2, kExprCatch);
EXPECT_LENGTH(1, kExprFinally);
}
TEST_F(WasmOpcodeLengthTest, MiscExpressions) {
......@@ -2097,6 +2188,13 @@ TEST_F(WasmOpcodeArityTest, Control) {
EXPECT_ARITY(0, kExprReturn, ARITY_0);
EXPECT_ARITY(1, kExprReturn, ARITY_1);
}
EXPECT_ARITY(0, kExprThrow);
EXPECT_ARITY(0, kExprTryCatch);
EXPECT_ARITY(0, kExprTryFinally);
EXPECT_ARITY(0, kExprTryCatchFinally);
EXPECT_ARITY(1, kExprCatch, 2);
EXPECT_ARITY(0, kExprFinally);
}
TEST_F(WasmOpcodeArityTest, Misc) {
......
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