Struct OperatorsReader
pub struct OperatorsReader<'a> { /* private fields */ }
Expand description
A reader for a core WebAssembly function’s operators. The OperatorsReader
internally
maintains a stack of the kinds of frames within an expression or function body.
This is necessary to enforce the syntactic requirements of the binary format.
The BinaryReader can also be used to read the operators by providing an external FrameStack
instance.
Implementations§
§impl<'a> OperatorsReader<'a>
impl<'a> OperatorsReader<'a>
pub fn new(reader: BinaryReader<'a>) -> OperatorsReader<'a>
pub fn new(reader: BinaryReader<'a>) -> OperatorsReader<'a>
Creates a new reader for an expression (instruction sequence).
This method, in conjunction with OperatorsReader::into_allocations
,
provides a means to reuse allocations across reading each
individual expression or function body. Note that it is also sufficient
to call this method with Default::default()
if no prior allocations are
available.
pub fn new_with_allocs(
reader: BinaryReader<'a>,
allocs: OperatorsReaderAllocations,
) -> OperatorsReader<'a>
pub fn new_with_allocs( reader: BinaryReader<'a>, allocs: OperatorsReaderAllocations, ) -> OperatorsReader<'a>
Same as OperatorsReader::new
except that the
OperatorsReaderAllocations
can be specified here to amortize the
cost of them over multiple readers.
pub fn get_binary_reader(&self) -> BinaryReader<'a>
pub fn get_binary_reader(&self) -> BinaryReader<'a>
Get binary reader
pub fn original_position(&self) -> usize
pub fn original_position(&self) -> usize
Gets the original position of the reader.
pub fn is_end_then_eof(&self) -> bool
pub fn is_end_then_eof(&self) -> bool
Returns whether there is an end
opcode followed by eof remaining in
this reader.
pub fn into_allocations(self) -> OperatorsReaderAllocations
pub fn into_allocations(self) -> OperatorsReaderAllocations
Consumes this reader and returns the underlying allocations that were used to store the frame stack.
The returned value here can be paired with
OperatorsReader::new
to reuse the allocations already
created by this reader.
pub fn read(&mut self) -> Result<Operator<'a>, BinaryReaderError>
pub fn read(&mut self) -> Result<Operator<'a>, BinaryReaderError>
Reads the next available Operator
.
§Errors
If OperatorsReader
has less bytes remaining than required to parse
the Operator
, or if the input is malformed.
pub fn visit_operator<T>(
&mut self,
visitor: &mut T,
) -> Result<<T as VisitOperator<'a>>::Output, BinaryReaderError>where
T: VisitOperator<'a>,
pub fn visit_operator<T>(
&mut self,
visitor: &mut T,
) -> Result<<T as VisitOperator<'a>>::Output, BinaryReaderError>where
T: VisitOperator<'a>,
Visit the next available operator with the specified VisitOperator
instance.
Note that this does not implicitly propagate any additional information such as instruction offsets. In order to do so, consider storing such data within the visitor before visiting.
§Errors
If OperatorsReader
has less bytes remaining than required to parse the Operator
,
or if the input is malformed.
§Examples
Store an offset for use in diagnostics or any other purposes:
pub fn dump(mut reader: OperatorsReader) -> Result<()> {
let mut visitor = Dumper { offset: 0 };
while !reader.eof() {
visitor.offset = reader.original_position();
reader.visit_operator(&mut visitor)?;
}
Ok(())
}
struct Dumper {
offset: usize
}
macro_rules! define_visit_operator {
($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
$(
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
println!("{}: {}", self.offset, stringify!($visit));
}
)*
}
}
impl<'a> VisitOperator<'a> for Dumper {
type Output = ();
for_each_visit_operator!(define_visit_operator);
}
pub fn read_with_offset(
&mut self,
) -> Result<(Operator<'a>, usize), BinaryReaderError>
pub fn read_with_offset( &mut self, ) -> Result<(Operator<'a>, usize), BinaryReaderError>
Reads an operator with its offset.
pub fn into_iter_with_offsets(self) -> OperatorsIteratorWithOffsets<'a> ⓘ
pub fn into_iter_with_offsets(self) -> OperatorsIteratorWithOffsets<'a> ⓘ
Converts to an iterator of operators paired with offsets.
pub fn finish(&self) -> Result<(), BinaryReaderError>
pub fn finish(&self) -> Result<(), BinaryReaderError>
Function that must be called after the last opcode has been processed.
This function returns an error if there is extra data after the operators. It does not check the binary format requirement that if the data count section is absent, a data index may not occur in the code section.
Trait Implementations§
§impl<'a> Clone for OperatorsReader<'a>
impl<'a> Clone for OperatorsReader<'a>
§fn clone(&self) -> OperatorsReader<'a>
fn clone(&self) -> OperatorsReader<'a>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more§impl<'a> FrameStack for OperatorsReader<'a>
impl<'a> FrameStack for OperatorsReader<'a>
§fn current_frame(&self) -> Option<FrameKind>
fn current_frame(&self) -> Option<FrameKind>
§impl<'a> IntoIterator for OperatorsReader<'a>
impl<'a> IntoIterator for OperatorsReader<'a>
§fn into_iter(self) -> <OperatorsReader<'a> as IntoIterator>::IntoIter
fn into_iter(self) -> <OperatorsReader<'a> as IntoIterator>::IntoIter
Reads content of the code section.
§Examples
let reader = BinaryReader::new(data, 0);
let code_reader = CodeSectionReader::new(reader).unwrap();
for body in code_reader {
let body = body.expect("function body");
let mut op_reader = body.get_operators_reader().expect("op reader");
let ops = op_reader.into_iter().collect::<Result<Vec<Operator>>>().expect("ops");
assert!(
if let [Operator::Nop, Operator::End] = ops.as_slice() { true } else { false },
"found {:?}",
ops
);
}
§type Item = Result<Operator<'a>, BinaryReaderError>
type Item = Result<Operator<'a>, BinaryReaderError>
§type IntoIter = OperatorsIterator<'a>
type IntoIter = OperatorsIterator<'a>
Auto Trait Implementations§
impl<'a> Freeze for OperatorsReader<'a>
impl<'a> RefUnwindSafe for OperatorsReader<'a>
impl<'a> Send for OperatorsReader<'a>
impl<'a> Sync for OperatorsReader<'a>
impl<'a> Unpin for OperatorsReader<'a>
impl<'a> UnwindSafe for OperatorsReader<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more