Skip to content

Commit

Permalink
Allow plain try with no catch or delegate (#1676)
Browse files Browse the repository at this point in the history
Matches recent changes in the exception handling spec that allowed
this case to reduce special cases in the syntax:

  WebAssembly/exception-handling#157
  • Loading branch information
takikawa authored Jun 30, 2021
1 parent 29323f0 commit 16ab434
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 67 deletions.
4 changes: 2 additions & 2 deletions src/binary-reader-ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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-delegate");
Expand Down Expand Up @@ -1041,7 +1041,7 @@ Result BinaryReaderIR::OnDelegateExpr(Index depth) {

auto* try_ = cast<TryExpr>(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");
Expand Down
4 changes: 2 additions & 2 deletions src/binary-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1012,8 +1012,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;
Expand Down
4 changes: 2 additions & 2 deletions src/expr-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,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;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ struct Catch {
typedef std::vector<Catch> CatchVector;

enum class TryKind {
Invalid,
Plain,
Catch,
Delegate
};
Expand Down Expand Up @@ -603,7 +603,7 @@ class IfExpr : public ExprMixin<ExprType::If> {
class TryExpr : public ExprMixin<ExprType::Try> {
public:
explicit TryExpr(const Location& loc = Location())
: ExprMixin<ExprType::Try>(loc), kind(TryKind::Invalid) {}
: ExprMixin<ExprType::Try>(loc), kind(TryKind::Plain) {}

TryKind kind;
Block block;
Expand Down
42 changes: 21 additions & 21 deletions src/wast-parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2597,8 +2597,6 @@ Result WastParser::ParseBlockInstr(std::unique_ptr<Expr>* out_expr) {
CHECK_RESULT(ParseVar(&var));
expr->delegate_target = var;
expr->kind = TryKind::Delegate;
} else {
return ErrorExpected({"catch", "catch_all", "delegate"});
}
CHECK_RESULT(ErrorIfLpar({"a valid try clause"}));
expr->block.end_loc = GetLocation();
Expand Down Expand Up @@ -2767,26 +2765,28 @@ 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::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::Delegate: {
Consume();
Var var;
CHECK_RESULT(ParseVar(&var));
expr->delegate_target = var;
expr->kind = TryKind::Delegate;
EXPECT(Rpar);
break;
}
default:
ErrorExpected({"catch", "catch_all", "delegate"});
break;
}
default:
ErrorExpected({"catch", "catch_all", "delegate"});
break;
}
CHECK_RESULT(ErrorIfLpar({"a valid try clause"}));
expr->block.end_loc = GetLocation();
Expand Down
4 changes: 2 additions & 2 deletions src/wat-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1171,8 +1171,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();
Expand Down
54 changes: 32 additions & 22 deletions test/dump/try.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
(module
(tag $e (param i32))
(func
try
nop
end
try $try1 (result i32)
nop
i32.const 7
Expand Down Expand Up @@ -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 tag
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 tag
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 ;;;
Expand All @@ -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 ;;)
10 changes: 10 additions & 0 deletions test/parse/expr/bad-try-clause.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
;;; TOOL: wat2wasm
;;; ARGS: --enable-exceptions
;;; ERROR: 1
(module
(func (try (do) (foo)))
(;; STDERR ;;;
out/test/parse/expr/bad-try-clause.txt:5:20: error: unexpected token "foo", expected catch, catch_all or delegate.
(func (try (do) (foo)))
^^^
;;; STDERR ;;)
14 changes: 0 additions & 14 deletions test/parse/expr/bad-try-no-catch.txt

This file was deleted.

6 changes: 6 additions & 0 deletions test/parse/expr/try.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
(module
(tag (param i32))

;; no catch
(func
try
nop
end)

;; bare
(func
try
Expand Down
8 changes: 8 additions & 0 deletions test/roundtrip/fold-try.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit 16ab434

Please sign in to comment.