/// A trait implemented for items that can be decoded directly from a /// `BinaryReader`, or that which can be parsed from the WebAssembly binary /// format. /// /// Note that this is also accessible as a [`BinaryReader::read`] method. pubtrait FromReader<'a>: Sized { /// Attempts to read `Self` from the provided binary reader, returning an /// error if it is unable to do so. fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self>;
}
/// A generic structure for reading a section of a WebAssembly binary which has /// a limited number of items within it. /// /// Many WebAssembly sections are a count of items followed by that many items. /// This helper structure can be used to parse these sections and provides /// an iteration-based API for reading the contents. /// /// Note that this always implements the [`Clone`] trait to represent the /// ability to parse the section multiple times. pubstruct SectionLimited<'a, T> {
reader: BinaryReader<'a>,
count: u32,
_marker: marker::PhantomData<T>,
}
impl<'a, T> SectionLimited<'a, T> { /// Creates a new section reader from the provided contents. /// /// The `data` provided here is the data of the section itself that will be /// parsed. The `offset` argument is the byte offset, in the original wasm /// binary, that the section was found. The `offset` argument is used /// for error reporting. /// /// # Errors /// /// Returns an error if a 32-bit count couldn't be read from the `data`. pubfn new(mut reader: BinaryReader<'a>) -> Result<Self> { let count = reader.read_var_u32()?;
Ok(SectionLimited {
reader,
count,
_marker: marker::PhantomData,
})
}
/// Returns the count of total items within this section. pubfn count(&self) -> u32 { self.count
}
/// Returns whether the original byte offset of this section. pubfn original_position(&self) -> usize { self.reader.original_position()
}
/// Returns the range, as byte offsets, of this section within the original /// wasm binary. pubfn range(&self) -> Range<usize> { self.reader.range()
}
/// Returns an iterator which yields not only each item in this section but /// additionally the offset of each item within the section. pubfn into_iter_with_offsets(self) -> SectionLimitedIntoIterWithOffsets<'a, T> where
T: FromReader<'a>,
{
SectionLimitedIntoIterWithOffsets {
iter: self.into_iter(),
}
}
}
/// A consuming iterator of a [`SectionLimited`]. /// /// This is created via the [`IntoIterator`] `impl` for the [`SectionLimited`] /// type. pubstruct SectionLimitedIntoIter<'a, T> {
section: SectionLimited<'a, T>,
remaining: u32,
end: bool,
}
impl<T> SectionLimitedIntoIter<'_, T> { /// Returns the current byte offset of the section within this iterator. pubfn original_position(&self) -> usize { self.section.reader.original_position()
}
}
impl<'a, T> Iterator for SectionLimitedIntoIter<'a, T> where
T: FromReader<'a>,
{ type Item = Result<T>;
fn next(&mutself) -> Option<Result<T>> { ifself.end { return None;
} ifself.remaining == 0 { self.end = true; ifself.section.reader.eof() { return None;
} return Some(Err(BinaryReaderError::new( "section size mismatch: unexpected data at the end of the section", self.section.reader.original_position(),
)));
} let result = self.section.reader.read(); self.end = result.is_err(); self.remaining -= 1;
Some(result)
}
fn size_hint(&self) -> (usize, Option<usize>) { let remaining = self.remaining as usize;
(remaining, Some(remaining))
}
}
impl<'a, T> ExactSizeIterator for SectionLimitedIntoIter<'a, T> where T: FromReader<'a> {}
/// An iterator over a limited section iterator. pubstruct SectionLimitedIntoIterWithOffsets<'a, T> {
iter: SectionLimitedIntoIter<'a, T>,
}
impl<'a, T> Iterator for SectionLimitedIntoIterWithOffsets<'a, T> where
T: FromReader<'a>,
{ type Item = Result<(usize, T)>;
impl<'a, T> ExactSizeIterator for SectionLimitedIntoIterWithOffsets<'a, T> where T: FromReader<'a> {}
/// A trait implemented for subsections of another outer section. /// /// This is currently only used for subsections within custom sections, such as /// the `name` section of core wasm. /// /// This is used in conjunction with [`Subsections`]. pubtrait Subsection<'a>: Sized { /// Converts the section identifier provided with the section contents into /// a typed section fn from_reader(id: u8, reader: BinaryReader<'a>) -> Result<Self>;
}
/// Iterator/reader over the contents of a section which is composed of /// subsections. /// /// This reader is used for the core `name` section, for example. This type /// primarily implements [`Iterator`] for advancing through the sections. pubstruct Subsections<'a, T> {
reader: BinaryReader<'a>,
_marker: marker::PhantomData<T>,
}
impl<'a, T> Subsections<'a, T> { /// Creates a new reader for the specified section contents starting at /// `offset` within the original wasm file. pubfn new(reader: BinaryReader<'a>) -> Self {
Subsections {
reader,
_marker: marker::PhantomData,
}
}
/// Returns whether the original byte offset of this section. pubfn original_position(&self) -> usize { self.reader.original_position()
}
/// Returns the range, as byte offsets, of this section within the original /// wasm binary. pubfn range(&self) -> Range<usize> { self.reader.range()
}
fn read(&mutself) -> Result<T> where
T: Subsection<'a>,
{ let subsection_id = self.reader.read_u7()?; let reader = self.reader.read_reader()?;
T::from_reader(subsection_id, reader)
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.