1use crate::error::{Error, ErrorKind, Result};
2use crate::leb128::Leb128;
3use crate::source::BinarySource;
4use std::borrow::Cow;
5use std::convert::TryInto;
6use std::marker::PhantomData;
7use std::str;
8use wain_ast::*;
9
10mod section_id {
11 pub const CUSTOM: u8 = 0;
12 pub const TYPE: u8 = 1;
13 pub const IMPORT: u8 = 2;
14 pub const FUNCTION: u8 = 3;
15 pub const TABLE: u8 = 4;
16 pub const MEMORY: u8 = 5;
17 pub const GLOBAL: u8 = 6;
18 pub const EXPORT: u8 = 7;
19 pub const START: u8 = 8;
20 pub const ELEMENT: u8 = 9;
21 pub const CODE: u8 = 10;
22 pub const DATA: u8 = 11;
23
24 pub fn to_name(id: u8) -> &'static str {
25 match id {
27 self::CUSTOM => "custom section",
28 self::TYPE => "type section",
29 self::IMPORT => "import section",
30 self::FUNCTION => "function section",
31 self::TABLE => "table section",
32 self::MEMORY => "memory section",
33 self::GLOBAL => "global section",
34 self::EXPORT => "export section",
35 self::START => "start section",
36 self::ELEMENT => "element section",
37 self::CODE => "code section",
38 self::DATA => "data section",
39 _ => unreachable!(),
40 }
41 }
42}
43
44struct VecItems<'p, 's, P: Parse<'s>> {
47 parser: &'p mut Parser<'s>,
48 count: usize,
49 phantom: PhantomData<P>, }
51
52impl<'p, 's, P: Parse<'s>> VecItems<'p, 's, P> {
53 fn new(parser: &'p mut Parser<'s>, count: usize) -> Self {
54 Self {
55 parser,
56 count,
57 phantom: PhantomData,
58 }
59 }
60
61 fn into_vec(self) -> Result<'s, Vec<P>> {
64 self.collect()
65 }
66}
67
68impl<'p, 's, P: Parse<'s>> Iterator for VecItems<'p, 's, P> {
69 type Item = Result<'s, P>;
70
71 fn next(&mut self) -> Option<Self::Item> {
72 if self.count == 0 {
73 return None;
74 }
75 self.count -= 1;
76 Some(self.parser.parse())
77 }
78
79 fn size_hint(&self) -> (usize, Option<usize>) {
80 (self.count, Some(self.count))
81 }
82}
83
84pub struct Parser<'source> {
85 source: &'source [u8],
86 input: &'source [u8],
87 rest_len: usize,
88 parsing: &'static str,
90}
91
92impl<'s> Parser<'s> {
93 pub fn new(input: &'s [u8]) -> Parser<'s> {
94 Self {
95 source: input,
96 input,
97 rest_len: 0,
98 parsing: "module",
99 }
100 }
101
102 fn eat(&mut self, bytes: usize) {
103 self.input = &self.input[bytes..];
104 }
105
106 fn consume(&mut self, expected: &'static str) -> Result<'s, u8> {
107 if self.input.is_empty() {
108 Err(self.error(ErrorKind::UnexpectedEof { expected }))
109 } else {
110 let b = self.input[0];
111 self.input = &self.input[1..];
112 Ok(b)
113 }
114 }
115
116 fn current_pos(&self) -> usize {
117 self.source.len() - self.input.len() - self.rest_len
118 }
119
120 fn error(&self, kind: ErrorKind) -> Box<Error<'s>> {
121 let pos = self.current_pos();
122 Error::new(kind, pos, self.source, self.parsing)
123 }
124
125 fn unexpected_byte<T: AsRef<[u8]>>(&self, expected: T, got: u8, what: &'static str) -> Box<Error<'s>> {
126 let pos = self.current_pos() - 1; let kind = ErrorKind::UnexpectedByte {
128 expected: expected.as_ref().to_vec(),
129 got,
130 what,
131 };
132 Error::new(kind, pos, self.source, self.parsing)
133 }
134
135 pub fn parse<P: Parse<'s>>(&mut self) -> Result<'s, P> {
136 Parse::parse(self)
137 }
138
139 fn parse_int<I: Leb128>(&mut self) -> Result<'s, I> {
140 match I::read_leb128(self.input) {
141 Ok((i, len)) => {
142 self.eat(len);
143 Ok(i)
144 }
145 Err(kind) => Err(self.error(*kind)),
146 }
147 }
148
149 fn check_len(&self, len: usize, what: &'static str) -> Result<'s, ()> {
150 if self.input.len() < len {
151 Err(self.error(ErrorKind::LengthOutOfInput {
152 input: self.input.len(),
153 specified: len,
154 what,
155 }))
156 } else {
157 Ok(())
158 }
159 }
160
161 fn sub_parser(&self, sub_len: usize, what: &'static str) -> Result<'s, Parser<'s>> {
162 self.check_len(sub_len, what)?;
163 Ok(Parser {
164 source: self.source,
165 rest_len: self.input.len() - sub_len,
166 input: &self.input[..sub_len],
167 parsing: what,
168 })
169 }
170
171 fn section_parser(&mut self) -> Result<'s, Parser<'s>> {
172 let section = section_id::to_name(self.input[0]);
173 self.eat(1); let size = self.parse_int::<u32>()? as usize;
175 let parser = self.sub_parser(size, section)?;
176 self.eat(size);
177 Ok(parser)
178 }
179
180 fn ignore_custom_sections(&mut self) -> Result<'s, ()> {
183 while let [section_id::CUSTOM, ..] = self.input {
184 let mut inner = self.section_parser()?;
185 let _: Name = inner.parse()?;
186 }
187 Ok(())
188 }
189
190 fn parse_flag(&mut self, byte: u8, what: &'static str) -> Result<'s, ()> {
191 let b = self.consume(what)?;
192 if b == byte {
193 Ok(())
194 } else {
195 Err(self.unexpected_byte([byte], b, what))
196 }
197 }
198
199 fn parse_vec<P: Parse<'s>>(&mut self) -> Result<'s, VecItems<'_, 's, P>> {
201 let size = self.parse_int::<u32>()? as usize;
202 self.check_len(size, "size of vec elements")?;
205 Ok(VecItems::new(self, size))
206 }
207
208 fn check_section_end(&self, section_id: u8) -> Result<'s, ()> {
209 if self.input.is_empty() {
210 Ok(())
211 } else {
212 Err(self.error(ErrorKind::MalformedSectionSize {
213 name: section_id::to_name(section_id),
214 remaining_bytes: self.input.len(),
215 }))
216 }
217 }
218
219 fn push_vec_items<P: Parse<'s>>(&mut self, section_id: u8, vec: &mut Vec<P>) -> Result<'s, ()> {
220 if let [b, ..] = self.input {
221 if *b == section_id {
222 let mut inner = self.section_parser()?;
223 let vec_items = inner.parse_vec()?;
224 vec.reserve(vec_items.count);
225 for elem in vec_items {
226 vec.push(elem?);
227 }
228 inner.check_section_end(section_id)?;
229 }
230 }
231 Ok(())
232 }
233}
234
235pub trait Parse<'source>: Sized {
236 fn parse(parser: &mut Parser<'source>) -> Result<'source, Self>;
237}
238
239impl<'s> Parse<'s> for u32 {
241 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
242 parser.parse_int()
243 }
244}
245
246impl<'s> Parse<'s> for Root<'s, BinarySource<'s>> {
247 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
248 Ok(Root {
249 module: parser.parse()?,
250 source: BinarySource(parser.source),
251 })
252 }
253}
254
255impl<'s> Parse<'s> for Module<'s> {
257 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
258 fn parse_section_into_vec<'s, P: Parse<'s>>(parser: &mut Parser<'s>, id: u8) -> Result<'s, Vec<P>> {
259 if parser.input.starts_with(&[id]) {
260 let mut inner = parser.section_parser()?;
261 let vec = inner.parse_vec()?.into_vec();
262 inner.check_section_end(id)?;
263 vec
264 } else {
265 Ok(vec![])
266 }
267 }
268
269 let start = parser.current_pos();
270
271 match parser.input {
272 [0x00, 0x61, 0x73, 0x6d, ..] => parser.eat(4), _ => return Err(parser.error(ErrorKind::WasmMagicNotFound)),
274 }
275
276 parser.check_len(4, "wasm version")?;
277 match parser.input {
278 [0x01, 0x00, 0x00, 0x00, ..] => parser.eat(4),
279 _ => {
280 let bytes = parser.input[..4].try_into().unwrap();
281 return Err(parser.error(ErrorKind::VersionMismatch(bytes)));
282 }
283 }
284
285 parser.ignore_custom_sections()?;
286
287 let types = parse_section_into_vec(parser, section_id::TYPE)?;
289
290 parser.ignore_custom_sections()?;
291
292 let mut funcs = vec![];
293 let mut tables = vec![];
294 let mut memories = vec![];
295 let mut globals = vec![];
296
297 if let [section_id::IMPORT, ..] = parser.input {
299 let mut inner = parser.section_parser()?;
300 for desc in inner.parse_vec()? {
301 match desc? {
302 ImportDesc::Func(f) => funcs.push(f),
303 ImportDesc::Table(t) => tables.push(t),
304 ImportDesc::Memory(m) => memories.push(m),
305 ImportDesc::Global(g) => globals.push(g),
306 }
307 }
308 inner.check_section_end(section_id::IMPORT)?;
309 }
310
311 parser.ignore_custom_sections()?;
312
313 let func_indices: Vec<u32> = parse_section_into_vec(parser, section_id::FUNCTION)?;
317 funcs.reserve(func_indices.len());
318
319 parser.ignore_custom_sections()?;
320
321 parser.push_vec_items(section_id::TABLE, &mut tables)?;
323
324 parser.ignore_custom_sections()?;
325
326 parser.push_vec_items(section_id::MEMORY, &mut memories)?;
328
329 parser.ignore_custom_sections()?;
330
331 parser.push_vec_items(section_id::GLOBAL, &mut globals)?;
333
334 parser.ignore_custom_sections()?;
335
336 let exports = parse_section_into_vec(parser, section_id::EXPORT)?;
337
338 parser.ignore_custom_sections()?;
339
340 let entrypoint = if let [section_id::START, ..] = parser.input {
342 let mut inner = parser.section_parser()?;
343 let start = inner.parse()?;
344 inner.check_section_end(section_id::START)?;
345 Some(start)
346 } else {
347 None
348 };
349
350 parser.ignore_custom_sections()?;
351
352 let elems = parse_section_into_vec(parser, section_id::ELEMENT)?;
354
355 parser.ignore_custom_sections()?;
356
357 if let [section_id::CODE, ..] = parser.input {
359 let mut inner = parser.section_parser()?;
360
361 let codes = inner.parse_vec::<Code>()?;
362 if codes.count != func_indices.len() {
363 return Err(codes.parser.error(ErrorKind::FuncCodeLengthMismatch {
364 num_funcs: func_indices.len(),
365 num_codes: codes.count,
366 }));
367 }
368
369 for (code, typeidx) in codes.zip(func_indices.into_iter()) {
370 let code = code?;
371 funcs.push(Func {
372 start: code.start,
373 idx: typeidx,
374 kind: FuncKind::Body {
375 locals: code.locals,
376 expr: code.expr,
377 },
378 });
379 }
380
381 inner.check_section_end(section_id::CODE)?
382 } else if !func_indices.is_empty() {
383 return Err(parser.error(ErrorKind::FuncCodeLengthMismatch {
384 num_funcs: func_indices.len(),
385 num_codes: 0,
386 }));
387 }
388
389 parser.ignore_custom_sections()?;
390
391 let data = parse_section_into_vec(parser, section_id::DATA)?;
392
393 parser.ignore_custom_sections()?;
394
395 if !parser.input.is_empty() {
396 return Err(parser.error(ErrorKind::ExpectedEof(parser.input[0])));
397 }
398
399 Ok(Module {
400 start,
401 id: None,
402 types,
403 exports,
404 funcs,
405 elems,
406 tables,
407 data,
408 memories,
409 globals,
410 entrypoint,
411 })
412 }
413}
414
415impl<'s> Parse<'s> for Name<'s> {
417 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
418 let size = parser.parse_int::<u32>()? as usize;
419 parser.check_len(size, "name")?;
420 match str::from_utf8(&parser.input[..size]) {
421 Ok(name) => {
422 parser.eat(size);
423 Ok(Name(Cow::Borrowed(name)))
424 }
425 Err(error) => Err(parser.error(ErrorKind::InvalidUtf8 { what: "name", error })),
426 }
427 }
428}
429
430impl<'s> Parse<'s> for FuncType {
432 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
433 let start = parser.current_pos();
434 parser.parse_flag(0x60, "function type")?;
435 let params = parser.parse_vec()?.into_vec()?;
436 let results = parser.parse_vec()?.into_vec()?;
437 Ok(FuncType { start, params, results })
438 }
439}
440
441impl<'s> Parse<'s> for ValType {
443 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
444 match parser.consume("value type")? {
445 0x7f => Ok(ValType::I32),
446 0x7e => Ok(ValType::I64),
447 0x7d => Ok(ValType::F32),
448 0x7c => Ok(ValType::F64),
449 b => Err(parser.unexpected_byte([0x7f, 0x7e, 0x7d, 0x7c], b, "value type")),
450 }
451 }
452}
453
454enum ImportDesc<'s> {
456 Func(Func<'s>),
457 Table(Table<'s>),
458 Memory(Memory<'s>),
459 Global(Global<'s>),
460}
461impl<'s> Parse<'s> for ImportDesc<'s> {
462 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
463 let start = parser.current_pos();
464 let import = Import {
465 mod_name: parser.parse()?,
466 name: parser.parse()?,
467 };
468 match parser.consume("import description")? {
469 0x00 => Ok(ImportDesc::Func(Func {
470 start,
471 idx: parser.parse()?,
472 kind: FuncKind::Import(import),
473 })),
474 0x01 => Ok(ImportDesc::Table(Table {
475 start,
476 ty: parser.parse()?,
477 import: Some(import),
478 })),
479 0x02 => Ok(ImportDesc::Memory(Memory {
480 start,
481 ty: parser.parse()?,
482 import: Some(import),
483 })),
484 0x03 => {
485 let GlobalType(mutable, ty) = parser.parse()?;
486 Ok(ImportDesc::Global(Global {
487 start,
488 mutable,
489 ty,
490 kind: GlobalKind::Import(import),
491 }))
492 }
493 b => Err(parser.unexpected_byte([0x00, 0x01, 0x02, 0x03], b, "import description")),
494 }
495 }
496}
497
498impl<'s> Parse<'s> for TableType {
500 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
501 parser.parse_flag(0x70, "funcref of table type")?;
502 Ok(TableType { limit: parser.parse()? })
503 }
504}
505
506impl<'s> Parse<'s> for Limits {
508 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
509 match parser.consume("limit")? {
510 0x00 => Ok(Limits::From(parser.parse_int()?)),
511 0x01 => Ok(Limits::Range(parser.parse_int()?, parser.parse_int()?)),
512 b => Err(parser.unexpected_byte([0x00, 0x01], b, "limit")),
513 }
514 }
515}
516
517impl<'s> Parse<'s> for MemType {
519 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
520 Ok(MemType { limit: parser.parse()? })
521 }
522}
523
524struct GlobalType(bool, ValType);
526impl<'s> Parse<'s> for GlobalType {
527 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
528 let ty = parser.parse()?;
529 let mutable = match parser.consume("mutability of global type")? {
530 0x00 => false,
531 0x01 => true,
532 b => return Err(parser.unexpected_byte([0x00, 0x01], b, "mutability of global type")),
533 };
534 Ok(GlobalType(mutable, ty))
535 }
536}
537
538impl<'s> Parse<'s> for Table<'s> {
540 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
541 Ok(Table {
542 start: parser.current_pos(),
543 ty: parser.parse()?,
544 import: None,
545 })
546 }
547}
548
549impl<'s> Parse<'s> for Memory<'s> {
551 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
552 Ok(Memory {
553 start: parser.current_pos(),
554 ty: parser.parse()?,
555 import: None,
556 })
557 }
558}
559
560impl<'s> Parse<'s> for Global<'s> {
562 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
563 let start = parser.current_pos();
564 let GlobalType(mutable, ty) = parser.parse()?;
565 let Expr(insns) = parser.parse()?;
566 Ok(Global {
567 start,
568 mutable,
569 ty,
570 kind: GlobalKind::Init(insns),
571 })
572 }
573}
574
575struct Expr(Vec<Instruction>);
577impl<'s> Parse<'s> for Expr {
578 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
579 let mut insns = vec![];
580 loop {
581 if let [0x0b, ..] = parser.input {
582 parser.eat(1);
583 return Ok(Expr(insns));
584 }
585 insns.push(parser.parse()?);
586 }
587 }
588}
589
590struct BlockType(Option<ValType>);
592impl<'s> Parse<'s> for BlockType {
593 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
594 if let [0x40, ..] = parser.input {
595 parser.eat(1);
596 return Ok(BlockType(None));
597 }
598 Ok(BlockType(Some(parser.parse()?)))
599 }
600}
601
602impl<'s> Parse<'s> for Instruction {
604 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
605 use InsnKind::*;
606 let start = parser.current_pos();
607 let kind = match parser.consume("instruction")? {
608 0x00 => Unreachable,
611 0x01 => Nop,
612 0x02 => {
613 let BlockType(ty) = parser.parse()?;
614 let Expr(body) = parser.parse()?;
615 Block { ty, body }
616 }
617 0x03 => {
618 let BlockType(ty) = parser.parse()?;
619 let Expr(body) = parser.parse()?;
620 Loop { ty, body }
621 }
622 0x04 => {
623 let BlockType(ty) = parser.parse()?;
624
625 let mut then_body = vec![];
626 let has_else = loop {
627 match parser.input {
628 [0x05, ..] => break true,
629 [0x0b, ..] => break false,
630 _ => then_body.push(parser.parse()?),
631 }
632 };
633 parser.eat(1);
634
635 let else_body = if has_else {
636 let Expr(insns) = parser.parse()?;
637 insns
638 } else {
639 vec![]
640 };
641
642 If {
643 ty,
644 then_body,
645 else_body,
646 }
647 }
648 0x0c => Br(parser.parse()?),
649 0x0d => BrIf(parser.parse()?),
650 0x0e => BrTable {
651 labels: parser.parse_vec()?.into_vec()?,
652 default_label: parser.parse()?,
653 },
654 0x0f => Return,
655 0x10 => Call(parser.parse()?),
656 0x11 => {
657 let insn = CallIndirect(parser.parse()?);
658 parser.parse_flag(0x00, "reserved byte in call_indirect")?;
659 insn
660 }
661 0x1a => Drop,
664 0x1b => Select,
665 0x20 => LocalGet(parser.parse()?),
668 0x21 => LocalSet(parser.parse()?),
669 0x22 => LocalTee(parser.parse()?),
670 0x23 => GlobalGet(parser.parse()?),
671 0x24 => GlobalSet(parser.parse()?),
672 0x28 => I32Load(parser.parse()?),
675 0x29 => I64Load(parser.parse()?),
676 0x2a => F32Load(parser.parse()?),
677 0x2b => F64Load(parser.parse()?),
678 0x2c => I32Load8S(parser.parse()?),
679 0x2d => I32Load8U(parser.parse()?),
680 0x2e => I32Load16S(parser.parse()?),
681 0x2f => I32Load16U(parser.parse()?),
682 0x30 => I64Load8S(parser.parse()?),
683 0x31 => I64Load8U(parser.parse()?),
684 0x32 => I64Load16S(parser.parse()?),
685 0x33 => I64Load16U(parser.parse()?),
686 0x34 => I64Load32S(parser.parse()?),
687 0x35 => I64Load32U(parser.parse()?),
688 0x36 => I32Store(parser.parse()?),
689 0x37 => I64Store(parser.parse()?),
690 0x38 => F32Store(parser.parse()?),
691 0x39 => F64Store(parser.parse()?),
692 0x3a => I32Store8(parser.parse()?),
693 0x3b => I32Store16(parser.parse()?),
694 0x3c => I64Store8(parser.parse()?),
695 0x3d => I64Store16(parser.parse()?),
696 0x3e => I64Store32(parser.parse()?),
697 0x3f => {
698 parser.parse_flag(0x00, "reserved byte in memory.size")?;
699 MemorySize
700 }
701 0x40 => {
702 parser.parse_flag(0x00, "reserved byte in memory.grow")?;
703 MemoryGrow
704 }
705 0x41 => I32Const(parser.parse_int()?),
708 0x42 => I64Const(parser.parse_int()?),
709 0x43 => F32Const(parser.parse()?),
710 0x44 => F64Const(parser.parse()?),
711 0x45 => I32Eqz,
713 0x46 => I32Eq,
714 0x47 => I32Ne,
715 0x48 => I32LtS,
716 0x49 => I32LtU,
717 0x4a => I32GtS,
718 0x4b => I32GtU,
719 0x4c => I32LeS,
720 0x4d => I32LeU,
721 0x4e => I32GeS,
722 0x4f => I32GeU,
723 0x50 => I64Eqz,
724 0x51 => I64Eq,
725 0x52 => I64Ne,
726 0x53 => I64LtS,
727 0x54 => I64LtU,
728 0x55 => I64GtS,
729 0x56 => I64GtU,
730 0x57 => I64LeS,
731 0x58 => I64LeU,
732 0x59 => I64GeS,
733 0x5a => I64GeU,
734 0x5b => F32Eq,
735 0x5c => F32Ne,
736 0x5d => F32Lt,
737 0x5e => F32Gt,
738 0x5f => F32Le,
739 0x60 => F32Ge,
740 0x61 => F64Eq,
741 0x62 => F64Ne,
742 0x63 => F64Lt,
743 0x64 => F64Gt,
744 0x65 => F64Le,
745 0x66 => F64Ge,
746 0x67 => I32Clz,
748 0x68 => I32Ctz,
749 0x69 => I32Popcnt,
750 0x6a => I32Add,
751 0x6b => I32Sub,
752 0x6c => I32Mul,
753 0x6d => I32DivS,
754 0x6e => I32DivU,
755 0x6f => I32RemS,
756 0x70 => I32RemU,
757 0x71 => I32And,
758 0x72 => I32Or,
759 0x73 => I32Xor,
760 0x74 => I32Shl,
761 0x75 => I32ShrS,
762 0x76 => I32ShrU,
763 0x77 => I32Rotl,
764 0x78 => I32Rotr,
765 0x79 => I64Clz,
767 0x7a => I64Ctz,
768 0x7b => I64Popcnt,
769 0x7c => I64Add,
770 0x7d => I64Sub,
771 0x7e => I64Mul,
772 0x7f => I64DivS,
773 0x80 => I64DivU,
774 0x81 => I64RemS,
775 0x82 => I64RemU,
776 0x83 => I64And,
777 0x84 => I64Or,
778 0x85 => I64Xor,
779 0x86 => I64Shl,
780 0x87 => I64ShrS,
781 0x88 => I64ShrU,
782 0x89 => I64Rotl,
783 0x8a => I64Rotr,
784 0x8b => F32Abs,
786 0x8c => F32Neg,
787 0x8d => F32Ceil,
788 0x8e => F32Floor,
789 0x8f => F32Trunc,
790 0x90 => F32Nearest,
791 0x91 => F32Sqrt,
792 0x92 => F32Add,
793 0x93 => F32Sub,
794 0x94 => F32Mul,
795 0x95 => F32Div,
796 0x96 => F32Min,
797 0x97 => F32Max,
798 0x98 => F32Copysign,
799 0x99 => F64Abs,
801 0x9a => F64Neg,
802 0x9b => F64Ceil,
803 0x9c => F64Floor,
804 0x9d => F64Trunc,
805 0x9e => F64Nearest,
806 0x9f => F64Sqrt,
807 0xa0 => F64Add,
808 0xa1 => F64Sub,
809 0xa2 => F64Mul,
810 0xa3 => F64Div,
811 0xa4 => F64Min,
812 0xa5 => F64Max,
813 0xa6 => F64Copysign,
814 0xa7 => I32WrapI64,
816 0xa8 => I32TruncF32S,
817 0xa9 => I32TruncF32U,
818 0xaa => I32TruncF64S,
819 0xab => I32TruncF64U,
820 0xac => I64ExtendI32S,
821 0xad => I64ExtendI32U,
822 0xae => I64TruncF32S,
823 0xaf => I64TruncF32U,
824 0xb0 => I64TruncF64S,
825 0xb1 => I64TruncF64U,
826 0xb2 => F32ConvertI32S,
827 0xb3 => F32ConvertI32U,
828 0xb4 => F32ConvertI64S,
829 0xb5 => F32ConvertI64U,
830 0xb6 => F32DemoteF64,
831 0xb7 => F64ConvertI32S,
832 0xb8 => F64ConvertI32U,
833 0xb9 => F64ConvertI64S,
834 0xba => F64ConvertI64U,
835 0xbb => F64PromoteF32,
836 0xbc => I32ReinterpretF32,
837 0xbd => I64ReinterpretF64,
838 0xbe => F32ReinterpretI32,
839 0xbf => F64ReinterpretI64,
840 0xc0 => I32Extend8S,
842 0xc1 => I32Extend16S,
843 0xc2 => I64Extend8S,
844 0xc3 => I64Extend16S,
845 0xc4 => I64Extend32S,
846 b => return Err(parser.unexpected_byte([], b, "instruction")),
848 };
849 Ok(Instruction { start, kind })
850 }
851}
852
853impl<'s> Parse<'s> for Mem {
855 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
856 let align = parser.parse_int()?;
857 let offset = parser.parse_int()?;
858 Ok(Mem { align, offset })
859 }
860}
861
862impl<'s> Parse<'s> for f32 {
864 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
865 if parser.input.len() < 4 {
866 return Err(parser.error(ErrorKind::UnexpectedEof {
867 expected: "32bit floating point number",
868 }));
869 }
870 let buf: [u8; 4] = parser.input[..4].try_into().unwrap();
871 parser.eat(4);
872 Ok(f32::from_le_bytes(buf))
873 }
874}
875
876impl<'s> Parse<'s> for f64 {
878 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
879 if parser.input.len() < 8 {
880 return Err(parser.error(ErrorKind::UnexpectedEof {
881 expected: "32bit floating point number",
882 }));
883 }
884 let buf: [u8; 8] = parser.input[..8].try_into().unwrap();
885 parser.eat(8);
886 Ok(f64::from_le_bytes(buf))
887 }
888}
889
890impl<'s> Parse<'s> for Export<'s> {
892 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
893 let start = parser.current_pos();
894 let name = parser.parse()?;
895 let kind = match parser.consume("export description")? {
896 0x00 => ExportKind::Func(parser.parse()?),
897 0x01 => ExportKind::Table(parser.parse()?),
898 0x02 => ExportKind::Memory(parser.parse()?),
899 0x03 => ExportKind::Global(parser.parse()?),
900 b => {
901 return Err(parser.unexpected_byte([0x00, 0x01, 0x02, 0x03], b, "export description"));
902 }
903 };
904 Ok(Export { start, name, kind })
905 }
906}
907
908impl<'s> Parse<'s> for StartFunction {
910 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
911 Ok(StartFunction {
912 start: parser.current_pos(),
913 idx: parser.parse()?,
914 })
915 }
916}
917
918impl<'s> Parse<'s> for ElemSegment {
920 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
921 let start = parser.current_pos();
922 let idx = parser.parse()?;
923 let Expr(offset) = parser.parse()?;
924 let init = parser.parse_vec()?.into_vec()?;
925 Ok(ElemSegment {
926 start,
927 idx,
928 offset,
929 init,
930 })
931 }
932}
933
934struct Code {
936 start: usize,
937 locals: Vec<ValType>,
938 expr: Vec<Instruction>,
939}
940impl<'s> Parse<'s> for Code {
941 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
942 let start = parser.current_pos();
943 let size = parser.parse_int::<u32>()? as usize;
944 let mut inner = parser.sub_parser(size, "code section")?;
947 parser.eat(size);
948
949 let mut locals = vec![];
950 for loc in inner.parse_vec::<Locals>()? {
951 let loc = loc?;
952 if let Some(c) = loc.count.checked_add(locals.len() as u32) {
953 locals.resize(c as usize, loc.ty);
954 } else {
955 return Err(parser.error(ErrorKind::TooManyLocalVariables(locals.len())));
956 }
957 }
958
959 let Expr(expr) = inner.parse()?;
960 if !inner.input.is_empty() {
961 return Err(inner.error(ErrorKind::MalformedCodeSize {
962 remaining_bytes: inner.input.len(),
963 }));
964 }
965 Ok(Code { start, locals, expr })
966 }
967}
968
969struct Locals {
971 count: u32,
972 ty: ValType,
973}
974impl<'s> Parse<'s> for Locals {
975 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
976 Ok(Locals {
977 count: parser.parse_int()?,
978 ty: parser.parse()?,
979 })
980 }
981}
982
983impl<'s> Parse<'s> for DataSegment<'s> {
985 fn parse(parser: &mut Parser<'s>) -> Result<'s, Self> {
986 let start = parser.current_pos();
987 let idx = parser.parse()?;
988 let Expr(offset) = parser.parse()?;
989
990 let size = parser.parse_int::<u32>()? as usize;
992 if size > parser.input.len() {
993 return Err(parser.error(ErrorKind::LengthOutOfInput {
994 input: parser.input.len(),
995 specified: size,
996 what: "byte buffer in data segment",
997 }));
998 }
999 let data = &parser.input[..size];
1000 parser.eat(size);
1001
1002 Ok(DataSegment {
1003 start,
1004 idx,
1005 offset,
1006 data: Cow::Borrowed(data),
1007 })
1008 }
1009}
1010
1011#[cfg(test)]
1012mod tests {
1013 use super::*;
1014 use std::env;
1015 use std::fs;
1016
1017 fn unwrap<T>(res: Result<'_, T>) -> T {
1018 match res {
1019 Ok(x) => x,
1020 Err(e) => panic!("unexpected error: {}", e),
1021 }
1022 }
1023
1024 fn read_hello_file(name: &'static str) -> Vec<u8> {
1025 let mut dir = env::current_dir().unwrap();
1026 dir.pop();
1027 dir.push("examples");
1028 dir.push("hello");
1029 dir.push(name);
1030 fs::read(dir).unwrap()
1031 }
1032
1033 #[test]
1035 fn hello_world() {
1036 let bin = read_hello_file("hello.wasm");
1037
1038 let mut parser = Parser::new(&bin);
1039 let root: Root<'_, _> = unwrap(parser.parse());
1040
1041 let t = &root.module.types;
1042 assert_eq!(t.len(), 3);
1043 assert_eq!(&t[0].params, &[ValType::I32]);
1044 assert_eq!(&t[0].results, &[ValType::I32]);
1045 assert_eq!(&t[1].params, &[ValType::I32]);
1046 assert_eq!(&t[1].results, &[]);
1047 assert_eq!(&t[2].params, &[]);
1048 assert_eq!(&t[2].results, &[]);
1049
1050 let f = &root.module.funcs;
1051 assert_eq!(f.len(), 3);
1052 assert!(matches!(&f[0], Func {
1053 idx: 0,
1054 kind: FuncKind::Import(Import {
1055 mod_name: Name(n1),
1056 name: Name(n2),
1057 }),
1058 ..
1059 } if n1 == "env" && n2 == "putchar"));
1060 assert!(matches!(
1061 &f[1],
1062 Func {
1063 idx: 1,
1064 kind: FuncKind::Body { .. },
1065 ..
1066 }
1067 ));
1068 assert!(matches!(
1069 &f[2],
1070 Func {
1071 idx: 2,
1072 kind: FuncKind::Body { .. },
1073 ..
1074 }
1075 ));
1076
1077 let e = &root.module.exports;
1078 assert_eq!(e.len(), 2);
1079 assert!(matches!(&e[0], Export {
1080 name: Name(n),
1081 kind: ExportKind::Memory(0),
1082 ..
1083 } if n == "memory"));
1084 assert!(matches!(&e[1], Export {
1085 name: Name(n),
1086 kind: ExportKind::Func(2),
1087 ..
1088 } if n == "_start"));
1089
1090 assert!(root.module.elems.is_empty());
1091
1092 let t = &root.module.tables;
1093 assert_eq!(t.len(), 1);
1094 assert!(matches!(
1095 &t[0],
1096 Table {
1097 ty: TableType {
1098 limit: Limits::Range(1, 1)
1099 },
1100 import: None,
1101 ..
1102 }
1103 ));
1104
1105 let m = &root.module.memories;
1106 assert_eq!(m.len(), 1);
1107 assert!(matches!(
1108 &m[0],
1109 Memory {
1110 ty: MemType { limit: Limits::From(2) },
1111 import: None,
1112 ..
1113 }
1114 ));
1115
1116 let d = &root.module.data;
1117 assert_eq!(d.len(), 1);
1118 assert_eq!(d[0].idx, 0);
1119 assert!(matches!(
1120 d[0].offset.as_slice(),
1121 [Instruction {
1122 kind: InsnKind::I32Const(1024),
1123 ..
1124 }]
1125 ));
1126 assert_eq!(d[0].data.as_ref(), b"Hello, world\n\0".as_ref());
1127
1128 let g = &root.module.globals;
1129 assert_eq!(g.len(), 1);
1130 assert!(matches!(&g[0], Global {
1131 mutable: true,
1132 ty: ValType::I32,
1133 kind: GlobalKind::Init(expr),
1134 ..
1135 } if matches!(
1136 expr.as_slice(),
1137 [
1138 Instruction {
1139 kind: InsnKind::I32Const(66576),
1140 ..
1141 }
1142 ]
1143 )));
1144
1145 assert!(root.module.entrypoint.is_none());
1146
1147 let bin = read_hello_file("hello_global.wasm");
1148 let mut parser = Parser::new(&bin);
1149 let _: Root<'_, _> = unwrap(parser.parse());
1150
1151 let bin = read_hello_file("hello_indirect_call.wasm");
1152 let mut parser = Parser::new(&bin);
1153 let _: Root<'_, _> = unwrap(parser.parse());
1154
1155 let bin = read_hello_file("hello_struct.wasm");
1156 let mut parser = Parser::new(&bin);
1157 let _: Root<'_, _> = unwrap(parser.parse());
1158 }
1159
1160 macro_rules! test_parse_error {
1161 ($name:ident, $expected:pat, $bin:expr) => {
1162 #[test]
1163 fn $name() {
1164 let bin: &[_] = $bin;
1165 let mut parser = Parser::new(bin);
1166 match parser.parse::<Module<'_>>() {
1167 Ok(_) => panic!("unexpected success"),
1168 Err(err) => assert!(matches!(err.kind, $expected)),
1169 }
1170 }
1171 };
1172 }
1173
1174 test_parse_error!(
1175 regression_issue_29,
1176 ErrorKind::VersionMismatch(_),
1177 b"\x00\x61\x73\x6d\x01\x31\x39\x00\x61\x73\x6d\x01\x31\x39\x35\x01" );
1179
1180 test_parse_error!(
1181 regression_issue_30,
1182 ErrorKind::LengthOutOfInput {
1183 what: "size of vec elements",
1184 ..
1185 },
1186 b"\x00\x61\x73\x6d\x01\x00\x00\x00\x05\x05\xff\xff\xff\x0d\xfb\x81\x05\x00\x00"
1187 );
1188
1189 test_parse_error!(
1190 code_size,
1191 ErrorKind::MalformedCodeSize { remaining_bytes: 1 },
1192 b"\x00\x61\x73\x6d\
1193 \x01\x00\x00\x00\
1194 \x01\x04\x01\x60\x00\x00\
1195 \x03\x02\x01\x00\
1196 \x0a\x05\x01\x03\x00\x0b\x0b"
1197 );
1198}