1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct GlobalSpec<'a> {
10 #[serde(borrow)]
11 global: Global<'a>,
12 export_names: Vec<&'a str>,
13}
14
15impl<'a> GlobalSpec<'a> {
16 pub fn new(global: Global<'a>, export_names: Vec<&'a str>) -> Self {
17 Self {
18 global,
19 export_names,
20 }
21 }
22
23 pub fn new_def(init_val: i64, export_names: Vec<&'a str>) -> Self {
25 Self::new(Global::Def(GlobalDef::I64(init_val)), export_names)
26 }
27
28 pub fn new_import(module: &'a str, field: &'a str, export_names: Vec<&'a str>) -> Self {
30 Self::new(Global::Import { module, field }, export_names)
31 }
32
33 pub fn global(&self) -> &Global<'_> {
34 &self.global
35 }
36
37 pub fn export_names(&self) -> &[&str] {
38 &self.export_names
39 }
40
41 pub fn is_internal(&self) -> bool {
42 self.export_names.len() == 0
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub enum Global<'a> {
54 Def(GlobalDef),
55 Import { module: &'a str, field: &'a str },
56}
57
58#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
60pub enum GlobalDef {
61 I32(i32),
62 I64(i64),
63 F32(f32),
64 F64(f64),
65}
66
67impl GlobalDef {
68 pub fn init_val(&self) -> GlobalValue {
69 match self {
70 GlobalDef::I32(i) => GlobalValue { i_32: *i },
71 GlobalDef::I64(i) => GlobalValue { i_64: *i },
72 GlobalDef::F32(f) => GlobalValue { f_32: *f },
73 GlobalDef::F64(f) => GlobalValue { f_64: *f },
74 }
75 }
76}
77
78#[derive(Copy, Clone)]
79pub union GlobalValue {
80 pub i_32: i32,
81 pub i_64: i64,
82 pub f_32: f32,
83 pub f_64: f64,
84}
85
86impl std::fmt::Debug for GlobalValue {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 writeln!(f, "GlobalValue {{")?;
97 unsafe {
98 writeln!(f, " i_32: {},", self.i_32)?;
99 writeln!(f, " i_64: {},", self.i_64)?;
100 writeln!(f, " f_32: {},", self.f_32)?;
101 writeln!(f, " f_64: {},", self.f_64)?;
102 }
103 writeln!(f, "}}")
104 }
105}
106
107pub struct OwnedGlobalSpec {
113 global: OwnedGlobal,
114 export_names: Vec<String>,
115}
116
117impl OwnedGlobalSpec {
118 pub fn new(global: OwnedGlobal, export_names: Vec<String>) -> Self {
119 Self {
120 global,
121 export_names,
122 }
123 }
124
125 pub fn new_def(init_val: i64, export_names: Vec<String>) -> Self {
127 Self::new(OwnedGlobal::Def(GlobalDef::I64(init_val)), export_names)
128 }
129
130 pub fn new_import(module: String, field: String, export_names: Vec<String>) -> Self {
132 Self::new(OwnedGlobal::Import { module, field }, export_names)
133 }
134
135 pub fn to_ref<'a>(&'a self) -> GlobalSpec<'a> {
138 GlobalSpec::new(
139 self.global.to_ref(),
140 self.export_names.iter().map(|x| x.as_str()).collect(),
141 )
142 }
143}
144
145pub enum OwnedGlobal {
149 Def(GlobalDef),
150 Import { module: String, field: String },
151}
152
153impl OwnedGlobal {
154 pub fn to_ref<'a>(&'a self) -> Global<'a> {
156 match self {
157 OwnedGlobal::Def(def) => Global::Def(def.clone()),
158 OwnedGlobal::Import { module, field } => Global::Import {
159 module: module.as_str(),
160 field: field.as_str(),
161 },
162 }
163 }
164}