tinywasm_wasmparser/readers/core/
code.rs1use crate::std::ops::Range;
17use crate::{BinaryReader, FromReader, OperatorsReader, Result, SectionLimited, ValType};
18
19pub type CodeSectionReader<'a> = SectionLimited<'a, FunctionBody<'a>>;
21
22#[derive(Debug, Clone)]
24pub struct FunctionBody<'a> {
25 reader: BinaryReader<'a>,
26}
27
28impl<'a> FunctionBody<'a> {
29 pub fn new(offset: usize, data: &'a [u8]) -> Self {
31 Self {
32 reader: BinaryReader::new_with_offset(data, offset),
33 }
34 }
35
36 pub fn allow_memarg64(&mut self, allow: bool) {
42 self.reader.allow_memarg64(allow);
43 }
44
45 pub fn get_binary_reader(&self) -> BinaryReader<'a> {
47 self.reader.clone()
48 }
49
50 fn skip_locals(reader: &mut BinaryReader) -> Result<()> {
51 let count = reader.read_var_u32()?;
52 for _ in 0..count {
53 reader.read_var_u32()?;
54 reader.read::<ValType>()?;
55 }
56 Ok(())
57 }
58
59 pub fn get_locals_reader(&self) -> Result<LocalsReader<'a>> {
61 let mut reader = self.reader.clone();
62 let count = reader.read_var_u32()?;
63 Ok(LocalsReader { reader, count })
64 }
65
66 pub fn get_operators_reader(&self) -> Result<OperatorsReader<'a>> {
68 let mut reader = self.reader.clone();
69 Self::skip_locals(&mut reader)?;
70 Ok(OperatorsReader::new(reader))
71 }
72
73 pub fn range(&self) -> Range<usize> {
75 self.reader.range()
76 }
77}
78
79impl<'a> FromReader<'a> for FunctionBody<'a> {
80 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
81 let reader = reader.read_reader("function body extends past end of the code section")?;
82 Ok(FunctionBody { reader })
83 }
84}
85
86pub struct LocalsReader<'a> {
88 reader: BinaryReader<'a>,
89 count: u32,
90}
91
92impl<'a> LocalsReader<'a> {
93 pub fn get_count(&self) -> u32 {
95 self.count
96 }
97
98 pub fn original_position(&self) -> usize {
100 self.reader.original_position()
101 }
102
103 pub fn read(&mut self) -> Result<(u32, ValType)> {
105 let count = self.reader.read()?;
106 let value_type = self.reader.read()?;
107 Ok((count, value_type))
108 }
109}
110
111impl<'a> IntoIterator for LocalsReader<'a> {
112 type Item = Result<(u32, ValType)>;
113 type IntoIter = LocalsIterator<'a>;
114 fn into_iter(self) -> Self::IntoIter {
115 let count = self.count;
116 LocalsIterator {
117 reader: self,
118 left: count,
119 err: false,
120 }
121 }
122}
123
124pub struct LocalsIterator<'a> {
126 reader: LocalsReader<'a>,
127 left: u32,
128 err: bool,
129}
130
131impl<'a> Iterator for LocalsIterator<'a> {
132 type Item = Result<(u32, ValType)>;
133 fn next(&mut self) -> Option<Self::Item> {
134 if self.err || self.left == 0 {
135 return None;
136 }
137 let result = self.reader.read();
138 self.err = result.is_err();
139 self.left -= 1;
140 Some(result)
141 }
142 fn size_hint(&self) -> (usize, Option<usize>) {
143 let count = self.reader.get_count() as usize;
144 (count, Some(count))
145 }
146}