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