wasmi 2.0.0-beta.3

WebAssembly interpreter
Documentation
#[cfg(target_arch = "x86_64")]
macro_rules! execution_handler {
    (
        fn $name:ident(
            $state:ident   : $state_ty:ty,
            $ip:ident      : $ip_ty:ty,
            $sp:ident      : $sp_ty:ty,
            $mem0_ptr:ident: $mem0_ptr_ty:ty,
            $mem0_len:ident: $mem0_len_ty:ty,
            $instance:ident: $instance_ty:ty,
            $ireg:ident    : $ireg_ty:ty,
            $freg32:ident  : $freg32_ty:ty,
            $freg64:ident  : $freg64_ty:ty,
        ) -> $done:ty = $body:tt
    ) => {
        #[cfg_attr(feature = "portable-dispatch", inline(always))]
        #[cfg_attr(not(feature = "portable-dispatch"), inline(never))]
        #[allow(improper_ctypes_definitions)] // not used in FFI
        #[allow(clippy::too_many_arguments)] // extern fns are ignored
        pub extern "sysv64" fn $name(
            $state: $state_ty,
            $ip: $ip_ty,
            $sp: $sp_ty,
            $mem0_ptr: $mem0_ptr_ty,
            $mem0_len: $mem0_len_ty,
            $instance: $instance_ty,
            $ireg: $ireg_ty,
            $freg32: $freg32_ty,
            $freg64: $freg64_ty,
        ) -> $done $body
    };
}

#[cfg(not(target_arch = "x86_64"))]
macro_rules! execution_handler {
    (
        fn $name:ident(
            $state:ident   : $state_ty:ty,
            $ip:ident      : $ip_ty:ty,
            $sp:ident      : $sp_ty:ty,
            $mem0_ptr:ident: $mem0_ptr_ty:ty,
            $mem0_len:ident: $mem0_len_ty:ty,
            $instance:ident: $instance_ty:ty,
            $ireg:ident    : $ireg_ty:ty,
            $freg32:ident  : $freg32_ty:ty,
            $freg64:ident  : $freg64_ty:ty,
        ) -> $done:ty = $body:tt
    ) => {
        #[cfg_attr(feature = "portable-dispatch", inline(always))]
        #[cfg_attr(not(feature = "portable-dispatch"), inline(never))]
        #[allow(improper_ctypes_definitions)] // not used in FFI
        #[expect(clippy::too_many_arguments)]
        pub fn $name(
            $state: $state_ty,
            $ip: $ip_ty,
            $sp: $sp_ty,
            $mem0_ptr: $mem0_ptr_ty,
            $mem0_len: $mem0_len_ty,
            $instance: $instance_ty,
            $ireg: $ireg_ty,
            $freg32: $freg32_ty,
            $freg64: $freg64_ty,
        ) -> $done $body
    };
}

macro_rules! handler_unary {
    ( $( fn $handler:ident($op:ident) = $eval:expr );* $(;)? ) => {
        $(
            execution_handler! {
                fn $handler(
                    state: &mut VmState,
                    ip: Ip,
                    sp: Sp,
                    mem0: Mem0Ptr,
                    mem0_len: Mem0Len,
                    instance: Inst,
                    ireg: Ireg,
                    freg32: Freg32,
                    freg64: Freg64,
                ) -> Done = {
                    let (ip, $crate::ir::decode::$op { result, value }) = unsafe { decode_op(ip) };
                    let value = get_value(value, sp, ireg, freg32, freg64);
                    let value = $eval(value).into_control()?;
                    set_value!(result, value, sp, ireg, freg32, freg64);
                    dispatch!(state, ip, sp, mem0, mem0_len, instance, ireg, freg32, freg64)
                }
            }
        )*
    };
}

macro_rules! handler_binary {
    ( $( fn $handler:ident($decode:ident) = $eval:expr );* $(;)? ) => {
        $(
            execution_handler! {
                fn $handler(
                    state: &mut VmState,
                    ip: Ip,
                    sp: Sp,
                    mem0: Mem0Ptr,
                    mem0_len: Mem0Len,
                    instance: Inst,
                    ireg: Ireg,
                    freg32: Freg32,
                    freg64: Freg64,
                ) -> Done = {
                    let (ip, $crate::ir::decode::$decode { result, lhs, rhs }) = unsafe { decode_op(ip) };
                    let lhs = get_value(lhs, sp, ireg, freg32, freg64);
                    let rhs = get_value(rhs, sp, ireg, freg32, freg64);
                    let value = $eval(lhs, rhs).into_control()?;
                    set_value!(result, value, sp, ireg, freg32, freg64);
                    dispatch!(state, ip, sp, mem0, mem0_len, instance, ireg, freg32, freg64)
                }
            }
        )*
    };
}

macro_rules! handler_load {
    ( $( fn $handler:ident($decode:ident) = $load:expr );* $(;)? ) => {
        $(
            execution_handler! {
                fn $handler(
                    state: &mut VmState,
                    ip: Ip,
                    sp: Sp,
                    mem0: Mem0Ptr,
                    mem0_len: Mem0Len,
                    instance: Inst,
                    ireg: Ireg,
                    freg32: Freg32,
                    freg64: Freg64,
                ) -> Done = {
                    let (
                        ip,
                        crate::ir::decode::$decode {
                            result,
                            ptr,
                            offset,
                            memory,
                        },
                    ) = unsafe { decode_op(ip) };
                    let ptr: u64 = get_value(ptr, sp, ireg, freg32, freg64);
                    let offset: u64 = get_value(offset, sp, ireg, freg32, freg64);
                    let mem_bytes = $crate::engine::executor::handler::utils::memory_bytes(memory, mem0, mem0_len, instance, state);
                    let loaded = $load(mem_bytes, ptr, offset).into_control()?;
                    set_value!(result, loaded, sp, ireg, freg32, freg64);
                    dispatch!(state, ip, sp, mem0, mem0_len, instance, ireg, freg32, freg64)
                }
            }
        )*
    };
}

macro_rules! handler_load_mem0_offset16_ss {
    ( $( fn $handler:ident($decode:ident) = $load:expr );* $(;)? ) => {
        $(
            execution_handler! {
                fn $handler(
                    state: &mut VmState,
                    ip: Ip,
                    sp: Sp,
                    mem0: Mem0Ptr,
                    mem0_len: Mem0Len,
                    instance: Inst,
                    ireg: Ireg,
                    freg32: Freg32,
                    freg64: Freg64,
                ) -> Done = {
                    let (
                        ip,
                        crate::ir::decode::$decode {
                            result,
                            ptr,
                            offset,
                        },
                    ) = unsafe { decode_op(ip) };
                    let ptr = get_value(ptr, sp, ireg, freg32, freg64);
                    let offset = get_value(offset, sp, ireg, freg32, freg64);
                    let mem_bytes = $crate::engine::executor::handler::state::mem0_bytes(mem0, mem0_len);
                    let loaded = $load(mem_bytes, ptr, u64::from(u16::from(offset))).into_control()?;
                    set_value!(result, loaded, sp, ireg, freg32, freg64);
                    dispatch!(state, ip, sp, mem0, mem0_len, instance, ireg, freg32, freg64)
                }
            }
        )*
    };
}

macro_rules! handler_store_sx {
    ( $( fn $handler:ident($decode:ident, $hint:ty) = $store:expr );* $(;)? ) => {
        $(
            execution_handler! {
                fn $handler(
                    state: &mut VmState,
                    ip: Ip,
                    sp: Sp,
                    mem0: Mem0Ptr,
                    mem0_len: Mem0Len,
                    instance: Inst,
                    ireg: Ireg,
                    freg32: Freg32,
                    freg64: Freg64,
                ) -> Done = {
                    let (
                        ip,
                        crate::ir::decode::$decode {
                            ptr,
                            offset,
                            value,
                            memory,
                        },
                    ) = unsafe { decode_op(ip) };
                    let ptr = get_value(ptr, sp, ireg, freg32, freg64);
                    let offset = get_value(offset, sp, ireg, freg32, freg64);
                    let value: $hint = get_value(value, sp, ireg, freg32, freg64);
                    let mem_bytes = $crate::engine::executor::handler::utils::memory_bytes(memory, mem0, mem0_len, instance, state);
                    $store(mem_bytes, ptr, offset, value.into()).into_control()?;
                    dispatch!(state, ip, sp, mem0, mem0_len, instance, ireg, freg32, freg64)
                }
            }
        )*
    };
}

macro_rules! handler_store_mem0_offset16_sx {
    ( $( fn $handler:ident($decode:ident, $hint:ty) = $store:expr );* $(;)? ) => {
        $(
            execution_handler! {
                fn $handler(
                    state: &mut VmState,
                    ip: Ip,
                    sp: Sp,
                    mem0: Mem0Ptr,
                    mem0_len: Mem0Len,
                    instance: Inst,
                    ireg: Ireg,
                    freg32: Freg32,
                    freg64: Freg64,
                ) -> Done = {
                    let (
                        ip,
                        crate::ir::decode::$decode {
                            ptr,
                            offset,
                            value,
                        },
                    ) = unsafe { decode_op(ip) };
                    let ptr = get_value(ptr, sp, ireg, freg32, freg64);
                    let offset = get_value(offset, sp, ireg, freg32, freg64);
                    let value: $hint = get_value(value, sp, ireg, freg32, freg64);
                    let mem_bytes = $crate::engine::executor::handler::state::mem0_bytes(mem0, mem0_len);
                    $store(mem_bytes, ptr, u64::from(u16::from(offset)), value.into()).into_control()?;
                    dispatch!(state, ip, sp, mem0, mem0_len, instance, ireg, freg32, freg64)
                }
            }
        )*
    };
}