web_assembler/
types.rs

1use std::ops::Deref;
2use util::*;
3use ops::Op;
4use Dump;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub enum ValueType {
8    I32,
9    I64,
10    F32,
11    F64,
12}
13
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub struct BlockType(pub Option<ValueType>);
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18pub enum ElemType {
19    AnyFunc,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct FuncType {
24    pub params: Vec<ValueType>,
25    pub ret: Option<ValueType>,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Hash)]
29pub struct GlobalType {
30    pub content: ValueType,
31    pub mutable: bool,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Hash)]
35pub struct TableType {
36    pub element: ElemType,
37    pub limits: ResizableLimits,
38}
39
40
41#[derive(Debug, Clone, PartialEq, Eq, Hash)]
42pub struct MemoryType {
43    pub limits: ResizableLimits,
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Hash)]
47pub struct ResizableLimits {
48    pub flags: u32,
49    pub initial: u32,
50    pub maximum: Option<u32>,
51}
52
53#[derive(Debug, Clone)]
54pub struct Code(pub Vec<Op>);
55
56#[derive(Debug, Clone)]
57pub struct InitExpr(pub Code);
58
59
60impl Dump for ValueType {
61    fn dump(&self, buf: &mut Vec<u8>) -> usize {
62        use self::ValueType::*;
63        match self {
64            &I32 => write_varint7(buf, -0x01),
65            &I64 => write_varint7(buf, -0x02),
66            &F32 => write_varint7(buf, -0x03),
67            &F64 => write_varint7(buf, -0x04),
68        }
69    }
70}
71
72impl Dump for BlockType {
73    fn dump(&self, buf: &mut Vec<u8>) -> usize {
74        match &self.0 {
75            &Some(ref v) => v.dump(buf),
76            &None => write_varint7(buf, -0x40),
77        }
78    }
79}
80
81impl Dump for ElemType {
82    fn dump(&self, buf: &mut Vec<u8>) -> usize {
83        use self::ElemType::*;
84        match self {
85            &AnyFunc => write_varint7(buf, -0x10),
86        }
87    }
88}
89impl Dump for FuncType {
90    fn dump(&self, buf: &mut Vec<u8>) -> usize {
91        let params = &self.params;
92        let ret = &self.ret;
93
94        let mut size = 0;
95        size += write_varint7(buf, -0x20);
96
97        size += write_varuint32(buf, params.len() as u32);
98        for param in params {
99            size += param.dump(buf);
100        }
101
102        size += write_varuint1(buf, ret.is_some() as u8);
103        for ret in ret {
104            size += ret.dump(buf);
105        }
106        size
107    }
108}
109
110impl Dump for GlobalType {
111    fn dump(&self, buf: &mut Vec<u8>) -> usize {
112        let mut size = 0;
113        size += self.content.dump(buf);
114        size += write_varuint1(buf, self.mutable as u8);
115        size
116    }
117}
118
119impl Dump for TableType {
120    fn dump(&self, buf: &mut Vec<u8>) -> usize {
121        let mut size = 0;
122        size += self.element.dump(buf);
123        size += self.limits.dump(buf);
124        size
125    }
126}
127
128impl Dump for MemoryType {
129    fn dump(&self, buf: &mut Vec<u8>) -> usize {
130        self.limits.dump(buf)
131    }
132}
133
134
135impl ResizableLimits {
136    pub fn new(limit: u32) -> Self {
137        ResizableLimits {
138            flags: 0,
139            initial: limit,
140            maximum: None,
141        }
142    }
143
144    pub fn max(mut self, maximum: u32) -> Self {
145        self.maximum = Some(maximum);
146        self
147    }
148
149    /// unstable
150    pub fn flags(mut self, flags: u32) -> Self {
151        self.flags = flags;
152        self
153    }
154}
155
156impl Dump for ResizableLimits {
157    fn dump(&self, buf: &mut Vec<u8>) -> usize {
158        let mut size = 0;
159        let flags = self.flags | (self.maximum.is_some() as u32);
160        size += write_varuint32(buf, flags);
161        size += write_varuint32(buf, self.initial);
162        if let Some(m) = self.maximum {
163            size += write_varuint32(buf, m);
164        }
165        size
166    }
167}
168
169impl Dump for Code {
170    fn dump(&self, buf: &mut Vec<u8>) -> usize {
171        let mut size = 0;
172        for op in self.0.iter() {
173            size += op.dump(buf);
174        }
175        size
176    }
177}
178
179
180impl Dump for InitExpr {
181    fn dump(&self, buf: &mut Vec<u8>) -> usize {
182        self.0.dump(buf)
183    }
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
187pub struct TypeIndex(u32);
188impl Deref for TypeIndex {
189    type Target = u32;
190    fn deref(&self) -> &u32 {
191        &self.0
192    }
193}
194#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
195pub struct ImportIndex(u32);
196impl Deref for ImportIndex {
197    type Target = u32;
198    fn deref(&self) -> &u32 {
199        &self.0
200    }
201}
202#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
203/// restrict to this crate
204pub struct FunctionIndex(pub u32);
205impl Deref for FunctionIndex {
206    type Target = u32;
207    fn deref(&self) -> &u32 {
208        &self.0
209    }
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
213pub struct ImportedFunctionIndex(pub u32);
214
215#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
216pub enum InnerFunctionSpaceIndex {
217    Import(ImportedFunctionIndex),
218    Function(FunctionIndex),
219}
220
221#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
222pub struct FunctionSpaceIndex(pub InnerFunctionSpaceIndex);
223
224impl Deref for FunctionSpaceIndex {
225    type Target = u32;
226    fn deref(&self) -> &u32 {
227        use self::InnerFunctionSpaceIndex::*;
228        match self.0 {
229            Import(ref i) => &i.0,
230            Function(ref f) => &**f,
231        }
232    }
233}
234
235impl Into<FunctionSpaceIndex> for FunctionIndex {
236    fn into(self) -> FunctionSpaceIndex {
237        FunctionSpaceIndex(InnerFunctionSpaceIndex::Function(self))
238    }
239}
240
241
242#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
243pub struct TableIndex(u32);
244impl Deref for TableIndex {
245    type Target = u32;
246    fn deref(&self) -> &u32 {
247        &self.0
248    }
249}
250#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
251pub struct MemoryIndex(u32);
252impl Deref for MemoryIndex {
253    type Target = u32;
254    fn deref(&self) -> &u32 {
255        &self.0
256    }
257}
258#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
259pub struct GlobalIndex(u32);
260impl Deref for GlobalIndex {
261    type Target = u32;
262    fn deref(&self) -> &u32 {
263        &self.0
264    }
265}
266#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
267pub struct ExportIndex(u32);
268impl Deref for ExportIndex {
269    type Target = u32;
270    fn deref(&self) -> &u32 {
271        &self.0
272    }
273}
274#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
275pub struct ElementIndex(u32);
276impl Deref for ElementIndex {
277    type Target = u32;
278    fn deref(&self) -> &u32 {
279        &self.0
280    }
281}
282#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
283pub struct CodeIndex(u32);
284impl Deref for CodeIndex {
285    type Target = u32;
286    fn deref(&self) -> &u32 {
287        &self.0
288    }
289}
290#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
291pub struct DataIndex(u32);
292impl Deref for DataIndex {
293    type Target = u32;
294    fn deref(&self) -> &u32 {
295        &self.0
296    }
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
300pub struct LocalIndex(u32);
301impl Deref for LocalIndex {
302    type Target = u32;
303    fn deref(&self) -> &u32 {
304        &self.0
305    }
306}
307
308
309pub mod internal {
310    use types::*;
311    macro_rules! impl_new {
312        ($name: tt) => {
313            impl $name {
314                pub fn new(u: u32) -> Self {
315                    $name(u)
316                }
317            }
318        }
319    }
320
321    impl_new!(TypeIndex);
322    impl_new!(ImportIndex);
323    impl_new!(FunctionIndex);
324    impl_new!(TableIndex);
325    impl_new!(MemoryIndex);
326    impl_new!(GlobalIndex);
327    impl_new!(ExportIndex);
328    impl_new!(ElementIndex);
329    impl_new!(CodeIndex);
330    impl_new!(DataIndex);
331
332    impl_new!(LocalIndex);
333}