wasm/execution/interpreter_loop/
variable.rs1use core::ops::ControlFlow;
2
3use crate::{
4 assert_validated::UnwrapValidatedExt,
5 core::{
6 indices::{GlobalIdx, LocalIdx},
7 reader::types::opcode,
8 },
9 execution::interpreter_loop::{define_instruction_fn, Args},
10};
11
12define_instruction_fn! {
13 local_get,
14 fuel_check = flat(opcode::LOCAL_GET),
15 |Args {
16 resumable, wasm, ..
17 }| {
18 let local_idx = unsafe { LocalIdx::read_unchecked(wasm) };
21 let value = *resumable.stack.get_local(local_idx);
22 resumable.stack.push_value(value)?;
23 trace!("Instruction: local.get {} [] -> [t]", local_idx);
24 Ok(ControlFlow::Continue(()))
25 }
26}
27
28define_instruction_fn! {
29 local_set,
30 fuel_check = flat(opcode::LOCAL_SET),
31 |Args {
32 resumable, wasm, ..
33 }| {
34 let local_idx = unsafe { LocalIdx::read_unchecked(wasm) };
37 let value = resumable.stack.pop_value();
38 *resumable.stack.get_local_mut(local_idx) = value;
39 trace!("Instruction: local.set {} [t] -> []", local_idx);
40 Ok(ControlFlow::Continue(()))
41 }
42}
43
44define_instruction_fn! {
45 local_tee,
46 fuel_check = flat(opcode::LOCAL_TEE),
47 |Args {
48 resumable, wasm, ..
49 }| {
50 let local_idx = unsafe { LocalIdx::read_unchecked(wasm) };
53 let value = resumable.stack.peek_value().unwrap_validated();
54 *resumable.stack.get_local_mut(local_idx) = value;
55 trace!("Instruction: local.tee {} [t] -> [t]", local_idx);
56 Ok(ControlFlow::Continue(()))
57 }
58}
59
60define_instruction_fn! {
61 global_get,
62 fuel_check = flat(opcode::GLOBAL_GET),
63 |Args {
64 store_inner,
65 modules,
66 resumable,
67 wasm,
68 current_module,
69 ..
70 }| {
71 let global_idx = unsafe { GlobalIdx::read_unchecked(wasm) };
74 let module = unsafe { modules.get(*current_module) };
79
80 let global_addr = *unsafe { module.global_addrs.get(global_idx) };
83 let global = unsafe { store_inner.globals.get(global_addr) };
86
87 resumable.stack.push_value(global.value)?;
88
89 trace!(
90 "Instruction: global.get '{}' [<GLOBAL>] -> [{:?}]",
91 global_idx,
92 global.value
93 );
94 Ok(ControlFlow::Continue(()))
95 }
96}
97
98define_instruction_fn! {
99 global_set,
100 fuel_check = flat(opcode::GLOBAL_SET),
101 |Args {
102 store_inner,
103 modules,
104 resumable,
105 wasm,
106 current_module,
107 ..
108 }| {
109 let global_idx = unsafe { GlobalIdx::read_unchecked(wasm) };
112 let module = unsafe { modules.get(*current_module) };
117 let global_addr = *unsafe { module.global_addrs.get(global_idx) };
120 let global = unsafe { store_inner.globals.get_mut(global_addr) };
123
124 global.value = resumable.stack.pop_value();
125 trace!("Instruction: GLOBAL_SET");
126 Ok(ControlFlow::Continue(()))
127 }
128}