Skip to content

Commit

Permalink
Fix validation of catch/catch_all with try params
Browse files Browse the repository at this point in the history
This commit fixes an accidental regression from bytecodealliance#697 in the refactoring
I added at the end where manual modification of `self.control` was
replaced with `self.push_ctrl`. For the exceptions proposal specifically
this is not valid since the `block_type` for the frame doesn't get the
parameters pushed when the `catch` and `catch_all` instructions are
encountered.
  • Loading branch information
alexcrichton committed Aug 11, 2022
1 parent 63f8ab3 commit 9e6c4f1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
19 changes: 16 additions & 3 deletions crates/wasmparser/src/validator/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ pub(crate) struct OperatorValidator {

// This structure corresponds to `ctrl_frame` as specified at in the validation
// appendix of the wasm spec
#[derive(Debug)]
struct Frame {
// Indicator for what kind of instruction pushed this frame.
kind: FrameKind,
Expand All @@ -85,7 +86,7 @@ struct Frame {
unreachable: bool,
}

#[derive(PartialEq, Copy, Clone)]
#[derive(PartialEq, Copy, Clone, Debug)]
enum FrameKind {
Block,
If,
Expand Down Expand Up @@ -923,7 +924,13 @@ where
bail_op_err!(offset, "catch found outside of an `try` block");
}
// Start a new frame and push `exnref` value.
self.push_ctrl(offset, FrameKind::Catch, frame.block_type)?;
let height = self.operands.len();
self.control.push(Frame {
kind: FrameKind::Catch,
block_type: frame.block_type,
height,
unreachable: false,
});
// Push exception argument types.
let ty = self.tag_at(index, offset)?;
for ty in ty.inputs() {
Expand Down Expand Up @@ -980,7 +987,13 @@ where
} else if frame.kind != FrameKind::Try && frame.kind != FrameKind::Catch {
bail_op_err!(offset, "catch_all found outside of a `try` block");
}
self.push_ctrl(offset, FrameKind::CatchAll, frame.block_type)?;
let height = self.operands.len();
self.control.push(Frame {
kind: FrameKind::CatchAll,
block_type: frame.block_type,
height,
unreachable: false,
});
Ok(())
}
fn visit_end(&mut self, offset: usize) -> Self::Output {
Expand Down
1 change: 1 addition & 0 deletions src/bin/wasm-tools/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ fn parse_features(arg: &str) -> Result<WasmFeatures> {
}),
("sign-extension", |f| &mut f.sign_extension),
("mutable-global", |f| &mut f.mutable_global),
("relaxed-simd", |f| &mut f.relaxed_simd),
];

for part in arg.split(',').map(|s| s.trim()).filter(|s| !s.is_empty()) {
Expand Down
16 changes: 16 additions & 0 deletions tests/local/exception-handling.wast
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@
drop
drop
)
(func $try-with-params
i32.const 0
try (param i32) (result i32 i64)
i32.popcnt
drop
call $check-throw
unreachable
catch 1
i64.const 2
catch_all
i32.const 0
i64.const 2
end
drop
drop
)
)

(assert_invalid
Expand Down

0 comments on commit 9e6c4f1

Please sign in to comment.