1use alloc::string::String;
2use crate::io;
3use super::{
4 Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint32, VarUint1, Uint8,
5 ValueType, TableElementType
6};
7
8const FLAG_HAS_MAX: u8 = 0x01;
9#[cfg(feature="atomics")]
10const FLAG_SHARED: u8 = 0x02;
11
12#[derive(Debug, Copy, Clone, PartialEq)]
14pub struct GlobalType {
15 content_type: ValueType,
16 is_mutable: bool,
17}
18
19impl GlobalType {
20 pub fn new(content_type: ValueType, is_mutable: bool) -> Self {
22 GlobalType {
23 content_type: content_type,
24 is_mutable: is_mutable,
25 }
26 }
27
28 pub fn content_type(&self) -> ValueType { self.content_type }
30
31 pub fn is_mutable(&self) -> bool { self.is_mutable }
33}
34
35impl Deserialize for GlobalType {
36 type Error = Error;
37
38 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
39 let content_type = ValueType::deserialize(reader)?;
40 let is_mutable = VarUint1::deserialize(reader)?;
41 Ok(GlobalType {
42 content_type: content_type,
43 is_mutable: is_mutable.into(),
44 })
45 }
46}
47
48impl Serialize for GlobalType {
49 type Error = Error;
50
51 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
52 self.content_type.serialize(writer)?;
53 VarUint1::from(self.is_mutable).serialize(writer)?;
54 Ok(())
55 }
56}
57
58#[derive(Debug, Copy, Clone, PartialEq)]
60pub struct TableType {
61 elem_type: TableElementType,
62 limits: ResizableLimits,
63}
64
65impl TableType {
66 pub fn new(min: u32, max: Option<u32>) -> Self {
68 TableType {
69 elem_type: TableElementType::AnyFunc,
70 limits: ResizableLimits::new(min, max),
71 }
72 }
73
74 pub fn limits(&self) -> &ResizableLimits { &self.limits }
76
77 pub fn elem_type(&self) -> TableElementType { self.elem_type }
79}
80
81impl Deserialize for TableType {
82 type Error = Error;
83
84 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
85 let elem_type = TableElementType::deserialize(reader)?;
86 let limits = ResizableLimits::deserialize(reader)?;
87 Ok(TableType {
88 elem_type: elem_type,
89 limits: limits,
90 })
91 }
92}
93
94impl Serialize for TableType {
95 type Error = Error;
96
97 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
98 self.elem_type.serialize(writer)?;
99 self.limits.serialize(writer)
100 }
101}
102
103#[derive(Debug, Copy, Clone, PartialEq)]
105pub struct ResizableLimits {
106 initial: u32,
107 maximum: Option<u32>,
108 #[cfg(feature = "atomics")]
109 shared: bool,
110}
111
112impl ResizableLimits {
113 pub fn new(min: u32, max: Option<u32>) -> Self {
115 ResizableLimits {
116 initial: min,
117 maximum: max,
118 #[cfg(feature = "atomics")]
119 shared: false,
120 }
121 }
122 pub fn initial(&self) -> u32 { self.initial }
124 pub fn maximum(&self) -> Option<u32> { self.maximum }
126
127 #[cfg(feature = "atomics")]
128 pub fn shared(&self) -> bool { self.shared }
130}
131
132impl Deserialize for ResizableLimits {
133 type Error = Error;
134
135 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
136 let flags: u8 = Uint8::deserialize(reader)?.into();
137 match flags {
138 0x00 | 0x01 => {},
140
141 #[cfg(feature="atomics")]
144 0x03 => {},
145
146 _ => return Err(Error::InvalidLimitsFlags(flags)),
147 }
148
149 let initial = VarUint32::deserialize(reader)?;
150 let maximum = if flags & FLAG_HAS_MAX != 0 {
151 Some(VarUint32::deserialize(reader)?.into())
152 } else {
153 None
154 };
155
156 Ok(ResizableLimits {
157 initial: initial.into(),
158 maximum: maximum,
159
160 #[cfg(feature="atomics")]
161 shared: flags & FLAG_SHARED != 0,
162 })
163 }
164}
165
166impl Serialize for ResizableLimits {
167 type Error = Error;
168
169 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
170 let mut flags: u8 = 0;
171 if self.maximum.is_some() {
172 flags |= FLAG_HAS_MAX;
173 }
174
175 #[cfg(feature="atomics")]
176 {
177 if self.shared {
180 flags |= FLAG_SHARED;
181 }
182 }
183 Uint8::from(flags).serialize(writer)?;
184 VarUint32::from(self.initial).serialize(writer)?;
185 if let Some(max) = self.maximum {
186 VarUint32::from(max).serialize(writer)?;
187 }
188 Ok(())
189 }
190}
191
192#[derive(Debug, Copy, Clone, PartialEq)]
194pub struct MemoryType(ResizableLimits);
195
196impl MemoryType {
197 pub fn new(min: u32, max: Option<u32>) -> Self {
199 let r = ResizableLimits::new(min, max);
200 MemoryType(r)
201 }
202
203 #[cfg(feature = "atomics")]
207 pub fn set_shared(&mut self, shared: bool) {
208 self.0.shared = shared;
209 }
210
211 pub fn limits(&self) -> &ResizableLimits {
213 &self.0
214 }
215}
216
217impl Deserialize for MemoryType {
218 type Error = Error;
219
220 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
221 Ok(MemoryType(ResizableLimits::deserialize(reader)?))
222 }
223}
224
225impl Serialize for MemoryType {
226 type Error = Error;
227
228 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
229 self.0.serialize(writer)
230 }
231}
232
233#[derive(Debug, Copy, Clone, PartialEq)]
235pub enum External {
236 Function(u32),
239 Table(TableType),
241 Memory(MemoryType),
243 Global(GlobalType),
245}
246
247impl Deserialize for External {
248 type Error = Error;
249
250 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
251 let kind = VarUint7::deserialize(reader)?;
252 match kind.into() {
253 0x00 => Ok(External::Function(VarUint32::deserialize(reader)?.into())),
254 0x01 => Ok(External::Table(TableType::deserialize(reader)?)),
255 0x02 => Ok(External::Memory(MemoryType::deserialize(reader)?)),
256 0x03 => Ok(External::Global(GlobalType::deserialize(reader)?)),
257 _ => Err(Error::UnknownExternalKind(kind.into())),
258 }
259 }
260}
261
262impl Serialize for External {
263 type Error = Error;
264
265 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
266 use self::External::*;
267
268 match self {
269 Function(index) => {
270 VarUint7::from(0x00).serialize(writer)?;
271 VarUint32::from(index).serialize(writer)?;
272 },
273 Table(tt) => {
274 VarInt7::from(0x01).serialize(writer)?;
275 tt.serialize(writer)?;
276 },
277 Memory(mt) => {
278 VarInt7::from(0x02).serialize(writer)?;
279 mt.serialize(writer)?;
280 },
281 Global(gt) => {
282 VarInt7::from(0x03).serialize(writer)?;
283 gt.serialize(writer)?;
284 },
285 }
286
287 Ok(())
288 }
289}
290
291#[derive(Debug, Clone, PartialEq)]
293pub struct ImportEntry {
294 module_str: String,
295 field_str: String,
296 external: External,
297}
298
299impl ImportEntry {
300 pub fn new(module_str: String, field_str: String, external: External) -> Self {
302 ImportEntry {
303 module_str: module_str,
304 field_str: field_str,
305 external: external,
306 }
307 }
308
309 pub fn module(&self) -> &str { &self.module_str }
311
312 pub fn module_mut(&mut self) -> &mut String {
314 &mut self.module_str
315 }
316
317 pub fn field(&self) -> &str { &self.field_str }
319
320 pub fn field_mut(&mut self) -> &mut String {
322 &mut self.field_str
323 }
324
325 pub fn external(&self) -> &External { &self.external }
327
328 pub fn external_mut(&mut self) -> &mut External { &mut self.external }
330}
331
332impl Deserialize for ImportEntry {
333 type Error = Error;
334
335 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
336 let module_str = String::deserialize(reader)?;
337 let field_str = String::deserialize(reader)?;
338 let external = External::deserialize(reader)?;
339
340 Ok(ImportEntry {
341 module_str: module_str,
342 field_str: field_str,
343 external: external,
344 })
345 }
346}
347
348impl Serialize for ImportEntry {
349 type Error = Error;
350
351 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
352 self.module_str.serialize(writer)?;
353 self.field_str.serialize(writer)?;
354 self.external.serialize(writer)
355 }
356}