1 use crate::{
2     BinaryReader, BinaryReaderError, ExternalKind, Range, Result, SectionIteratorLimited,
3     SectionReader, SectionWithLimitedItems,
4 };
5 
6 #[derive(Clone)]
7 pub struct InstanceSectionReader<'a> {
8     reader: BinaryReader<'a>,
9     count: u32,
10 }
11 
12 impl<'a> InstanceSectionReader<'a> {
new(data: &'a [u8], offset: usize) -> Result<InstanceSectionReader<'a>>13     pub fn new(data: &'a [u8], offset: usize) -> Result<InstanceSectionReader<'a>> {
14         let mut reader = BinaryReader::new_with_offset(data, offset);
15         let count = reader.read_var_u32()?;
16         Ok(InstanceSectionReader { reader, count })
17     }
18 
original_position(&self) -> usize19     pub fn original_position(&self) -> usize {
20         self.reader.original_position()
21     }
22 
get_count(&self) -> u3223     pub fn get_count(&self) -> u32 {
24         self.count
25     }
26 
read(&mut self) -> Result<Instance<'a>>27     pub fn read(&mut self) -> Result<Instance<'a>> {
28         let instance = Instance::new(
29             &self.reader.buffer[self.reader.position..],
30             self.original_position(),
31         )?;
32 
33         // FIXME(#188): should probably figure out a different API for
34         // wasmparser such that we don't have to read instances to skip them
35         // here.
36         let mut args = instance.args()?;
37         for _ in 0..args.get_count() {
38             args.read()?;
39         }
40         self.reader = args.reader;
41         Ok(instance)
42     }
43 }
44 
45 impl<'a> SectionReader for InstanceSectionReader<'a> {
46     type Item = Instance<'a>;
47 
read(&mut self) -> Result<Self::Item>48     fn read(&mut self) -> Result<Self::Item> {
49         InstanceSectionReader::read(self)
50     }
eof(&self) -> bool51     fn eof(&self) -> bool {
52         self.reader.eof()
53     }
original_position(&self) -> usize54     fn original_position(&self) -> usize {
55         InstanceSectionReader::original_position(self)
56     }
range(&self) -> Range57     fn range(&self) -> Range {
58         self.reader.range()
59     }
60 }
61 
62 impl<'a> SectionWithLimitedItems for InstanceSectionReader<'a> {
get_count(&self) -> u3263     fn get_count(&self) -> u32 {
64         InstanceSectionReader::get_count(self)
65     }
66 }
67 
68 impl<'a> IntoIterator for InstanceSectionReader<'a> {
69     type Item = Result<Instance<'a>>;
70     type IntoIter = SectionIteratorLimited<InstanceSectionReader<'a>>;
71 
into_iter(self) -> Self::IntoIter72     fn into_iter(self) -> Self::IntoIter {
73         SectionIteratorLimited::new(self)
74     }
75 }
76 
77 #[derive(Clone)]
78 pub struct Instance<'a> {
79     reader: BinaryReader<'a>,
80     module: u32,
81 }
82 
83 impl<'a> Instance<'a> {
new(data: &'a [u8], offset: usize) -> Result<Instance<'a>>84     pub fn new(data: &'a [u8], offset: usize) -> Result<Instance<'a>> {
85         let mut reader = BinaryReader::new_with_offset(data, offset);
86         if reader.read_u8()? != 0 {
87             return Err(BinaryReaderError::new(
88                 "instantiate instruction not found",
89                 offset,
90             ));
91         }
92         let module = reader.read_var_u32()?;
93         Ok(Instance { module, reader })
94     }
95 
original_position(&self) -> usize96     pub fn original_position(&self) -> usize {
97         self.reader.original_position()
98     }
99 
module(&self) -> u32100     pub fn module(&self) -> u32 {
101         self.module
102     }
103 
args(&self) -> Result<InstanceArgsReader<'a>>104     pub fn args(&self) -> Result<InstanceArgsReader<'a>> {
105         let mut reader = self.reader.clone();
106         let count = reader.read_var_u32()?;
107         Ok(InstanceArgsReader {
108             count,
109             remaining: count,
110             reader,
111         })
112     }
113 }
114 
115 #[derive(Clone)]
116 pub struct InstanceArgsReader<'a> {
117     reader: BinaryReader<'a>,
118     count: u32,
119     remaining: u32,
120 }
121 
122 #[derive(Clone, Copy, Debug)]
123 pub struct InstanceArg<'a> {
124     pub name: &'a str,
125     pub kind: ExternalKind,
126     pub index: u32,
127 }
128 
129 impl<'a> InstanceArgsReader<'a> {
original_position(&self) -> usize130     pub fn original_position(&self) -> usize {
131         self.reader.original_position()
132     }
133 
read(&mut self) -> Result<InstanceArg<'a>>134     pub fn read(&mut self) -> Result<InstanceArg<'a>> {
135         self.remaining -= 1;
136         Ok(InstanceArg {
137             name: self.reader.read_string()?,
138             kind: self.reader.read_external_kind()?,
139             index: self.reader.read_var_u32()?,
140         })
141     }
142 }
143 
144 impl<'a> SectionReader for InstanceArgsReader<'a> {
145     type Item = InstanceArg<'a>;
146 
read(&mut self) -> Result<Self::Item>147     fn read(&mut self) -> Result<Self::Item> {
148         InstanceArgsReader::read(self)
149     }
eof(&self) -> bool150     fn eof(&self) -> bool {
151         self.remaining == 0
152     }
original_position(&self) -> usize153     fn original_position(&self) -> usize {
154         InstanceArgsReader::original_position(self)
155     }
range(&self) -> Range156     fn range(&self) -> Range {
157         self.reader.range()
158     }
159 }
160 
161 impl<'a> SectionWithLimitedItems for InstanceArgsReader<'a> {
get_count(&self) -> u32162     fn get_count(&self) -> u32 {
163         self.count
164     }
165 }
166 
167 impl<'a> IntoIterator for InstanceArgsReader<'a> {
168     type Item = Result<InstanceArg<'a>>;
169     type IntoIter = SectionIteratorLimited<InstanceArgsReader<'a>>;
170 
into_iter(self) -> Self::IntoIter171     fn into_iter(self) -> Self::IntoIter {
172         SectionIteratorLimited::new(self)
173     }
174 }
175