Struct OperatorsReader

Source
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>

Source

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.

Source

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.

Source

pub fn get_binary_reader(&self) -> BinaryReader<'a>

Get binary reader

Source

pub fn eof(&self) -> bool

Determines if the reader is at the end of the operators.

Source

pub fn original_position(&self) -> usize

Gets the original position of the reader.

Source

pub fn is_end_then_eof(&self) -> bool

Returns whether there is an end opcode followed by eof remaining in this reader.

Source

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.

Source

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.

Source

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);
}
Source

pub fn read_with_offset(&mut self) -> Result<(Operator<'a>, usize)>

Reads an operator with its offset.

Source

pub fn into_iter_with_offsets(self) -> OperatorsIteratorWithOffsets<'a>

Converts to an iterator of operators paired with offsets.

Source

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>

Source§

fn clone(&self) -> OperatorsReader<'a>

Returns a duplicate of the value. Read more
1.0.0 · Source§

const fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> FrameStack for OperatorsReader<'a>

Source§

fn current_frame(&self) -> Option<FrameKind>

The current frame kind.
Source§

impl<'a> IntoIterator for OperatorsReader<'a>

Source§

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
    );
}
Source§

type Item = Result<Operator<'a>, BinaryReaderError>

The type of the elements being iterated over.
Source§

type IntoIter = OperatorsIterator<'a>

Which kind of iterator are we turning this into?

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.