wasm/execution/interpreter_loop/
reference.rs1use core::ops::ControlFlow;
2
3use crate::{
4 assert_validated::UnwrapValidatedExt,
5 core::{indices::FuncIdx, reader::types::opcode},
6 execution::interpreter_loop::{define_instruction_fn, Args},
7 value::Ref,
8 RefType, Value,
9};
10
11define_instruction_fn! {
12 ref_null,
13 fuel_check = flat(opcode::REF_NULL),
14 |Args {
15 wasm, resumable, ..
16 }| {
17 let reftype = RefType::read(wasm).unwrap_validated();
18
19 resumable.stack.push_value(Value::Ref(Ref::Null(reftype)))?;
20 trace!("Instruction: ref.null '{:?}' -> [{:?}]", reftype, reftype);
21 Ok(ControlFlow::Continue(()))
22 }
23}
24
25define_instruction_fn! {
26 ref_is_null,
27 fuel_check = flat(opcode::REF_IS_NULL),
28 |Args { resumable, .. }| {
29 let rref: Ref = resumable.stack.pop_value().try_into().unwrap_validated();
30 let is_null = matches!(rref, Ref::Null(_));
31
32 let res = if is_null { 1 } else { 0 };
33 trace!("Instruction: ref.is_null [{}] -> [{}]", rref, res);
34 resumable.stack.push_value(Value::I32(res))?;
35 Ok(ControlFlow::Continue(()))
36 }
37}
38
39define_instruction_fn! {
41 ref_func,
42 fuel_check = flat(opcode::REF_FUNC),
43 |Args {
44 wasm,
45 resumable,
46 modules,
47 current_module,
48 ..
49 }| {
50 let func_idx = unsafe { FuncIdx::read_unchecked(wasm) };
53
54 let current_module = unsafe { modules.get(*current_module) };
59 let func_addr = unsafe { current_module.func_addrs.get(func_idx) };
62 resumable
63 .stack
64 .push_value(Value::Ref(Ref::Func(*func_addr)))?;
65 Ok(ControlFlow::Continue(()))
66 }
67}