Skip to content

Commit 037cce4

Browse files
authored
validator/operators.rs: refine some handling of control stack + comments (#2427)
1 parent ded44b8 commit 037cce4

1 file changed

Lines changed: 23 additions & 44 deletions

File tree

crates/wasmparser/src/validator/operators.rs

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl LocalInits {
116116
self.local_inits.resize(new_len, is_defaultable);
117117
}
118118

119-
/// Returns `true` if the local at `local_index` has already been initialized.
119+
/// Returns `true` if the local at `local_index` has not been initialized.
120120
#[inline]
121121
pub fn is_uninit(&self, local_index: u32) -> bool {
122122
if local_index < self.first_non_default_local {
@@ -134,8 +134,8 @@ impl LocalInits {
134134
}
135135
}
136136

137-
/// Registers a new control frame and returns its `height`.
138-
pub fn push_ctrl(&mut self) -> usize {
137+
/// Returns the current `height` (number of local inits).
138+
pub fn height(&self) -> usize {
139139
self.inits.len()
140140
}
141141

@@ -951,23 +951,29 @@ where
951951
/// breaks interact with this block's type. Additionally the type signature
952952
/// of the block is specified by `ty`.
953953
fn push_ctrl(&mut self, kind: FrameKind, ty: BlockType) -> Result<()> {
954+
self.push_bare_ctrl(kind, ty);
955+
// All of the parameters are now also available in this control frame,
956+
// so we push them here in order.
957+
for ty in self.params(ty)? {
958+
self.push_operand(ty)?;
959+
}
960+
Ok(())
961+
}
962+
963+
/// Pushes a new frame onto the control stack, without its block params.
964+
/// This is used by `push_ctrl` above and directly by LegacyCatch and LegacyCatchAll.
965+
fn push_bare_ctrl(&mut self, kind: FrameKind, ty: BlockType) {
954966
// Push a new frame which has a snapshot of the height of the current
955967
// operand stack.
956968
let height = self.operands.len();
957-
let init_height = self.local_inits.push_ctrl();
969+
let init_height = self.local_inits.height();
958970
self.control.push(Frame {
959971
kind,
960972
block_type: ty,
961973
height,
962974
unreachable: false,
963975
init_height,
964976
});
965-
// All of the parameters are now also available in this control frame,
966-
// so we push them here in order.
967-
for ty in self.params(ty)? {
968-
self.push_operand(ty)?;
969-
}
970-
Ok(())
971977
}
972978

973979
/// Pops a frame from the control stack.
@@ -1987,9 +1993,7 @@ where
19871993
}
19881994
fn visit_else(&mut self) -> Self::Output {
19891995
let frame = self.pop_ctrl()?;
1990-
if frame.kind != FrameKind::If {
1991-
bail!(self.offset, "else found outside of an `if` block");
1992-
}
1996+
debug_assert_eq!(frame.kind, FrameKind::If); // syntactic requirement, enforced by reader
19931997
self.push_ctrl(FrameKind::Else, frame.block_type)?;
19941998
Ok(())
19951999
}
@@ -4210,20 +4214,9 @@ where
42104214
}
42114215
fn visit_catch(&mut self, index: u32) -> Self::Output {
42124216
let frame = self.pop_ctrl()?;
4213-
if frame.kind != FrameKind::LegacyTry && frame.kind != FrameKind::LegacyCatch {
4214-
bail!(self.offset, "catch found outside of an `try` block");
4215-
}
4216-
// Start a new frame and push `exnref` value.
4217-
let height = self.operands.len();
4218-
let init_height = self.local_inits.push_ctrl();
4219-
self.control.push(Frame {
4220-
kind: FrameKind::LegacyCatch,
4221-
block_type: frame.block_type,
4222-
height,
4223-
unreachable: false,
4224-
init_height,
4225-
});
4226-
// Push exception argument types.
4217+
debug_assert!(frame.kind == FrameKind::LegacyTry || frame.kind == FrameKind::LegacyCatch);
4218+
// Start a new frame and push exception argument types.
4219+
self.push_bare_ctrl(FrameKind::LegacyCatch, frame.block_type);
42274220
let ty = self.exception_tag_at(index)?;
42284221
for ty in ty.params() {
42294222
self.push_operand(*ty)?;
@@ -4245,9 +4238,7 @@ where
42454238
}
42464239
fn visit_delegate(&mut self, relative_depth: u32) -> Self::Output {
42474240
let frame = self.pop_ctrl()?;
4248-
if frame.kind != FrameKind::LegacyTry {
4249-
bail!(self.offset, "delegate found outside of an `try` block");
4250-
}
4241+
debug_assert_eq!(frame.kind, FrameKind::LegacyTry);
42514242
// This operation is not a jump, but we need to check the
42524243
// depth for validity
42534244
let _ = self.jump(relative_depth)?;
@@ -4258,20 +4249,8 @@ where
42584249
}
42594250
fn visit_catch_all(&mut self) -> Self::Output {
42604251
let frame = self.pop_ctrl()?;
4261-
if frame.kind == FrameKind::LegacyCatchAll {
4262-
bail!(self.offset, "only one catch_all allowed per `try` block");
4263-
} else if frame.kind != FrameKind::LegacyTry && frame.kind != FrameKind::LegacyCatch {
4264-
bail!(self.offset, "catch_all found outside of a `try` block");
4265-
}
4266-
let height = self.operands.len();
4267-
let init_height = self.local_inits.push_ctrl();
4268-
self.control.push(Frame {
4269-
kind: FrameKind::LegacyCatchAll,
4270-
block_type: frame.block_type,
4271-
height,
4272-
unreachable: false,
4273-
init_height,
4274-
});
4252+
debug_assert!(frame.kind == FrameKind::LegacyTry || frame.kind == FrameKind::LegacyCatch);
4253+
self.push_bare_ctrl(FrameKind::LegacyCatchAll, frame.block_type);
42754254
Ok(())
42764255
}
42774256
fn visit_cont_new(&mut self, type_index: u32) -> Self::Output {

0 commit comments

Comments
 (0)