wasmer/backend/sys/entities/
global.rs1use crate::{
4 error::RuntimeError,
5 store::{AsStoreMut, AsStoreRef},
6 value::Value,
7 vm::{VMExtern, VMExternGlobal},
8};
9use wasmer_types::{GlobalType, Mutability};
10use wasmer_vm::{StoreHandle, VMGlobal};
11
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
14pub struct Global {
16 handle: StoreHandle<VMGlobal>,
17}
18
19impl Global {
20 pub(crate) fn from_value(
22 store: &mut impl AsStoreMut,
23 val: Value,
24 mutability: Mutability,
25 ) -> Result<Self, RuntimeError> {
26 if !val.is_from_store(store) {
27 return Err(RuntimeError::new("cross-`Store` values are not supported"));
28 }
29 let global = VMGlobal::new(GlobalType {
30 mutability,
31 ty: val.ty(),
32 });
33 unsafe {
34 global.vmglobal().as_mut().val = val.as_raw(store);
35 }
36
37 Ok(Self {
38 handle: StoreHandle::new(store.objects_mut().as_sys_mut(), global),
39 })
40 }
41
42 pub(crate) fn ty(&self, store: &impl AsStoreRef) -> GlobalType {
43 *self
44 .handle
45 .get(store.as_store_ref().objects().as_sys())
46 .ty()
47 }
48
49 pub(crate) fn get(&self, store: &mut impl AsStoreMut) -> Value {
50 unsafe {
51 let raw = self
52 .handle
53 .get(store.as_store_ref().objects().as_sys())
54 .vmglobal()
55 .as_ref()
56 .val;
57 let ty = self
58 .handle
59 .get(store.as_store_ref().objects().as_sys())
60 .ty()
61 .ty;
62 Value::from_raw(store, ty, raw)
63 }
64 }
65
66 pub(crate) fn set(&self, store: &mut impl AsStoreMut, val: Value) -> Result<(), RuntimeError> {
67 if !val.is_from_store(store) {
68 return Err(RuntimeError::new("cross-`Store` values are not supported"));
69 }
70 if self.ty(store).mutability != Mutability::Var {
71 return Err(RuntimeError::new("Attempted to set an immutable global"));
72 }
73 if val.ty() != self.ty(store).ty {
74 return Err(RuntimeError::new(format!(
75 "Attempted to operate on a global of type {expected} as a global of type {found}",
76 expected = self.ty(store).ty,
77 found = val.ty(),
78 )));
79 }
80 unsafe {
81 self.handle
82 .get_mut(store.as_store_mut().objects_mut().as_sys_mut())
83 .vmglobal()
84 .as_mut()
85 .val = val.as_raw(store);
86 }
87 Ok(())
88 }
89
90 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, vm_extern: VMExternGlobal) -> Self {
91 Self {
92 handle: unsafe {
93 StoreHandle::from_internal(
94 store.as_store_ref().objects().id(),
95 vm_extern.into_sys(),
96 )
97 },
98 }
99 }
100
101 pub(crate) fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
102 self.handle.store_id() == store.as_store_ref().objects().id()
103 }
104
105 pub(crate) fn to_vm_extern(&self) -> VMExtern {
106 VMExtern::Sys(wasmer_vm::VMExtern::Global(self.handle.internal_handle()))
107 }
108}
109
110impl std::cmp::PartialEq for Global {
111 fn eq(&self, other: &Self) -> bool {
112 self.handle == other.handle
113 }
114}
115
116impl std::cmp::Eq for Global {}