wasmer_runtime_core_x/
global.rs1use crate::{
4 export::Export,
5 import::IsExport,
6 types::{GlobalDescriptor, Type, Value},
7 vm,
8};
9use std::{
10 fmt,
11 sync::{Arc, Mutex},
12};
13
14pub struct Global {
16 desc: GlobalDescriptor,
17 storage: Arc<Mutex<vm::LocalGlobal>>,
18}
19
20impl Global {
21 pub fn new(value: Value) -> Self {
31 Self::new_internal(value, false)
32 }
33
34 pub fn new_mutable(value: Value) -> Self {
44 Self::new_internal(value, true)
45 }
46
47 fn new_internal(value: Value, mutable: bool) -> Self {
48 let desc = GlobalDescriptor {
49 mutable,
50 ty: value.ty(),
51 };
52
53 let local_global = vm::LocalGlobal {
54 data: match value {
55 Value::I32(x) => x as u128,
56 Value::I64(x) => x as u128,
57 Value::F32(x) => x.to_bits() as u128,
58 Value::F64(x) => x.to_bits() as u128,
59 Value::V128(x) => x,
60 },
61 };
62
63 Self {
64 desc,
65 storage: Arc::new(Mutex::new(local_global)),
66 }
67 }
68
69 pub fn descriptor(&self) -> GlobalDescriptor {
73 self.desc
74 }
75
76 pub fn set(&self, value: Value) {
81 if self.desc.mutable {
82 if self.desc.ty == value.ty() {
83 let local_global = vm::LocalGlobal {
84 data: match value {
85 Value::I32(x) => x as u128,
86 Value::I64(x) => x as u128,
87 Value::F32(x) => x.to_bits() as u128,
88 Value::F64(x) => x.to_bits() as u128,
89 Value::V128(x) => x,
90 },
91 };
92 let mut storage = self.storage.lock().unwrap();
93 *storage = local_global;
94 } else {
95 panic!("Wrong type for setting this global")
96 }
97 } else {
98 panic!("Cannot modify global immutable by default")
99 }
100 }
101
102 pub fn get(&self) -> Value {
104 let storage = self.storage.lock().unwrap();
105 let data = storage.data;
106
107 match self.desc.ty {
108 Type::I32 => Value::I32(data as i32),
109 Type::I64 => Value::I64(data as i64),
110 Type::F32 => Value::F32(f32::from_bits(data as u32)),
111 Type::F64 => Value::F64(f64::from_bits(data as u64)),
112 Type::V128 => Value::V128(data),
113 }
114 }
115
116 pub(crate) fn vm_local_global(&mut self) -> *mut vm::LocalGlobal {
118 let mut storage = self.storage.lock().unwrap();
119 &mut *storage
120 }
121}
122
123impl IsExport for Global {
124 fn to_export(&self) -> Export {
125 Export::Global(self.clone())
126 }
127}
128
129impl Clone for Global {
130 fn clone(&self) -> Self {
131 Self {
132 desc: self.desc,
133 storage: Arc::clone(&self.storage),
134 }
135 }
136}
137
138impl fmt::Debug for Global {
139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 f.debug_struct("Global")
141 .field("desc", &self.desc)
142 .field("value", &self.get())
143 .finish()
144 }
145}