nowasm/
decode.rs

1use crate::vector::Vector;
2use crate::{reader::Reader, VectorFactory};
3use core::fmt::{Display, Formatter};
4use core::str::Utf8Error;
5
6pub trait Decode<V: VectorFactory>: Sized {
7    fn decode(reader: &mut Reader) -> Result<Self, DecodeError>;
8
9    fn decode_vector(reader: &mut Reader) -> Result<V::Vector<Self>, DecodeError> {
10        let len = reader.read_usize()?;
11        let mut items = V::create_vector(Some(len));
12        for _ in 0..len {
13            items.push(Self::decode(reader)?);
14        }
15        Ok(items)
16    }
17}
18
19impl<V: VectorFactory> Decode<V> for u8 {
20    fn decode(reader: &mut Reader) -> Result<Self, DecodeError> {
21        reader.read_u8()
22    }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub enum DecodeError {
27    UnexpectedEndOfBytes,
28    InvalidMagic {
29        value: [u8; 4],
30    },
31    InvalidVersion {
32        value: [u8; 4],
33    },
34    InvalidSectionId {
35        value: u8,
36    },
37    InvalidImportDescTag {
38        value: u8,
39    },
40    InvalidExportDescTag {
41        value: u8,
42    },
43    InvalidLimitsFlag {
44        value: u8,
45    },
46    InvalidValType {
47        value: u8,
48    },
49    InvalidMutabilityFlag {
50        value: u8,
51    },
52    InvalidElemType {
53        value: u8,
54    },
55    InvalidFuncTypeTag {
56        value: u8,
57    },
58    InvalidMemoryCount {
59        value: usize,
60    },
61    InvalidTableCount {
62        value: usize,
63    },
64    InvalidResultArity {
65        value: usize,
66    },
67    InvalidMemIdx {
68        value: u32,
69    },
70    InvalidTableIdx {
71        value: u32,
72    },
73    InvalidOpcode {
74        value: u8,
75    },
76    UnexpectedExpr,
77    InvalidSectionOrder {
78        last_section_id: u8,
79        current_section_id: u8,
80    },
81    InvalidSectionByteSize {
82        section_id: u8,
83        expected_byte_size: usize,
84        actual_byte_size: usize,
85    },
86    InvalidUtf8(Utf8Error),
87    MismatchFunctionAndCodeSectionSize {
88        function_section_size: usize,
89        code_section_size: usize,
90    },
91    MalformedInteger,
92}
93
94impl Display for DecodeError {
95    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
96        match self {
97            Self::UnexpectedEndOfBytes => write!(f, "Unexpected end-of-bytes"),
98            Self::InvalidMagic { value } => write!(f, "Invalid magic number {value:?}"),
99            Self::InvalidVersion { value } => write!(f, "Invalid version number {value:?}"),
100            Self::InvalidSectionId { value } => write!(f, "Invalid section ID {value:?}"),
101            Self::InvalidImportDescTag { value } => {
102                write!(f, "Invalid import description tag {value:?})")
103            }
104            Self::InvalidExportDescTag { value } => {
105                write!(f, "Invalid export description tag {value:?})")
106            }
107            Self::InvalidLimitsFlag { value } => write!(f, "Invalid limits flag {value:?}"),
108            Self::InvalidValType { value } => write!(f, "Invalid value type {value:?}"),
109            Self::InvalidMutabilityFlag { value } => write!(f, "Invalid mutability flag {value:?}"),
110            Self::InvalidElemType { value } => write!(f, "Invalid element type {value:?}"),
111            Self::InvalidFuncTypeTag { value } => write!(f, "Invalid function type {value:?}"),
112            Self::InvalidMemoryCount { value } => write!(f, "Invalid memory count {value:?}"),
113            Self::InvalidTableCount { value } => write!(f, "Invalid table count {value:?}"),
114            Self::InvalidResultArity { value } => write!(f, "Invalid result arity {value:?}"),
115            Self::InvalidMemIdx { value } => write!(f, "Invalid memory index {value:?}"),
116            Self::InvalidTableIdx { value } => write!(f, "Invalid table index {value:?}"),
117            Self::InvalidOpcode { value } => write!(f, "Invalid opcode {value:?}"),
118            Self::UnexpectedExpr => write!(f, "Unexpected expression"),
119            Self::InvalidSectionOrder {
120                last_section_id,
121                current_section_id,
122            } => write!(
123                f,
124                "Invalid section order (last={last_section_id:?}), current={current_section_id:?})"
125            ),
126            Self::InvalidSectionByteSize {
127                section_id,
128                expected_byte_size,
129                actual_byte_size
130            } => write!(f, "Invalid section {section_id:?} byte size (expected={expected_byte_size:?} bytes, actual={actual_byte_size:?} bytes)"),
131            Self::InvalidUtf8(e) => write!(f,"Invalid UTF-8 bytes ({e})"),
132            Self::MismatchFunctionAndCodeSectionSize {
133                function_section_size,
134                code_section_size
135            } => write!(f, "Mismatch function section size ({function_section_size:?}) and code section size ({code_section_size:?})"),
136            Self::MalformedInteger => write!(f,"Malformed LEB128 integer"),
137        }
138    }
139}
140
141#[cfg(feature = "std")]
142impl std::error::Error for DecodeError {}