1use types::*;
2use util::*;
3use Dump;
4
5#[derive(Debug, Clone)]
6pub enum Op {
7 Unreachable,
8 Nop,
9 Block { sig: BlockType },
10 Loop { sig: BlockType },
11 If { sig: BlockType },
12 Else,
13 End,
14 Br { depth: u32 },
16 BrIf { depth: u32 },
17 BrTable(BrTarget),
18 Return,
19 Call { index: FunctionSpaceIndex },
20 CallIndirect { index: TypeIndex, reserved: bool },
22 Drop,
23 Select,
24 GetLocal(LocalIndex),
25 SetLocal(LocalIndex),
26 TeeLocal(LocalIndex),
27 GetGlobal(GlobalIndex),
28 SetGlobal(GlobalIndex),
29 I32Load { imm: MemoryImmediate },
30 I64Load { imm: MemoryImmediate },
31 F32Load { imm: MemoryImmediate },
32 F64Load { imm: MemoryImmediate },
33 I32Load8S { imm: MemoryImmediate },
34 I32Load8U { imm: MemoryImmediate },
35 I32Load16S { imm: MemoryImmediate },
36 I32Load16U { imm: MemoryImmediate },
37 I64Load8S { imm: MemoryImmediate },
38 I64Load8U { imm: MemoryImmediate },
39 I64Load16S { imm: MemoryImmediate },
40 I64Load16U { imm: MemoryImmediate },
41 I64load32S { imm: MemoryImmediate },
42 I64load32U { imm: MemoryImmediate },
43 I32Store { imm: MemoryImmediate },
44 I64Store { imm: MemoryImmediate },
45 F32Store { imm: MemoryImmediate },
46 F64Store { imm: MemoryImmediate },
47 I32Store8 { imm: MemoryImmediate },
48 I32Store16 { imm: MemoryImmediate },
49 I64Store8 { imm: MemoryImmediate },
50 I64Store16 { imm: MemoryImmediate },
51 I64Store32 { imm: MemoryImmediate },
52 CurrentMemory { reserved: bool },
53 GrowMemory { reserved: bool },
54 I32Const(i32),
55 I64Const(i64),
56 F32Const(f32),
57 F64Const(f64),
58 I32Eqz,
59 I32Eq,
60 I32NE,
61 I32LtS,
62 I32LtU,
63 I32GtS,
64 I32GtU,
65 I32LeS,
66 I32LeU,
67 I32GeS,
68 I32GeU,
69 I64Eqz,
70 I64Eq,
71 I64Ne,
72 I64LtS,
73 I64LtU,
74 I64GtS,
75 I64GtU,
76 I64LeS,
77 I64LeU,
78 I64GeS,
79 I64GeU,
80 F32Eq,
81 F32Ne,
82 F32Lt,
83 F32Gt,
84 F32Le,
85 F32Ge,
86 F64Eq,
87 F64Ne,
88 F64Lt,
89 F64Gt,
90 F64Le,
91 F64Ge,
92 I32Clz,
93 I32Ctz,
94 I32Popcnt,
95 I32Add,
96 I32Sub,
97 I32Mul,
98 I32DivS,
99 I32DivU,
100 I32RemS,
101 I32RemU,
102 I32And,
103 I32Or,
104 I32Xor,
105 I32Shl,
106 I32ShrS,
107 I32ShrU,
108 I32Rotl,
109 I32Rotr,
110 I64Clz,
111 I64Ctz,
112 I64Popcnt,
113 I64Add,
114 I64Sub,
115 I64Mul,
116 I64DivS,
117 I64DivU,
118 I64RemS,
119 I64RemU,
120 I64And,
121 I64Or,
122 I64Xor,
123 I64Shl,
124 I64ShrS,
125 I64ShrU,
126 I64Rotl,
127 I64Rotr,
128 F32Abs,
129 F32Neg,
130 F32Ceil,
131 F32Floor,
132 F32Trunc,
133 F32Nearest,
134 F32Sqrt,
135 F32Add,
136 F32Sub,
137 F32Mul,
138 F32Div,
139 F32Min,
140 F32Max,
141 F32Copysign,
142 F64Abs,
143 F64Neg,
144 F64Ceil,
145 F64Floor,
146 F64Trunc,
147 F64Nearest,
148 F64Sqrt,
149 F64Add,
150 F64Sub,
151 F64Mul,
152 F64Div,
153 F64Min,
154 F64Max,
155 F64Copysign,
156 I32wrapI64,
157 I32TruncSF32,
158 I32TruncUF32,
159 I32TruncSF64,
160 I32TruncUF64,
161 I64ExtendSI32,
162 I64ExtendUI32,
163 I64TruncSF32,
164 I64TruncUF32,
165 I64TruncSF64,
166 I64TruncUF64,
167 F32ConvertSI32,
168 F32ConvertUI32,
169 F32ConvertSI64,
170 F32ConvertUI64,
171 F32DemoteF64,
172 F64ConvertSI32,
173 F64ConvertUI32,
174 F64ConvertSI64,
175 F64ConvertUI64,
176 F64PromoteF32,
177 I32ReinterpretF32,
178 I64ReinterpretF64,
179 F32ReinterpretI32,
180 F64ReinterpretI64,
181}
182
183impl Op {
184 pub fn resolve_functions(&mut self, nimports: u32) {
185 match *self {
186 Op::Call { ref mut index } => {
187 use InnerFunctionSpaceIndex::*;
188 match index.0 {
189 Function(ref mut f) => {
190 f.0 += nimports;
191 }
192 _ => (),
193 }
194 }
195 _ => (),
196 }
197 }
198}
199
200impl Dump for Op {
201 fn dump(&self, buf: &mut Vec<u8>) -> usize {
202 use self::Op::*;
203 fn do_imm(buf: &mut Vec<u8>, imm: &MemoryImmediate, code: u8) -> usize {
204 let mut size = 0;
205
206 size += write_uint8(buf, code);
207 size += imm.dump(buf);
208
209 size
210 }
211 let mut size = 0;
212
213 match self {
214 &Unreachable => size += write_uint8(buf, 0x00),
215 &Nop => size += write_uint8(buf, 0x01),
216 &Block { ref sig } => {
217 size += write_uint8(buf, 0x02);
218 size += sig.dump(buf);
219 }
220 &Loop { ref sig } => {
221 size += write_uint8(buf, 0x03);
222 size += sig.dump(buf);
223 }
224 &If { ref sig } => {
225 size += write_uint8(buf, 0x04);
226 size += sig.dump(buf);
227 }
228 &Else => size += write_uint8(buf, 0x05),
229 &End => size += write_uint8(buf, 0x0b),
230 &Br { ref depth } => {
231 size += write_uint8(buf, 0x0c);
232 size += write_varuint32(buf, *depth);
233 }
234 &BrIf { ref depth } => {
235 size += write_uint8(buf, 0x0d);
236 size += write_varuint32(buf, *depth);
237 }
238 &BrTable(ref br_target) => {
239 size += write_uint8(buf, 0x0e);
240 size += br_target.dump(buf);
241 }
242 &Return => size += write_uint8(buf, 0x0f),
243 &Call { ref index } => {
244 size += write_uint8(buf, 0x10);
245 size += write_varuint32(buf, **index);
246 }
247
248 &CallIndirect {
249 ref index,
250 ref reserved,
251 } => {
252 size += write_uint8(buf, 0x11);
253 size += write_varuint32(buf, **index);
254 size += write_varuint1(buf, *reserved as u8);
255 }
256 &Drop => size += write_uint8(buf, 0x1a),
257 &Select => size += write_uint8(buf, 0x1b),
258 &GetLocal(ref i) => {
259 size += write_uint8(buf, 0x20);
260 size += write_varuint32(buf, **i);
261 }
262 &SetLocal(ref i) => {
263 size += write_uint8(buf, 0x21);
264 size += write_varuint32(buf, **i);
265 }
266 &TeeLocal(ref i) => {
267 size += write_uint8(buf, 0x22);
268 size += write_varuint32(buf, **i);
269 }
270 &GetGlobal(ref i) => {
271 size += write_uint8(buf, 0x023);
272 size += write_varuint32(buf, **i);
273 }
274 &SetGlobal(ref i) => {
275 size += write_uint8(buf, 0x24);
276 size += write_varuint32(buf, **i);
277 }
278 &I32Load { ref imm } => size += do_imm(buf, imm, 0x28),
279 &I64Load { ref imm } => size += do_imm(buf, imm, 0x29),
280 &F32Load { ref imm } => size += do_imm(buf, imm, 0x2a),
281 &F64Load { ref imm } => size += do_imm(buf, imm, 0x2b),
282 &I32Load8S { ref imm } => size += do_imm(buf, imm, 0x2c),
283 &I32Load8U { ref imm } => size += do_imm(buf, imm, 0x2d),
284 &I32Load16S { ref imm } => size += do_imm(buf, imm, 0x2e),
285 &I32Load16U { ref imm } => size += do_imm(buf, imm, 0x2f),
286 &I64Load8S { ref imm } => size += do_imm(buf, imm, 0x30),
287 &I64Load8U { ref imm } => size += do_imm(buf, imm, 0x31),
288 &I64Load16S { ref imm } => size += do_imm(buf, imm, 0x32),
289 &I64Load16U { ref imm } => size += do_imm(buf, imm, 0x33),
290 &I64load32S { ref imm } => size += do_imm(buf, imm, 0x34),
291 &I64load32U { ref imm } => size += do_imm(buf, imm, 0x35),
292 &I32Store { ref imm } => size += do_imm(buf, imm, 0x36),
293 &I64Store { ref imm } => size += do_imm(buf, imm, 0x37),
294 &F32Store { ref imm } => size += do_imm(buf, imm, 0x38),
295 &F64Store { ref imm } => size += do_imm(buf, imm, 0x39),
296 &I32Store8 { ref imm } => size += do_imm(buf, imm, 0x3a),
297 &I32Store16 { ref imm } => size += do_imm(buf, imm, 0x3b),
298 &I64Store8 { ref imm } => size += do_imm(buf, imm, 0x3c),
299 &I64Store16 { ref imm } => size += do_imm(buf, imm, 0x3d),
300 &I64Store32 { ref imm } => size += do_imm(buf, imm, 0x3e),
301 &CurrentMemory { ref reserved } => {
302 size += write_uint8(buf, 0x3f);
303 size += write_varuint1(buf, *reserved as u8);
304 }
305 &GrowMemory { ref reserved } => {
306 size += write_uint8(buf, 0x40);
307 size += write_varuint1(buf, *reserved as u8);
308 }
309 &I32Const(ref i) => {
310 size += write_uint8(buf, 0x41);
311 size += write_varint32(buf, *i);
312 }
313 &I64Const(ref i) => {
314 size += write_uint8(buf, 0x42);
315 size += write_varint64(buf, *i);
316 }
317 &F32Const(ref f) => {
318 size += write_uint8(buf, 0x43);
319 unsafe {
320 size += write_uint32(buf, ::std::mem::transmute::<f32, u32>(*f));
321 }
322 }
323 &F64Const(ref f) => {
324 size += write_uint8(buf, 0x44);
325 unsafe {
326 size += write_uint64(buf, ::std::mem::transmute::<f64, u64>(*f));
327 }
328 }
329 &I32Eqz => size += write_uint8(buf, 0x45),
330 &I32Eq => size += write_uint8(buf, 0x46),
331 &I32NE => size += write_uint8(buf, 0x47),
332 &I32LtS => size += write_uint8(buf, 0x48),
333 &I32LtU => size += write_uint8(buf, 0x49),
334 &I32GtS => size += write_uint8(buf, 0x4a),
335 &I32GtU => size += write_uint8(buf, 0x4b),
336 &I32LeS => size += write_uint8(buf, 0x4c),
337 &I32LeU => size += write_uint8(buf, 0x4d),
338 &I32GeS => size += write_uint8(buf, 0x4e),
339 &I32GeU => size += write_uint8(buf, 0x4f),
340 &I64Eqz => size += write_uint8(buf, 0x50),
341 &I64Eq => size += write_uint8(buf, 0x51),
342 &I64Ne => size += write_uint8(buf, 0x52),
343 &I64LtS => size += write_uint8(buf, 0x53),
344 &I64LtU => size += write_uint8(buf, 0x54),
345 &I64GtS => size += write_uint8(buf, 0x55),
346 &I64GtU => size += write_uint8(buf, 0x56),
347 &I64LeS => size += write_uint8(buf, 0x57),
348 &I64LeU => size += write_uint8(buf, 0x58),
349 &I64GeS => size += write_uint8(buf, 0x59),
350 &I64GeU => size += write_uint8(buf, 0x5a),
351 &F32Eq => size += write_uint8(buf, 0x5b),
352 &F32Ne => size += write_uint8(buf, 0x5c),
353 &F32Lt => size += write_uint8(buf, 0x5d),
354 &F32Gt => size += write_uint8(buf, 0x5e),
355 &F32Le => size += write_uint8(buf, 0x5f),
356 &F32Ge => size += write_uint8(buf, 0x60),
357 &F64Eq => size += write_uint8(buf, 0x61),
358 &F64Ne => size += write_uint8(buf, 0x62),
359 &F64Lt => size += write_uint8(buf, 0x63),
360 &F64Gt => size += write_uint8(buf, 0x64),
361 &F64Le => size += write_uint8(buf, 0x65),
362 &F64Ge => size += write_uint8(buf, 0x66),
363 &I32Clz => size += write_uint8(buf, 0x67),
364 &I32Ctz => size += write_uint8(buf, 0x68),
365 &I32Popcnt => size += write_uint8(buf, 0x69),
366 &I32Add => size += write_uint8(buf, 0x6a),
367 &I32Sub => size += write_uint8(buf, 0x6b),
368 &I32Mul => size += write_uint8(buf, 0x6c),
369 &I32DivS => size += write_uint8(buf, 0x6d),
370 &I32DivU => size += write_uint8(buf, 0x6e),
371 &I32RemS => size += write_uint8(buf, 0x6f),
372 &I32RemU => size += write_uint8(buf, 0x70),
373 &I32And => size += write_uint8(buf, 0x71),
374 &I32Or => size += write_uint8(buf, 0x72),
375 &I32Xor => size += write_uint8(buf, 0x73),
376 &I32Shl => size += write_uint8(buf, 0x74),
377 &I32ShrS => size += write_uint8(buf, 0x75),
378 &I32ShrU => size += write_uint8(buf, 0x76),
379 &I32Rotl => size += write_uint8(buf, 0x77),
380 &I32Rotr => size += write_uint8(buf, 0x78),
381 &I64Clz => size += write_uint8(buf, 0x79),
382 &I64Ctz => size += write_uint8(buf, 0x7a),
383 &I64Popcnt => size += write_uint8(buf, 0x7b),
384 &I64Add => size += write_uint8(buf, 0x7c),
385 &I64Sub => size += write_uint8(buf, 0x7d),
386 &I64Mul => size += write_uint8(buf, 0x7e),
387 &I64DivS => size += write_uint8(buf, 0x7f),
388 &I64DivU => size += write_uint8(buf, 0x80),
389 &I64RemS => size += write_uint8(buf, 0x81),
390 &I64RemU => size += write_uint8(buf, 0x82),
391 &I64And => size += write_uint8(buf, 0x83),
392 &I64Or => size += write_uint8(buf, 0x84),
393 &I64Xor => size += write_uint8(buf, 0x85),
394 &I64Shl => size += write_uint8(buf, 0x86),
395 &I64ShrS => size += write_uint8(buf, 0x87),
396 &I64ShrU => size += write_uint8(buf, 0x88),
397 &I64Rotl => size += write_uint8(buf, 0x89),
398 &I64Rotr => size += write_uint8(buf, 0x8a),
399 &F32Abs => size += write_uint8(buf, 0x8b),
400 &F32Neg => size += write_uint8(buf, 0x8c),
401 &F32Ceil => size += write_uint8(buf, 0x8d),
402 &F32Floor => size += write_uint8(buf, 0x8e),
403 &F32Trunc => size += write_uint8(buf, 0x8f),
404 &F32Nearest => size += write_uint8(buf, 0x90),
405 &F32Sqrt => size += write_uint8(buf, 0x91),
406 &F32Add => size += write_uint8(buf, 0x92),
407 &F32Sub => size += write_uint8(buf, 0x93),
408 &F32Mul => size += write_uint8(buf, 0x94),
409 &F32Div => size += write_uint8(buf, 0x95),
410 &F32Min => size += write_uint8(buf, 0x96),
411 &F32Max => size += write_uint8(buf, 0x97),
412 &F32Copysign => size += write_uint8(buf, 0x98),
413 &F64Abs => size += write_uint8(buf, 0x99),
414 &F64Neg => size += write_uint8(buf, 0x9a),
415 &F64Ceil => size += write_uint8(buf, 0x9b),
416 &F64Floor => size += write_uint8(buf, 0x9c),
417 &F64Trunc => size += write_uint8(buf, 0x9d),
418 &F64Nearest => size += write_uint8(buf, 0x9e),
419 &F64Sqrt => size += write_uint8(buf, 0x9f),
420 &F64Add => size += write_uint8(buf, 0xa0),
421 &F64Sub => size += write_uint8(buf, 0xa1),
422 &F64Mul => size += write_uint8(buf, 0xa2),
423 &F64Div => size += write_uint8(buf, 0xa3),
424 &F64Min => size += write_uint8(buf, 0xa4),
425 &F64Max => size += write_uint8(buf, 0xa5),
426 &F64Copysign => size += write_uint8(buf, 0xa6),
427 &I32wrapI64 => size += write_uint8(buf, 0xa7),
428 &I32TruncSF32 => size += write_uint8(buf, 0xa8),
429 &I32TruncUF32 => size += write_uint8(buf, 0xa9),
430 &I32TruncSF64 => size += write_uint8(buf, 0xaa),
431 &I32TruncUF64 => size += write_uint8(buf, 0xab),
432 &I64ExtendSI32 => size += write_uint8(buf, 0xac),
433 &I64ExtendUI32 => size += write_uint8(buf, 0xad),
434 &I64TruncSF32 => size += write_uint8(buf, 0xae),
435 &I64TruncUF32 => size += write_uint8(buf, 0xaf),
436 &I64TruncSF64 => size += write_uint8(buf, 0xb0),
437 &I64TruncUF64 => size += write_uint8(buf, 0xb1),
438 &F32ConvertSI32 => size += write_uint8(buf, 0xb2),
439 &F32ConvertUI32 => size += write_uint8(buf, 0xb3),
440 &F32ConvertSI64 => size += write_uint8(buf, 0xb4),
441 &F32ConvertUI64 => size += write_uint8(buf, 0xb5),
442 &F32DemoteF64 => size += write_uint8(buf, 0xb6),
443 &F64ConvertSI32 => size += write_uint8(buf, 0xb7),
444 &F64ConvertUI32 => size += write_uint8(buf, 0xb8),
445 &F64ConvertSI64 => size += write_uint8(buf, 0xb9),
446 &F64ConvertUI64 => size += write_uint8(buf, 0xba),
447 &F64PromoteF32 => size += write_uint8(buf, 0xbb),
448 &I32ReinterpretF32 => size += write_uint8(buf, 0xbc),
449 &I64ReinterpretF64 => size += write_uint8(buf, 0xbd),
450 &F32ReinterpretI32 => size += write_uint8(buf, 0xbe),
451 &F64ReinterpretI64 => size += write_uint8(buf, 0xbf),
452 };
453 size
454 }
455}
456
457impl From<i32> for Op {
458 fn from(i: i32) -> Self {
459 Op::I32Const(i)
460 }
461}
462impl From<i64> for Op {
463 fn from(i: i64) -> Self {
464 Op::I64Const(i)
465 }
466}
467impl From<f32> for Op {
468 fn from(f: f32) -> Self {
469 Op::F32Const(f)
470 }
471}
472impl From<f64> for Op {
473 fn from(f: f64) -> Self {
474 Op::F64Const(f)
475 }
476}
477
478#[derive(Debug, Clone)]
479pub struct MemoryImmediate {
480 pub flags: u32,
481 pub offset: u32,
482}
483
484impl Dump for MemoryImmediate {
485 fn dump(&self, buf: &mut Vec<u8>) -> usize {
486 let mut size = 0;
487
488 size += write_varuint32(buf, self.flags);
489 size += write_varuint32(buf, self.offset);
490
491 size
492 }
493}
494
495#[derive(Debug, Clone)]
496pub struct BrTarget {
497 pub table: Vec<u32>,
499 pub default_target: u32,
500}
501
502impl Dump for BrTarget {
503 fn dump(&self, buf: &mut Vec<u8>) -> usize {
504 let mut size = 0;
505 let table = &self.table;
506
507 size += write_varuint32(buf, table.len() as u32);
508 for t in table {
509 size += write_varuint32(buf, *t);
510 }
511
512 size += write_varuint32(buf, self.default_target);
513
514 size
515 }
516}