use crate::{Function, Result};
use wasmparser::{Operator, VisitOperator};
pub struct ValidateThenVisit<'a, T>(pub T, pub &'a mut Function);
macro_rules! validate_then_visit {
($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => {
$(
fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output {
self.0.$visit($($($arg.clone()),*)?)?;
let visit_when_unreachable = visit_op_when_unreachable(Operator::$op $({ $($arg: $arg.clone()),* })?);
if true || visit_when_unreachable {
Ok(self.1.$visit($($($arg),*)?))
} else {
Ok(Ok(()))
}
}
)*
};
}
fn visit_op_when_unreachable(op: Operator) -> bool {
use Operator::*;
matches!(op, If { .. } | Block { .. } | Loop { .. } | Else | End)
}
impl<'a, T> VisitOperator<'a> for ValidateThenVisit<'_, T>
where
T: VisitOperator<'a, Output = wasmparser::Result<()>>,
{
type Output = Result<Result<()>>;
wasmparser::for_each_operator!(validate_then_visit);
}