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 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)]
203pub 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}