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§
Source§impl<'a> OperatorsReader<'a>
impl<'a> OperatorsReader<'a>
Sourcepub fn new(reader: BinaryReader<'a>) -> Self
pub fn new(reader: BinaryReader<'a>) -> Self
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.
Sourcepub fn new_with_allocs(
reader: BinaryReader<'a>,
allocs: OperatorsReaderAllocations,
) -> Self
pub fn new_with_allocs( reader: BinaryReader<'a>, allocs: OperatorsReaderAllocations, ) -> Self
Same as OperatorsReader::new
except that the
OperatorsReaderAllocations
can be specified here to amortize the
cost of them over multiple readers.
Sourcepub fn get_binary_reader(&self) -> BinaryReader<'a>
pub fn get_binary_reader(&self) -> BinaryReader<'a>
Get binary reader
Sourcepub fn original_position(&self) -> usize
pub fn original_position(&self) -> usize
Gets the original position of the reader.
Sourcepub 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.
Sourcepub 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.
Sourcepub fn read(&mut self) -> Result<Operator<'a>>
pub fn read(&mut self) -> Result<Operator<'a>>
Reads the next available Operator
.
§Errors
If OperatorsReader
has less bytes remaining than required to parse
the Operator
, or if the input is malformed.
Sourcepub fn visit_operator<T>(
&mut self,
visitor: &mut T,
) -> Result<<T as VisitOperator<'a>>::Output>where
T: VisitOperator<'a>,
pub fn visit_operator<T>(
&mut self,
visitor: &mut T,
) -> Result<<T as VisitOperator<'a>>::Output>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);
}
Sourcepub fn read_with_offset(&mut self) -> Result<(Operator<'a>, usize)>
pub fn read_with_offset(&mut self) -> Result<(Operator<'a>, usize)>
Reads an operator with its offset.
Sourcepub 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.
Sourcepub fn finish(&self) -> Result<()>
pub fn finish(&self) -> Result<()>
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§
Source§impl<'a> Clone for OperatorsReader<'a>
impl<'a> Clone for OperatorsReader<'a>
Source§fn clone(&self) -> OperatorsReader<'a>
fn clone(&self) -> OperatorsReader<'a>
1.0.0 · Source§const fn clone_from(&mut self, source: &Self)
const fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<'a> FrameStack for OperatorsReader<'a>
impl<'a> FrameStack for OperatorsReader<'a>
Source§fn current_frame(&self) -> Option<FrameKind>
fn current_frame(&self) -> Option<FrameKind>
Source§impl<'a> IntoIterator for OperatorsReader<'a>
impl<'a> IntoIterator for OperatorsReader<'a>
Source§fn into_iter(self) -> Self::IntoIter
fn into_iter(self) -> Self::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
);
}