Skip to main content

wasmi/engine/executor/instrs/
global.rs

1use super::Executor;
2use crate::{
3    core::{hint, UntypedVal},
4    ir::{index, Const16, Slot},
5    store::StoreInner,
6};
7
8#[cfg(doc)]
9use crate::ir::Op;
10
11impl Executor<'_> {
12    /// Executes an [`Op::GlobalGet`].
13    pub fn execute_global_get(&mut self, store: &StoreInner, result: Slot, global: index::Global) {
14        let value = match u32::from(global) {
15            0 => unsafe { self.cache.global.get() },
16            _ => {
17                hint::cold();
18                let global = self.get_global(global);
19                *store.resolve_global(&global).get_untyped()
20            }
21        };
22        self.set_stack_slot(result, value);
23        self.next_instr()
24    }
25
26    /// Executes an [`Op::GlobalSet`].
27    pub fn execute_global_set(
28        &mut self,
29        store: &mut StoreInner,
30        global: index::Global,
31        input: Slot,
32    ) {
33        let input = self.get_stack_slot(input);
34        self.execute_global_set_impl(store, global, input)
35    }
36
37    /// Executes an [`Op::GlobalSetI32Imm16`].
38    pub fn execute_global_set_i32imm16(
39        &mut self,
40        store: &mut StoreInner,
41        global: index::Global,
42        input: Const16<i32>,
43    ) {
44        let input = i32::from(input).into();
45        self.execute_global_set_impl(store, global, input)
46    }
47
48    /// Executes an [`Op::GlobalSetI64Imm16`].
49    pub fn execute_global_set_i64imm16(
50        &mut self,
51        store: &mut StoreInner,
52        global: index::Global,
53        input: Const16<i64>,
54    ) {
55        let input = i64::from(input).into();
56        self.execute_global_set_impl(store, global, input)
57    }
58
59    /// Executes a generic `global.set` instruction.
60    fn execute_global_set_impl(
61        &mut self,
62        store: &mut StoreInner,
63        global: index::Global,
64        new_value: UntypedVal,
65    ) {
66        match u32::from(global) {
67            0 => unsafe { self.cache.global.set(new_value) },
68            _ => {
69                hint::cold();
70                let global = self.get_global(global);
71                let mut ptr = store.resolve_global_mut(&global).get_untyped_ptr();
72                // Safety:
73                // - Wasmi translation won't create `global.set` instructions for immutable globals.
74                // - Wasm validation ensures that values with matching types are written to globals.
75                unsafe {
76                    *ptr.as_mut() = new_value;
77                }
78            }
79        };
80        self.next_instr()
81    }
82}