wasmi/
global.rs

1use super::{AsContext, AsContextMut, Stored};
2use crate::{
3    collections::arena::ArenaIndex,
4    core::CoreGlobal,
5    errors::GlobalError,
6    GlobalType,
7    Mutability,
8    Val,
9};
10
11/// A raw index to a global variable entity.
12#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
13pub struct GlobalIdx(u32);
14
15impl ArenaIndex for GlobalIdx {
16    fn into_usize(self) -> usize {
17        self.0 as usize
18    }
19
20    fn from_usize(value: usize) -> Self {
21        let value = value.try_into().unwrap_or_else(|error| {
22            panic!("index {value} is out of bounds as global index: {error}")
23        });
24        Self(value)
25    }
26}
27
28/// A Wasm global variable reference.
29#[derive(Debug, Copy, Clone)]
30#[repr(transparent)]
31pub struct Global(Stored<GlobalIdx>);
32
33impl Global {
34    /// Creates a new stored global variable reference.
35    ///
36    /// # Note
37    ///
38    /// This API is primarily used by the [`Store`] itself.
39    ///
40    /// [`Store`]: [`crate::Store`]
41    pub(super) fn from_inner(stored: Stored<GlobalIdx>) -> Self {
42        Self(stored)
43    }
44
45    /// Returns the underlying stored representation.
46    pub(super) fn as_inner(&self) -> &Stored<GlobalIdx> {
47        &self.0
48    }
49
50    /// Creates a new global variable to the store.
51    pub fn new(mut ctx: impl AsContextMut, initial_value: Val, mutability: Mutability) -> Self {
52        ctx.as_context_mut()
53            .store
54            .inner
55            .alloc_global(CoreGlobal::new(initial_value.into(), mutability))
56    }
57
58    /// Returns the [`GlobalType`] of the global variable.
59    pub fn ty(&self, ctx: impl AsContext) -> GlobalType {
60        ctx.as_context().store.inner.resolve_global(self).ty()
61    }
62
63    /// Sets a new value to the global variable.
64    ///
65    /// # Errors
66    ///
67    /// - If the global variable is immutable.
68    /// - If there is a type mismatch between the global variable and the new value.
69    ///
70    /// # Panics
71    ///
72    /// Panics if `ctx` does not own this [`Global`].
73    pub fn set(&self, mut ctx: impl AsContextMut, new_value: Val) -> Result<(), GlobalError> {
74        ctx.as_context_mut()
75            .store
76            .inner
77            .resolve_global_mut(self)
78            .set(new_value.into())
79    }
80
81    /// Returns the current value of the global variable.
82    ///
83    /// # Panics
84    ///
85    /// Panics if `ctx` does not own this [`Global`].
86    pub fn get(&self, ctx: impl AsContext) -> Val {
87        ctx.as_context()
88            .store
89            .inner
90            .resolve_global(self)
91            .get()
92            .into()
93    }
94}