use super::cell::Cell;
use super::Execution;
use crate::error::ir_get;
use crate::instance::Instance;
use crate::module::op::{Op, Slot};
use crate::store::StoreInner;
use crate::trap::Trap;
use crate::value::Val;
use crate::{Error, Result};
impl Execution {
pub(super) fn exec_ref(
&mut self,
inner: &StoreInner,
op: &Op,
instance: Instance,
base: u32,
) -> Result<()> {
let at = |s: Slot| super::step::slot(base, s);
match op {
Op::RefNull(heap, s) => self.set_val(at(*s), Val::null_for_heap(heap)),
Op::RefFunc(f, s) => {
let func = *ir_get(&inner.instance(instance).funcs, *f)?;
self.set_val(at(*s), Val::FuncRef(Some(func)))
}
Op::RefIsNull(s) => {
let at = at(*s);
let is_null = self.ref_at(at)?.0.is_null();
self.set_scalar(at, Cell::from_i32(i32::from(is_null)))
}
Op::RefAsNonNull(s) => {
let at = at(*s);
if self.ref_at(at)?.0.is_null() {
return Err(Trap::NullReference.into());
}
Ok(()) }
_ => Err(Error::msg(format!("not a ref op: {op:?}"))),
}
}
}