1use alloc::vec::Vec;
14use core::fmt;
15
16use crate::encode::{SECTIONS, section};
17use crate::ids::{ConstId, FuncId, GlobalId, ImportId, Reg, StrId, Target, TypeId};
18use crate::inst::{Inst, InstError};
19use crate::module::{
20 Callee, Const, Export, ExportItem, Function, Global, Handler, Hook, HookBinding, Import,
21 JumpTable, LineRow, LocalVar, Module, Strings,
22};
23use crate::types::{Field, FuncType, Method, StructDef, TypeDef, ValType};
24use crate::{FORMAT_VERSION, MAGIC};
25
26#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
51#[non_exhaustive]
52pub struct Limits {
53 pub max_bytes: usize,
55 pub max_strings: usize,
57 pub max_types: usize,
59 pub max_consts: usize,
61 pub max_const_depth: u32,
64 pub max_functions: usize,
66 pub max_insts: usize,
68 pub max_total_insts: usize,
70 pub max_items: usize,
75}
76
77impl Default for Limits {
78 fn default() -> Self {
79 Limits {
80 max_bytes: 256 << 20,
81 max_strings: 1 << 22,
82 max_types: 1 << 20,
83 max_consts: 1 << 22,
84 max_const_depth: 64,
85 max_functions: 1 << 20,
86 max_insts: 1 << 24,
87 max_total_insts: 1 << 25,
88 max_items: 1 << 24,
89 }
90 }
91}
92
93#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
103#[non_exhaustive]
104pub enum Limit {
105 Bytes,
107 Strings,
109 Types,
111 Consts,
113 ConstDepth,
115 Functions,
117 Insts,
119 TotalInsts,
121 Items,
123 PerFunction,
127}
128
129impl fmt::Display for Limit {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 f.write_str(match self {
132 Limit::Bytes => "input size",
133 Limit::Strings => "string count",
134 Limit::Types => "type count",
135 Limit::Consts => "constant count",
136 Limit::ConstDepth => "constant nesting depth",
137 Limit::Functions => "function count",
138 Limit::Insts => "instructions per function",
139 Limit::TotalInsts => "total instructions",
140 Limit::Items => "list length",
141 Limit::PerFunction => "16-bit table size (65,536 entries)",
142 })
143 }
144}
145
146#[derive(Clone, Copy, PartialEq, Eq, Debug)]
157#[non_exhaustive]
158pub enum DecodeErrorKind {
159 UnexpectedEnd,
161 BadMagic,
163 UnsupportedVersion(u32),
165 ReservedFlags(u32),
167 SectionOutOfOrder {
169 expected: u32,
171 found: u32,
173 },
174 SectionLength(u32),
176 TrailingBytes,
178 LimitExceeded(Limit),
180 InvalidUtf8,
182 InvalidTag {
184 what: &'static str,
186 tag: u8,
188 },
189 InvalidChar(u32),
191 ConstForwardRef {
193 index: u32,
195 child: u32,
197 },
198 HookOrder,
200 DebugCount {
203 expected: u32,
205 found: u32,
207 },
208 Inst(InstError),
210}
211
212impl fmt::Display for DecodeErrorKind {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 match self {
215 DecodeErrorKind::UnexpectedEnd => f.write_str("unexpected end of input"),
216 DecodeErrorKind::BadMagic => f.write_str("not an LSB module (bad magic)"),
217 DecodeErrorKind::UnsupportedVersion(v) => write!(
218 f,
219 "unsupported format version {v} (this decoder reads version {FORMAT_VERSION})"
220 ),
221 DecodeErrorKind::ReservedFlags(v) => write!(f, "reserved header flags set ({v:#x})"),
222 DecodeErrorKind::SectionOutOfOrder { expected, found } => {
223 write!(f, "expected section {expected}, found {found}")
224 }
225 DecodeErrorKind::SectionLength(id) => {
226 write!(f, "section {id} does not match its declared length")
227 }
228 DecodeErrorKind::TrailingBytes => f.write_str("bytes after the last section"),
229 DecodeErrorKind::LimitExceeded(limit) => write!(f, "{limit} limit exceeded"),
230 DecodeErrorKind::InvalidUtf8 => f.write_str("string is not valid UTF-8"),
231 DecodeErrorKind::InvalidTag { what, tag } => write!(f, "invalid {what} tag {tag}"),
232 DecodeErrorKind::InvalidChar(v) => {
233 write!(f, "{v:#x} is not a Unicode scalar value")
234 }
235 DecodeErrorKind::ConstForwardRef { index, child } => write!(
236 f,
237 "constant k{index} refers to k{child}, which is not an earlier constant"
238 ),
239 DecodeErrorKind::HookOrder => {
240 f.write_str("hook bindings are not in strictly increasing order")
241 }
242 DecodeErrorKind::DebugCount { expected, found } => write!(
243 f,
244 "debug section describes {found} functions, the module has {expected}"
245 ),
246 DecodeErrorKind::Inst(e) => write!(f, "{e}"),
247 }
248 }
249}
250
251#[derive(Clone, Copy, PartialEq, Eq, Debug)]
267pub struct DecodeError {
268 offset: usize,
269 kind: DecodeErrorKind,
270}
271
272impl DecodeError {
273 #[must_use]
283 pub fn offset(&self) -> usize {
284 self.offset
285 }
286
287 #[must_use]
297 pub fn kind(&self) -> &DecodeErrorKind {
298 &self.kind
299 }
300}
301
302impl fmt::Display for DecodeError {
303 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
304 write!(f, "at byte {}: {}", self.offset, self.kind)
305 }
306}
307
308impl core::error::Error for DecodeError {}
309
310type Result<T> = core::result::Result<T, DecodeError>;
311
312struct Reader<'a> {
314 bytes: &'a [u8],
315 pos: usize,
316 end: usize,
317}
318
319impl<'a> Reader<'a> {
320 fn fail<T>(&self, at: usize, kind: DecodeErrorKind) -> Result<T> {
321 Err(DecodeError { offset: at, kind })
322 }
323
324 fn remaining(&self) -> usize {
325 self.end.saturating_sub(self.pos)
326 }
327
328 fn take(&mut self, n: usize) -> Result<&'a [u8]> {
329 let slice = self
330 .pos
331 .checked_add(n)
332 .filter(|&stop| stop <= self.end)
333 .and_then(|stop| self.bytes.get(self.pos..stop));
334 match slice {
335 Some(s) => {
336 self.pos += n;
337 Ok(s)
338 }
339 None => self.fail(self.pos, DecodeErrorKind::UnexpectedEnd),
340 }
341 }
342
343 fn array<const N: usize>(&mut self) -> Result<[u8; N]> {
344 let at = self.pos;
345 match <[u8; N]>::try_from(self.take(N)?) {
346 Ok(a) => Ok(a),
347 Err(_) => self.fail(at, DecodeErrorKind::UnexpectedEnd),
348 }
349 }
350
351 fn u8(&mut self) -> Result<u8> {
352 Ok(self.array::<1>()?[0])
353 }
354
355 fn u16(&mut self) -> Result<u16> {
356 Ok(u16::from_le_bytes(self.array()?))
357 }
358
359 fn u32(&mut self) -> Result<u32> {
360 Ok(u32::from_le_bytes(self.array()?))
361 }
362
363 fn u64(&mut self) -> Result<u64> {
364 Ok(u64::from_le_bytes(self.array()?))
365 }
366
367 fn count(&mut self, limit: usize, which: Limit, min_size: usize) -> Result<usize> {
371 let at = self.pos;
372 let n = self.u32()? as usize;
373 if n > limit {
374 return self.fail(at, DecodeErrorKind::LimitExceeded(which));
375 }
376 if n.saturating_mul(min_size) > self.remaining() {
377 return self.fail(at, DecodeErrorKind::UnexpectedEnd);
378 }
379 Ok(n)
380 }
381
382 fn bool(&mut self, what: &'static str) -> Result<bool> {
383 let at = self.pos;
384 match self.u8()? {
385 0 => Ok(false),
386 1 => Ok(true),
387 tag => self.fail(at, DecodeErrorKind::InvalidTag { what, tag }),
388 }
389 }
390
391 fn opt_u32(&mut self) -> Result<Option<u32>> {
392 if self.bool("option")? {
393 Ok(Some(self.u32()?))
394 } else {
395 Ok(None)
396 }
397 }
398
399 fn val_type(&mut self) -> Result<ValType> {
400 let at = self.pos;
401 let tag = self.u8()?;
402 if let Some(ty) = ValType::from_simple_tag(tag) {
403 return Ok(ty);
404 }
405 if tag == ValType::Ref(TypeId(0)).tag() {
406 return Ok(ValType::Ref(TypeId(self.u32()?)));
407 }
408 self.fail(
409 at,
410 DecodeErrorKind::InvalidTag {
411 what: "value type",
412 tag,
413 },
414 )
415 }
416
417 fn val_types(&mut self, limit: usize, which: Limit) -> Result<Vec<ValType>> {
418 let n = self.count(limit, which, 1)?;
419 let mut out = Vec::with_capacity(n);
420 for _ in 0..n {
421 out.push(self.val_type()?);
422 }
423 Ok(out)
424 }
425}
426
427const PER_FUNCTION: usize = 1 << 16;
429
430struct Decoder<'a, 'l> {
431 r: Reader<'a>,
432 limits: &'l Limits,
433 total_insts: usize,
434}
435
436impl Decoder<'_, '_> {
437 fn items(&mut self, min_size: usize) -> Result<usize> {
438 self.r.count(self.limits.max_items, Limit::Items, min_size)
439 }
440
441 fn per_function(&mut self, min_size: usize) -> Result<usize> {
442 let (limit, which) = if self.limits.max_items < PER_FUNCTION {
443 (self.limits.max_items, Limit::Items)
444 } else {
445 (PER_FUNCTION, Limit::PerFunction)
446 };
447 self.r.count(limit, which, min_size)
448 }
449
450 fn strings(&mut self) -> Result<Strings> {
451 let n = self.r.count(self.limits.max_strings, Limit::Strings, 4)?;
452 let mut strings = Strings::with_capacity(n, self.r.remaining());
453 for _ in 0..n {
454 let len = self.r.u32()? as usize;
455 let at = self.r.pos;
456 let bytes = self.r.take(len)?;
457 let Ok(s) = core::str::from_utf8(bytes) else {
458 return self.r.fail(at, DecodeErrorKind::InvalidUtf8);
459 };
460 if !strings.push(s) {
461 return self
462 .r
463 .fail(at, DecodeErrorKind::LimitExceeded(Limit::Bytes));
464 }
465 }
466 Ok(strings)
467 }
468
469 fn type_def(&mut self) -> Result<TypeDef> {
470 let at = self.r.pos;
471 Ok(match self.r.u8()? {
472 0 => {
473 let params = self.r.val_types(self.limits.max_items, Limit::Items)?;
474 let results = self.r.val_types(self.limits.max_items, Limit::Items)?;
475 TypeDef::Func(FuncType { params, results })
476 }
477 1 => {
478 let name = StrId(self.r.u32()?);
479 let parent = self.r.opt_u32()?.map(TypeId);
480 let n = self.per_function(5)?;
481 let mut fields = Vec::with_capacity(n);
482 for _ in 0..n {
483 let name = StrId(self.r.u32()?);
484 let ty = self.r.val_type()?;
485 fields.push(Field { name, ty });
486 }
487 let n = self.items(8)?;
488 let mut methods = Vec::with_capacity(n);
489 for _ in 0..n {
490 let name = StrId(self.r.u32()?);
491 let func = FuncId(self.r.u32()?);
492 methods.push(Method { name, func });
493 }
494 TypeDef::Struct(StructDef {
495 name,
496 parent,
497 fields,
498 methods,
499 })
500 }
501 2 => TypeDef::Array(self.r.val_type()?),
502 3 => {
503 let key = self.r.val_type()?;
504 let value = self.r.val_type()?;
505 TypeDef::Map { key, value }
506 }
507 4 => TypeDef::Cell(self.r.val_type()?),
508 5 => {
509 let key = self.r.val_type()?;
510 let value = self.r.val_type()?;
511 TypeDef::Iter { key, value }
512 }
513 6 => TypeDef::Coroutine,
514 tag => {
515 return self
516 .r
517 .fail(at, DecodeErrorKind::InvalidTag { what: "type", tag });
518 }
519 })
520 }
521
522 fn types(&mut self) -> Result<Vec<TypeDef>> {
523 let n = self.r.count(self.limits.max_types, Limit::Types, 1)?;
525 let mut types = Vec::with_capacity(n);
526 for _ in 0..n {
527 types.push(self.type_def()?);
528 }
529 Ok(types)
530 }
531
532 fn consts(&mut self) -> Result<Vec<Const>> {
533 let n = self.r.count(self.limits.max_consts, Limit::Consts, 2)?;
534 let mut consts = Vec::with_capacity(n);
535 let mut depth: Vec<u32> = Vec::with_capacity(n);
538 for index in 0..n {
539 let at = self.r.pos;
540 let c = match self.r.u8()? {
541 0 => Const::Bool(self.r.bool("boolean")?),
542 1 => Const::Int(i64::from_le_bytes(self.r.array()?)),
543 2 => Const::UInt(self.r.u64()?),
544 3 => Const::F32(self.r.u32()?),
545 4 => Const::F64(self.r.u64()?),
546 5 => {
547 let char_at = self.r.pos;
548 let v = self.r.u32()?;
549 match char::from_u32(v) {
550 Some(c) => Const::Char(c),
551 None => return self.r.fail(char_at, DecodeErrorKind::InvalidChar(v)),
552 }
553 }
554 6 => Const::Str(StrId(self.r.u32()?)),
555 7 => {
556 let len = self.items(1)?;
557 Const::Bytes(self.r.take(len)?.to_vec())
558 }
559 8 => {
560 let len = self.items(4)?;
561 let mut items = Vec::with_capacity(len);
562 for _ in 0..len {
563 items.push(ConstId(self.r.u32()?));
564 }
565 Const::Array(items)
566 }
567 9 => {
568 let len = self.items(8)?;
569 let mut entries = Vec::with_capacity(len);
570 for _ in 0..len {
571 let k = ConstId(self.r.u32()?);
572 let v = ConstId(self.r.u32()?);
573 entries.push((k, v));
574 }
575 Const::Map(entries)
576 }
577 tag => {
578 return self.r.fail(
579 at,
580 DecodeErrorKind::InvalidTag {
581 what: "constant",
582 tag,
583 },
584 );
585 }
586 };
587 let mut d = 1u32;
588 for child in c.children() {
589 match depth.get(child.index()) {
590 Some(&cd) => d = d.max(cd.saturating_add(1)),
591 None => {
592 let index = u32::try_from(index).unwrap_or(u32::MAX);
593 let kind = DecodeErrorKind::ConstForwardRef {
594 index,
595 child: child.0,
596 };
597 return self.r.fail(at, kind);
598 }
599 }
600 }
601 if d > self.limits.max_const_depth {
602 return self
603 .r
604 .fail(at, DecodeErrorKind::LimitExceeded(Limit::ConstDepth));
605 }
606 depth.push(d);
607 consts.push(c);
608 }
609 Ok(consts)
610 }
611
612 fn imports(&mut self) -> Result<Vec<Import>> {
613 let n = self.items(12)?;
614 let mut imports = Vec::with_capacity(n);
615 for _ in 0..n {
616 let module = StrId(self.r.u32()?);
617 let name = StrId(self.r.u32()?);
618 let sig = TypeId(self.r.u32()?);
619 imports.push(Import { module, name, sig });
620 }
621 Ok(imports)
622 }
623
624 fn globals(&mut self) -> Result<Vec<Global>> {
625 let n = self.items(7)?;
626 let mut globals = Vec::with_capacity(n);
627 for _ in 0..n {
628 let name = StrId(self.r.u32()?);
629 let ty = self.r.val_type()?;
630 let mutable = self.r.bool("boolean")?;
631 let init = self.r.opt_u32()?.map(ConstId);
632 globals.push(Global {
633 name,
634 ty,
635 mutable,
636 init,
637 });
638 }
639 Ok(globals)
640 }
641
642 fn function(&mut self) -> Result<Function> {
643 let name = StrId(self.r.u32()?);
644 let sig = TypeId(self.r.u32()?);
645 let regs = {
646 let n = self.per_function(1)?;
647 let mut v = Vec::with_capacity(n);
648 for _ in 0..n {
649 v.push(self.r.val_type()?);
650 }
651 v
652 };
653 let captures = {
654 let n = self.per_function(1)?;
655 let mut v = Vec::with_capacity(n);
656 for _ in 0..n {
657 v.push(self.r.val_type()?);
658 }
659 v
660 };
661 let names = {
662 let n = self.per_function(4)?;
663 let mut v = Vec::with_capacity(n);
664 for _ in 0..n {
665 v.push(StrId(self.r.u32()?));
666 }
667 v
668 };
669 let type_refs = {
670 let n = self.per_function(4)?;
671 let mut v = Vec::with_capacity(n);
672 for _ in 0..n {
673 v.push(TypeId(self.r.u32()?));
674 }
675 v
676 };
677 let tables = {
678 let n = self.items(8)?;
679 let mut v = Vec::with_capacity(n);
680 for _ in 0..n {
681 let default = Target(self.r.u32()?);
682 let len = self.items(4)?;
683 let mut targets = Vec::with_capacity(len);
684 for _ in 0..len {
685 targets.push(Target(self.r.u32()?));
686 }
687 v.push(JumpTable { targets, default });
688 }
689 v
690 };
691 let handlers = {
692 let n = self.items(14)?;
693 let mut v = Vec::with_capacity(n);
694 for _ in 0..n {
695 let start = self.r.u32()?;
696 let end = self.r.u32()?;
697 let target = Target(self.r.u32()?);
698 let catch = Reg(self.r.u16()?);
699 v.push(Handler {
700 start,
701 end,
702 target,
703 catch,
704 });
705 }
706 v
707 };
708 let code = {
709 let at = self.r.pos;
710 let n = self.r.count(self.limits.max_insts, Limit::Insts, 8)?;
711 self.total_insts = self.total_insts.saturating_add(n);
712 if self.total_insts > self.limits.max_total_insts {
713 return self
714 .r
715 .fail(at, DecodeErrorKind::LimitExceeded(Limit::TotalInsts));
716 }
717 let start = self.r.pos;
720 let words = self.r.take(n.saturating_mul(8))?;
721 let mut code = Vec::with_capacity(n);
722 for (i, word) in words.chunks_exact(8).enumerate() {
723 let mut bytes = [0u8; 8];
724 bytes.copy_from_slice(word);
725 match Inst::from_bytes(bytes) {
726 Ok(inst) => code.push(inst),
727 Err(e) => return self.r.fail(start + i * 8, DecodeErrorKind::Inst(e)),
728 }
729 }
730 code
731 };
732 Ok(Function {
733 name,
734 sig,
735 regs,
736 captures,
737 names,
738 type_refs,
739 tables,
740 handlers,
741 code,
742 lines: Vec::new(),
743 locals: Vec::new(),
744 })
745 }
746
747 fn functions(&mut self) -> Result<Vec<Function>> {
748 let n = self
750 .r
751 .count(self.limits.max_functions, Limit::Functions, 36)?;
752 let mut functions = Vec::with_capacity(n);
753 for _ in 0..n {
754 functions.push(self.function()?);
755 }
756 Ok(functions)
757 }
758
759 fn exports(&mut self) -> Result<Vec<Export>> {
760 let n = self.items(9)?;
761 let mut exports = Vec::with_capacity(n);
762 for _ in 0..n {
763 let name = StrId(self.r.u32()?);
764 let at = self.r.pos;
765 let tag = self.r.u8()?;
766 let index = self.r.u32()?;
767 let item = match tag {
768 0 => ExportItem::Func(FuncId(index)),
769 1 => ExportItem::Global(GlobalId(index)),
770 2 => ExportItem::Type(TypeId(index)),
771 tag => {
772 return self.r.fail(
773 at,
774 DecodeErrorKind::InvalidTag {
775 what: "export",
776 tag,
777 },
778 );
779 }
780 };
781 exports.push(Export { name, item });
782 }
783 Ok(exports)
784 }
785
786 fn hooks(&mut self) -> Result<Vec<HookBinding>> {
787 let n = self.r.count(Hook::ALL.len(), Limit::Items, 6)?;
788 let mut hooks: Vec<HookBinding> = Vec::with_capacity(n);
789 for _ in 0..n {
790 let at = self.r.pos;
791 let code = self.r.u8()?;
792 let Some(hook) = Hook::from_code(code) else {
793 return self.r.fail(
794 at,
795 DecodeErrorKind::InvalidTag {
796 what: "hook",
797 tag: code,
798 },
799 );
800 };
801 if hooks.last().is_some_and(|prev| prev.hook >= hook) {
802 return self.r.fail(at, DecodeErrorKind::HookOrder);
803 }
804 let callee_at = self.r.pos;
805 let tag = self.r.u8()?;
806 let index = self.r.u32()?;
807 let callee = match tag {
808 0 => Callee::Func(FuncId(index)),
809 1 => Callee::Import(ImportId(index)),
810 tag => {
811 return self.r.fail(
812 callee_at,
813 DecodeErrorKind::InvalidTag {
814 what: "callee",
815 tag,
816 },
817 );
818 }
819 };
820 hooks.push(HookBinding { hook, callee });
821 }
822 Ok(hooks)
823 }
824
825 fn debug(&mut self, functions: &mut [Function]) -> Result<()> {
826 let at = self.r.pos;
827 let n = self.r.u32()?;
828 if n as usize != functions.len() {
829 let expected = u32::try_from(functions.len()).unwrap_or(u32::MAX);
830 return self
831 .r
832 .fail(at, DecodeErrorKind::DebugCount { expected, found: n });
833 }
834 for f in functions {
835 let rows = self.items(16)?;
836 f.lines.reserve_exact(rows);
837 for _ in 0..rows {
838 let pc = self.r.u32()?;
839 let file = StrId(self.r.u32()?);
840 let line = self.r.u32()?;
841 let column = self.r.u32()?;
842 f.lines.push(LineRow {
843 pc,
844 file,
845 line,
846 column,
847 });
848 }
849 let locals = self.items(14)?;
850 f.locals.reserve_exact(locals);
851 for _ in 0..locals {
852 let reg = Reg(self.r.u16()?);
853 let name = StrId(self.r.u32()?);
854 let start = self.r.u32()?;
855 let end = self.r.u32()?;
856 f.locals.push(LocalVar {
857 reg,
858 name,
859 start,
860 end,
861 });
862 }
863 }
864 Ok(())
865 }
866
867 fn open(&mut self, id: u32) -> Result<usize> {
870 let at = self.r.pos;
871 let found = self.r.u32()?;
872 if found != id {
873 return self.r.fail(
874 at,
875 DecodeErrorKind::SectionOutOfOrder {
876 expected: id,
877 found,
878 },
879 );
880 }
881 let len = self.r.u32()? as usize;
882 let start = self.r.pos;
883 match start.checked_add(len).filter(|&end| end <= self.r.end) {
884 Some(end) => {
885 let outer = self.r.end;
886 self.r.end = end;
887 Ok(outer)
888 }
889 None => self.r.fail(start, DecodeErrorKind::UnexpectedEnd),
890 }
891 }
892
893 fn close(&mut self, id: u32, outer: usize) -> Result<()> {
895 if self.r.pos != self.r.end {
896 return self.r.fail(self.r.pos, DecodeErrorKind::SectionLength(id));
897 }
898 self.r.end = outer;
899 Ok(())
900 }
901}
902
903pub(crate) fn decode(bytes: &[u8], limits: &Limits) -> Result<Module> {
905 if bytes.len() > limits.max_bytes {
906 return Err(DecodeError {
907 offset: 0,
908 kind: DecodeErrorKind::LimitExceeded(Limit::Bytes),
909 });
910 }
911 let mut d = Decoder {
912 r: Reader {
913 bytes,
914 pos: 0,
915 end: bytes.len(),
916 },
917 limits,
918 total_insts: 0,
919 };
920 let magic: [u8; 4] = d.r.array()?;
921 if magic != MAGIC {
922 return d.r.fail(0, DecodeErrorKind::BadMagic);
923 }
924 let version = d.r.u32()?;
925 if version != FORMAT_VERSION {
926 return d.r.fail(4, DecodeErrorKind::UnsupportedVersion(version));
927 }
928 let flags = d.r.u32()?;
929 if flags != 0 {
930 return d.r.fail(8, DecodeErrorKind::ReservedFlags(flags));
931 }
932
933 let mut module = Module::default();
934 for id in (1u32..).take(SECTIONS) {
935 let outer = d.open(id)?;
936 match id {
937 section::STRINGS => module.strings = d.strings()?,
938 section::TYPES => module.types = d.types()?,
939 section::CONSTS => module.consts = d.consts()?,
940 section::IMPORTS => module.imports = d.imports()?,
941 section::GLOBALS => module.globals = d.globals()?,
942 section::FUNCTIONS => module.functions = d.functions()?,
943 section::EXPORTS => module.exports = d.exports()?,
944 section::HOOKS => module.hooks = d.hooks()?,
945 section::META => {
946 module.name = d.r.opt_u32()?.map(StrId);
947 module.start = d.r.opt_u32()?.map(FuncId);
948 }
949 _ => d.debug(&mut module.functions)?,
950 }
951 d.close(id, outer)?;
952 }
953 if d.r.pos != bytes.len() {
954 return d.r.fail(d.r.pos, DecodeErrorKind::TrailingBytes);
955 }
956 Ok(module)
957}