Skip to content

Commit

Permalink
Fix ref.is_null translation constant propagation (#1189)
Browse files Browse the repository at this point in the history
* fix ref.is_null translation const prop

* add ValueStack::drop method

* apply rustfmt

* use ValueStack::drop where needed (fixes clippy)
  • Loading branch information
Robbepop committed Sep 20, 2024
1 parent 4bf9fc6 commit f09d121
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 3 deletions.
12 changes: 10 additions & 2 deletions crates/wasmi/src/engine/translator/stack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl ValueStack {
pub fn trunc(&mut self, height: usize) {
assert!(height <= self.height());
while self.height() != height {
self.pop();
self.drop();
}
}

Expand Down Expand Up @@ -279,7 +279,15 @@ impl ValueStack {
Ok(reg)
}

/// Drops the top-most [`Provider`] from the [`ValueStack`].
pub fn drop(&mut self) {
self.reg_alloc.pop_provider(self.providers.pop());
}

/// Pops the top-most [`Provider`] from the [`ValueStack`].
///
/// Use [`Self::drop`] if you are not interested in the returned provider.
#[must_use]
pub fn pop(&mut self) -> TypedProvider {
self.reg_alloc.pop_provider(self.providers.pop())
}
Expand Down Expand Up @@ -321,7 +329,7 @@ impl ValueStack {
/// Removes the `n` top-most [`Provider`] from the [`ValueStack`].
pub fn remove_n(&mut self, n: usize) {
for _ in 0..n {
self.pop();
self.drop();
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/wasmi/src/engine/translator/tests/op/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod local_preserve;
mod local_set;
mod loop_;
mod memory;
mod ref_;
mod return_;
mod return_call;
mod select;
Expand Down
17 changes: 17 additions & 0 deletions crates/wasmi/src/engine/translator/tests/op/ref_.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use super::*;

#[test]
#[cfg_attr(miri, ignore)]
fn const_prop() {
let wasm = r"
(module
(func (result i32)
ref.null func
ref.is_null
)
)
";
TranslationTest::from_wat(wasm)
.expect_func_instrs([Instruction::return_imm32(1_i32)])
.run()
}
15 changes: 14 additions & 1 deletion crates/wasmi/src/engine/translator/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ impl<'a> VisitOperator<'a> for FuncTranslator {

fn visit_drop(&mut self) -> Self::Output {
bail_unreachable!(self);
self.alloc.stack.pop();
self.alloc.stack.drop();
Ok(())
}

Expand Down Expand Up @@ -1199,6 +1199,19 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
}

fn visit_ref_is_null(&mut self) -> Self::Output {
bail_unreachable!(self);
let input = self.alloc.stack.peek();
if let Provider::Const(input) = input {
self.alloc.stack.drop();
let untyped = input.untyped();
let is_null = match input.ty() {
ValType::FuncRef => FuncRef::from(untyped).is_null(),
ValType::ExternRef => ExternRef::from(untyped).is_null(),
invalid => panic!("ref.is_null: encountered invalid input type: {invalid:?}"),
};
self.alloc.stack.push_const(i32::from(is_null));
return Ok(());
}
// Note: Since `funcref` and `externref` both serialize to `UntypedValue`
// as raw `u64` values we can use `i64.eqz` translation for `ref.is_null`.
self.visit_i64_eqz()
Expand Down

0 comments on commit f09d121

Please sign in to comment.