diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index d060be08ab..45056f77fe 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -1010,7 +1010,7 @@ Result BinaryReaderIR::AppendCatch(Catch&& catch_) { return Result::Error; } - if (try_->kind == TryKind::Invalid) { + if (try_->kind == TryKind::Plain) { try_->kind = TryKind::Catch; } else if (try_->kind != TryKind::Catch) { PrintError("catch not allowed in try-unwind or try-delegate"); @@ -1041,7 +1041,7 @@ Result BinaryReaderIR::OnUnwindExpr() { auto* try_ = cast(label->context); - if (try_->kind == TryKind::Invalid) { + if (try_->kind == TryKind::Plain) { try_->kind = TryKind::Unwind; } else if (try_->kind != TryKind::Unwind) { PrintError("unwind not allowed in try-catch or try-delegate"); @@ -1063,7 +1063,7 @@ Result BinaryReaderIR::OnDelegateExpr(Index depth) { auto* try_ = cast(label->context); - if (try_->kind == TryKind::Invalid) { + if (try_->kind == TryKind::Plain) { try_->kind = TryKind::Delegate; } else if (try_->kind != TryKind::Delegate) { PrintError("delegate not allowed in try-catch or try-unwind"); diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 54b5a4a92a..99b725ddbf 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -1018,8 +1018,8 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { GetLabelVarDepth(&try_expr->delegate_target), "delegate depth"); break; - case TryKind::Invalid: - // Should not occur. + case TryKind::Plain: + WriteOpcode(stream_, Opcode::End); break; } break; diff --git a/src/expr-visitor.cc b/src/expr-visitor.cc index 5ef2b473d2..edf5ded6ad 100644 --- a/src/expr-visitor.cc +++ b/src/expr-visitor.cc @@ -114,8 +114,8 @@ Result ExprVisitor::VisitExpr(Expr* root_expr) { case TryKind::Delegate: CHECK_RESULT(delegate_->OnDelegateExpr(try_expr)); break; - case TryKind::Invalid: - // Should not happen. + case TryKind::Plain: + CHECK_RESULT(delegate_->EndTryExpr(try_expr)); break; } } diff --git a/src/ir.h b/src/ir.h index fb21870554..b29c2de09f 100644 --- a/src/ir.h +++ b/src/ir.h @@ -378,7 +378,7 @@ struct Catch { typedef std::vector CatchVector; enum class TryKind { - Invalid, + Plain, Catch, Unwind, Delegate @@ -604,7 +604,7 @@ class IfExpr : public ExprMixin { class TryExpr : public ExprMixin { public: explicit TryExpr(const Location& loc = Location()) - : ExprMixin(loc), kind(TryKind::Invalid) {} + : ExprMixin(loc), kind(TryKind::Plain) {} TryKind kind; Block block; diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 3eee1eeb3d..d18f3878a6 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -2601,8 +2601,6 @@ Result WastParser::ParseBlockInstr(std::unique_ptr* out_expr) { CHECK_RESULT(ParseVar(&var)); expr->delegate_target = var; expr->kind = TryKind::Delegate; - } else { - return ErrorExpected({"catch", "catch_all", "unwind", "delegate"}); } CHECK_RESULT(ErrorIfLpar({"a valid try clause"})); expr->block.end_loc = GetLocation(); @@ -2771,32 +2769,33 @@ Result WastParser::ParseExpr(ExprList* exprs) { EXPECT(Do); CHECK_RESULT(ParseInstrList(&expr->block.exprs)); EXPECT(Rpar); - EXPECT(Lpar); - TokenType type = Peek(); - switch (type) { - case TokenType::Catch: - case TokenType::CatchAll: - CHECK_RESULT(ParseCatchExprList(&expr->catches)); - expr->kind = TryKind::Catch; - break; - case TokenType::Unwind: - Consume(); - CHECK_RESULT(ParseTerminatingInstrList(&expr->unwind)); - expr->kind = TryKind::Unwind; - EXPECT(Rpar); - break; - case TokenType::Delegate: { - Consume(); - Var var; - CHECK_RESULT(ParseVar(&var)); - expr->delegate_target = var; - expr->kind = TryKind::Delegate; - EXPECT(Rpar); - break; + if (PeekMatch(TokenType::Lpar)) { + Consume(); + TokenType type = Peek(); + switch (type) { + case TokenType::Catch: + case TokenType::CatchAll: + CHECK_RESULT(ParseCatchExprList(&expr->catches)); + expr->kind = TryKind::Catch; + break; + case TokenType::Unwind: + Consume(); + CHECK_RESULT(ParseTerminatingInstrList(&expr->unwind)); + expr->kind = TryKind::Unwind; + EXPECT(Rpar); + break; + case TokenType::Delegate: { + Consume(); + Var var; + CHECK_RESULT(ParseVar(&var)); + expr->delegate_target = var; + expr->kind = TryKind::Delegate; + EXPECT(Rpar); + break; + } + default: + break; } - default: - ErrorExpected({"catch", "catch_all", "unwind", "delegate"}); - break; } CHECK_RESULT(ErrorIfLpar({"a valid try clause"})); expr->block.end_loc = GetLocation(); diff --git a/src/wat-writer.cc b/src/wat-writer.cc index 93ac48865a..aa0820131e 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc @@ -1187,8 +1187,8 @@ void WatWriter::FlushExprTree(const ExprTree& expr_tree) { WriteVar(try_expr->delegate_target, NextChar::None); WritePuts(")", NextChar::Newline); break; - case TryKind::Invalid: - // Should not occur. + case TryKind::Plain: + // Nothing to do. break; } WriteCloseNewline(); diff --git a/test/dump/try.txt b/test/dump/try.txt index 23c750b706..83db473f77 100644 --- a/test/dump/try.txt +++ b/test/dump/try.txt @@ -3,6 +3,9 @@ (module (event $e (param i32)) (func + try + nop + end try $try1 (result i32) nop i32.const 7 @@ -55,22 +58,26 @@ 0000021: 00 ; func body size (guess) 0000022: 00 ; local decl count 0000023: 06 ; try -0000024: 7f ; i32 +0000024: 40 ; void 0000025: 01 ; nop -0000026: 41 ; i32.const -0000027: 07 ; i32 literal -0000028: 07 ; catch -0000029: 00 ; catch event -000002a: 1a ; drop -000002b: 41 ; i32.const -000002c: 08 ; i32 literal -000002d: 0b ; end +0000026: 0b ; end +0000027: 06 ; try +0000028: 7f ; i32 +0000029: 01 ; nop +000002a: 41 ; i32.const +000002b: 07 ; i32 literal +000002c: 07 ; catch +000002d: 00 ; catch event 000002e: 1a ; drop -000002f: 0b ; end -0000021: 0e ; FIXUP func body size -000001f: 10 ; FIXUP section size -; move data: [1e, 30) -> [1b, 2d) -; truncate to 45 (0x2d) +000002f: 41 ; i32.const +0000030: 08 ; i32 literal +0000031: 0b ; end +0000032: 1a ; drop +0000033: 0b ; end +0000021: 12 ; FIXUP func body size +000001f: 14 ; FIXUP section size +; move data: [1e, 34) -> [1b, 31) +; truncate to 49 (0x31) ;;; STDERR ;;) (;; STDOUT ;;; @@ -79,13 +86,16 @@ try.wasm: file format wasm 0x1 Code Disassembly: 00001f func[0]: - 000020: 06 7f | try i32 + 000020: 06 40 | try 000022: 01 | nop - 000023: 41 07 | i32.const 7 - 000025: 07 00 | catch 0 - 000027: 1a | drop - 000028: 41 08 | i32.const 8 - 00002a: 0b | end - 00002b: 1a | drop - 00002c: 0b | end + 000023: 0b | end + 000024: 06 7f | try i32 + 000026: 01 | nop + 000027: 41 07 | i32.const 7 + 000029: 07 00 | catch 0 + 00002b: 1a | drop + 00002c: 41 08 | i32.const 8 + 00002e: 0b | end + 00002f: 1a | drop + 000030: 0b | end ;;; STDOUT ;;) diff --git a/test/parse/expr/bad-try-no-catch.txt b/test/parse/expr/bad-try-no-catch.txt deleted file mode 100644 index a1e5ebdec8..0000000000 --- a/test/parse/expr/bad-try-no-catch.txt +++ /dev/null @@ -1,14 +0,0 @@ -;;; TOOL: wat2wasm -;;; ARGS: --enable-exceptions -;;; ERROR: 1 -(module - (func try nop end) - (func (try (do nop)))) -(;; STDERR ;;; -out/test/parse/expr/bad-try-no-catch.txt:5:17: error: unexpected token "end", expected catch, catch_all, unwind or delegate. - (func try nop end) - ^^^ -out/test/parse/expr/bad-try-no-catch.txt:6:22: error: unexpected token ), expected (. - (func (try (do nop)))) - ^ -;;; STDERR ;;) diff --git a/test/parse/expr/try.txt b/test/parse/expr/try.txt index fabb994c18..d0a4c88f57 100644 --- a/test/parse/expr/try.txt +++ b/test/parse/expr/try.txt @@ -3,6 +3,12 @@ (module (event (param i32)) + ;; no catch + (func + try + nop + end) + ;; bare (func try diff --git a/test/roundtrip/fold-try.txt b/test/roundtrip/fold-try.txt index d33dbbe20c..412e34ca42 100644 --- a/test/roundtrip/fold-try.txt +++ b/test/roundtrip/fold-try.txt @@ -2,6 +2,10 @@ ;;; ARGS: --stdout --fold-exprs --enable-exceptions --debug-names (module (func (result i32) + try (result i32) + i32.const 6 + end + drop try (result i32) nop i32.const 7 @@ -14,6 +18,10 @@ (module (type (;0;) (func (result i32))) (func (;0;) (type 0) (result i32) + (drop + (try (result i32) ;; label = @1 + (do + (i32.const 6)))) (try (result i32) ;; label = @1 (do (nop)