1
0
mirror of https://github.com/fluencelabs/wasmer synced 2025-03-27 21:11:04 +00:00

136 lines
3.6 KiB
Rust
Raw Normal View History

2019-01-28 10:59:05 -08:00
use crate::{
2019-01-28 11:55:44 -08:00
export::Export,
import::IsExport,
2019-01-29 13:04:42 -08:00
types::{GlobalDescriptor, Type, Value},
2019-01-28 10:59:05 -08:00
vm,
};
2019-01-28 11:55:44 -08:00
use std::{cell::RefCell, fmt, rc::Rc};
2019-01-28 10:59:05 -08:00
pub struct Global {
2019-01-29 13:04:42 -08:00
desc: GlobalDescriptor,
2019-01-28 11:02:53 -08:00
storage: Rc<RefCell<vm::LocalGlobal>>,
2019-01-28 10:59:05 -08:00
}
impl Global {
2019-01-29 15:44:15 -08:00
/// Create a new `Global` value.
///
/// Usage:
///
/// ```
/// # use wasmer_runtime_core::global::Global;
/// # use wasmer_runtime_core::types::Value;
/// let global = Global::new(Value::I32(42));
/// ```
2019-01-28 10:59:05 -08:00
pub fn new(value: Value) -> Self {
2019-01-29 12:49:51 -08:00
Self::new_internal(value, false)
2019-01-28 10:59:05 -08:00
}
2019-01-29 15:44:15 -08:00
/// Create a new, mutable `Global` value.
///
/// Usage:
///
/// ```
/// # use wasmer_runtime_core::global::Global;
/// # use wasmer_runtime_core::types::Value;
/// let global = Global::new_mutable(Value::I32(42));
/// ```
2019-01-28 10:59:05 -08:00
pub fn new_mutable(value: Value) -> Self {
2019-01-29 12:49:51 -08:00
Self::new_internal(value, true)
2019-01-28 10:59:05 -08:00
}
2019-01-29 12:49:51 -08:00
fn new_internal(value: Value, mutable: bool) -> Self {
2019-01-29 13:04:42 -08:00
let desc = GlobalDescriptor {
2019-01-28 10:59:05 -08:00
mutable,
ty: value.ty(),
};
let local_global = vm::LocalGlobal {
data: match value {
Value::I32(x) => x as u128,
Value::I64(x) => x as u128,
Value::F32(x) => x.to_bits() as u128,
Value::F64(x) => x.to_bits() as u128,
Value::V128(x) => x,
2019-01-28 10:59:05 -08:00
},
};
Self {
desc,
2019-01-28 11:55:44 -08:00
storage: Rc::new(RefCell::new(local_global)),
2019-01-28 10:59:05 -08:00
}
}
2019-01-29 15:44:15 -08:00
/// Get the [`GlobalDescriptor`] generated for this global.
///
/// [`GlobalDescriptor`]: struct.GlobalDescriptor.html
2019-01-29 13:04:42 -08:00
pub fn descriptor(&self) -> GlobalDescriptor {
2019-01-28 10:59:05 -08:00
self.desc
}
2019-01-29 15:44:15 -08:00
/// Set the value help by this global.
///
/// This method will panic if the value is
/// the wrong type.
2019-01-28 11:02:53 -08:00
pub fn set(&self, value: Value) {
2019-01-28 10:59:05 -08:00
if self.desc.mutable {
if self.desc.ty == value.ty() {
let local_global = vm::LocalGlobal {
data: match value {
Value::I32(x) => x as u128,
Value::I64(x) => x as u128,
Value::F32(x) => x.to_bits() as u128,
Value::F64(x) => x.to_bits() as u128,
Value::V128(x) => x,
2019-01-28 10:59:05 -08:00
},
};
2019-01-28 11:02:53 -08:00
*self.storage.borrow_mut() = local_global;
2019-01-28 10:59:05 -08:00
} else {
panic!("Wrong type for setting this global")
}
} else {
panic!("Cannot modify global immutable by default")
}
}
2019-01-29 15:44:15 -08:00
/// Get the value held by this global.
2019-01-28 10:59:05 -08:00
pub fn get(&self) -> Value {
2019-01-28 11:02:53 -08:00
let data = self.storage.borrow().data;
2019-01-28 10:59:05 -08:00
match self.desc.ty {
Type::I32 => Value::I32(data as i32),
Type::I64 => Value::I64(data as i64),
Type::F32 => Value::F32(f32::from_bits(data as u32)),
Type::F64 => Value::F64(f64::from_bits(data as u64)),
Type::V128 => Value::V128(data),
2019-01-28 10:59:05 -08:00
}
}
pub(crate) fn vm_local_global(&mut self) -> *mut vm::LocalGlobal {
2019-01-28 11:02:53 -08:00
&mut *self.storage.borrow_mut()
2019-01-28 10:59:05 -08:00
}
}
2019-01-28 11:55:44 -08:00
impl IsExport for Global {
2019-02-02 15:58:33 -08:00
fn to_export(&self) -> Export {
2019-01-28 11:55:44 -08:00
Export::Global(self.clone())
}
}
2019-01-28 10:59:05 -08:00
impl Clone for Global {
fn clone(&self) -> Self {
Self {
desc: self.desc,
storage: Rc::clone(&self.storage),
}
}
2019-01-28 11:55:44 -08:00
}
impl fmt::Debug for Global {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Global")
.field("desc", &self.desc)
.field("value", &self.get())
.finish()
}
}