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