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