Skip to content

Commit 31f229e

Browse files
committed
Add br_table type checks for loop start types
1 parent 5eda928 commit 31f229e

2 files changed

Lines changed: 22 additions & 27 deletions

File tree

crates/wasmparser/src/operators_validator.rs

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ impl BlockState {
3939
fn is_stack_polymorphic(&self) -> bool {
4040
self.polymorphic_values.is_some()
4141
}
42+
fn jump_exit_types(&self) -> &Vec<Type> {
43+
if self.jump_to_top {
44+
&self.start_types
45+
} else {
46+
&self.return_types
47+
}
48+
}
4249
}
4350

4451
#[derive(Debug)]
@@ -225,18 +232,7 @@ impl FuncState {
225232
Ok(())
226233
}
227234
fn change_frame_to_exact_types_from(&mut self, depth: usize) -> OperatorValidatorResult<()> {
228-
let types = match self.block_at(depth) {
229-
BlockState {
230-
jump_to_top: false,
231-
return_types,
232-
..
233-
} => return_types.clone(),
234-
BlockState {
235-
jump_to_top: true,
236-
start_types,
237-
..
238-
} => start_types.clone(),
239-
};
235+
let types = self.block_at(depth).jump_exit_types().clone();
240236
let last_block = self.blocks.last_mut().unwrap();
241237
let keep = last_block.stack_starts_at;
242238
if keep + types.len() <= self.stack_types.len() {
@@ -589,21 +585,7 @@ impl OperatorValidator {
589585
}
590586
let block1 = self.func_state.block_at(depth1 as usize);
591587
let block2 = self.func_state.block_at(depth2 as usize);
592-
let return_types1 = &block1.return_types;
593-
let return_types2 = &block2.return_types;
594-
if block1.jump_to_top || block2.jump_to_top {
595-
if block1.jump_to_top {
596-
if !block2.jump_to_top && !return_types2.is_empty() {
597-
return Err(OperatorValidatorError::new(
598-
"type mismatch: block types do not match",
599-
));
600-
}
601-
} else if !return_types1.is_empty() {
602-
return Err(OperatorValidatorError::new(
603-
"type mismatch: block types do not match",
604-
));
605-
}
606-
} else if *return_types1 != *return_types2 {
588+
if block1.jump_exit_types() != block2.jump_exit_types() {
607589
return Err(OperatorValidatorError::new(
608590
"type mismatch: block types do not match",
609591
));
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
;;; --enable-multi-value
2+
(module
3+
(func (param i32) (result i32)
4+
(local i32)
5+
local.get 1
6+
loop (param i32) ;; label = @1
7+
i32.const -458751
8+
br_table 0 (;@1;) 1 (;@0;) 0 (;@1;)
9+
unreachable
10+
end
11+
unreachable
12+
)
13+
)

0 commit comments

Comments
 (0)