rwasm 0.4.3

ZK-friendly WebAssembly runtime optimized for blockchain and zero-knowledge applications
Documentation
use crate::{types::UntypedValue, vm::executor::RwasmExecutor, TrapCode};

macro_rules! impl_visit_unary {
    ( $( fn $visit_ident:ident($untyped_ident:ident); )* ) => {
        $(
            #[inline(always)]
            pub(crate) fn $visit_ident(&mut self) {
                self.sp.eval_top(UntypedValue::$untyped_ident);
                self.ip.add(1);
            }
        )*
    }
}

impl<'a, T> RwasmExecutor<'a, T> {
    impl_visit_unary! {
        fn visit_i32_eqz(i32_eqz);

        fn visit_i32_clz(i32_clz);
        fn visit_i32_ctz(i32_ctz);
        fn visit_i32_popcnt(i32_popcnt);

        fn visit_i32_wrap_i64(i32_wrap_i64);

        fn visit_i32_extend8_s(i32_extend8_s);
        fn visit_i32_extend16_s(i32_extend16_s);
    }
}

macro_rules! impl_visit_binary {
    ( $( fn $visit_ident:ident($untyped_ident:ident); )* ) => {
        $(
            #[inline(always)]
            pub(crate) fn $visit_ident(&mut self) {
                self.sp.eval_top2(UntypedValue::$untyped_ident);
                self.ip.add(1);
            }
        )*
    }
}

impl<'a, T> RwasmExecutor<'a, T> {
    impl_visit_binary! {
        fn visit_i32_eq(i32_eq);
        fn visit_i32_ne(i32_ne);
        fn visit_i32_lt_s(i32_lt_s);
        fn visit_i32_lt_u(i32_lt_u);
        fn visit_i32_gt_s(i32_gt_s);
        fn visit_i32_gt_u(i32_gt_u);
        fn visit_i32_le_s(i32_le_s);
        fn visit_i32_le_u(i32_le_u);
        fn visit_i32_ge_s(i32_ge_s);
        fn visit_i32_ge_u(i32_ge_u);

        fn visit_i32_add(i32_add);
        fn visit_i32_sub(i32_sub);
        fn visit_i32_mul(i32_mul);
        fn visit_i32_and(i32_and);
        fn visit_i32_or(i32_or);
        fn visit_i32_xor(i32_xor);
        fn visit_i32_shl(i32_shl);
        fn visit_i32_shr_s(i32_shr_s);
        fn visit_i32_shr_u(i32_shr_u);
        fn visit_i32_rotl(i32_rotl);
        fn visit_i32_rotr(i32_rotr);
    }

    pub(crate) fn visit_i32_mul64(&mut self) {
        let (lhs, rhs) = self.sp.pop2();
        let res = lhs.as_i64().wrapping_mul(rhs.as_i64());
        self.sp.push_i64(res);
        self.ip.add(1);
    }

    pub(crate) fn visit_i32_add64(&mut self) {
        let (lhs, rhs) = self.sp.pop2();
        let res = lhs.as_i64().wrapping_add(rhs.as_i64());
        self.sp.push_i64(res);
        self.ip.add(1);
    }
}

macro_rules! impl_visit_fallible_binary {
    ( $( fn $visit_ident:ident($untyped_ident:ident); )* ) => {
        $(
            #[inline(always)]
            pub(crate) fn $visit_ident(&mut self) -> Result<(), TrapCode> {
                self.sp.try_eval_top2(UntypedValue::$untyped_ident)?;
                self.ip.add(1);
                Ok(())
            }
        )*
    }
}

impl<'a, T> RwasmExecutor<'a, T> {
    impl_visit_fallible_binary! {
        fn visit_i32_div_s(i32_div_s);
        fn visit_i32_div_u(i32_div_u);
        fn visit_i32_rem_s(i32_rem_s);
        fn visit_i32_rem_u(i32_rem_u);
    }
}