Skip to content

Commit

Permalink
Allow bare try blocks for exceptions
Browse files Browse the repository at this point in the history
The exception handling spec now allows bare `try` blocks that
have no corresponding `catch` (or other) clauses following it.
These blocks are semantically equivalent to `block`.

Related spec PR:

  WebAssembly/exception-handling#157
  • Loading branch information
takikawa committed Jun 14, 2021
1 parent b185388 commit 4c614f5
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 15 deletions.
3 changes: 0 additions & 3 deletions crates/wasmparser/src/operators_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,9 +677,6 @@ impl OperatorValidator {
self.push_ctrl(FrameKind::Else, frame.block_type, resources)?;
frame = self.pop_ctrl(resources)?;
}
FrameKind::Try => {
bail_op_err!("expected catch block");
}
_ => (),
}

Expand Down
11 changes: 3 additions & 8 deletions crates/wast/src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,12 @@ impl<'a> ExpressionParser<'a> {
self.instrs.push(Instruction::End(None));
}

// Both `do` and `catch` are required in a `try` statement, so
// we will signal those errors here. Otherwise, terminate with
// The `do` clause is required in a `try` statement, so
// we will signal that error here. Otherwise, terminate with
// an `end` or `delegate` instruction.
Level::Try(Try::Do(_)) => {
return Err(parser.error("previous `try` had no `do`"));
}
Level::Try(Try::CatchOrDelegate) => {
return Err(parser.error(
"previous `try` had no `catch`, `catch_all`, or `delegate`",
));
}
Level::Try(Try::Delegate) => {}
Level::Try(_) => {
self.instrs.push(Instruction::End(None));
Expand Down Expand Up @@ -372,7 +367,7 @@ impl<'a> ExpressionParser<'a> {
Paren::Right => return Ok(true),
}
}
return Ok(false);
return Err(parser.error("expected a `catch`, `catch_all`, or `delegate`"));
}

if let Try::Catch = i {
Expand Down
14 changes: 10 additions & 4 deletions tests/local/try.wast
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
;; --enable-exceptions

(assert_malformed
(module quote
"(func (try))"
)
"previous `try` had no `do`")

(assert_malformed
(module quote
"(func (try (catch $exn)))"
Expand All @@ -14,15 +20,15 @@

(assert_malformed
(module quote
"(func (try (do)))"
"(func (try (do) (unreachable)))"
)
"previous `try` had no `catch`")
"expected a `catch`, `catch_all`, or `delegate`")

(assert_malformed
(module quote
"(func (try (do) (unreachable)))"
"(func (try (do) (catch_all) (unreachable)))"
)
"previous `try` had no `catch`")
"too many payloads inside of `(try)`")

(assert_malformed
(module quote
Expand Down
1 change: 1 addition & 0 deletions tests/local/try.wat
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
(module $m
(type (func))
(event $exn (type 0))
(func (try (do)))
(func (try (do) (catch $exn)))
(func (try (do) (catch $exn rethrow 0)))
(func (try (do) (catch_all rethrow 0)))
Expand Down

0 comments on commit 4c614f5

Please sign in to comment.