use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GlobalSpec<'a> {
#[serde(borrow)]
global: Global<'a>,
export_names: Vec<&'a str>,
}
impl<'a> GlobalSpec<'a> {
pub fn new(global: Global<'a>, export_names: Vec<&'a str>) -> Self {
Self {
global,
export_names,
}
}
pub fn new_def(init_val: i64, export_names: Vec<&'a str>) -> Self {
Self::new(Global::Def(GlobalDef::I64(init_val)), export_names)
}
pub fn new_import(module: &'a str, field: &'a str, export_names: Vec<&'a str>) -> Self {
Self::new(Global::Import { module, field }, export_names)
}
pub fn global(&self) -> &Global<'_> {
&self.global
}
pub fn export_names(&self) -> &[&str] {
&self.export_names
}
pub fn is_internal(&self) -> bool {
self.export_names.len() == 0
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Global<'a> {
Def(GlobalDef),
Import { module: &'a str, field: &'a str },
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum GlobalDef {
I32(i32),
I64(i64),
F32(f32),
F64(f64),
}
impl GlobalDef {
pub fn init_val(&self) -> GlobalValue {
match self {
GlobalDef::I32(i) => GlobalValue { i_32: *i },
GlobalDef::I64(i) => GlobalValue { i_64: *i },
GlobalDef::F32(f) => GlobalValue { f_32: *f },
GlobalDef::F64(f) => GlobalValue { f_64: *f },
}
}
}
#[derive(Copy, Clone)]
pub union GlobalValue {
pub i_32: i32,
pub i_64: i64,
pub f_32: f32,
pub f_64: f64,
}
impl std::fmt::Debug for GlobalValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "GlobalValue {{")?;
unsafe {
writeln!(f, " i_32: {},", self.i_32)?;
writeln!(f, " i_64: {},", self.i_64)?;
writeln!(f, " f_32: {},", self.f_32)?;
writeln!(f, " f_64: {},", self.f_64)?;
}
writeln!(f, "}}")
}
}
pub struct OwnedGlobalSpec {
global: OwnedGlobal,
export_names: Vec<String>,
}
impl OwnedGlobalSpec {
pub fn new(global: OwnedGlobal, export_names: Vec<String>) -> Self {
Self {
global,
export_names,
}
}
pub fn new_def(init_val: i64, export_names: Vec<String>) -> Self {
Self::new(OwnedGlobal::Def(GlobalDef::I64(init_val)), export_names)
}
pub fn new_import(module: String, field: String, export_names: Vec<String>) -> Self {
Self::new(OwnedGlobal::Import { module, field }, export_names)
}
pub fn to_ref<'a>(&'a self) -> GlobalSpec<'a> {
GlobalSpec::new(
self.global.to_ref(),
self.export_names.iter().map(|x| x.as_str()).collect(),
)
}
}
pub enum OwnedGlobal {
Def(GlobalDef),
Import { module: String, field: String },
}
impl OwnedGlobal {
pub fn to_ref<'a>(&'a self) -> Global<'a> {
match self {
OwnedGlobal::Def(def) => Global::Def(def.clone()),
OwnedGlobal::Import { module, field } => Global::Import {
module: module.as_str(),
field: field.as_str(),
},
}
}
}