Skip to content

Commit 8f4297b

Browse files
authored
Fix bug in multi-value br_table translation (#1972)
* fix outdated docs * add skip parameter to copy_operands_to_temp * copy operands to temp for multi-value br_table before this, operands were copied to the default target's branch params. However, this could lead to incorrect overwrites if the default target had a lower stack height than other targets. * update Wasmi .wast testsuite
1 parent 8cf1f98 commit 8f4297b

4 files changed

Lines changed: 18 additions & 13 deletions

File tree

crates/wasmi/src/engine/translator/func/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -730,13 +730,18 @@ impl FuncTranslator {
730730
fn copy_operands_to_temp(
731731
&mut self,
732732
len: u16,
733+
skip: u16,
733734
fuel_pos: Option<Pos<ir::BlockFuel>>,
734735
) -> Result<BoundedSlotSpan, Error> {
735736
if len == 0 {
736737
return Ok(BoundedSlotSpan::new(self.stack.next_temp_slots(), 0));
737738
}
738-
let dst = self.stack.peek(usize::from(len) - 1).temp_slots().span();
739-
self.copy_operands_to_dst(dst, len, 0, fuel_pos)
739+
let dst = self
740+
.stack
741+
.peek(usize::from(len + skip) - 1)
742+
.temp_slots()
743+
.span();
744+
self.copy_operands_to_dst(dst, len, skip, fuel_pos)
740745
}
741746

742747
/// Skips the top `skip` operands and copies the remaining top `len` operands to `dst`.
@@ -1087,11 +1092,10 @@ impl FuncTranslator {
10871092
&mut self,
10881093
table: wasmparser::BrTable,
10891094
index: Location,
1090-
default_branch_params: BranchParams,
1095+
values: BoundedSlotSpan,
10911096
) -> Result<(), Error> {
10921097
let len_targets = table.len() + 1;
10931098
debug_assert_eq!(self.immediates.len(), len_targets as usize);
1094-
let values = default_branch_params.temp_slots();
10951099
let op = match index {
10961100
Location::Reg(_) => Op::branch_table_span_r(len_targets, values),
10971101
Location::Slot(index) => Op::branch_table_span_s(len_targets, index, values),
@@ -1615,8 +1619,7 @@ impl FuncTranslator {
16151619
fn adjust_stack_for_call(&mut self, ty: &FuncType) -> Result<BoundedSlotSpan, Error> {
16161620
let fuel_pos = self.stack.fuel_pos();
16171621
self.preserve_regs(fuel_pos)?;
1618-
let fuel_pos = self.stack.fuel_pos();
1619-
let params = self.copy_operands_to_temp(ty.len_params(), fuel_pos)?;
1622+
let params = self.copy_operands_to_temp(ty.len_params(), 0, fuel_pos)?;
16201623
for _ in 0..ty.len_params() {
16211624
self.stack.pop();
16221625
}

crates/wasmi/src/engine/translator/func/stack/operands.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,7 @@ impl OperandStack {
616616
///
617617
/// # Note
618618
///
619-
/// - Returns the [`Operand`] at `depth` before being converted to an [`Operand::Temp`].
620-
/// - [`Operand::Temp`] will have their optional `instr` set to `None`.
619+
/// Returns the [`Operand`] at `depth` before being converted to an [`Operand::Temp`].
621620
///
622621
/// # Panics
623622
///

crates/wasmi/src/engine/translator/func/visit.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,15 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
378378
}
379379
}
380380
};
381-
self.copy_branch_params(default_branch_params, fuel_pos)?;
382-
let required_temp_copies = default_branch_params.len_temps() != 0;
383-
let requires_branch_copies = required_temp_copies && equal_heights;
381+
let len_temps = default_branch_params.len_temps();
382+
let len_regs = default_branch_params.len_regs();
383+
let values = self.copy_operands_to_temp(len_temps, len_regs, fuel_pos)?;
384+
self.copy_branch_params_regs(default_branch_params, fuel_pos)?;
385+
let required_temp_copies = len_temps != 0;
386+
let requires_branch_copies = required_temp_copies && !equal_heights;
384387
match requires_branch_copies {
385388
false => self.encode_br_table_0(table, index_loc)?,
386-
true => self.encode_br_table_n(table, index_loc, default_branch_params)?,
389+
true => self.encode_br_table_n(table, index_loc, values)?,
387390
};
388391
self.reachable = false;
389392
Ok(())

crates/wast/tests/wasmi

0 commit comments

Comments
 (0)