From 6c9ef22af731f66c33ec3e6db85674cb8b2e980e Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Fri, 9 May 2025 14:30:20 +0300 Subject: [PATCH] wasmparser: merge VisitSimdOperator back into VisitOperator The `simd` feature remains in place, but now does not affect the API in this way. Rather parts of implementation pertaining to SIMD in wasmparser get disabled, reducing the compilation time and artifact size impact slightly, though less than in the original approach. The results on my machine are roughly: * origin/main simd: 4.26s producing 30M .rlib * origin/main !simd: 3.49s producing 23M .rlib * this simd: 4.19s producing a 26M .rlib * this !simd: 3.96s producing a 25M .rlib I'm not quite sure why the rlib size decreased so significantly when the SIMD feature is enabled (I guess less inlining is occurring?) and there is indeed a .5s hit on the compilation time to this PR. Are those half a second worth a clunkier API? I'm not convinced :) --- crates/wasmparser/benches/benchmark.rs | 13 +- crates/wasmparser/src/lib.rs | 43 +- .../wasmparser/src/readers/core/operators.rs | 722 ++++++++--------- crates/wasmparser/src/validator/core.rs | 52 +- crates/wasmparser/src/validator/func.rs | 11 - crates/wasmparser/src/validator/operators.rs | 68 +- .../src/validator/operators/simd.rs | 755 +++++++++--------- crates/wasmprinter/src/operator.rs | 8 - crates/wit-component/src/gc.rs | 11 +- src/bin/wasm-tools/dump.rs | 10 +- 10 files changed, 767 insertions(+), 926 deletions(-) diff --git a/crates/wasmparser/benches/benchmark.rs b/crates/wasmparser/benches/benchmark.rs index 7e4b48c7e0..c5ea12ae52 100644 --- a/crates/wasmparser/benches/benchmark.rs +++ b/crates/wasmparser/benches/benchmark.rs @@ -4,7 +4,6 @@ use once_cell::unsync::Lazy; use std::fs; use std::path::Path; use std::path::PathBuf; -use wasmparser::VisitSimdOperator; use wasmparser::{DataKind, ElementKind, Parser, Payload, Validator, VisitOperator, WasmFeatures}; /// A benchmark input. @@ -375,15 +374,5 @@ macro_rules! define_visit_operator { #[allow(unused_variables)] impl<'a> VisitOperator<'a> for NopVisit { type Output = (); - - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - - wasmparser::for_each_visit_operator!(define_visit_operator); -} - -#[allow(unused_variables)] -impl<'a> VisitSimdOperator<'a> for NopVisit { - wasmparser::for_each_visit_simd_operator!(define_visit_operator); + wasmparser::for_each_operator!(define_visit_operator); } diff --git a/crates/wasmparser/src/lib.rs b/crates/wasmparser/src/lib.rs index f1c9071bf8..082cb44828 100644 --- a/crates/wasmparser/src/lib.rs +++ b/crates/wasmparser/src/lib.rs @@ -827,12 +827,6 @@ macro_rules! define_for_each_non_simd_operator { $m! { $($t)* } } } - - // When simd is disabled then this macro is additionally the - // `for_each_operator!` macro implementation - #[cfg(not(feature = "simd"))] - #[doc(hidden)] - pub use _for_each_visit_operator_impl as _for_each_operator_impl; }; } _for_each_operator_group!(define_for_each_non_simd_operator); @@ -840,8 +834,7 @@ _for_each_operator_group!(define_for_each_non_simd_operator); /// When the simd feature is enabled then `_for_each_operator_impl` is defined /// to be the same as the above `define_for_each_non_simd_operator` macro except /// with all proposals thrown in. -#[cfg(feature = "simd")] -macro_rules! define_for_each_operator_impl_with_simd { +macro_rules! define_for_each_operator_impl { ( $( @$proposal:ident { @@ -864,14 +857,12 @@ macro_rules! define_for_each_operator_impl_with_simd { } }; } -#[cfg(feature = "simd")] -_for_each_operator_group!(define_for_each_operator_impl_with_simd); +_for_each_operator_group!(define_for_each_operator_impl); /// Helper macro to define the `_for_each_simd_operator_impl` macro. /// /// This is basically the same as `define_for_each_non_simd_operator` above /// except that it's filtering on different proposals. -#[cfg(feature = "simd")] macro_rules! define_for_each_simd_operator { // Switch to "tt muncher" mode (@ $($t:tt)*) => {define_for_each_simd_operator!(filter [] @ $($t)*);}; @@ -924,7 +915,7 @@ macro_rules! define_for_each_simd_operator { } }; } -#[cfg(feature = "simd")] + _for_each_operator_group!(define_for_each_simd_operator); /// Used to implement routines for the [`Operator`] enum. @@ -1085,10 +1076,10 @@ pub use _for_each_operator_impl as for_each_operator; /// - `@stack_switching`: [Wasm `stack-switching` proposal] /// - `@wide_arithmetic`: [Wasm `wide-arithmetic` proposal] /// -/// Note that this macro does not iterate over the SIMD-related proposals. Those -/// are provided in [`VisitSimdOperator`] and [`for_each_visit_simd_operator`]. -/// This macro only handles non-SIMD related operators and so users wanting to -/// handle the SIMD-class of operators need to use that trait/macro as well. +/// Note that this macro does not iterate over the SIMD-related proposals. To include SIMD +/// instructions use [`for_each_visit_simd_operator`] or [`for_each_operator`] instead. This macro +/// only handles non-SIMD related operators and so users wanting to handle the SIMD-class of +/// operators need to use that trait/macro as well. /// /// [Wasm `exception-handling` proposal]: /// https://github.com/WebAssembly/exception-handling @@ -1218,7 +1209,7 @@ pub use _for_each_operator_impl as for_each_operator; #[doc(inline)] pub use _for_each_visit_operator_impl as for_each_visit_operator; -/// Used to implement the [`VisitSimdOperator`] trait. +/// Used to implement the methods for simd extension of `VisitOperator` trait. /// /// The list of specializable Wasm proposals is as follows: /// @@ -1234,22 +1225,12 @@ pub use _for_each_visit_operator_impl as for_each_visit_operator; /// [Wasm `relaxed-simd` proposal]: /// https://github.com/WebAssembly/relaxed-simd /// -/// [`VisitSimdOperator`]: crate::VisitSimdOperator -/// /// ``` /// # macro_rules! define_visit_operator { /// # ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { /// # $( fn $visit(&mut self $($(,$arg: $argty)*)?) {} )* /// # } /// # } -/// pub struct VisitAndDoNothing; -/// -/// impl<'a> wasmparser::VisitOperator<'a> for VisitAndDoNothing { -/// type Output = (); -/// -/// // implement all the visit methods .. -/// # wasmparser::for_each_visit_operator!(define_visit_operator); -/// } /// /// macro_rules! define_visit_simd_operator { /// // The outer layer of repetition represents how all operators are @@ -1267,12 +1248,16 @@ pub use _for_each_visit_operator_impl as for_each_visit_operator; /// )* /// } /// } +/// pub struct VisitAndDoNothing; +/// +/// impl<'a> wasmparser::VisitOperator<'a> for VisitAndDoNothing { +/// type Output = (); /// -/// impl<'a> wasmparser::VisitSimdOperator<'a> for VisitAndDoNothing { +/// // implement all the visit methods .. +/// wasmparser::for_each_visit_operator!(define_visit_operator); /// wasmparser::for_each_visit_simd_operator!(define_visit_simd_operator); /// } /// ``` -#[cfg(feature = "simd")] #[doc(inline)] pub use _for_each_visit_simd_operator_impl as for_each_visit_simd_operator; diff --git a/crates/wasmparser/src/readers/core/operators.rs b/crates/wasmparser/src/readers/core/operators.rs index d8e013ea65..ed10d28fa1 100644 --- a/crates/wasmparser/src/readers/core/operators.rs +++ b/crates/wasmparser/src/readers/core/operators.rs @@ -792,13 +792,7 @@ impl<'a> OperatorsReader<'a> { 0xfb => self.visit_0xfb_operator(pos, visitor)?, 0xfc => self.visit_0xfc_operator(pos, visitor)?, - 0xfd => { - #[cfg(feature = "simd")] - if let Some(mut visitor) = visitor.simd_visitor() { - return self.visit_0xfd_operator(pos, &mut visitor); - } - bail!(pos, "unexpected SIMD opcode: 0x{code:x}") - } + 0xfd => self.visit_0xfd_operator(pos, visitor)?, 0xfe => self.visit_0xfe_operator(pos, visitor)?, _ => bail!(pos, "illegal opcode: 0x{code:x}"), @@ -1052,321 +1046,328 @@ impl<'a> OperatorsReader<'a> { }) } - #[cfg(feature = "simd")] pub(super) fn visit_0xfd_operator( &mut self, pos: usize, visitor: &mut T, ) -> Result<>::Output> where - T: VisitSimdOperator<'a>, + T: VisitOperator<'a>, { let code = self.reader.read_var_u32()?; - Ok(match code { - 0x00 => visitor.visit_v128_load(self.read_memarg(4)?), - 0x01 => visitor.visit_v128_load8x8_s(self.read_memarg(3)?), - 0x02 => visitor.visit_v128_load8x8_u(self.read_memarg(3)?), - 0x03 => visitor.visit_v128_load16x4_s(self.read_memarg(3)?), - 0x04 => visitor.visit_v128_load16x4_u(self.read_memarg(3)?), - 0x05 => visitor.visit_v128_load32x2_s(self.read_memarg(3)?), - 0x06 => visitor.visit_v128_load32x2_u(self.read_memarg(3)?), - 0x07 => visitor.visit_v128_load8_splat(self.read_memarg(0)?), - 0x08 => visitor.visit_v128_load16_splat(self.read_memarg(1)?), - 0x09 => visitor.visit_v128_load32_splat(self.read_memarg(2)?), - 0x0a => visitor.visit_v128_load64_splat(self.read_memarg(3)?), - - 0x0b => visitor.visit_v128_store(self.read_memarg(4)?), - 0x0c => visitor.visit_v128_const(self.read_v128()?), - 0x0d => { - let mut lanes: [u8; 16] = [0; 16]; - for lane in &mut lanes { - *lane = self.read_lane_index()? + #[cfg(not(feature = "simd"))] + { + let _ = visitor; + bail!(pos, "unexpected SIMD opcode: 0x{code:x}"); + } + #[cfg(feature = "simd")] + { + Ok(match code { + 0x00 => visitor.visit_v128_load(self.read_memarg(4)?), + 0x01 => visitor.visit_v128_load8x8_s(self.read_memarg(3)?), + 0x02 => visitor.visit_v128_load8x8_u(self.read_memarg(3)?), + 0x03 => visitor.visit_v128_load16x4_s(self.read_memarg(3)?), + 0x04 => visitor.visit_v128_load16x4_u(self.read_memarg(3)?), + 0x05 => visitor.visit_v128_load32x2_s(self.read_memarg(3)?), + 0x06 => visitor.visit_v128_load32x2_u(self.read_memarg(3)?), + 0x07 => visitor.visit_v128_load8_splat(self.read_memarg(0)?), + 0x08 => visitor.visit_v128_load16_splat(self.read_memarg(1)?), + 0x09 => visitor.visit_v128_load32_splat(self.read_memarg(2)?), + 0x0a => visitor.visit_v128_load64_splat(self.read_memarg(3)?), + + 0x0b => visitor.visit_v128_store(self.read_memarg(4)?), + 0x0c => visitor.visit_v128_const(self.read_v128()?), + 0x0d => { + let mut lanes: [u8; 16] = [0; 16]; + for lane in &mut lanes { + *lane = self.read_lane_index()? + } + visitor.visit_i8x16_shuffle(lanes) } - visitor.visit_i8x16_shuffle(lanes) - } - - 0x0e => visitor.visit_i8x16_swizzle(), - 0x0f => visitor.visit_i8x16_splat(), - 0x10 => visitor.visit_i16x8_splat(), - 0x11 => visitor.visit_i32x4_splat(), - 0x12 => visitor.visit_i64x2_splat(), - 0x13 => visitor.visit_f32x4_splat(), - 0x14 => visitor.visit_f64x2_splat(), - - 0x15 => visitor.visit_i8x16_extract_lane_s(self.read_lane_index()?), - 0x16 => visitor.visit_i8x16_extract_lane_u(self.read_lane_index()?), - 0x17 => visitor.visit_i8x16_replace_lane(self.read_lane_index()?), - 0x18 => visitor.visit_i16x8_extract_lane_s(self.read_lane_index()?), - 0x19 => visitor.visit_i16x8_extract_lane_u(self.read_lane_index()?), - 0x1a => visitor.visit_i16x8_replace_lane(self.read_lane_index()?), - 0x1b => visitor.visit_i32x4_extract_lane(self.read_lane_index()?), - - 0x1c => visitor.visit_i32x4_replace_lane(self.read_lane_index()?), - 0x1d => visitor.visit_i64x2_extract_lane(self.read_lane_index()?), - 0x1e => visitor.visit_i64x2_replace_lane(self.read_lane_index()?), - 0x1f => visitor.visit_f32x4_extract_lane(self.read_lane_index()?), - 0x20 => visitor.visit_f32x4_replace_lane(self.read_lane_index()?), - 0x21 => visitor.visit_f64x2_extract_lane(self.read_lane_index()?), - 0x22 => visitor.visit_f64x2_replace_lane(self.read_lane_index()?), - - 0x23 => visitor.visit_i8x16_eq(), - 0x24 => visitor.visit_i8x16_ne(), - 0x25 => visitor.visit_i8x16_lt_s(), - 0x26 => visitor.visit_i8x16_lt_u(), - 0x27 => visitor.visit_i8x16_gt_s(), - 0x28 => visitor.visit_i8x16_gt_u(), - 0x29 => visitor.visit_i8x16_le_s(), - 0x2a => visitor.visit_i8x16_le_u(), - 0x2b => visitor.visit_i8x16_ge_s(), - 0x2c => visitor.visit_i8x16_ge_u(), - 0x2d => visitor.visit_i16x8_eq(), - 0x2e => visitor.visit_i16x8_ne(), - 0x2f => visitor.visit_i16x8_lt_s(), - 0x30 => visitor.visit_i16x8_lt_u(), - 0x31 => visitor.visit_i16x8_gt_s(), - 0x32 => visitor.visit_i16x8_gt_u(), - 0x33 => visitor.visit_i16x8_le_s(), - 0x34 => visitor.visit_i16x8_le_u(), - 0x35 => visitor.visit_i16x8_ge_s(), - 0x36 => visitor.visit_i16x8_ge_u(), - 0x37 => visitor.visit_i32x4_eq(), - 0x38 => visitor.visit_i32x4_ne(), - 0x39 => visitor.visit_i32x4_lt_s(), - 0x3a => visitor.visit_i32x4_lt_u(), - 0x3b => visitor.visit_i32x4_gt_s(), - 0x3c => visitor.visit_i32x4_gt_u(), - 0x3d => visitor.visit_i32x4_le_s(), - 0x3e => visitor.visit_i32x4_le_u(), - 0x3f => visitor.visit_i32x4_ge_s(), - 0x40 => visitor.visit_i32x4_ge_u(), - 0x41 => visitor.visit_f32x4_eq(), - 0x42 => visitor.visit_f32x4_ne(), - 0x43 => visitor.visit_f32x4_lt(), - 0x44 => visitor.visit_f32x4_gt(), - 0x45 => visitor.visit_f32x4_le(), - 0x46 => visitor.visit_f32x4_ge(), - 0x47 => visitor.visit_f64x2_eq(), - 0x48 => visitor.visit_f64x2_ne(), - 0x49 => visitor.visit_f64x2_lt(), - 0x4a => visitor.visit_f64x2_gt(), - 0x4b => visitor.visit_f64x2_le(), - 0x4c => visitor.visit_f64x2_ge(), - 0x4d => visitor.visit_v128_not(), - 0x4e => visitor.visit_v128_and(), - 0x4f => visitor.visit_v128_andnot(), - 0x50 => visitor.visit_v128_or(), - 0x51 => visitor.visit_v128_xor(), - 0x52 => visitor.visit_v128_bitselect(), - 0x53 => visitor.visit_v128_any_true(), - - 0x54 => { - let memarg = self.read_memarg(0)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_load8_lane(memarg, lane) - } - 0x55 => { - let memarg = self.read_memarg(1)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_load16_lane(memarg, lane) - } - 0x56 => { - let memarg = self.read_memarg(2)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_load32_lane(memarg, lane) - } - 0x57 => { - let memarg = self.read_memarg(3)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_load64_lane(memarg, lane) - } - 0x58 => { - let memarg = self.read_memarg(0)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_store8_lane(memarg, lane) - } - 0x59 => { - let memarg = self.read_memarg(1)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_store16_lane(memarg, lane) - } - 0x5a => { - let memarg = self.read_memarg(2)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_store32_lane(memarg, lane) - } - 0x5b => { - let memarg = self.read_memarg(3)?; - let lane = self.read_lane_index()?; - visitor.visit_v128_store64_lane(memarg, lane) - } - - 0x5c => visitor.visit_v128_load32_zero(self.read_memarg(2)?), - 0x5d => visitor.visit_v128_load64_zero(self.read_memarg(3)?), - 0x5e => visitor.visit_f32x4_demote_f64x2_zero(), - 0x5f => visitor.visit_f64x2_promote_low_f32x4(), - 0x60 => visitor.visit_i8x16_abs(), - 0x61 => visitor.visit_i8x16_neg(), - 0x62 => visitor.visit_i8x16_popcnt(), - 0x63 => visitor.visit_i8x16_all_true(), - 0x64 => visitor.visit_i8x16_bitmask(), - 0x65 => visitor.visit_i8x16_narrow_i16x8_s(), - 0x66 => visitor.visit_i8x16_narrow_i16x8_u(), - 0x67 => visitor.visit_f32x4_ceil(), - 0x68 => visitor.visit_f32x4_floor(), - 0x69 => visitor.visit_f32x4_trunc(), - 0x6a => visitor.visit_f32x4_nearest(), - 0x6b => visitor.visit_i8x16_shl(), - 0x6c => visitor.visit_i8x16_shr_s(), - 0x6d => visitor.visit_i8x16_shr_u(), - 0x6e => visitor.visit_i8x16_add(), - 0x6f => visitor.visit_i8x16_add_sat_s(), - 0x70 => visitor.visit_i8x16_add_sat_u(), - 0x71 => visitor.visit_i8x16_sub(), - 0x72 => visitor.visit_i8x16_sub_sat_s(), - 0x73 => visitor.visit_i8x16_sub_sat_u(), - 0x74 => visitor.visit_f64x2_ceil(), - 0x75 => visitor.visit_f64x2_floor(), - 0x76 => visitor.visit_i8x16_min_s(), - 0x77 => visitor.visit_i8x16_min_u(), - 0x78 => visitor.visit_i8x16_max_s(), - 0x79 => visitor.visit_i8x16_max_u(), - 0x7a => visitor.visit_f64x2_trunc(), - 0x7b => visitor.visit_i8x16_avgr_u(), - 0x7c => visitor.visit_i16x8_extadd_pairwise_i8x16_s(), - 0x7d => visitor.visit_i16x8_extadd_pairwise_i8x16_u(), - 0x7e => visitor.visit_i32x4_extadd_pairwise_i16x8_s(), - 0x7f => visitor.visit_i32x4_extadd_pairwise_i16x8_u(), - 0x80 => visitor.visit_i16x8_abs(), - 0x81 => visitor.visit_i16x8_neg(), - 0x82 => visitor.visit_i16x8_q15mulr_sat_s(), - 0x83 => visitor.visit_i16x8_all_true(), - 0x84 => visitor.visit_i16x8_bitmask(), - 0x85 => visitor.visit_i16x8_narrow_i32x4_s(), - 0x86 => visitor.visit_i16x8_narrow_i32x4_u(), - 0x87 => visitor.visit_i16x8_extend_low_i8x16_s(), - 0x88 => visitor.visit_i16x8_extend_high_i8x16_s(), - 0x89 => visitor.visit_i16x8_extend_low_i8x16_u(), - 0x8a => visitor.visit_i16x8_extend_high_i8x16_u(), - 0x8b => visitor.visit_i16x8_shl(), - 0x8c => visitor.visit_i16x8_shr_s(), - 0x8d => visitor.visit_i16x8_shr_u(), - 0x8e => visitor.visit_i16x8_add(), - 0x8f => visitor.visit_i16x8_add_sat_s(), - 0x90 => visitor.visit_i16x8_add_sat_u(), - 0x91 => visitor.visit_i16x8_sub(), - 0x92 => visitor.visit_i16x8_sub_sat_s(), - 0x93 => visitor.visit_i16x8_sub_sat_u(), - 0x94 => visitor.visit_f64x2_nearest(), - 0x95 => visitor.visit_i16x8_mul(), - 0x96 => visitor.visit_i16x8_min_s(), - 0x97 => visitor.visit_i16x8_min_u(), - 0x98 => visitor.visit_i16x8_max_s(), - 0x99 => visitor.visit_i16x8_max_u(), - 0x9b => visitor.visit_i16x8_avgr_u(), - 0x9c => visitor.visit_i16x8_extmul_low_i8x16_s(), - 0x9d => visitor.visit_i16x8_extmul_high_i8x16_s(), - 0x9e => visitor.visit_i16x8_extmul_low_i8x16_u(), - 0x9f => visitor.visit_i16x8_extmul_high_i8x16_u(), - 0xa0 => visitor.visit_i32x4_abs(), - 0xa1 => visitor.visit_i32x4_neg(), - 0xa3 => visitor.visit_i32x4_all_true(), - 0xa4 => visitor.visit_i32x4_bitmask(), - 0xa7 => visitor.visit_i32x4_extend_low_i16x8_s(), - 0xa8 => visitor.visit_i32x4_extend_high_i16x8_s(), - 0xa9 => visitor.visit_i32x4_extend_low_i16x8_u(), - 0xaa => visitor.visit_i32x4_extend_high_i16x8_u(), - 0xab => visitor.visit_i32x4_shl(), - 0xac => visitor.visit_i32x4_shr_s(), - 0xad => visitor.visit_i32x4_shr_u(), - 0xae => visitor.visit_i32x4_add(), - 0xb1 => visitor.visit_i32x4_sub(), - 0xb5 => visitor.visit_i32x4_mul(), - 0xb6 => visitor.visit_i32x4_min_s(), - 0xb7 => visitor.visit_i32x4_min_u(), - 0xb8 => visitor.visit_i32x4_max_s(), - 0xb9 => visitor.visit_i32x4_max_u(), - 0xba => visitor.visit_i32x4_dot_i16x8_s(), - 0xbc => visitor.visit_i32x4_extmul_low_i16x8_s(), - 0xbd => visitor.visit_i32x4_extmul_high_i16x8_s(), - 0xbe => visitor.visit_i32x4_extmul_low_i16x8_u(), - 0xbf => visitor.visit_i32x4_extmul_high_i16x8_u(), - 0xc0 => visitor.visit_i64x2_abs(), - 0xc1 => visitor.visit_i64x2_neg(), - 0xc3 => visitor.visit_i64x2_all_true(), - 0xc4 => visitor.visit_i64x2_bitmask(), - 0xc7 => visitor.visit_i64x2_extend_low_i32x4_s(), - 0xc8 => visitor.visit_i64x2_extend_high_i32x4_s(), - 0xc9 => visitor.visit_i64x2_extend_low_i32x4_u(), - 0xca => visitor.visit_i64x2_extend_high_i32x4_u(), - 0xcb => visitor.visit_i64x2_shl(), - 0xcc => visitor.visit_i64x2_shr_s(), - 0xcd => visitor.visit_i64x2_shr_u(), - 0xce => visitor.visit_i64x2_add(), - 0xd1 => visitor.visit_i64x2_sub(), - 0xd5 => visitor.visit_i64x2_mul(), - 0xd6 => visitor.visit_i64x2_eq(), - 0xd7 => visitor.visit_i64x2_ne(), - 0xd8 => visitor.visit_i64x2_lt_s(), - 0xd9 => visitor.visit_i64x2_gt_s(), - 0xda => visitor.visit_i64x2_le_s(), - 0xdb => visitor.visit_i64x2_ge_s(), - 0xdc => visitor.visit_i64x2_extmul_low_i32x4_s(), - 0xdd => visitor.visit_i64x2_extmul_high_i32x4_s(), - 0xde => visitor.visit_i64x2_extmul_low_i32x4_u(), - 0xdf => visitor.visit_i64x2_extmul_high_i32x4_u(), - 0xe0 => visitor.visit_f32x4_abs(), - 0xe1 => visitor.visit_f32x4_neg(), - 0xe3 => visitor.visit_f32x4_sqrt(), - 0xe4 => visitor.visit_f32x4_add(), - 0xe5 => visitor.visit_f32x4_sub(), - 0xe6 => visitor.visit_f32x4_mul(), - 0xe7 => visitor.visit_f32x4_div(), - 0xe8 => visitor.visit_f32x4_min(), - 0xe9 => visitor.visit_f32x4_max(), - 0xea => visitor.visit_f32x4_pmin(), - 0xeb => visitor.visit_f32x4_pmax(), - 0xec => visitor.visit_f64x2_abs(), - 0xed => visitor.visit_f64x2_neg(), - 0xef => visitor.visit_f64x2_sqrt(), - 0xf0 => visitor.visit_f64x2_add(), - 0xf1 => visitor.visit_f64x2_sub(), - 0xf2 => visitor.visit_f64x2_mul(), - 0xf3 => visitor.visit_f64x2_div(), - 0xf4 => visitor.visit_f64x2_min(), - 0xf5 => visitor.visit_f64x2_max(), - 0xf6 => visitor.visit_f64x2_pmin(), - 0xf7 => visitor.visit_f64x2_pmax(), - 0xf8 => visitor.visit_i32x4_trunc_sat_f32x4_s(), - 0xf9 => visitor.visit_i32x4_trunc_sat_f32x4_u(), - 0xfa => visitor.visit_f32x4_convert_i32x4_s(), - 0xfb => visitor.visit_f32x4_convert_i32x4_u(), - 0xfc => visitor.visit_i32x4_trunc_sat_f64x2_s_zero(), - 0xfd => visitor.visit_i32x4_trunc_sat_f64x2_u_zero(), - 0xfe => visitor.visit_f64x2_convert_low_i32x4_s(), - 0xff => visitor.visit_f64x2_convert_low_i32x4_u(), - 0x100 => visitor.visit_i8x16_relaxed_swizzle(), - 0x101 => visitor.visit_i32x4_relaxed_trunc_f32x4_s(), - 0x102 => visitor.visit_i32x4_relaxed_trunc_f32x4_u(), - 0x103 => visitor.visit_i32x4_relaxed_trunc_f64x2_s_zero(), - 0x104 => visitor.visit_i32x4_relaxed_trunc_f64x2_u_zero(), - 0x105 => visitor.visit_f32x4_relaxed_madd(), - 0x106 => visitor.visit_f32x4_relaxed_nmadd(), - 0x107 => visitor.visit_f64x2_relaxed_madd(), - 0x108 => visitor.visit_f64x2_relaxed_nmadd(), - 0x109 => visitor.visit_i8x16_relaxed_laneselect(), - 0x10a => visitor.visit_i16x8_relaxed_laneselect(), - 0x10b => visitor.visit_i32x4_relaxed_laneselect(), - 0x10c => visitor.visit_i64x2_relaxed_laneselect(), - 0x10d => visitor.visit_f32x4_relaxed_min(), - 0x10e => visitor.visit_f32x4_relaxed_max(), - 0x10f => visitor.visit_f64x2_relaxed_min(), - 0x110 => visitor.visit_f64x2_relaxed_max(), - 0x111 => visitor.visit_i16x8_relaxed_q15mulr_s(), - 0x112 => visitor.visit_i16x8_relaxed_dot_i8x16_i7x16_s(), - 0x113 => visitor.visit_i32x4_relaxed_dot_i8x16_i7x16_add_s(), - - _ => bail!(pos, "unknown 0xfd subopcode: 0x{code:x}"), - }) + + 0x0e => visitor.visit_i8x16_swizzle(), + 0x0f => visitor.visit_i8x16_splat(), + 0x10 => visitor.visit_i16x8_splat(), + 0x11 => visitor.visit_i32x4_splat(), + 0x12 => visitor.visit_i64x2_splat(), + 0x13 => visitor.visit_f32x4_splat(), + 0x14 => visitor.visit_f64x2_splat(), + + 0x15 => visitor.visit_i8x16_extract_lane_s(self.read_lane_index()?), + 0x16 => visitor.visit_i8x16_extract_lane_u(self.read_lane_index()?), + 0x17 => visitor.visit_i8x16_replace_lane(self.read_lane_index()?), + 0x18 => visitor.visit_i16x8_extract_lane_s(self.read_lane_index()?), + 0x19 => visitor.visit_i16x8_extract_lane_u(self.read_lane_index()?), + 0x1a => visitor.visit_i16x8_replace_lane(self.read_lane_index()?), + 0x1b => visitor.visit_i32x4_extract_lane(self.read_lane_index()?), + + 0x1c => visitor.visit_i32x4_replace_lane(self.read_lane_index()?), + 0x1d => visitor.visit_i64x2_extract_lane(self.read_lane_index()?), + 0x1e => visitor.visit_i64x2_replace_lane(self.read_lane_index()?), + 0x1f => visitor.visit_f32x4_extract_lane(self.read_lane_index()?), + 0x20 => visitor.visit_f32x4_replace_lane(self.read_lane_index()?), + 0x21 => visitor.visit_f64x2_extract_lane(self.read_lane_index()?), + 0x22 => visitor.visit_f64x2_replace_lane(self.read_lane_index()?), + + 0x23 => visitor.visit_i8x16_eq(), + 0x24 => visitor.visit_i8x16_ne(), + 0x25 => visitor.visit_i8x16_lt_s(), + 0x26 => visitor.visit_i8x16_lt_u(), + 0x27 => visitor.visit_i8x16_gt_s(), + 0x28 => visitor.visit_i8x16_gt_u(), + 0x29 => visitor.visit_i8x16_le_s(), + 0x2a => visitor.visit_i8x16_le_u(), + 0x2b => visitor.visit_i8x16_ge_s(), + 0x2c => visitor.visit_i8x16_ge_u(), + 0x2d => visitor.visit_i16x8_eq(), + 0x2e => visitor.visit_i16x8_ne(), + 0x2f => visitor.visit_i16x8_lt_s(), + 0x30 => visitor.visit_i16x8_lt_u(), + 0x31 => visitor.visit_i16x8_gt_s(), + 0x32 => visitor.visit_i16x8_gt_u(), + 0x33 => visitor.visit_i16x8_le_s(), + 0x34 => visitor.visit_i16x8_le_u(), + 0x35 => visitor.visit_i16x8_ge_s(), + 0x36 => visitor.visit_i16x8_ge_u(), + 0x37 => visitor.visit_i32x4_eq(), + 0x38 => visitor.visit_i32x4_ne(), + 0x39 => visitor.visit_i32x4_lt_s(), + 0x3a => visitor.visit_i32x4_lt_u(), + 0x3b => visitor.visit_i32x4_gt_s(), + 0x3c => visitor.visit_i32x4_gt_u(), + 0x3d => visitor.visit_i32x4_le_s(), + 0x3e => visitor.visit_i32x4_le_u(), + 0x3f => visitor.visit_i32x4_ge_s(), + 0x40 => visitor.visit_i32x4_ge_u(), + 0x41 => visitor.visit_f32x4_eq(), + 0x42 => visitor.visit_f32x4_ne(), + 0x43 => visitor.visit_f32x4_lt(), + 0x44 => visitor.visit_f32x4_gt(), + 0x45 => visitor.visit_f32x4_le(), + 0x46 => visitor.visit_f32x4_ge(), + 0x47 => visitor.visit_f64x2_eq(), + 0x48 => visitor.visit_f64x2_ne(), + 0x49 => visitor.visit_f64x2_lt(), + 0x4a => visitor.visit_f64x2_gt(), + 0x4b => visitor.visit_f64x2_le(), + 0x4c => visitor.visit_f64x2_ge(), + 0x4d => visitor.visit_v128_not(), + 0x4e => visitor.visit_v128_and(), + 0x4f => visitor.visit_v128_andnot(), + 0x50 => visitor.visit_v128_or(), + 0x51 => visitor.visit_v128_xor(), + 0x52 => visitor.visit_v128_bitselect(), + 0x53 => visitor.visit_v128_any_true(), + + 0x54 => { + let memarg = self.read_memarg(0)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_load8_lane(memarg, lane) + } + 0x55 => { + let memarg = self.read_memarg(1)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_load16_lane(memarg, lane) + } + 0x56 => { + let memarg = self.read_memarg(2)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_load32_lane(memarg, lane) + } + 0x57 => { + let memarg = self.read_memarg(3)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_load64_lane(memarg, lane) + } + 0x58 => { + let memarg = self.read_memarg(0)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_store8_lane(memarg, lane) + } + 0x59 => { + let memarg = self.read_memarg(1)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_store16_lane(memarg, lane) + } + 0x5a => { + let memarg = self.read_memarg(2)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_store32_lane(memarg, lane) + } + 0x5b => { + let memarg = self.read_memarg(3)?; + let lane = self.read_lane_index()?; + visitor.visit_v128_store64_lane(memarg, lane) + } + + 0x5c => visitor.visit_v128_load32_zero(self.read_memarg(2)?), + 0x5d => visitor.visit_v128_load64_zero(self.read_memarg(3)?), + 0x5e => visitor.visit_f32x4_demote_f64x2_zero(), + 0x5f => visitor.visit_f64x2_promote_low_f32x4(), + 0x60 => visitor.visit_i8x16_abs(), + 0x61 => visitor.visit_i8x16_neg(), + 0x62 => visitor.visit_i8x16_popcnt(), + 0x63 => visitor.visit_i8x16_all_true(), + 0x64 => visitor.visit_i8x16_bitmask(), + 0x65 => visitor.visit_i8x16_narrow_i16x8_s(), + 0x66 => visitor.visit_i8x16_narrow_i16x8_u(), + 0x67 => visitor.visit_f32x4_ceil(), + 0x68 => visitor.visit_f32x4_floor(), + 0x69 => visitor.visit_f32x4_trunc(), + 0x6a => visitor.visit_f32x4_nearest(), + 0x6b => visitor.visit_i8x16_shl(), + 0x6c => visitor.visit_i8x16_shr_s(), + 0x6d => visitor.visit_i8x16_shr_u(), + 0x6e => visitor.visit_i8x16_add(), + 0x6f => visitor.visit_i8x16_add_sat_s(), + 0x70 => visitor.visit_i8x16_add_sat_u(), + 0x71 => visitor.visit_i8x16_sub(), + 0x72 => visitor.visit_i8x16_sub_sat_s(), + 0x73 => visitor.visit_i8x16_sub_sat_u(), + 0x74 => visitor.visit_f64x2_ceil(), + 0x75 => visitor.visit_f64x2_floor(), + 0x76 => visitor.visit_i8x16_min_s(), + 0x77 => visitor.visit_i8x16_min_u(), + 0x78 => visitor.visit_i8x16_max_s(), + 0x79 => visitor.visit_i8x16_max_u(), + 0x7a => visitor.visit_f64x2_trunc(), + 0x7b => visitor.visit_i8x16_avgr_u(), + 0x7c => visitor.visit_i16x8_extadd_pairwise_i8x16_s(), + 0x7d => visitor.visit_i16x8_extadd_pairwise_i8x16_u(), + 0x7e => visitor.visit_i32x4_extadd_pairwise_i16x8_s(), + 0x7f => visitor.visit_i32x4_extadd_pairwise_i16x8_u(), + 0x80 => visitor.visit_i16x8_abs(), + 0x81 => visitor.visit_i16x8_neg(), + 0x82 => visitor.visit_i16x8_q15mulr_sat_s(), + 0x83 => visitor.visit_i16x8_all_true(), + 0x84 => visitor.visit_i16x8_bitmask(), + 0x85 => visitor.visit_i16x8_narrow_i32x4_s(), + 0x86 => visitor.visit_i16x8_narrow_i32x4_u(), + 0x87 => visitor.visit_i16x8_extend_low_i8x16_s(), + 0x88 => visitor.visit_i16x8_extend_high_i8x16_s(), + 0x89 => visitor.visit_i16x8_extend_low_i8x16_u(), + 0x8a => visitor.visit_i16x8_extend_high_i8x16_u(), + 0x8b => visitor.visit_i16x8_shl(), + 0x8c => visitor.visit_i16x8_shr_s(), + 0x8d => visitor.visit_i16x8_shr_u(), + 0x8e => visitor.visit_i16x8_add(), + 0x8f => visitor.visit_i16x8_add_sat_s(), + 0x90 => visitor.visit_i16x8_add_sat_u(), + 0x91 => visitor.visit_i16x8_sub(), + 0x92 => visitor.visit_i16x8_sub_sat_s(), + 0x93 => visitor.visit_i16x8_sub_sat_u(), + 0x94 => visitor.visit_f64x2_nearest(), + 0x95 => visitor.visit_i16x8_mul(), + 0x96 => visitor.visit_i16x8_min_s(), + 0x97 => visitor.visit_i16x8_min_u(), + 0x98 => visitor.visit_i16x8_max_s(), + 0x99 => visitor.visit_i16x8_max_u(), + 0x9b => visitor.visit_i16x8_avgr_u(), + 0x9c => visitor.visit_i16x8_extmul_low_i8x16_s(), + 0x9d => visitor.visit_i16x8_extmul_high_i8x16_s(), + 0x9e => visitor.visit_i16x8_extmul_low_i8x16_u(), + 0x9f => visitor.visit_i16x8_extmul_high_i8x16_u(), + 0xa0 => visitor.visit_i32x4_abs(), + 0xa1 => visitor.visit_i32x4_neg(), + 0xa3 => visitor.visit_i32x4_all_true(), + 0xa4 => visitor.visit_i32x4_bitmask(), + 0xa7 => visitor.visit_i32x4_extend_low_i16x8_s(), + 0xa8 => visitor.visit_i32x4_extend_high_i16x8_s(), + 0xa9 => visitor.visit_i32x4_extend_low_i16x8_u(), + 0xaa => visitor.visit_i32x4_extend_high_i16x8_u(), + 0xab => visitor.visit_i32x4_shl(), + 0xac => visitor.visit_i32x4_shr_s(), + 0xad => visitor.visit_i32x4_shr_u(), + 0xae => visitor.visit_i32x4_add(), + 0xb1 => visitor.visit_i32x4_sub(), + 0xb5 => visitor.visit_i32x4_mul(), + 0xb6 => visitor.visit_i32x4_min_s(), + 0xb7 => visitor.visit_i32x4_min_u(), + 0xb8 => visitor.visit_i32x4_max_s(), + 0xb9 => visitor.visit_i32x4_max_u(), + 0xba => visitor.visit_i32x4_dot_i16x8_s(), + 0xbc => visitor.visit_i32x4_extmul_low_i16x8_s(), + 0xbd => visitor.visit_i32x4_extmul_high_i16x8_s(), + 0xbe => visitor.visit_i32x4_extmul_low_i16x8_u(), + 0xbf => visitor.visit_i32x4_extmul_high_i16x8_u(), + 0xc0 => visitor.visit_i64x2_abs(), + 0xc1 => visitor.visit_i64x2_neg(), + 0xc3 => visitor.visit_i64x2_all_true(), + 0xc4 => visitor.visit_i64x2_bitmask(), + 0xc7 => visitor.visit_i64x2_extend_low_i32x4_s(), + 0xc8 => visitor.visit_i64x2_extend_high_i32x4_s(), + 0xc9 => visitor.visit_i64x2_extend_low_i32x4_u(), + 0xca => visitor.visit_i64x2_extend_high_i32x4_u(), + 0xcb => visitor.visit_i64x2_shl(), + 0xcc => visitor.visit_i64x2_shr_s(), + 0xcd => visitor.visit_i64x2_shr_u(), + 0xce => visitor.visit_i64x2_add(), + 0xd1 => visitor.visit_i64x2_sub(), + 0xd5 => visitor.visit_i64x2_mul(), + 0xd6 => visitor.visit_i64x2_eq(), + 0xd7 => visitor.visit_i64x2_ne(), + 0xd8 => visitor.visit_i64x2_lt_s(), + 0xd9 => visitor.visit_i64x2_gt_s(), + 0xda => visitor.visit_i64x2_le_s(), + 0xdb => visitor.visit_i64x2_ge_s(), + 0xdc => visitor.visit_i64x2_extmul_low_i32x4_s(), + 0xdd => visitor.visit_i64x2_extmul_high_i32x4_s(), + 0xde => visitor.visit_i64x2_extmul_low_i32x4_u(), + 0xdf => visitor.visit_i64x2_extmul_high_i32x4_u(), + 0xe0 => visitor.visit_f32x4_abs(), + 0xe1 => visitor.visit_f32x4_neg(), + 0xe3 => visitor.visit_f32x4_sqrt(), + 0xe4 => visitor.visit_f32x4_add(), + 0xe5 => visitor.visit_f32x4_sub(), + 0xe6 => visitor.visit_f32x4_mul(), + 0xe7 => visitor.visit_f32x4_div(), + 0xe8 => visitor.visit_f32x4_min(), + 0xe9 => visitor.visit_f32x4_max(), + 0xea => visitor.visit_f32x4_pmin(), + 0xeb => visitor.visit_f32x4_pmax(), + 0xec => visitor.visit_f64x2_abs(), + 0xed => visitor.visit_f64x2_neg(), + 0xef => visitor.visit_f64x2_sqrt(), + 0xf0 => visitor.visit_f64x2_add(), + 0xf1 => visitor.visit_f64x2_sub(), + 0xf2 => visitor.visit_f64x2_mul(), + 0xf3 => visitor.visit_f64x2_div(), + 0xf4 => visitor.visit_f64x2_min(), + 0xf5 => visitor.visit_f64x2_max(), + 0xf6 => visitor.visit_f64x2_pmin(), + 0xf7 => visitor.visit_f64x2_pmax(), + 0xf8 => visitor.visit_i32x4_trunc_sat_f32x4_s(), + 0xf9 => visitor.visit_i32x4_trunc_sat_f32x4_u(), + 0xfa => visitor.visit_f32x4_convert_i32x4_s(), + 0xfb => visitor.visit_f32x4_convert_i32x4_u(), + 0xfc => visitor.visit_i32x4_trunc_sat_f64x2_s_zero(), + 0xfd => visitor.visit_i32x4_trunc_sat_f64x2_u_zero(), + 0xfe => visitor.visit_f64x2_convert_low_i32x4_s(), + 0xff => visitor.visit_f64x2_convert_low_i32x4_u(), + 0x100 => visitor.visit_i8x16_relaxed_swizzle(), + 0x101 => visitor.visit_i32x4_relaxed_trunc_f32x4_s(), + 0x102 => visitor.visit_i32x4_relaxed_trunc_f32x4_u(), + 0x103 => visitor.visit_i32x4_relaxed_trunc_f64x2_s_zero(), + 0x104 => visitor.visit_i32x4_relaxed_trunc_f64x2_u_zero(), + 0x105 => visitor.visit_f32x4_relaxed_madd(), + 0x106 => visitor.visit_f32x4_relaxed_nmadd(), + 0x107 => visitor.visit_f64x2_relaxed_madd(), + 0x108 => visitor.visit_f64x2_relaxed_nmadd(), + 0x109 => visitor.visit_i8x16_relaxed_laneselect(), + 0x10a => visitor.visit_i16x8_relaxed_laneselect(), + 0x10b => visitor.visit_i32x4_relaxed_laneselect(), + 0x10c => visitor.visit_i64x2_relaxed_laneselect(), + 0x10d => visitor.visit_f32x4_relaxed_min(), + 0x10e => visitor.visit_f32x4_relaxed_max(), + 0x10f => visitor.visit_f64x2_relaxed_min(), + 0x110 => visitor.visit_f64x2_relaxed_max(), + 0x111 => visitor.visit_i16x8_relaxed_q15mulr_s(), + 0x112 => visitor.visit_i16x8_relaxed_dot_i8x16_i7x16_s(), + 0x113 => visitor.visit_i32x4_relaxed_dot_i8x16_i7x16_add_s(), + + _ => bail!(pos, "unknown 0xfd subopcode: 0x{code:x}"), + }) + } } fn visit_0xfe_operator( @@ -1808,81 +1809,13 @@ pub trait VisitOperator<'a> { ($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {{ match op { $( Operator::$op $({ $($arg),* })? => self.$visit($($($arg.clone()),*)?), )* - #[cfg(feature = "simd")] - other => visit_simd_operator(self, other), } }}; } - crate::for_each_visit_operator!(visit_operator) - } - - /// Returns a mutable reference to a [`VisitSimdOperator`] visitor. - /// - /// - If an implementer does _not_ want to support Wasm `simd` proposal - /// nothing has to be done since the default implementation already suffices. - /// - If an implementer _does_ want to support Wasm `simd` proposal this - /// method usually is implemented as `Some(self)` where the implementing - /// type (`Self`) typically also implements `VisitSimdOperator`. - /// - /// # Example - /// - /// ``` - /// # macro_rules! define_visit_operator { - /// # ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { - /// # $( fn $visit(&mut self $($(,$arg: $argty)*)?) {} )* - /// # } - /// # } - /// # use wasmparser::{VisitOperator, VisitSimdOperator}; - /// pub struct MyVisitor; - /// - /// impl<'a> VisitOperator<'a> for MyVisitor { - /// type Output = (); - /// - /// fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - /// Some(self) - /// } - /// - /// // implement remaining visitation methods here ... - /// # wasmparser::for_each_visit_operator!(define_visit_operator); - /// } - /// - /// impl VisitSimdOperator<'_> for MyVisitor { - /// // implement SIMD visitation methods here ... - /// # wasmparser::for_each_visit_simd_operator!(define_visit_operator); - /// } - /// ``` - #[cfg(feature = "simd")] - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - None + crate::for_each_operator!(visit_operator) } crate::for_each_visit_operator!(define_visit_operator); -} - -/// Special handler for visiting `simd` and `relaxed-simd` [`Operator`] variants. -#[cfg(feature = "simd")] -fn visit_simd_operator<'a, V>(visitor: &mut V, op: &Operator<'a>) -> V::Output -where - V: VisitOperator<'a> + ?Sized, -{ - let Some(simd_visitor) = visitor.simd_visitor() else { - panic!("missing SIMD visitor to visit operator: {op:?}") - }; - macro_rules! visit_simd_operator { - ($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {{ - match op { - $( Operator::$op $({ $($arg),* })? => simd_visitor.$visit($($($arg.clone()),*)?), )* - unexpected => unreachable!("unexpected non-SIMD operator: {unexpected:?}"), - } - }}; - } - crate::for_each_visit_simd_operator!(visit_simd_operator) -} - -/// Trait implemented by types that can visit all Wasm `simd` and `relaxed-simd` [`Operator`]s. -#[cfg(feature = "simd")] -#[allow(missing_docs)] -pub trait VisitSimdOperator<'a>: VisitOperator<'a> { crate::for_each_visit_simd_operator!(define_visit_operator); } @@ -1901,15 +1834,7 @@ impl<'a, 'b, V: VisitOperator<'a> + ?Sized> VisitOperator<'a> for &'b mut V { fn visit_operator(&mut self, op: &Operator<'a>) -> Self::Output { V::visit_operator(*self, op) } - #[cfg(feature = "simd")] - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = V::Output>> { - V::simd_visitor(*self) - } crate::for_each_visit_operator!(define_visit_operator_delegate); -} - -#[cfg(feature = "simd")] -impl<'a, 'b, V: VisitSimdOperator<'a> + ?Sized> VisitSimdOperator<'a> for &'b mut V { crate::for_each_visit_simd_operator!(define_visit_operator_delegate); } @@ -1918,15 +1843,7 @@ impl<'a, V: VisitOperator<'a> + ?Sized> VisitOperator<'a> for Box { fn visit_operator(&mut self, op: &Operator<'a>) -> Self::Output { V::visit_operator(&mut *self, op) } - #[cfg(feature = "simd")] - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = V::Output>> { - V::simd_visitor(&mut *self) - } crate::for_each_visit_operator!(define_visit_operator_delegate); -} - -#[cfg(feature = "simd")] -impl<'a, V: VisitSimdOperator<'a> + ?Sized> VisitSimdOperator<'a> for Box { crate::for_each_visit_simd_operator!(define_visit_operator_delegate); } @@ -2064,15 +1981,6 @@ macro_rules! define_visit_operator { impl<'a> VisitOperator<'a> for OperatorFactory<'a> { type Output = Operator<'a>; - #[cfg(feature = "simd")] - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - crate::for_each_visit_operator!(define_visit_operator); -} - -#[cfg(feature = "simd")] -impl<'a> VisitSimdOperator<'a> for OperatorFactory<'a> { crate::for_each_visit_simd_operator!(define_visit_operator); } diff --git a/crates/wasmparser/src/validator/core.rs b/crates/wasmparser/src/validator/core.rs index 849aac028d..135fe77c9d 100644 --- a/crates/wasmparser/src/validator/core.rs +++ b/crates/wasmparser/src/validator/core.rs @@ -10,8 +10,6 @@ use super::{ operators::{ty_to_str, OperatorValidator, OperatorValidatorAllocations}, types::{CoreTypeId, EntityType, RecGroupId, TypeAlloc, TypeList}, }; -#[cfg(feature = "simd")] -use crate::VisitSimdOperator; use crate::{ limits::*, BinaryReaderError, ConstExpr, Data, DataKind, Element, ElementKind, ExternalKind, FuncType, Global, GlobalType, HeapType, MemoryType, RecGroup, RefType, Result, SubType, Table, @@ -234,6 +232,15 @@ impl ModuleState { self.ops.with_resources(&self.resources, self.offset) } + #[cold] + #[cfg(not(feature = "simd"))] + fn simd_unavailable(&mut self) -> Result<()> { + Err(BinaryReaderError::new( + format!("SIMD not enabled at compile time"), + self.offset, + )) + } + fn validate_extended_const(&mut self, op: &str) -> Result<()> { if self.ops.features.extended_const() { Ok(()) @@ -326,12 +333,28 @@ impl ModuleState { #[cfg_attr(not(feature = "simd"), allow(unused_macro_rules))] macro_rules! define_visit_operator { ($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { - $( - #[allow(unused_variables)] - fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { - define_visit_operator!(@visit self $visit $($($arg)*)?) - } - )* + $(define_visit_operator!(expand @$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)* + }; + + (expand @simd $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { + #[cfg(not(feature = "simd"))] + #[allow(unused_variables)] + fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { + self.simd_unavailable() + } + + #[cfg(feature = "simd")] + #[allow(unused_variables)] + fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { + define_visit_operator!(@visit self $visit $($($arg)*)?) + } + }; + + (expand @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { + #[allow(unused_variables)] + fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { + define_visit_operator!(@visit self $visit $($($arg)*)?) + } }; // These are always valid in const expressions @@ -348,7 +371,7 @@ impl ModuleState { $self.validator().visit_f64_const($val) }}; (@visit $self:ident visit_v128_const $val:ident) => {{ - $self.validator().simd_visitor().unwrap().visit_v128_const($val) + $self.validator().visit_v128_const($val) }}; (@visit $self:ident visit_ref_null $val:ident) => {{ $self.validator().visit_ref_null($val) @@ -444,18 +467,7 @@ impl ModuleState { impl<'a> VisitOperator<'a> for VisitConstOperator<'a> { type Output = Result<()>; - #[cfg(feature = "simd")] - fn simd_visitor( - &mut self, - ) -> Option<&mut dyn crate::VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - crate::for_each_visit_operator!(define_visit_operator); - } - - #[cfg(feature = "simd")] - impl<'a> VisitSimdOperator<'a> for VisitConstOperator<'a> { crate::for_each_visit_simd_operator!(define_visit_operator); } } diff --git a/crates/wasmparser/src/validator/func.rs b/crates/wasmparser/src/validator/func.rs index f92365acc8..ddf4310efd 100644 --- a/crates/wasmparser/src/validator/func.rs +++ b/crates/wasmparser/src/validator/func.rs @@ -176,17 +176,6 @@ impl FuncValidator { self.validator.with_resources(&self.resources, offset) } - /// Same as [`FuncValidator::visitor`] except that the returned type - /// implements the [`VisitSimdOperator`](crate::VisitSimdOperator) trait as - /// well. - #[cfg(feature = "simd")] - pub fn simd_visitor<'this, 'a: 'this>( - &'this mut self, - offset: usize, - ) -> impl crate::VisitSimdOperator<'a, Output = Result<()>> + ModuleArity + 'this { - self.validator.with_resources_simd(&self.resources, offset) - } - /// Returns the Wasm features enabled for this validator. pub fn features(&self) -> &WasmFeatures { &self.validator.features diff --git a/crates/wasmparser/src/validator/operators.rs b/crates/wasmparser/src/validator/operators.rs index 02da112307..4f03f188a0 100644 --- a/crates/wasmparser/src/validator/operators.rs +++ b/crates/wasmparser/src/validator/operators.rs @@ -22,8 +22,6 @@ // confusing it's recommended to read over that section to see how it maps to // the various methods here. -#[cfg(feature = "simd")] -use crate::VisitSimdOperator; use crate::{ limits::MAX_WASM_FUNCTION_LOCALS, AbstractHeapType, BinaryReaderError, BlockType, BrTable, Catch, ContType, FieldType, FrameKind, FuncType, GlobalType, Handle, HeapType, Ieee32, Ieee64, @@ -488,25 +486,6 @@ impl OperatorValidator { }) } - /// Same as `with_resources` above but guarantees it's able to visit simd - /// operators as well. - #[cfg(feature = "simd")] - pub fn with_resources_simd<'a, 'validator, 'resources, T>( - &'validator mut self, - resources: &'resources T, - offset: usize, - ) -> impl VisitSimdOperator<'a, Output = Result<()>> + ModuleArity + 'validator - where - T: WasmModuleResources, - 'resources: 'validator, - { - WasmProposalValidator(OperatorValidatorTemp { - offset, - inner: self, - resources, - }) - } - pub fn into_allocations(mut self) -> OperatorValidatorAllocations { fn clear(mut tmp: Vec) -> Vec { tmp.clear(); @@ -998,6 +977,12 @@ where Ok(()) } + #[cold] + #[cfg(not(feature = "simd"))] + fn simd_unavailable(&self) -> Result<()> { + bail!(self.offset, "SIMD not compiled-in"); + } + fn check_shared_memarg(&self, memarg: MemArg) -> Result { if memarg.align != memarg.max_align { bail!( @@ -1693,7 +1678,6 @@ impl WasmProposalValidator<'_, '_, T> { } } -#[cfg_attr(not(feature = "simd"), allow(unused_macro_rules))] macro_rules! validate_proposal { ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { $( @@ -1732,21 +1716,7 @@ where T: WasmModuleResources, { type Output = Result<()>; - - #[cfg(feature = "simd")] - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - - crate::for_each_visit_operator!(validate_proposal); -} - -#[cfg(feature = "simd")] -impl<'a, T> VisitSimdOperator<'a> for WasmProposalValidator<'_, '_, T> -where - T: WasmModuleResources, -{ - crate::for_each_visit_simd_operator!(validate_proposal); + crate::for_each_operator!(validate_proposal); } #[track_caller] @@ -1764,17 +1734,29 @@ fn debug_assert_type_indices_are_ids(ty: ValType) { } } +macro_rules! delegate_to_simd { + ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { + $( + #[cfg(feature = "simd")] + fn $visit(&mut self $($(,$arg: $argty)*)?) -> Result<()> { + simd::SimdOperatorValidatorTemp(self).$visit($( $($arg),* )?) + } + + #[cfg(not(feature = "simd"))] + #[allow(unused_variables)] + fn $visit(&mut self $($(,$arg: $argty)*)?) -> Result<()> { + self.simd_unavailable() + } + )* + }; +} + impl<'a, T> VisitOperator<'a> for OperatorValidatorTemp<'_, '_, T> where T: WasmModuleResources, { type Output = Result<()>; - #[cfg(feature = "simd")] - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - fn visit_nop(&mut self) -> Self::Output { Ok(()) } @@ -4197,6 +4179,8 @@ where fn visit_i64_mul_wide_u(&mut self) -> Result<()> { self.check_i64_mul_wide() } + + crate::for_each_visit_simd_operator!(delegate_to_simd); } #[derive(Clone, Debug)] diff --git a/crates/wasmparser/src/validator/operators/simd.rs b/crates/wasmparser/src/validator/operators/simd.rs index b52015a259..01d2d81890 100644 --- a/crates/wasmparser/src/validator/operators/simd.rs +++ b/crates/wasmparser/src/validator/operators/simd.rs @@ -1,971 +1,970 @@ use super::OperatorValidatorTemp; +use crate::V128; use crate::{MemArg, Result, ValType, WasmModuleResources}; -use crate::{VisitSimdOperator, V128}; -impl<'resources, R> OperatorValidatorTemp<'_, 'resources, R> +pub(crate) struct SimdOperatorValidatorTemp<'a, 'b, 'resources, R>( + pub(crate) &'a mut OperatorValidatorTemp<'b, 'resources, R>, +); + +impl<'resources, R> SimdOperatorValidatorTemp<'_, '_, 'resources, R> where R: WasmModuleResources, { fn check_simd_lane_index(&self, index: u8, max: u8) -> Result<()> { if index >= max { - bail!(self.offset, "SIMD index out of bounds"); + bail!(self.0.offset, "SIMD index out of bounds"); } Ok(()) } /// Checks a [`V128`] splat operator. fn check_v128_splat(&mut self, src_ty: ValType) -> Result<()> { - self.pop_operand(Some(src_ty))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(src_ty))?; + self.0.push_operand(ValType::V128)?; Ok(()) } /// Checks a [`V128`] binary operator. fn check_v128_binary_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } /// Checks a [`V128`] binary float operator. fn check_v128_fbinary_op(&mut self) -> Result<()> { - self.check_floats_enabled()?; + self.0.check_floats_enabled()?; self.check_v128_binary_op() } /// Checks a [`V128`] unary operator. fn check_v128_unary_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } /// Checks a [`V128`] unary float operator. fn check_v128_funary_op(&mut self) -> Result<()> { - self.check_floats_enabled()?; + self.0.check_floats_enabled()?; self.check_v128_unary_op() } /// Checks a [`V128`] relaxed ternary operator. fn check_v128_ternary_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } /// Checks a [`V128`] test operator. fn check_v128_bitmask_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::I32)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::I32)?; Ok(()) } /// Checks a [`V128`] shift operator. fn check_v128_shift_op(&mut self) -> Result<()> { - self.pop_operand(Some(ValType::I32))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::I32))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } /// Checks a [`V128`] common load operator. fn check_v128_load_op(&mut self, memarg: MemArg) -> Result<()> { - let idx = self.check_memarg(memarg)?; - self.pop_operand(Some(idx))?; - self.push_operand(ValType::V128)?; + let idx = self.0.check_memarg(memarg)?; + self.0.pop_operand(Some(idx))?; + self.0.push_operand(ValType::V128)?; Ok(()) } -} -impl<'a, T> VisitSimdOperator<'a> for OperatorValidatorTemp<'_, '_, T> -where - T: WasmModuleResources, -{ - fn visit_v128_load(&mut self, memarg: MemArg) -> Self::Output { - let ty = self.check_memarg(memarg)?; - self.pop_operand(Some(ty))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_v128_load(&mut self, memarg: MemArg) -> Result<()> { + let ty = self.0.check_memarg(memarg)?; + self.0.pop_operand(Some(ty))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_store(&mut self, memarg: MemArg) -> Self::Output { - let ty = self.check_memarg(memarg)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ty))?; + pub(crate) fn visit_v128_store(&mut self, memarg: MemArg) -> Result<()> { + let ty = self.0.check_memarg(memarg)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ty))?; Ok(()) } - fn visit_v128_const(&mut self, _value: V128) -> Self::Output { - self.push_operand(ValType::V128)?; + pub(crate) fn visit_v128_const(&mut self, _value: V128) -> Result<()> { + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i8x16_splat(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_splat(&mut self) -> Result<()> { self.check_v128_splat(ValType::I32) } - fn visit_i16x8_splat(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_splat(&mut self) -> Result<()> { self.check_v128_splat(ValType::I32) } - fn visit_i32x4_splat(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_splat(&mut self) -> Result<()> { self.check_v128_splat(ValType::I32) } - fn visit_i64x2_splat(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_splat(&mut self) -> Result<()> { self.check_v128_splat(ValType::I64) } - fn visit_f32x4_splat(&mut self) -> Self::Output { - self.check_floats_enabled()?; + pub(crate) fn visit_f32x4_splat(&mut self) -> Result<()> { + self.0.check_floats_enabled()?; self.check_v128_splat(ValType::F32) } - fn visit_f64x2_splat(&mut self) -> Self::Output { - self.check_floats_enabled()?; + pub(crate) fn visit_f64x2_splat(&mut self) -> Result<()> { + self.0.check_floats_enabled()?; self.check_v128_splat(ValType::F64) } - fn visit_i8x16_extract_lane_s(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i8x16_extract_lane_s(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 16)?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::I32)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::I32)?; Ok(()) } - fn visit_i8x16_extract_lane_u(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i8x16_extract_lane_u(&mut self, lane: u8) -> Result<()> { self.visit_i8x16_extract_lane_s(lane) } - fn visit_i16x8_extract_lane_s(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i16x8_extract_lane_s(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 8)?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::I32)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::I32)?; Ok(()) } - fn visit_i16x8_extract_lane_u(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i16x8_extract_lane_u(&mut self, lane: u8) -> Result<()> { self.visit_i16x8_extract_lane_s(lane) } - fn visit_i32x4_extract_lane(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i32x4_extract_lane(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 4)?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::I32)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::I32)?; Ok(()) } - fn visit_i8x16_replace_lane(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i8x16_replace_lane(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 16)?; - self.pop_operand(Some(ValType::I32))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::I32))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i16x8_replace_lane(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i16x8_replace_lane(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 8)?; - self.pop_operand(Some(ValType::I32))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::I32))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i32x4_replace_lane(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i32x4_replace_lane(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 4)?; - self.pop_operand(Some(ValType::I32))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::I32))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i64x2_extract_lane(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i64x2_extract_lane(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 2)?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::I64)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::I64)?; Ok(()) } - fn visit_i64x2_replace_lane(&mut self, lane: u8) -> Self::Output { + pub(crate) fn visit_i64x2_replace_lane(&mut self, lane: u8) -> Result<()> { self.check_simd_lane_index(lane, 2)?; - self.pop_operand(Some(ValType::I64))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::I64))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_f32x4_extract_lane(&mut self, lane: u8) -> Self::Output { - self.check_floats_enabled()?; + pub(crate) fn visit_f32x4_extract_lane(&mut self, lane: u8) -> Result<()> { + self.0.check_floats_enabled()?; self.check_simd_lane_index(lane, 4)?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::F32)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::F32)?; Ok(()) } - fn visit_f32x4_replace_lane(&mut self, lane: u8) -> Self::Output { - self.check_floats_enabled()?; + pub(crate) fn visit_f32x4_replace_lane(&mut self, lane: u8) -> Result<()> { + self.0.check_floats_enabled()?; self.check_simd_lane_index(lane, 4)?; - self.pop_operand(Some(ValType::F32))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::F32))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_f64x2_extract_lane(&mut self, lane: u8) -> Self::Output { - self.check_floats_enabled()?; + pub(crate) fn visit_f64x2_extract_lane(&mut self, lane: u8) -> Result<()> { + self.0.check_floats_enabled()?; self.check_simd_lane_index(lane, 2)?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::F64)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::F64)?; Ok(()) } - fn visit_f64x2_replace_lane(&mut self, lane: u8) -> Self::Output { - self.check_floats_enabled()?; + pub(crate) fn visit_f64x2_replace_lane(&mut self, lane: u8) -> Result<()> { + self.0.check_floats_enabled()?; self.check_simd_lane_index(lane, 2)?; - self.pop_operand(Some(ValType::F64))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::F64))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_f32x4_eq(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_eq(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_ne(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_ne(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_lt(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_lt(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_gt(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_gt(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_le(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_le(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_ge(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_ge(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_eq(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_eq(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_ne(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_ne(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_lt(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_lt(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_gt(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_gt(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_le(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_le(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_ge(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_ge(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_add(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_add(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_sub(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_sub(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_mul(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_mul(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_div(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_div(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_min(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_min(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_max(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_max(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_pmin(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_pmin(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f32x4_pmax(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_pmax(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_add(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_add(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_sub(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_sub(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_mul(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_mul(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_div(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_div(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_min(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_min(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_max(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_max(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_pmin(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_pmin(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_f64x2_pmax(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_pmax(&mut self) -> Result<()> { self.check_v128_fbinary_op() } - fn visit_i8x16_eq(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_eq(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_ne(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_ne(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_lt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_lt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_lt_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_lt_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_gt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_gt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_gt_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_gt_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_le_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_le_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_le_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_le_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_ge_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_ge_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_ge_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_ge_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_eq(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_eq(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_ne(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_ne(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_lt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_lt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_lt_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_lt_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_gt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_gt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_gt_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_gt_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_le_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_le_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_le_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_le_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_ge_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_ge_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_ge_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_ge_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_eq(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_eq(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_ne(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_ne(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_lt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_lt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_lt_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_lt_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_gt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_gt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_gt_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_gt_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_le_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_le_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_le_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_le_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_ge_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_ge_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_ge_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_ge_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_eq(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_eq(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_ne(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_ne(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_lt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_lt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_gt_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_gt_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_le_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_le_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_ge_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_ge_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_v128_and(&mut self) -> Self::Output { + pub(crate) fn visit_v128_and(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_v128_andnot(&mut self) -> Self::Output { + pub(crate) fn visit_v128_andnot(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_v128_or(&mut self) -> Self::Output { + pub(crate) fn visit_v128_or(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_v128_xor(&mut self) -> Self::Output { + pub(crate) fn visit_v128_xor(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_add(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_add(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_add_sat_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_add_sat_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_add_sat_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_add_sat_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_sub(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_sub(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_sub_sat_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_sub_sat_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_sub_sat_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_sub_sat_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_min_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_min_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_min_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_min_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_max_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_max_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_max_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_max_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_add(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_add(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_add_sat_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_add_sat_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_add_sat_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_add_sat_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_sub(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_sub(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_sub_sat_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_sub_sat_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_sub_sat_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_sub_sat_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_mul(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_mul(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_min_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_min_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_min_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_min_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_max_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_max_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_max_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_max_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_add(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_add(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_sub(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_sub(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_mul(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_mul(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_min_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_min_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_min_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_min_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_max_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_max_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_max_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_max_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_dot_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_dot_i16x8_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_add(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_add(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_sub(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_sub(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_mul(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_mul(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_avgr_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_avgr_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_avgr_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_avgr_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_narrow_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_narrow_i16x8_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i8x16_narrow_i16x8_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_narrow_i16x8_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_narrow_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_narrow_i32x4_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_narrow_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_narrow_i32x4_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_extmul_low_i8x16_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extmul_low_i8x16_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_extmul_high_i8x16_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extmul_high_i8x16_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_extmul_low_i8x16_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extmul_low_i8x16_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_extmul_high_i8x16_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extmul_high_i8x16_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_extmul_low_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extmul_low_i16x8_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_extmul_high_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extmul_high_i16x8_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_extmul_low_i16x8_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extmul_low_i16x8_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_extmul_high_i16x8_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extmul_high_i16x8_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_extmul_low_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extmul_low_i32x4_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_extmul_high_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extmul_high_i32x4_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_extmul_low_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extmul_low_i32x4_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i64x2_extmul_high_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extmul_high_i32x4_u(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_q15mulr_sat_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_q15mulr_sat_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_f32x4_ceil(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_ceil(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_floor(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_floor(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_trunc(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_trunc(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_nearest(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_nearest(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_ceil(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_ceil(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_floor(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_floor(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_trunc(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_trunc(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_nearest(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_nearest(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_abs(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_abs(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_neg(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_neg(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_sqrt(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_sqrt(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_abs(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_abs(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_neg(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_neg(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_sqrt(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_sqrt(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_demote_f64x2_zero(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_demote_f64x2_zero(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_promote_low_f32x4(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_promote_low_f32x4(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_convert_low_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_convert_low_i32x4_s(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f64x2_convert_low_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_convert_low_i32x4_u(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_i32x4_trunc_sat_f32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_trunc_sat_f32x4_s(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_i32x4_trunc_sat_f32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_trunc_sat_f32x4_u(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_i32x4_trunc_sat_f64x2_s_zero(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_trunc_sat_f64x2_s_zero(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_i32x4_trunc_sat_f64x2_u_zero(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_trunc_sat_f64x2_u_zero(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_convert_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_convert_i32x4_s(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_f32x4_convert_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_convert_i32x4_u(&mut self) -> Result<()> { self.check_v128_funary_op() } - fn visit_v128_not(&mut self) -> Self::Output { + pub(crate) fn visit_v128_not(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i8x16_abs(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_abs(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i8x16_neg(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_neg(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i8x16_popcnt(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_popcnt(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_abs(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_abs(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_neg(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_neg(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_abs(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_abs(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_neg(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_neg(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i64x2_abs(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_abs(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i64x2_neg(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_neg(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_extend_low_i8x16_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extend_low_i8x16_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_extend_high_i8x16_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extend_high_i8x16_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_extend_low_i8x16_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extend_low_i8x16_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_extend_high_i8x16_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extend_high_i8x16_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_extend_low_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extend_low_i16x8_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_extend_high_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extend_high_i16x8_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_extend_low_i16x8_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extend_low_i16x8_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_extend_high_i16x8_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extend_high_i16x8_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i64x2_extend_low_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extend_low_i32x4_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i64x2_extend_high_i32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extend_high_i32x4_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i64x2_extend_low_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extend_low_i32x4_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i64x2_extend_high_i32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_extend_high_i32x4_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_extadd_pairwise_i8x16_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extadd_pairwise_i8x16_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i16x8_extadd_pairwise_i8x16_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_extadd_pairwise_i8x16_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_extadd_pairwise_i16x8_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extadd_pairwise_i16x8_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_extadd_pairwise_i16x8_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_extadd_pairwise_i16x8_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_v128_bitselect(&mut self) -> Self::Output { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_v128_bitselect(&mut self) -> Result<()> { + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i8x16_relaxed_swizzle(&mut self) -> Self::Output { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_i8x16_relaxed_swizzle(&mut self) -> Result<()> { + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i32x4_relaxed_trunc_f32x4_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_relaxed_trunc_f32x4_s(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_relaxed_trunc_f32x4_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_relaxed_trunc_f32x4_u(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_relaxed_trunc_f64x2_s_zero(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_relaxed_trunc_f64x2_s_zero(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_i32x4_relaxed_trunc_f64x2_u_zero(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_relaxed_trunc_f64x2_u_zero(&mut self) -> Result<()> { self.check_v128_unary_op() } - fn visit_f32x4_relaxed_madd(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_relaxed_madd(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_f32x4_relaxed_nmadd(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_relaxed_nmadd(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_f64x2_relaxed_madd(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_relaxed_madd(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_f64x2_relaxed_nmadd(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_relaxed_nmadd(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_i8x16_relaxed_laneselect(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_relaxed_laneselect(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_i16x8_relaxed_laneselect(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_relaxed_laneselect(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_i32x4_relaxed_laneselect(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_relaxed_laneselect(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_i64x2_relaxed_laneselect(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_relaxed_laneselect(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_f32x4_relaxed_min(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_relaxed_min(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_f32x4_relaxed_max(&mut self) -> Self::Output { + pub(crate) fn visit_f32x4_relaxed_max(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_f64x2_relaxed_min(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_relaxed_min(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_f64x2_relaxed_max(&mut self) -> Self::Output { + pub(crate) fn visit_f64x2_relaxed_max(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_relaxed_q15mulr_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_relaxed_q15mulr_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i16x8_relaxed_dot_i8x16_i7x16_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_relaxed_dot_i8x16_i7x16_s(&mut self) -> Result<()> { self.check_v128_binary_op() } - fn visit_i32x4_relaxed_dot_i8x16_i7x16_add_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_relaxed_dot_i8x16_i7x16_add_s(&mut self) -> Result<()> { self.check_v128_ternary_op() } - fn visit_v128_any_true(&mut self) -> Self::Output { + pub(crate) fn visit_v128_any_true(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i8x16_all_true(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_all_true(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i8x16_bitmask(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_bitmask(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i16x8_all_true(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_all_true(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i16x8_bitmask(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_bitmask(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i32x4_all_true(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_all_true(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i32x4_bitmask(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_bitmask(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i64x2_all_true(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_all_true(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i64x2_bitmask(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_bitmask(&mut self) -> Result<()> { self.check_v128_bitmask_op() } - fn visit_i8x16_shl(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_shl(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i8x16_shr_s(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_shr_s(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i8x16_shr_u(&mut self) -> Self::Output { + pub(crate) fn visit_i8x16_shr_u(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i16x8_shl(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_shl(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i16x8_shr_s(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_shr_s(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i16x8_shr_u(&mut self) -> Self::Output { + pub(crate) fn visit_i16x8_shr_u(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i32x4_shl(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_shl(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i32x4_shr_s(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_shr_s(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i32x4_shr_u(&mut self) -> Self::Output { + pub(crate) fn visit_i32x4_shr_u(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i64x2_shl(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_shl(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i64x2_shr_s(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_shr_s(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i64x2_shr_u(&mut self) -> Self::Output { + pub(crate) fn visit_i64x2_shr_u(&mut self) -> Result<()> { self.check_v128_shift_op() } - fn visit_i8x16_swizzle(&mut self) -> Self::Output { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_i8x16_swizzle(&mut self) -> Result<()> { + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Self::Output { - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(ValType::V128))?; + pub(crate) fn visit_i8x16_shuffle(&mut self, lanes: [u8; 16]) -> Result<()> { + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(ValType::V128))?; for i in lanes { self.check_simd_lane_index(i, 32)?; } - self.push_operand(ValType::V128)?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load8_splat(&mut self, memarg: MemArg) -> Self::Output { - let ty = self.check_memarg(memarg)?; - self.pop_operand(Some(ty))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_v128_load8_splat(&mut self, memarg: MemArg) -> Result<()> { + let ty = self.0.check_memarg(memarg)?; + self.0.pop_operand(Some(ty))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load16_splat(&mut self, memarg: MemArg) -> Self::Output { - let ty = self.check_memarg(memarg)?; - self.pop_operand(Some(ty))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_v128_load16_splat(&mut self, memarg: MemArg) -> Result<()> { + let ty = self.0.check_memarg(memarg)?; + self.0.pop_operand(Some(ty))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load32_splat(&mut self, memarg: MemArg) -> Self::Output { - let ty = self.check_memarg(memarg)?; - self.pop_operand(Some(ty))?; - self.push_operand(ValType::V128)?; + pub(crate) fn visit_v128_load32_splat(&mut self, memarg: MemArg) -> Result<()> { + let ty = self.0.check_memarg(memarg)?; + self.0.pop_operand(Some(ty))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load32_zero(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load32_zero(&mut self, memarg: MemArg) -> Result<()> { self.visit_v128_load32_splat(memarg) } - fn visit_v128_load64_splat(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load64_splat(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load64_zero(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load64_zero(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load8x8_s(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load8x8_s(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load8x8_u(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load8x8_u(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load16x4_s(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load16x4_s(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load16x4_u(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load16x4_u(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load32x2_s(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load32x2_s(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load32x2_u(&mut self, memarg: MemArg) -> Self::Output { + pub(crate) fn visit_v128_load32x2_u(&mut self, memarg: MemArg) -> Result<()> { self.check_v128_load_op(memarg) } - fn visit_v128_load8_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_load8_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 16)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load16_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_load16_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 8)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load32_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_load32_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 4)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_load64_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_load64_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 2)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; - self.push_operand(ValType::V128)?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; + self.0.push_operand(ValType::V128)?; Ok(()) } - fn visit_v128_store8_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_store8_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 16)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; Ok(()) } - fn visit_v128_store16_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_store16_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 8)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; Ok(()) } - fn visit_v128_store32_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_store32_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 4)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; Ok(()) } - fn visit_v128_store64_lane(&mut self, memarg: MemArg, lane: u8) -> Self::Output { - let idx = self.check_memarg(memarg)?; + pub(crate) fn visit_v128_store64_lane(&mut self, memarg: MemArg, lane: u8) -> Result<()> { + let idx = self.0.check_memarg(memarg)?; self.check_simd_lane_index(lane, 2)?; - self.pop_operand(Some(ValType::V128))?; - self.pop_operand(Some(idx))?; + self.0.pop_operand(Some(ValType::V128))?; + self.0.pop_operand(Some(idx))?; Ok(()) } } diff --git a/crates/wasmprinter/src/operator.rs b/crates/wasmprinter/src/operator.rs index 65324de96b..572503cc81 100644 --- a/crates/wasmprinter/src/operator.rs +++ b/crates/wasmprinter/src/operator.rs @@ -1,7 +1,6 @@ use super::{Config, Print, PrintTermcolor, Printer, State}; use anyhow::{anyhow, bail, Result}; use termcolor::{Ansi, NoColor}; -use wasmparser::VisitSimdOperator; use wasmparser::{ BlockType, BrTable, Catch, CompositeInnerType, ContType, FrameKind, FuncType, Handle, MemArg, ModuleArity, Operator, OperatorsReader, Ordering, RefType, ResumeTable, SubType, TryTable, @@ -1391,14 +1390,7 @@ macro_rules! define_visit { impl<'a> VisitOperator<'a> for PrintOperator<'_, '_, '_, '_> { type Output = Result<()>; - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - wasmparser::for_each_visit_operator!(define_visit); -} - -impl<'a> VisitSimdOperator<'a> for PrintOperator<'_, '_, '_, '_> { wasmparser::for_each_visit_simd_operator!(define_visit); } diff --git a/crates/wit-component/src/gc.rs b/crates/wit-component/src/gc.rs index f9a66e8b8a..d12800ddc4 100644 --- a/crates/wit-component/src/gc.rs +++ b/crates/wit-component/src/gc.rs @@ -993,16 +993,7 @@ macro_rules! define_visit { impl<'a> VisitOperator<'a> for Module<'a> { type Output = (); - - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - - wasmparser::for_each_visit_operator!(define_visit); -} - -impl<'a> VisitSimdOperator<'a> for Module<'a> { - wasmparser::for_each_visit_simd_operator!(define_visit); + wasmparser::for_each_operator!(define_visit); } /// Helper function to filter `iter` based on the `live` set, yielding an diff --git a/src/bin/wasm-tools/dump.rs b/src/bin/wasm-tools/dump.rs index 06dd81a793..535c346e5f 100644 --- a/src/bin/wasm-tools/dump.rs +++ b/src/bin/wasm-tools/dump.rs @@ -864,13 +864,5 @@ macro_rules! define_visit_operator { impl<'a> VisitOperator<'a> for Dump<'_> { type Output = (); - fn simd_visitor(&mut self) -> Option<&mut dyn VisitSimdOperator<'a, Output = Self::Output>> { - Some(self) - } - - wasmparser::for_each_visit_operator!(define_visit_operator); -} - -impl<'a> VisitSimdOperator<'a> for Dump<'_> { - wasmparser::for_each_visit_simd_operator!(define_visit_operator); + wasmparser::for_each_operator!(define_visit_operator); }