wasmparser/readers/core/
code.rs1use crate::{BinaryReader, FromReader, OperatorsReader, Result, SectionLimited, ValType};
17use core::ops::Range;
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(reader: BinaryReader<'a>) -> Self {
31 Self { reader }
32 }
33
34 pub fn get_binary_reader(&self) -> BinaryReader<'a> {
36 self.reader.clone()
37 }
38
39 fn skip_locals(reader: &mut BinaryReader) -> Result<()> {
40 let count = reader.read_var_u32()?;
41 for _ in 0..count {
42 reader.read_var_u32()?;
43 reader.read::<ValType>()?;
44 }
45 Ok(())
46 }
47
48 pub fn get_locals_reader(&self) -> Result<LocalsReader<'a>> {
50 let mut reader = self.reader.clone();
51 let declaration_count = reader.read_var_u32()?;
52 Ok(LocalsReader {
53 reader,
54 declaration_count,
55 total_count: 0,
56 })
57 }
58
59 pub fn get_operators_reader(&self) -> Result<OperatorsReader<'a>> {
61 let mut reader = self.reader.clone();
62 Self::skip_locals(&mut reader)?;
63 Ok(OperatorsReader::new(reader))
64 }
65
66 pub fn range(&self) -> Range<usize> {
68 self.reader.range()
69 }
70
71 pub fn as_bytes(&self) -> &'a [u8] {
75 self.reader.remaining_buffer()
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()?;
82 Ok(FunctionBody::new(reader))
83 }
84}
85
86pub struct LocalsReader<'a> {
88 reader: BinaryReader<'a>,
89 declaration_count: u32,
90 total_count: u32,
91}
92
93impl<'a> LocalsReader<'a> {
94 pub fn get_count(&self) -> u32 {
96 self.declaration_count
97 }
98
99 pub fn original_position(&self) -> usize {
101 self.reader.original_position()
102 }
103
104 pub fn read(&mut self) -> Result<(u32, ValType)> {
106 let count = self.reader.read()?;
107 match self.total_count.checked_add(count) {
108 Some(total) => self.total_count = total,
109 None => bail!(self.reader.original_position(), "too many locals"),
110 }
111 let value_type = self.reader.read()?;
112 Ok((count, value_type))
113 }
114
115 pub fn get_binary_reader(self) -> BinaryReader<'a> {
117 self.reader
118 }
119}
120
121impl<'a> IntoIterator for LocalsReader<'a> {
122 type Item = Result<(u32, ValType)>;
123 type IntoIter = LocalsIterator<'a>;
124 fn into_iter(self) -> Self::IntoIter {
125 let count = self.declaration_count;
126 LocalsIterator {
127 reader: self,
128 left: count,
129 err: false,
130 }
131 }
132}
133
134pub struct LocalsIterator<'a> {
136 reader: LocalsReader<'a>,
137 left: u32,
138 err: bool,
139}
140
141impl<'a> Iterator for LocalsIterator<'a> {
142 type Item = Result<(u32, ValType)>;
143 fn next(&mut self) -> Option<Self::Item> {
144 if self.err || self.left == 0 {
145 return None;
146 }
147 let result = self.reader.read();
148 self.err = result.is_err();
149 self.left -= 1;
150 Some(result)
151 }
152 fn size_hint(&self) -> (usize, Option<usize>) {
153 let count = self.reader.get_count() as usize;
154 (count, Some(count))
155 }
156}
157
158impl<'a> LocalsIterator<'a> {
159 pub fn into_operators_reader(self) -> OperatorsReader<'a> {
161 debug_assert!(self.err || self.left == 0);
162 OperatorsReader::new(self.reader.get_binary_reader())
163 }
164}