wasmer/entities/global/inner.rs
1use crate::{
2 ExportError, Exportable, Extern,
3 error::RuntimeError,
4 macros::backend::{gen_rt_ty, match_rt},
5 store::{AsStoreMut, AsStoreRef, StoreMut, StoreRef},
6 value::Value,
7 vm::{VMExtern, VMExternGlobal},
8};
9use wasmer_types::{GlobalType, Mutability};
10
11/// A WebAssembly `global` instance.
12///
13/// A global instance is the runtime representation of a global variable.
14/// It consists of an individual value and a flag indicating whether it is mutable.
15///
16/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
17gen_rt_ty!(Global
18 @cfg feature = "artifact-size" => derive(loupe::MemoryUsage)
19 @derives Debug, Clone, PartialEq, Eq, derive_more::From
20);
21
22impl BackendGlobal {
23 /// Create a new global with the initial [`Value`].
24 ///
25 /// # Example
26 ///
27 /// ```
28 /// # use wasmer::{Global, Mutability, Store, Value};
29 /// # let mut store = Store::default();
30 /// #
31 /// let g = Global::new(&mut store, Value::I32(1));
32 ///
33 /// assert_eq!(g.get(&mut store), Value::I32(1));
34 /// assert_eq!(g.ty(&mut store).mutability, Mutability::Const);
35 /// ```
36 #[inline]
37 pub fn new(store: &mut impl AsStoreMut, val: Value) -> Self {
38 Self::from_value(store, val, Mutability::Const).unwrap()
39 }
40
41 /// Create a mutable global with the initial [`Value`].
42 ///
43 /// # Example
44 ///
45 /// ```
46 /// # use wasmer::{Global, Mutability, Store, Value};
47 /// # let mut store = Store::default();
48 /// #
49 /// let g = Global::new_mut(&mut store, Value::I32(1));
50 ///
51 /// assert_eq!(g.get(&mut store), Value::I32(1));
52 /// assert_eq!(g.ty(&mut store).mutability, Mutability::Var);
53 /// ```
54 #[inline]
55 pub fn new_mut(store: &mut impl AsStoreMut, val: Value) -> Self {
56 Self::from_value(store, val, Mutability::Var).unwrap()
57 }
58
59 /// Create a global with the initial [`Value`] and the provided [`Mutability`].
60 #[inline]
61 pub(crate) fn from_value(
62 store: &mut impl AsStoreMut,
63 val: Value,
64 mutability: Mutability,
65 ) -> Result<Self, RuntimeError> {
66 match &store.as_store_mut().inner.store {
67 #[cfg(feature = "sys")]
68 crate::BackendStore::Sys(_) => Ok(Self::Sys(
69 crate::backend::sys::global::Global::from_value(store, val, mutability)?,
70 )),
71 #[cfg(feature = "wamr")]
72 crate::BackendStore::Wamr(_) => Ok(Self::Wamr(
73 crate::backend::wamr::global::Global::from_value(store, val, mutability)?,
74 )),
75
76 #[cfg(feature = "wasmi")]
77 crate::BackendStore::Wasmi(_) => Ok(Self::Wasmi(
78 crate::backend::wasmi::global::Global::from_value(store, val, mutability)?,
79 )),
80 #[cfg(feature = "v8")]
81 crate::BackendStore::V8(_) => Ok(Self::V8(
82 crate::backend::v8::global::Global::from_value(store, val, mutability)?,
83 )),
84 #[cfg(feature = "js")]
85 crate::BackendStore::Js(_) => Ok(Self::Js(
86 crate::backend::js::global::Global::from_value(store, val, mutability)?,
87 )),
88 #[cfg(feature = "jsc")]
89 crate::BackendStore::Jsc(_) => Ok(Self::Jsc(
90 crate::backend::jsc::global::Global::from_value(store, val, mutability)?,
91 )),
92 }
93 }
94
95 /// Returns the [`GlobalType`] of the global.
96 ///
97 /// # Example
98 ///
99 /// ```
100 /// # use wasmer::{Global, Mutability, Store, Type, Value, GlobalType};
101 /// # let mut store = Store::default();
102 /// #
103 /// let c = Global::new(&mut store, Value::I32(1));
104 /// let v = Global::new_mut(&mut store, Value::I64(1));
105 ///
106 /// assert_eq!(c.ty(&mut store), GlobalType::new(Type::I32, Mutability::Const));
107 /// assert_eq!(v.ty(&mut store), GlobalType::new(Type::I64, Mutability::Var));
108 /// ```
109 #[inline]
110 pub fn ty(&self, store: &impl AsStoreRef) -> GlobalType {
111 match_rt!(on self => g {
112 g.ty(store)
113 })
114 }
115
116 /// Retrieves the current value [`Value`] that the global has.
117 ///
118 /// # Example
119 ///
120 /// ```
121 /// # use wasmer::{Global, Store, Value};
122 /// # let mut store = Store::default();
123 /// #
124 /// let g = Global::new(&mut store, Value::I32(1));
125 ///
126 /// assert_eq!(g.get(&mut store), Value::I32(1));
127 /// ```
128 #[inline]
129 pub fn get(&self, store: &mut impl AsStoreMut) -> Value {
130 match_rt!(on self => g {
131 g.get(store)
132 })
133 }
134
135 /// Sets a custom [`Value`] to the runtime global.
136 ///
137 /// # Example
138 ///
139 /// ```
140 /// # use wasmer::{Global, Store, Value};
141 /// # let mut store = Store::default();
142 /// #
143 /// let g = Global::new_mut(&mut store, Value::I32(1));
144 ///
145 /// assert_eq!(g.get(&mut store), Value::I32(1));
146 ///
147 /// g.set(&mut store, Value::I32(2));
148 ///
149 /// assert_eq!(g.get(&mut store), Value::I32(2));
150 /// ```
151 ///
152 /// # Errors
153 ///
154 /// Trying to mutate a immutable global will raise an error:
155 ///
156 /// ```should_panic
157 /// # use wasmer::{Global, Store, Value};
158 /// # let mut store = Store::default();
159 /// #
160 /// let g = Global::new(&mut store, Value::I32(1));
161 ///
162 /// g.set(&mut store, Value::I32(2)).unwrap();
163 /// ```
164 ///
165 /// Trying to set a value of a incompatible type will raise an error:
166 ///
167 /// ```should_panic
168 /// # use wasmer::{Global, Store, Value};
169 /// # let mut store = Store::default();
170 /// #
171 /// let g = Global::new(&mut store, Value::I32(1));
172 ///
173 /// // This results in an error: `RuntimeError`.
174 /// g.set(&mut store, Value::I64(2)).unwrap();
175 /// ```
176 #[inline]
177 pub fn set(&self, store: &mut impl AsStoreMut, val: Value) -> Result<(), RuntimeError> {
178 match_rt!(on self => s {
179 s.set(store, val)
180 })
181 }
182
183 #[inline]
184 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExternGlobal) -> Self {
185 match &store.as_store_mut().inner.store {
186 #[cfg(feature = "sys")]
187 crate::BackendStore::Sys(_) => Self::Sys(
188 crate::backend::sys::global::Global::from_vm_extern(store, vm_extern),
189 ),
190 #[cfg(feature = "wamr")]
191 crate::BackendStore::Wamr(_) => Self::Wamr(
192 crate::backend::wamr::global::Global::from_vm_extern(store, vm_extern),
193 ),
194 #[cfg(feature = "wasmi")]
195 crate::BackendStore::Wasmi(_) => Self::Wasmi(
196 crate::backend::wasmi::global::Global::from_vm_extern(store, vm_extern),
197 ),
198 #[cfg(feature = "v8")]
199 crate::BackendStore::V8(_) => Self::V8(
200 crate::backend::v8::global::Global::from_vm_extern(store, vm_extern),
201 ),
202 #[cfg(feature = "js")]
203 crate::BackendStore::Js(_) => Self::Js(
204 crate::backend::js::global::Global::from_vm_extern(store, vm_extern),
205 ),
206 #[cfg(feature = "jsc")]
207 crate::BackendStore::Jsc(_) => Self::Jsc(
208 crate::backend::jsc::global::Global::from_vm_extern(store, vm_extern),
209 ),
210 }
211 }
212
213 /// Checks whether this global can be used with the given context.
214 #[inline]
215 pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
216 match_rt!(on self => s {
217 s.is_from_store(store)
218 })
219 }
220
221 /// Create a [`VMExtern`] from self.
222 #[inline]
223 pub(crate) fn to_vm_extern(&self) -> VMExtern {
224 match_rt!(on self => s {
225 s.to_vm_extern()
226 })
227 }
228}