Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/wasmparser/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 73 kB image not shown  

Quelle  lib.rs

  Sprache: Rust
 

/* Copyright 2017 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


//! A simple event-driven library for parsing WebAssembly binary files
//! (or streams).
//!
//! The parser library reports events as they happen and only stores
//! parsing information for a brief period of time, making it very fast
//! and memory-efficient. The event-driven model, however, has some drawbacks.
//! If you need random access to the entire WebAssembly data-structure,
//! this is not the right library for you. You could however, build such
//! a data-structure using this library.
//!
//! To get started, create a [`Parser`] using [`Parser::new`] and then follow
//! the examples documented for [`Parser::parse`] or [`Parser::parse_all`].

#![deny(missing_docs)]
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]

extern crate alloc;
#[cfg(feature = "std")]
#[macro_use]
extern crate std;

/// A small "prelude" to use throughout this crate.
///
/// This crate is tagged with `#![no_std]` meaning that we get libcore's prelude
/// by default. This crate also uses `alloc`, however, and common types there
/// like `String`. This custom prelude helps bring those types into scope to
/// avoid having to import each of them manually.
mod prelude {
    pub use alloc::borrow::ToOwned;
    pub use alloc::boxed::Box;
    pub use alloc::format;
    pub use alloc::string::{String, ToString};
    pub use alloc::vec;
    pub use alloc::vec::Vec;

    #[cfg(all(feature = "validate", feature = "component-model"))]
    pub use crate::collections::IndexSet;
    #[cfg(feature = "validate")]
    pub use crate::collections::{IndexMap, Map, Set};
}

/// A helper macro which is used to itself define further macros below.
///
/// This is a little complicated, so first off sorry about that. The idea here
/// though is that there's one source of truth for the listing of instructions
/// in `wasmparser` and this is the one location. All other locations should be
/// derivative from this. As this one source of truth it has all instructions
/// from all proposals all grouped together. Down below though, for compile
/// time, currently the simd instructions are split out into their own macro.
/// The structure/syntax of this macro is to facilitate easily splitting out
/// entire groups of instructions.
///
/// This is used below to define more macros.
macro_rules! _for_each_operator_group {
    ($mac:ident) => {
        $mac! {
            @mvp {
                Unreachable => visit_unreachable (arity 0 -> 0)
                Nop => visit_nop (arity 0 -> 0)
                Block { blockty: $crate::BlockType } => visit_block (arity custom)
                Loop { blockty: $crate::BlockType } => visit_loop (arity custom)
                If { blockty: $crate::BlockType } => visit_if (arity custom)
                Else => visit_else (arity custom)
                End => visit_end (arity custom)
                Br { relative_depth: u32 } => visit_br (arity custom)
                BrIf { relative_depth: u32 } => visit_br_if (arity custom)
                BrTable { targets: $crate::BrTable<'a> } => visit_br_table (arity custom)
                Return => visit_return (arity custom)
                Call { function_index: u32 } => visit_call (arity custom)
                CallIndirect { type_index: u32, table_index: u32 } => visit_call_indirect (arity custom)
                Drop => visit_drop (arity 1 -> 0)
                Select => visit_select (arity 3 -> 1)
                LocalGet { local_index: u32 } => visit_local_get (arity 0 -> 1)
                LocalSet { local_index: u32 } => visit_local_set (arity 1 -> 0)
                LocalTee { local_index: u32 } => visit_local_tee (arity 1 -> 1)
                GlobalGet { global_index: u32 } => visit_global_get (arity 0 -> 1)
                GlobalSet { global_index: u32 } => visit_global_set (arity 1 -> 0)
                I32Load { memarg: $crate::MemArg } => visit_i32_load (arity 1 -> 1)
                I64Load { memarg: $crate::MemArg } => visit_i64_load (arity 1 -> 1)
                F32Load { memarg: $crate::MemArg } => visit_f32_load (arity 1 -> 1)
                F64Load { memarg: $crate::MemArg } => visit_f64_load (arity 1 -> 1)
                I32Load8S { memarg: $crate::MemArg } => visit_i32_load8_s (arity 1 -> 1)
                I32Load8U { memarg: $crate::MemArg } => visit_i32_load8_u (arity 1 -> 1)
                I32Load16S { memarg: $crate::MemArg } => visit_i32_load16_s (arity 1 -> 1)
                I32Load16U { memarg: $crate::MemArg } => visit_i32_load16_u (arity 1 -> 1)
                I64Load8S { memarg: $crate::MemArg } => visit_i64_load8_s (arity 1 -> 1)
                I64Load8U { memarg: $crate::MemArg } => visit_i64_load8_u (arity 1 -> 1)
                I64Load16S { memarg: $crate::MemArg } => visit_i64_load16_s (arity 1 -> 1)
                I64Load16U { memarg: $crate::MemArg } => visit_i64_load16_u (arity 1 -> 1)
                I64Load32S { memarg: $crate::MemArg } => visit_i64_load32_s (arity 1 -> 1)
                I64Load32U { memarg: $crate::MemArg } => visit_i64_load32_u (arity 1 -> 1)
                I32Store { memarg: $crate::MemArg } => visit_i32_store (arity 2 -> 0)
                I64Store { memarg: $crate::MemArg } => visit_i64_store (arity 2 -> 0)
                F32Store { memarg: $crate::MemArg } => visit_f32_store (arity 2 -> 0)
                F64Store { memarg: $crate::MemArg } => visit_f64_store (arity 2 -> 0)
                I32Store8 { memarg: $crate::MemArg } => visit_i32_store8 (arity 2 -> 0)
                I32Store16 { memarg: $crate::MemArg } => visit_i32_store16 (arity 2 -> 0)
                I64Store8 { memarg: $crate::MemArg } => visit_i64_store8 (arity 2 -> 0)
                I64Store16 { memarg: $crate::MemArg } => visit_i64_store16 (arity 2 -> 0)
                I64Store32 { memarg: $crate::MemArg } => visit_i64_store32 (arity 2 -> 0)
                MemorySize { mem: u32 } => visit_memory_size (arity 0 -> 1)
                MemoryGrow { mem: u32 } => visit_memory_grow (arity 1 -> 1)
                I32Const { value: i32 } => visit_i32_const (arity 0 -> 1)
                I64Const { value: i64 } => visit_i64_const (arity 0 -> 1)
                F32Const { value: $crate::Ieee32 } => visit_f32_const (arity 0 -> 1)
                F64Const { value: $crate::Ieee64 } => visit_f64_const (arity 0 -> 1)
                I32Eqz => visit_i32_eqz (arity 1 -> 1)
                I32Eq => visit_i32_eq (arity 2 -> 1)
                I32Ne => visit_i32_ne (arity 2 -> 1)
                I32LtS => visit_i32_lt_s (arity 2 -> 1)
                I32LtU => visit_i32_lt_u (arity 2 -> 1)
                I32GtS => visit_i32_gt_s (arity 2 -> 1)
                I32GtU => visit_i32_gt_u (arity 2 -> 1)
                I32LeS => visit_i32_le_s (arity 2 -> 1)
                I32LeU => visit_i32_le_u (arity 2 -> 1)
                I32GeS => visit_i32_ge_s (arity 2 -> 1)
                I32GeU => visit_i32_ge_u (arity 2 -> 1)
                I64Eqz => visit_i64_eqz (arity 1 -> 1)
                I64Eq => visit_i64_eq (arity 2 -> 1)
                I64Ne => visit_i64_ne (arity 2 -> 1)
                I64LtS => visit_i64_lt_s (arity 2 -> 1)
                I64LtU => visit_i64_lt_u (arity 2 -> 1)
                I64GtS => visit_i64_gt_s (arity 2 -> 1)
                I64GtU => visit_i64_gt_u (arity 2 -> 1)
                I64LeS => visit_i64_le_s (arity 2 -> 1)
                I64LeU => visit_i64_le_u (arity 2 -> 1)
                I64GeS => visit_i64_ge_s (arity 2 -> 1)
                I64GeU => visit_i64_ge_u (arity 2 -> 1)
                F32Eq => visit_f32_eq (arity 2 -> 1)
                F32Ne => visit_f32_ne (arity 2 -> 1)
                F32Lt => visit_f32_lt (arity 2 -> 1)
                F32Gt => visit_f32_gt (arity 2 -> 1)
                F32Le => visit_f32_le (arity 2 -> 1)
                F32Ge => visit_f32_ge (arity 2 -> 1)
                F64Eq => visit_f64_eq (arity 2 -> 1)
                F64Ne => visit_f64_ne (arity 2 -> 1)
                F64Lt => visit_f64_lt (arity 2 -> 1)
                F64Gt => visit_f64_gt (arity 2 -> 1)
                F64Le => visit_f64_le (arity 2 -> 1)
                F64Ge => visit_f64_ge (arity 2 -> 1)
                I32Clz => visit_i32_clz (arity 1 -> 1)
                I32Ctz => visit_i32_ctz (arity 1 -> 1)
                I32Popcnt => visit_i32_popcnt (arity 1 -> 1)
                I32Add => visit_i32_add (arity 2 -> 1)
                I32Sub => visit_i32_sub (arity 2 -> 1)
                I32Mul => visit_i32_mul (arity 2 -> 1)
                I32DivS => visit_i32_div_s (arity 2 -> 1)
                I32DivU => visit_i32_div_u (arity 2 -> 1)
                I32RemS => visit_i32_rem_s (arity 2 -> 1)
                I32RemU => visit_i32_rem_u (arity 2 -> 1)
                I32And => visit_i32_and (arity 2 -> 1)
                I32Or => visit_i32_or (arity 2 -> 1)
                I32Xor => visit_i32_xor (arity 2 -> 1)
                I32Shl => visit_i32_shl (arity 2 -> 1)
                I32ShrS => visit_i32_shr_s (arity 2 -> 1)
                I32ShrU => visit_i32_shr_u (arity 2 -> 1)
                I32Rotl => visit_i32_rotl (arity 2 -> 1)
                I32Rotr => visit_i32_rotr (arity 2 -> 1)
                I64Clz => visit_i64_clz (arity 1 -> 1)
                I64Ctz => visit_i64_ctz (arity 1 -> 1)
                I64Popcnt => visit_i64_popcnt (arity 1 -> 1)
                I64Add => visit_i64_add (arity 2 -> 1)
                I64Sub => visit_i64_sub (arity 2 -> 1)
                I64Mul => visit_i64_mul (arity 2 -> 1)
                I64DivS => visit_i64_div_s (arity 2 -> 1)
                I64DivU => visit_i64_div_u (arity 2 -> 1)
                I64RemS => visit_i64_rem_s (arity 2 -> 1)
                I64RemU => visit_i64_rem_u (arity 2 -> 1)
                I64And => visit_i64_and (arity 2 -> 1)
                I64Or => visit_i64_or (arity 2 -> 1)
                I64Xor => visit_i64_xor (arity 2 -> 1)
                I64Shl => visit_i64_shl (arity 2 -> 1)
                I64ShrS => visit_i64_shr_s (arity 2 -> 1)
                I64ShrU => visit_i64_shr_u (arity 2 -> 1)
                I64Rotl => visit_i64_rotl (arity 2 -> 1)
                I64Rotr => visit_i64_rotr (arity 2 -> 1)
                F32Abs => visit_f32_abs (arity 1 -> 1)
                F32Neg => visit_f32_neg (arity 1 -> 1)
                F32Ceil => visit_f32_ceil (arity 1 -> 1)
                F32Floor => visit_f32_floor (arity 1 -> 1)
                F32Trunc => visit_f32_trunc (arity 1 -> 1)
                F32Nearest => visit_f32_nearest (arity 1 -> 1)
                F32Sqrt => visit_f32_sqrt (arity 1 -> 1)
                F32Add => visit_f32_add (arity 2 -> 1)
                F32Sub => visit_f32_sub (arity 2 -> 1)
                F32Mul => visit_f32_mul (arity 2 -> 1)
                F32Div => visit_f32_div (arity 2 -> 1)
                F32Min => visit_f32_min (arity 2 -> 1)
                F32Max => visit_f32_max (arity 2 -> 1)
                F32Copysign => visit_f32_copysign (arity 2 -> 1)
                F64Abs => visit_f64_abs (arity 1 -> 1)
                F64Neg => visit_f64_neg (arity 1 -> 1)
                F64Ceil => visit_f64_ceil (arity 1 -> 1)
                F64Floor => visit_f64_floor (arity 1 -> 1)
                F64Trunc => visit_f64_trunc (arity 1 -> 1)
                F64Nearest => visit_f64_nearest (arity 1 -> 1)
                F64Sqrt => visit_f64_sqrt (arity 1 -> 1)
                F64Add => visit_f64_add (arity 2 -> 1)
                F64Sub => visit_f64_sub (arity 2 -> 1)
                F64Mul => visit_f64_mul (arity 2 -> 1)
                F64Div => visit_f64_div (arity 2 -> 1)
                F64Min => visit_f64_min (arity 2 -> 1)
                F64Max => visit_f64_max (arity 2 -> 1)
                F64Copysign => visit_f64_copysign (arity 2 -> 1)
                I32WrapI64 => visit_i32_wrap_i64 (arity 1 -> 1)
                I32TruncF32S => visit_i32_trunc_f32_s (arity 1 -> 1)
                I32TruncF32U => visit_i32_trunc_f32_u (arity 1 -> 1)
                I32TruncF64S => visit_i32_trunc_f64_s (arity 1 -> 1)
                I32TruncF64U => visit_i32_trunc_f64_u (arity 1 -> 1)
                I64ExtendI32S => visit_i64_extend_i32_s (arity 1 -> 1)
                I64ExtendI32U => visit_i64_extend_i32_u (arity 1 -> 1)
                I64TruncF32S => visit_i64_trunc_f32_s (arity 1 -> 1)
                I64TruncF32U => visit_i64_trunc_f32_u (arity 1 -> 1)
                I64TruncF64S => visit_i64_trunc_f64_s (arity 1 -> 1)
                I64TruncF64U => visit_i64_trunc_f64_u (arity 1 -> 1)
                F32ConvertI32S => visit_f32_convert_i32_s (arity 1 -> 1)
                F32ConvertI32U => visit_f32_convert_i32_u (arity 1 -> 1)
                F32ConvertI64S => visit_f32_convert_i64_s (arity 1 -> 1)
                F32ConvertI64U => visit_f32_convert_i64_u (arity 1 -> 1)
                F32DemoteF64 => visit_f32_demote_f64 (arity 1 -> 1)
                F64ConvertI32S => visit_f64_convert_i32_s (arity 1 -> 1)
                F64ConvertI32U => visit_f64_convert_i32_u (arity 1 -> 1)
                F64ConvertI64S => visit_f64_convert_i64_s (arity 1 -> 1)
                F64ConvertI64U => visit_f64_convert_i64_u (arity 1 -> 1)
                F64PromoteF32 => visit_f64_promote_f32 (arity 1 -> 1)
                I32ReinterpretF32 => visit_i32_reinterpret_f32 (arity 1 -> 1)
                I64ReinterpretF64 => visit_i64_reinterpret_f64 (arity 1 -> 1)
                F32ReinterpretI32 => visit_f32_reinterpret_i32 (arity 1 -> 1)
                F64ReinterpretI64 => visit_f64_reinterpret_i64 (arity 1 -> 1)
            }

            @sign_extension {
                I32Extend8S => visit_i32_extend8_s (arity 1 -> 1)
                I32Extend16S => visit_i32_extend16_s (arity 1 -> 1)
                I64Extend8S => visit_i64_extend8_s (arity 1 -> 1)
                I64Extend16S => visit_i64_extend16_s (arity 1 -> 1)
                I64Extend32S => visit_i64_extend32_s (arity 1 -> 1)
            }

            // 0xFB prefixed operators
            // Garbage Collection
            // http://github.com/WebAssembly/gc
            @gc {
                RefEq => visit_ref_eq (arity 2 -> 1)
                StructNew { struct_type_index: u32 } => visit_struct_new (arity custom)
                StructNewDefault { struct_type_index: u32 } => visit_struct_new_default (arity 0 -> 1)
                StructGet { struct_type_index: u32, field_index: u32 } => visit_struct_get (arity 1 -> 1)
                StructGetS { struct_type_index: u32, field_index: u32 } => visit_struct_get_s (arity 1 -> 1)
                StructGetU { struct_type_index: u32, field_index: u32 } => visit_struct_get_u (arity 1 -> 1)
                StructSet { struct_type_index: u32, field_index: u32 } => visit_struct_set (arity 2 -> 0)
                ArrayNew { array_type_index: u32 } => visit_array_new (arity 2 -> 1)
                ArrayNewDefault { array_type_index: u32 } => visit_array_new_default (arity 1 -> 1)
                ArrayNewFixed { array_type_index: u32, array_size: u32 } => visit_array_new_fixed (arity custom)
                ArrayNewData { array_type_index: u32, array_data_index: u32 } => visit_array_new_data (arity 2 -> 1)
                ArrayNewElem { array_type_index: u32, array_elem_index: u32 } => visit_array_new_elem (arity 2 -> 1)
                ArrayGet { array_type_index: u32 } => visit_array_get (arity 2 -> 1)
                ArrayGetS { array_type_index: u32 } => visit_array_get_s (arity 2 -> 1)
                ArrayGetU { array_type_index: u32 } => visit_array_get_u (arity 2 -> 1)
                ArraySet { array_type_index: u32 } => visit_array_set (arity 3 -> 0)
                ArrayLen => visit_array_len (arity 1 -> 1)
                ArrayFill { array_type_index: u32 } => visit_array_fill (arity 4 -> 0)
                ArrayCopy { array_type_index_dst: u32, array_type_index_src: u32 } => visit_array_copy (arity 5 -> 0)
                ArrayInitData { array_type_index: u32, array_data_index: u32 } => visit_array_init_data (arity 4 -> 0)
                ArrayInitElem { array_type_index: u32, array_elem_index: u32 } => visit_array_init_elem (arity 4 -> 0)
                RefTestNonNull { hty: $crate::HeapType } => visit_ref_test_non_null (arity 1 -> 1)
                RefTestNullable { hty: $crate::HeapType } => visit_ref_test_nullable (arity 1 -> 1)
                RefCastNonNull { hty: $crate::HeapType } => visit_ref_cast_non_null (arity 1 -> 1)
                RefCastNullable { hty: $crate::HeapType } => visit_ref_cast_nullable (arity 1 -> 1)
                BrOnCast {
                    relative_depth: u32,
                    from_ref_type: $crate::RefType,
                    to_ref_type: $crate::RefType
                } => visit_br_on_cast (arity custom)
                BrOnCastFail {
                    relative_depth: u32,
                    from_ref_type: $crate::RefType,
                    to_ref_type: $crate::RefType
                } => visit_br_on_cast_fail (arity custom)
                AnyConvertExtern => visit_any_convert_extern  (arity 1 -> 1)
                ExternConvertAny => visit_extern_convert_any (arity 1 -> 1)
                RefI31 => visit_ref_i31 (arity 1 -> 1)
                I31GetS => visit_i31_get_s (arity 1 -> 1)
                I31GetU => visit_i31_get_u (arity 1 -> 1)
            }

            @custom_descriptors {
                StructNewDesc { struct_type_index: u32 } => visit_struct_new_desc (arity custom)
                StructNewDefaultDesc { struct_type_index: u32 } => visit_struct_new_default_desc (arity 1 -> 1)
                RefGetDesc { type_index: u32 } => visit_ref_get_desc (arity 1 -> 1)
                RefCastDescNonNull { hty: $crate::HeapType } => visit_ref_cast_desc_non_null (arity 2 -> 1)
                RefCastDescNullable { hty: $crate::HeapType } => visit_ref_cast_desc_nullable (arity 2 -> 1)
                BrOnCastDesc {
                    relative_depth: u32,
                    from_ref_type: $crate::RefType,
                    to_ref_type: $crate::RefType
                } => visit_br_on_cast_desc (arity custom)
                BrOnCastDescFail {
                    relative_depth: u32,
                    from_ref_type: $crate::RefType,
                    to_ref_type: $crate::RefType
                } => visit_br_on_cast_desc_fail (arity custom)
            }

            // 0xFC operators
            // Non-trapping Float-to-int Conversions
            // https://github.com/WebAssembly/nontrapping-float-to-int-conversions
            @saturating_float_to_int {
                I32TruncSatF32S => visit_i32_trunc_sat_f32_s (arity 1 -> 1)
                I32TruncSatF32U => visit_i32_trunc_sat_f32_u (arity 1 -> 1)
                I32TruncSatF64S => visit_i32_trunc_sat_f64_s (arity 1 -> 1)
                I32TruncSatF64U => visit_i32_trunc_sat_f64_u (arity 1 -> 1)
                I64TruncSatF32S => visit_i64_trunc_sat_f32_s (arity 1 -> 1)
                I64TruncSatF32U => visit_i64_trunc_sat_f32_u (arity 1 -> 1)
                I64TruncSatF64S => visit_i64_trunc_sat_f64_s (arity 1 -> 1)
                I64TruncSatF64U => visit_i64_trunc_sat_f64_u (arity 1 -> 1)
            }

            // 0xFC prefixed operators
            // bulk memory operations
            // https://github.com/WebAssembly/bulk-memory-operations
            @bulk_memory {
                MemoryInit { data_index: u32, mem: u32 } => visit_memory_init (arity 3 -> 0)
                DataDrop { data_index: u32 } => visit_data_drop (arity 0 -> 0)
                MemoryCopy { dst_mem: u32, src_mem: u32 } => visit_memory_copy (arity 3 -> 0)
                MemoryFill { mem: u32 } => visit_memory_fill (arity 3 -> 0)
                TableInit { elem_index: u32, table: u32 } => visit_table_init (arity 3 -> 0)
                ElemDrop { elem_index: u32 } => visit_elem_drop (arity 0 -> 0)
                TableCopy { dst_table: u32, src_table: u32 } => visit_table_copy (arity 3 -> 0)
            }

            // 0xFC prefixed operators
            // reference-types
            // https://github.com/WebAssembly/reference-types
            @reference_types {
                TypedSelect { ty: $crate::ValType } => visit_typed_select (arity 3 -> 1)
                // multi-result select is currently invalid, but can be parsed and printed
                TypedSelectMulti { tys: Vec<$crate::ValType> } => visit_typed_select_multi (arity custom)
                RefNull { hty: $crate::HeapType } => visit_ref_null (arity 0 -> 1)
                RefIsNull => visit_ref_is_null (arity 1 -> 1)
                RefFunc { function_index: u32 } => visit_ref_func (arity 0 -> 1)
                TableFill { table: u32 } => visit_table_fill (arity 3 -> 0)
                TableGet { table: u32 } => visit_table_get (arity 1 -> 1)
                TableSet { table: u32 } => visit_table_set (arity 2 -> 0)
                TableGrow { table: u32 } => visit_table_grow (arity 2 -> 1)
                TableSize { table: u32 } => visit_table_size (arity 0 -> 1)
            }

            // Wasm tail-call proposal
            // https://github.com/WebAssembly/tail-call
            @tail_call {
                ReturnCall { function_index: u32 } => visit_return_call (arity custom)
                ReturnCallIndirect { type_index: u32, table_index: u32 } => visit_return_call_indirect (arity custom)
            }

            // OxFC prefixed operators
            // memory control (experimental)
            // https://github.com/WebAssembly/design/issues/1439
            @memory_control {
                MemoryDiscard { mem: u32 } => visit_memory_discard (arity 2 -> 0)
            }

            // 0xFE prefixed operators
            // threads
            // https://github.com/WebAssembly/threads
            @threads {
                MemoryAtomicNotify { memarg: $crate::MemArg } => visit_memory_atomic_notify (arity 2 -> 1)
                MemoryAtomicWait32 { memarg: $crate::MemArg } => visit_memory_atomic_wait32 (arity 3 -> 1)
                MemoryAtomicWait64 { memarg: $crate::MemArg } => visit_memory_atomic_wait64 (arity 3 -> 1)
                AtomicFence => visit_atomic_fence (arity 0 -> 0)
                I32AtomicLoad { memarg: $crate::MemArg } => visit_i32_atomic_load (arity 1 -> 1)
                I64AtomicLoad { memarg: $crate::MemArg } => visit_i64_atomic_load (arity 1 -> 1)
                I32AtomicLoad8U { memarg: $crate::MemArg } => visit_i32_atomic_load8_u (arity 1 -> 1)
                I32AtomicLoad16U { memarg: $crate::MemArg } => visit_i32_atomic_load16_u (arity 1 -> 1)
                I64AtomicLoad8U { memarg: $crate::MemArg } => visit_i64_atomic_load8_u (arity 1 -> 1)
                I64AtomicLoad16U { memarg: $crate::MemArg } => visit_i64_atomic_load16_u (arity 1 -> 1)
                I64AtomicLoad32U { memarg: $crate::MemArg } => visit_i64_atomic_load32_u (arity 1 -> 1)
                I32AtomicStore { memarg: $crate::MemArg } => visit_i32_atomic_store (arity 2 -> 0)
                I64AtomicStore { memarg: $crate::MemArg } => visit_i64_atomic_store (arity 2 -> 0)
                I32AtomicStore8 { memarg: $crate::MemArg } => visit_i32_atomic_store8 (arity 2 -> 0)
                I32AtomicStore16 { memarg: $crate::MemArg } => visit_i32_atomic_store16 (arity 2 -> 0)
                I64AtomicStore8 { memarg: $crate::MemArg } => visit_i64_atomic_store8 (arity 2 -> 0)
                I64AtomicStore16 { memarg: $crate::MemArg } => visit_i64_atomic_store16 (arity 2 -> 0)
                I64AtomicStore32 { memarg: $crate::MemArg } => visit_i64_atomic_store32 (arity 2 -> 0)
                I32AtomicRmwAdd { memarg: $crate::MemArg } => visit_i32_atomic_rmw_add (arity 2 -> 1)
                I64AtomicRmwAdd { memarg: $crate::MemArg } => visit_i64_atomic_rmw_add (arity 2 -> 1)
                I32AtomicRmw8AddU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_add_u (arity 2 -> 1)
                I32AtomicRmw16AddU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_add_u (arity 2 -> 1)
                I64AtomicRmw8AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_add_u (arity 2 -> 1)
                I64AtomicRmw16AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_add_u (arity 2 -> 1)
                I64AtomicRmw32AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_add_u (arity 2 -> 1)
                I32AtomicRmwSub { memarg: $crate::MemArg } => visit_i32_atomic_rmw_sub (arity 2 -> 1)
                I64AtomicRmwSub { memarg: $crate::MemArg } => visit_i64_atomic_rmw_sub (arity 2 -> 1)
                I32AtomicRmw8SubU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_sub_u (arity 2 -> 1)
                I32AtomicRmw16SubU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_sub_u (arity 2 -> 1)
                I64AtomicRmw8SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_sub_u (arity 2 -> 1)
                I64AtomicRmw16SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_sub_u (arity 2 -> 1)
                I64AtomicRmw32SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_sub_u (arity 2 -> 1)
                I32AtomicRmwAnd { memarg: $crate::MemArg } => visit_i32_atomic_rmw_and (arity 2 -> 1)
                I64AtomicRmwAnd { memarg: $crate::MemArg } => visit_i64_atomic_rmw_and (arity 2 -> 1)
                I32AtomicRmw8AndU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_and_u (arity 2 -> 1)
                I32AtomicRmw16AndU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_and_u (arity 2 -> 1)
                I64AtomicRmw8AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_and_u (arity 2 -> 1)
                I64AtomicRmw16AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_and_u (arity 2 -> 1)
                I64AtomicRmw32AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_and_u (arity 2 -> 1)
                I32AtomicRmwOr { memarg: $crate::MemArg } => visit_i32_atomic_rmw_or (arity 2 -> 1)
                I64AtomicRmwOr { memarg: $crate::MemArg } => visit_i64_atomic_rmw_or (arity 2 -> 1)
                I32AtomicRmw8OrU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_or_u (arity 2 -> 1)
                I32AtomicRmw16OrU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_or_u (arity 2 -> 1)
                I64AtomicRmw8OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_or_u (arity 2 -> 1)
                I64AtomicRmw16OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_or_u (arity 2 -> 1)
                I64AtomicRmw32OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_or_u (arity 2 -> 1)
                I32AtomicRmwXor { memarg: $crate::MemArg } => visit_i32_atomic_rmw_xor (arity 2 -> 1)
                I64AtomicRmwXor { memarg: $crate::MemArg } => visit_i64_atomic_rmw_xor (arity 2 -> 1)
                I32AtomicRmw8XorU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_xor_u (arity 2 -> 1)
                I32AtomicRmw16XorU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_xor_u (arity 2 -> 1)
                I64AtomicRmw8XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_xor_u (arity 2 -> 1)
                I64AtomicRmw16XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_xor_u (arity 2 -> 1)
                I64AtomicRmw32XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_xor_u (arity 2 -> 1)
                I32AtomicRmwXchg { memarg: $crate::MemArg } => visit_i32_atomic_rmw_xchg (arity 2 -> 1)
                I64AtomicRmwXchg { memarg: $crate::MemArg } => visit_i64_atomic_rmw_xchg (arity 2 -> 1)
                I32AtomicRmw8XchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_xchg_u (arity 2 -> 1)
                I32AtomicRmw16XchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_xchg_u (arity 2 -> 1)
                I64AtomicRmw8XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_xchg_u (arity 2 -> 1)
                I64AtomicRmw16XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_xchg_u (arity 2 -> 1)
                I64AtomicRmw32XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_xchg_u (arity 2 -> 1)
                I32AtomicRmwCmpxchg { memarg: $crate::MemArg } => visit_i32_atomic_rmw_cmpxchg (arity 3 -> 1)
                I64AtomicRmwCmpxchg { memarg: $crate::MemArg } => visit_i64_atomic_rmw_cmpxchg (arity 3 -> 1)
                I32AtomicRmw8CmpxchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_cmpxchg_u (arity 3 -> 1)
                I32AtomicRmw16CmpxchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_cmpxchg_u (arity 3 -> 1)
                I64AtomicRmw8CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_cmpxchg_u (arity 3 -> 1)
                I64AtomicRmw16CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_cmpxchg_u (arity 3 -> 1)
                I64AtomicRmw32CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_cmpxchg_u (arity 3 -> 1)
            }

            // 0xFD operators
            // 128-bit SIMD
            // - https://github.com/webassembly/simd
            // - https://webassembly.github.io/simd/core/binary/instructions.html
            @simd {
                V128Load { memarg: $crate::MemArg } => visit_v128_load (arity 1 -> 1)
                V128Load8x8S { memarg: $crate::MemArg } => visit_v128_load8x8_s (arity 1 -> 1)
                V128Load8x8U { memarg: $crate::MemArg } => visit_v128_load8x8_u (arity 1 -> 1)
                V128Load16x4S { memarg: $crate::MemArg } => visit_v128_load16x4_s (arity 1 -> 1)
                V128Load16x4U { memarg: $crate::MemArg } => visit_v128_load16x4_u (arity 1 -> 1)
                V128Load32x2S { memarg: $crate::MemArg } => visit_v128_load32x2_s (arity 1 -> 1)
                V128Load32x2U { memarg: $crate::MemArg } => visit_v128_load32x2_u (arity 1 -> 1)
                V128Load8Splat { memarg: $crate::MemArg } => visit_v128_load8_splat (arity 1 -> 1)
                V128Load16Splat { memarg: $crate::MemArg } => visit_v128_load16_splat (arity 1 -> 1)
                V128Load32Splat { memarg: $crate::MemArg } => visit_v128_load32_splat (arity 1 -> 1)
                V128Load64Splat { memarg: $crate::MemArg } => visit_v128_load64_splat (arity 1 -> 1)
                V128Load32Zero { memarg: $crate::MemArg } => visit_v128_load32_zero (arity 1 -> 1)
                V128Load64Zero { memarg: $crate::MemArg } => visit_v128_load64_zero (arity 1 -> 1)
                V128Store { memarg: $crate::MemArg } => visit_v128_store (arity 2 -> 0)
                V128Load8Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load8_lane (arity 2 -> 1)
                V128Load16Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load16_lane (arity 2 -> 1)
                V128Load32Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load32_lane (arity 2 -> 1)
                V128Load64Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load64_lane (arity 2 -> 1)
                V128Store8Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store8_lane (arity 2 -> 0)
                V128Store16Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store16_lane (arity 2 -> 0)
                V128Store32Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store32_lane (arity 2 -> 0)
                V128Store64Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store64_lane (arity 2 -> 0)
                V128Const { value: $crate::V128 } => visit_v128_const (arity 0 -> 1)
                I8x16Shuffle { lanes: [u8; 16] } => visit_i8x16_shuffle (arity 2 -> 1)
                I8x16ExtractLaneS { lane: u8 } => visit_i8x16_extract_lane_s (arity 1 -> 1)
                I8x16ExtractLaneU { lane: u8 } => visit_i8x16_extract_lane_u (arity 1 -> 1)
                I8x16ReplaceLane { lane: u8 } => visit_i8x16_replace_lane (arity 2 -> 1)
                I16x8ExtractLaneS { lane: u8 } => visit_i16x8_extract_lane_s (arity 1 -> 1)
                I16x8ExtractLaneU { lane: u8 } => visit_i16x8_extract_lane_u (arity 1 -> 1)
                I16x8ReplaceLane { lane: u8 } => visit_i16x8_replace_lane (arity 2 -> 1)
                I32x4ExtractLane { lane: u8 } => visit_i32x4_extract_lane (arity 1 -> 1)
                I32x4ReplaceLane { lane: u8 } => visit_i32x4_replace_lane (arity 2 -> 1)
                I64x2ExtractLane { lane: u8 } => visit_i64x2_extract_lane (arity 1 -> 1)
                I64x2ReplaceLane { lane: u8 } => visit_i64x2_replace_lane (arity 2 -> 1)
                F32x4ExtractLane { lane: u8 } => visit_f32x4_extract_lane (arity 1 -> 1)
                F32x4ReplaceLane { lane: u8 } => visit_f32x4_replace_lane (arity 2 -> 1)
                F64x2ExtractLane { lane: u8 } => visit_f64x2_extract_lane (arity 1 -> 1)
                F64x2ReplaceLane { lane: u8 } => visit_f64x2_replace_lane (arity 2 -> 1)
                I8x16Swizzle => visit_i8x16_swizzle (arity 2 -> 1)
                I8x16Splat => visit_i8x16_splat (arity 1 -> 1)
                I16x8Splat => visit_i16x8_splat (arity 1 -> 1)
                I32x4Splat => visit_i32x4_splat (arity 1 -> 1)
                I64x2Splat => visit_i64x2_splat (arity 1 -> 1)
                F32x4Splat => visit_f32x4_splat (arity 1 -> 1)
                F64x2Splat => visit_f64x2_splat (arity 1 -> 1)
                I8x16Eq => visit_i8x16_eq (arity 2 -> 1)
                I8x16Ne => visit_i8x16_ne (arity 2 -> 1)
                I8x16LtS => visit_i8x16_lt_s (arity 2 -> 1)
                I8x16LtU => visit_i8x16_lt_u (arity 2 -> 1)
                I8x16GtS => visit_i8x16_gt_s (arity 2 -> 1)
                I8x16GtU => visit_i8x16_gt_u (arity 2 -> 1)
                I8x16LeS => visit_i8x16_le_s (arity 2 -> 1)
                I8x16LeU => visit_i8x16_le_u (arity 2 -> 1)
                I8x16GeS => visit_i8x16_ge_s (arity 2 -> 1)
                I8x16GeU => visit_i8x16_ge_u (arity 2 -> 1)
                I16x8Eq => visit_i16x8_eq (arity 2 -> 1)
                I16x8Ne => visit_i16x8_ne (arity 2 -> 1)
                I16x8LtS => visit_i16x8_lt_s (arity 2 -> 1)
                I16x8LtU => visit_i16x8_lt_u (arity 2 -> 1)
                I16x8GtS => visit_i16x8_gt_s (arity 2 -> 1)
                I16x8GtU => visit_i16x8_gt_u (arity 2 -> 1)
                I16x8LeS => visit_i16x8_le_s (arity 2 -> 1)
                I16x8LeU => visit_i16x8_le_u (arity 2 -> 1)
                I16x8GeS => visit_i16x8_ge_s (arity 2 -> 1)
                I16x8GeU => visit_i16x8_ge_u (arity 2 -> 1)
                I32x4Eq => visit_i32x4_eq (arity 2 -> 1)
                I32x4Ne => visit_i32x4_ne (arity 2 -> 1)
                I32x4LtS => visit_i32x4_lt_s (arity 2 -> 1)
                I32x4LtU => visit_i32x4_lt_u (arity 2 -> 1)
                I32x4GtS => visit_i32x4_gt_s (arity 2 -> 1)
                I32x4GtU => visit_i32x4_gt_u (arity 2 -> 1)
                I32x4LeS => visit_i32x4_le_s (arity 2 -> 1)
                I32x4LeU => visit_i32x4_le_u (arity 2 -> 1)
                I32x4GeS => visit_i32x4_ge_s (arity 2 -> 1)
                I32x4GeU => visit_i32x4_ge_u (arity 2 -> 1)
                I64x2Eq => visit_i64x2_eq (arity 2 -> 1)
                I64x2Ne => visit_i64x2_ne (arity 2 -> 1)
                I64x2LtS => visit_i64x2_lt_s (arity 2 -> 1)
                I64x2GtS => visit_i64x2_gt_s (arity 2 -> 1)
                I64x2LeS => visit_i64x2_le_s (arity 2 -> 1)
                I64x2GeS => visit_i64x2_ge_s (arity 2 -> 1)
                F32x4Eq => visit_f32x4_eq (arity 2 -> 1)
                F32x4Ne => visit_f32x4_ne (arity 2 -> 1)
                F32x4Lt => visit_f32x4_lt (arity 2 -> 1)
                F32x4Gt => visit_f32x4_gt (arity 2 -> 1)
                F32x4Le => visit_f32x4_le (arity 2 -> 1)
                F32x4Ge => visit_f32x4_ge (arity 2 -> 1)
                F64x2Eq => visit_f64x2_eq (arity 2 -> 1)
                F64x2Ne => visit_f64x2_ne (arity 2 -> 1)
                F64x2Lt => visit_f64x2_lt (arity 2 -> 1)
                F64x2Gt => visit_f64x2_gt (arity 2 -> 1)
                F64x2Le => visit_f64x2_le (arity 2 -> 1)
                F64x2Ge => visit_f64x2_ge (arity 2 -> 1)
                V128Not => visit_v128_not (arity 1 -> 1)
                V128And => visit_v128_and (arity 2 -> 1)
                V128AndNot => visit_v128_andnot (arity 2 -> 1)
                V128Or => visit_v128_or (arity 2 -> 1)
                V128Xor => visit_v128_xor (arity 2 -> 1)
                V128Bitselect => visit_v128_bitselect (arity 3 -> 1)
                V128AnyTrue => visit_v128_any_true (arity 1 -> 1)
                I8x16Abs => visit_i8x16_abs (arity 1 -> 1)
                I8x16Neg => visit_i8x16_neg (arity 1 -> 1)
                I8x16Popcnt => visit_i8x16_popcnt (arity 1 -> 1)
                I8x16AllTrue => visit_i8x16_all_true (arity 1 -> 1)
                I8x16Bitmask => visit_i8x16_bitmask (arity 1 -> 1)
                I8x16NarrowI16x8S => visit_i8x16_narrow_i16x8_s (arity 2 -> 1)
                I8x16NarrowI16x8U => visit_i8x16_narrow_i16x8_u (arity 2 -> 1)
                I8x16Shl => visit_i8x16_shl (arity 2 -> 1)
                I8x16ShrS => visit_i8x16_shr_s (arity 2 -> 1)
                I8x16ShrU => visit_i8x16_shr_u (arity 2 -> 1)
                I8x16Add => visit_i8x16_add (arity 2 -> 1)
                I8x16AddSatS => visit_i8x16_add_sat_s (arity 2 -> 1)
                I8x16AddSatU => visit_i8x16_add_sat_u (arity 2 -> 1)
                I8x16Sub => visit_i8x16_sub (arity 2 -> 1)
                I8x16SubSatS => visit_i8x16_sub_sat_s (arity 2 -> 1)
                I8x16SubSatU => visit_i8x16_sub_sat_u (arity 2 -> 1)
                I8x16MinS => visit_i8x16_min_s (arity 2 -> 1)
                I8x16MinU => visit_i8x16_min_u (arity 2 -> 1)
                I8x16MaxS => visit_i8x16_max_s (arity 2 -> 1)
                I8x16MaxU => visit_i8x16_max_u (arity 2 -> 1)
                I8x16AvgrU => visit_i8x16_avgr_u (arity 2 -> 1)
                I16x8ExtAddPairwiseI8x16S => visit_i16x8_extadd_pairwise_i8x16_s (arity 1 -> 1)
                I16x8ExtAddPairwiseI8x16U => visit_i16x8_extadd_pairwise_i8x16_u (arity 1 -> 1)
                I16x8Abs => visit_i16x8_abs (arity 1 -> 1)
                I16x8Neg => visit_i16x8_neg (arity 1 -> 1)
                I16x8Q15MulrSatS => visit_i16x8_q15mulr_sat_s (arity 2 -> 1)
                I16x8AllTrue => visit_i16x8_all_true (arity 1 -> 1)
                I16x8Bitmask => visit_i16x8_bitmask (arity 1 -> 1)
                I16x8NarrowI32x4S => visit_i16x8_narrow_i32x4_s (arity 2 -> 1)
                I16x8NarrowI32x4U => visit_i16x8_narrow_i32x4_u (arity 2 -> 1)
                I16x8ExtendLowI8x16S => visit_i16x8_extend_low_i8x16_s (arity 1 -> 1)
                I16x8ExtendHighI8x16S => visit_i16x8_extend_high_i8x16_s (arity 1 -> 1)
                I16x8ExtendLowI8x16U => visit_i16x8_extend_low_i8x16_u (arity 1 -> 1)
                I16x8ExtendHighI8x16U => visit_i16x8_extend_high_i8x16_u (arity 1 -> 1)
                I16x8Shl => visit_i16x8_shl (arity 2 -> 1)
                I16x8ShrS => visit_i16x8_shr_s (arity 2 -> 1)
                I16x8ShrU => visit_i16x8_shr_u (arity 2 -> 1)
                I16x8Add => visit_i16x8_add (arity 2 -> 1)
                I16x8AddSatS => visit_i16x8_add_sat_s (arity 2 -> 1)
                I16x8AddSatU => visit_i16x8_add_sat_u (arity 2 -> 1)
                I16x8Sub => visit_i16x8_sub (arity 2 -> 1)
                I16x8SubSatS => visit_i16x8_sub_sat_s (arity 2 -> 1)
                I16x8SubSatU => visit_i16x8_sub_sat_u (arity 2 -> 1)
                I16x8Mul => visit_i16x8_mul (arity 2 -> 1)
                I16x8MinS => visit_i16x8_min_s (arity 2 -> 1)
                I16x8MinU => visit_i16x8_min_u (arity 2 -> 1)
                I16x8MaxS => visit_i16x8_max_s (arity 2 -> 1)
                I16x8MaxU => visit_i16x8_max_u (arity 2 -> 1)
                I16x8AvgrU => visit_i16x8_avgr_u (arity 2 -> 1)
                I16x8ExtMulLowI8x16S => visit_i16x8_extmul_low_i8x16_s (arity 2 -> 1)
                I16x8ExtMulHighI8x16S => visit_i16x8_extmul_high_i8x16_s (arity 2 -> 1)
                I16x8ExtMulLowI8x16U => visit_i16x8_extmul_low_i8x16_u (arity 2 -> 1)
                I16x8ExtMulHighI8x16U => visit_i16x8_extmul_high_i8x16_u (arity 2 -> 1)
                I32x4ExtAddPairwiseI16x8S => visit_i32x4_extadd_pairwise_i16x8_s (arity 1 -> 1)
                I32x4ExtAddPairwiseI16x8U => visit_i32x4_extadd_pairwise_i16x8_u (arity 1 -> 1)
                I32x4Abs => visit_i32x4_abs (arity 1 -> 1)
                I32x4Neg => visit_i32x4_neg (arity 1 -> 1)
                I32x4AllTrue => visit_i32x4_all_true (arity 1 -> 1)
                I32x4Bitmask => visit_i32x4_bitmask (arity 1 -> 1)
                I32x4ExtendLowI16x8S => visit_i32x4_extend_low_i16x8_s (arity 1 -> 1)
                I32x4ExtendHighI16x8S => visit_i32x4_extend_high_i16x8_s (arity 1 -> 1)
                I32x4ExtendLowI16x8U => visit_i32x4_extend_low_i16x8_u (arity 1 -> 1)
                I32x4ExtendHighI16x8U => visit_i32x4_extend_high_i16x8_u (arity 1 -> 1)
                I32x4Shl => visit_i32x4_shl (arity 2 -> 1)
                I32x4ShrS => visit_i32x4_shr_s (arity 2 -> 1)
                I32x4ShrU => visit_i32x4_shr_u (arity 2 -> 1)
                I32x4Add => visit_i32x4_add (arity 2 -> 1)
                I32x4Sub => visit_i32x4_sub (arity 2 -> 1)
                I32x4Mul => visit_i32x4_mul (arity 2 -> 1)
                I32x4MinS => visit_i32x4_min_s (arity 2 -> 1)
                I32x4MinU => visit_i32x4_min_u (arity 2 -> 1)
                I32x4MaxS => visit_i32x4_max_s (arity 2 -> 1)
                I32x4MaxU => visit_i32x4_max_u (arity 2 -> 1)
                I32x4DotI16x8S => visit_i32x4_dot_i16x8_s (arity 2 -> 1)
                I32x4ExtMulLowI16x8S => visit_i32x4_extmul_low_i16x8_s (arity 2 -> 1)
                I32x4ExtMulHighI16x8S => visit_i32x4_extmul_high_i16x8_s (arity 2 -> 1)
                I32x4ExtMulLowI16x8U => visit_i32x4_extmul_low_i16x8_u (arity 2 -> 1)
                I32x4ExtMulHighI16x8U => visit_i32x4_extmul_high_i16x8_u (arity 2 -> 1)
                I64x2Abs => visit_i64x2_abs (arity 1 -> 1)
                I64x2Neg => visit_i64x2_neg (arity 1 -> 1)
                I64x2AllTrue => visit_i64x2_all_true (arity 1 -> 1)
                I64x2Bitmask => visit_i64x2_bitmask (arity 1 -> 1)
                I64x2ExtendLowI32x4S => visit_i64x2_extend_low_i32x4_s (arity 1 -> 1)
                I64x2ExtendHighI32x4S => visit_i64x2_extend_high_i32x4_s (arity 1 -> 1)
                I64x2ExtendLowI32x4U => visit_i64x2_extend_low_i32x4_u (arity 1 -> 1)
                I64x2ExtendHighI32x4U => visit_i64x2_extend_high_i32x4_u (arity 1 -> 1)
                I64x2Shl => visit_i64x2_shl (arity 2 -> 1)
                I64x2ShrS => visit_i64x2_shr_s (arity 2 -> 1)
                I64x2ShrU => visit_i64x2_shr_u (arity 2 -> 1)
                I64x2Add => visit_i64x2_add (arity 2 -> 1)
                I64x2Sub => visit_i64x2_sub (arity 2 -> 1)
                I64x2Mul => visit_i64x2_mul (arity 2 -> 1)
                I64x2ExtMulLowI32x4S => visit_i64x2_extmul_low_i32x4_s (arity 2 -> 1)
                I64x2ExtMulHighI32x4S => visit_i64x2_extmul_high_i32x4_s (arity 2 -> 1)
                I64x2ExtMulLowI32x4U => visit_i64x2_extmul_low_i32x4_u (arity 2 -> 1)
                I64x2ExtMulHighI32x4U => visit_i64x2_extmul_high_i32x4_u (arity 2 -> 1)
                F32x4Ceil => visit_f32x4_ceil (arity 1 -> 1)
                F32x4Floor => visit_f32x4_floor (arity 1 -> 1)
                F32x4Trunc => visit_f32x4_trunc (arity 1 -> 1)
                F32x4Nearest => visit_f32x4_nearest (arity 1 -> 1)
                F32x4Abs => visit_f32x4_abs (arity 1 -> 1)
                F32x4Neg => visit_f32x4_neg (arity 1 -> 1)
                F32x4Sqrt => visit_f32x4_sqrt (arity 1 -> 1)
                F32x4Add => visit_f32x4_add (arity 2 -> 1)
                F32x4Sub => visit_f32x4_sub (arity 2 -> 1)
                F32x4Mul => visit_f32x4_mul (arity 2 -> 1)
                F32x4Div => visit_f32x4_div (arity 2 -> 1)
                F32x4Min => visit_f32x4_min (arity 2 -> 1)
                F32x4Max => visit_f32x4_max (arity 2 -> 1)
                F32x4PMin => visit_f32x4_pmin (arity 2 -> 1)
                F32x4PMax => visit_f32x4_pmax (arity 2 -> 1)
                F64x2Ceil => visit_f64x2_ceil (arity 1 -> 1)
                F64x2Floor => visit_f64x2_floor (arity 1 -> 1)
                F64x2Trunc => visit_f64x2_trunc (arity 1 -> 1)
                F64x2Nearest => visit_f64x2_nearest (arity 1 -> 1)
                F64x2Abs => visit_f64x2_abs (arity 1 -> 1)
                F64x2Neg => visit_f64x2_neg (arity 1 -> 1)
                F64x2Sqrt => visit_f64x2_sqrt (arity 1 -> 1)
                F64x2Add => visit_f64x2_add (arity 2 -> 1)
                F64x2Sub => visit_f64x2_sub (arity 2 -> 1)
                F64x2Mul => visit_f64x2_mul (arity 2 -> 1)
                F64x2Div => visit_f64x2_div (arity 2 -> 1)
                F64x2Min => visit_f64x2_min (arity 2 -> 1)
                F64x2Max => visit_f64x2_max (arity 2 -> 1)
                F64x2PMin => visit_f64x2_pmin (arity 2 -> 1)
                F64x2PMax => visit_f64x2_pmax (arity 2 -> 1)
                I32x4TruncSatF32x4S => visit_i32x4_trunc_sat_f32x4_s (arity 1 -> 1)
                I32x4TruncSatF32x4U => visit_i32x4_trunc_sat_f32x4_u (arity 1 -> 1)
                F32x4ConvertI32x4S => visit_f32x4_convert_i32x4_s (arity 1 -> 1)
                F32x4ConvertI32x4U => visit_f32x4_convert_i32x4_u (arity 1 -> 1)
                I32x4TruncSatF64x2SZero => visit_i32x4_trunc_sat_f64x2_s_zero (arity 1 -> 1)
                I32x4TruncSatF64x2UZero => visit_i32x4_trunc_sat_f64x2_u_zero (arity 1 -> 1)
                F64x2ConvertLowI32x4S => visit_f64x2_convert_low_i32x4_s (arity 1 -> 1)
                F64x2ConvertLowI32x4U => visit_f64x2_convert_low_i32x4_u (arity 1 -> 1)
                F32x4DemoteF64x2Zero => visit_f32x4_demote_f64x2_zero (arity 1 -> 1)
                F64x2PromoteLowF32x4 => visit_f64x2_promote_low_f32x4 (arity 1 -> 1)
            }

            // Relaxed SIMD operators
            // https://github.com/WebAssembly/relaxed-simd
            @relaxed_simd {
                I8x16RelaxedSwizzle => visit_i8x16_relaxed_swizzle (arity 2 -> 1)
                I32x4RelaxedTruncF32x4S => visit_i32x4_relaxed_trunc_f32x4_s (arity 1 -> 1)
                I32x4RelaxedTruncF32x4U => visit_i32x4_relaxed_trunc_f32x4_u (arity 1 -> 1)
                I32x4RelaxedTruncF64x2SZero => visit_i32x4_relaxed_trunc_f64x2_s_zero (arity 1 -> 1)
                I32x4RelaxedTruncF64x2UZero => visit_i32x4_relaxed_trunc_f64x2_u_zero (arity 1 -> 1)
                F32x4RelaxedMadd => visit_f32x4_relaxed_madd (arity 3 -> 1)
                F32x4RelaxedNmadd => visit_f32x4_relaxed_nmadd (arity 3 -> 1)
                F64x2RelaxedMadd => visit_f64x2_relaxed_madd  (arity 3 -> 1)
                F64x2RelaxedNmadd => visit_f64x2_relaxed_nmadd (arity 3 -> 1)
                I8x16RelaxedLaneselect => visit_i8x16_relaxed_laneselect (arity 3 -> 1)
                I16x8RelaxedLaneselect => visit_i16x8_relaxed_laneselect (arity 3 -> 1)
                I32x4RelaxedLaneselect => visit_i32x4_relaxed_laneselect (arity 3 -> 1)
                I64x2RelaxedLaneselect => visit_i64x2_relaxed_laneselect (arity 3 -> 1)
                F32x4RelaxedMin => visit_f32x4_relaxed_min (arity 2 -> 1)
                F32x4RelaxedMax => visit_f32x4_relaxed_max (arity 2 -> 1)
                F64x2RelaxedMin => visit_f64x2_relaxed_min (arity 2 -> 1)
                F64x2RelaxedMax => visit_f64x2_relaxed_max (arity 2 -> 1)
                I16x8RelaxedQ15mulrS => visit_i16x8_relaxed_q15mulr_s (arity 2 -> 1)
                I16x8RelaxedDotI8x16I7x16S => visit_i16x8_relaxed_dot_i8x16_i7x16_s (arity 2 -> 1)
                I32x4RelaxedDotI8x16I7x16AddS => visit_i32x4_relaxed_dot_i8x16_i7x16_add_s (arity 3 -> 1)
            }

            @exceptions {
                TryTable { try_table: $crate::TryTable } => visit_try_table (arity custom)
                Throw { tag_index: u32 } => visit_throw (arity custom)
                ThrowRef => visit_throw_ref (arity 1 -> 0)
            }
            // Deprecated old instructions from the exceptions proposal
            @legacy_exceptions {
                Try { blockty: $crate::BlockType } => visit_try (arity custom)
                Catch { tag_index: u32 } => visit_catch (arity custom)
                Rethrow { relative_depth: u32 } => visit_rethrow (arity 0 -> 0)
                Delegate { relative_depth: u32 } => visit_delegate (arity custom)
                CatchAll => visit_catch_all (arity custom)
            }

            // Also 0xFE prefixed operators
            // shared-everything threads
            // https://github.com/WebAssembly/shared-everything-threads
            @shared_everything_threads {
                GlobalAtomicGet { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_get (arity 0 -> 1)
                GlobalAtomicSet { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_set (arity 1 -> 0)
                GlobalAtomicRmwAdd { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_add (arity 1 -> 1)
                GlobalAtomicRmwSub { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_sub (arity 1 -> 1)
                GlobalAtomicRmwAnd { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_and (arity 1 -> 1)
                GlobalAtomicRmwOr { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_or (arity 1 -> 1)
                GlobalAtomicRmwXor { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_xor (arity 1 -> 1)
                GlobalAtomicRmwXchg { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_xchg (arity 1 -> 1)
                GlobalAtomicRmwCmpxchg { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_cmpxchg (arity 2 -> 1)
                TableAtomicGet { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_get (arity 1 -> 1)
                TableAtomicSet { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_set (arity 2 -> 0)
                TableAtomicRmwXchg { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_rmw_xchg (arity 2 -> 1)
                TableAtomicRmwCmpxchg { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_rmw_cmpxchg (arity 3 -> 1)
                StructAtomicGet { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_get (arity 1 -> 1)
                StructAtomicGetS { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_get_s (arity 1 -> 1)
                StructAtomicGetU { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_get_u (arity 1 -> 1)
                StructAtomicSet { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_set (arity 2 -> 0)
                StructAtomicRmwAdd { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_add (arity 2 -> 1)
                StructAtomicRmwSub { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_sub (arity 2 -> 1)
                StructAtomicRmwAnd { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_and (arity 2 -> 1)
                StructAtomicRmwOr { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_or (arity 2 -> 1)
                StructAtomicRmwXor { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_xor (arity 2 -> 1)
                StructAtomicRmwXchg { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_xchg (arity 2 -> 1)
                StructAtomicRmwCmpxchg { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_cmpxchg (arity 3 -> 1)
                ArrayAtomicGet { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get (arity 2 -> 1)
                ArrayAtomicGetS { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get_s (arity 2 -> 1)
                ArrayAtomicGetU { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get_u (arity 2 -> 1)
                ArrayAtomicSet { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_set (arity 3 -> 0)
                ArrayAtomicRmwAdd { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_add (arity 3 -> 1)
                ArrayAtomicRmwSub { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_sub (arity 3 -> 1)
                ArrayAtomicRmwAnd { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_and (arity 3 -> 1)
                ArrayAtomicRmwOr { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_or (arity 3 -> 1)
                ArrayAtomicRmwXor { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_xor (arity 3 -> 1)
                ArrayAtomicRmwXchg { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_xchg (arity 3 -> 1)
                ArrayAtomicRmwCmpxchg { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_cmpxchg (arity 4 -> 1)
                RefI31Shared => visit_ref_i31_shared (arity 1 -> 1)
            }

            // Typed Function references
            @function_references {
                CallRef { type_index: u32 } => visit_call_ref (arity custom)
                ReturnCallRef { type_index: u32 } => visit_return_call_ref (arity custom)
                RefAsNonNull => visit_ref_as_non_null (arity 1 -> 1)
                BrOnNull { relative_depth: u32 } => visit_br_on_null (arity custom)
                BrOnNonNull { relative_depth: u32 } => visit_br_on_non_null (arity custom)
            }

            // Stack switching
            @stack_switching {
                ContNew { cont_type_index: u32 } => visit_cont_new (arity 1 -> 1)
                ContBind { argument_index: u32, result_index: u32 } => visit_cont_bind (arity custom)
                Suspend { tag_index: u32 } => visit_suspend (arity custom)
                Resume { cont_type_index: u32, resume_table: $crate::ResumeTable } => visit_resume (arity custom)
                ResumeThrow { cont_type_index: u32, tag_index: u32, resume_table: $crate::ResumeTable } => visit_resume_throw (arity custom)
                Switch { cont_type_index: u32, tag_index: u32 } => visit_switch (arity custom)
            }

            @wide_arithmetic {
                I64Add128 => visit_i64_add128 (arity 4 -> 2)
                I64Sub128 => visit_i64_sub128 (arity 4 -> 2)
                I64MulWideS => visit_i64_mul_wide_s (arity 2 -> 2)
                I64MulWideU => visit_i64_mul_wide_u (arity 2 -> 2)
            }
        }
    };
}

/// Helper macro to define a `_for_each_non_simd_operator` which receives
/// the syntax of each instruction individually, but only the non-simd
/// operators.
macro_rules! define_for_each_non_simd_operator {
    // Switch from `_for_each_operator_group` syntax to this macro's syntax to
    // be a "tt muncher macro"
    (@ $($t:tt)*) => {define_for_each_non_simd_operator!(filter [] @ $($t)*);};

    // filter out simd/relaxed-simd proposals
    (filter $filter:tt @simd $simd:tt $($rest:tt)*) => {
        define_for_each_non_simd_operator!(filter $filter $($rest)*);
    };
    (filter $filter:tt @relaxed_simd $simd:tt $($rest:tt)*) => {
        define_for_each_non_simd_operator!(filter $filter $($rest)*);
    };

    // For all other proposals add in tokens where the `@proposal` is prepended
    // before each instruction.
    (
        filter [$($t:tt)*]
        @$proposal:ident {
            $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
        }
        $($rest:tt)*
    ) => {
        define_for_each_non_simd_operator!(
            filter [
                $($t)*
                $( @$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*) )*
            ]
            $($rest)*
        );
    };

    // At the end the `$t` list here is how we want to define
    // `_for_each_non_simd_operator`, so define the macro with these tokens.
    (filter [$($t:tt)*]) => {
        #[macro_export]
        #[doc(hidden)]
        macro_rules! _for_each_visit_operator_impl {
            ($m:ident) => {
                $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);

/// 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 {
    (
        $(
            @$proposal:ident {
                $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
            }
        )*
    ) => {
        #[macro_export]
        #[doc(hidden)]
        macro_rules! _for_each_operator_impl {
            ($m:ident) => {
                $m! {
                    $(
                        $(
                            @$proposal $op $({$($arg: $argty),*})? => $visit ($($ann)*)
                        )*
                    )*
                }
            }
        }
    };
}
#[cfg(feature = "simd")]
_for_each_operator_group!(define_for_each_operator_impl_with_simd);

/// 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)*);};

    // Collect the `@simd` and `@relaxed_simd` proposals.
    (
        filter [$($t:tt)*]
        @simd {
            $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
        }
        $($rest:tt)*
    ) => {
        define_for_each_simd_operator!(
            filter [
                $($t)*
                $( @simd $op $({ $($arg: $argty),* })? => $visit ($($ann)*) )*
            ]
            $($rest)*
        );
    };
    (
        filter [$($t:tt)*]
        @relaxed_simd {
            $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
        }
        $($rest:tt)*
    ) => {
        define_for_each_simd_operator!(
            filter [
                $($t)*
                $( @relaxed_simd $op $({ $($arg: $argty),* })? => $visit ($($ann)*) )*
            ]
            $($rest)*
        );
    };

    // Skip all other proposals.
    (filter $filter:tt @$proposal:ident $instrs:tt $($rest:tt)*) => {
        define_for_each_simd_operator!(filter $filter $($rest)*);
    };

    // Base case to define the base macro.
    (filter [$($t:tt)*]) => {
        #[macro_export]
        #[doc(hidden)]
        macro_rules! _for_each_visit_simd_operator_impl {
            ($m:ident) => {
                $m! { $($t)* }
            }
        }
    };
}
#[cfg(feature = "simd")]
_for_each_operator_group!(define_for_each_simd_operator);

/// Used to implement routines for the [`Operator`] enum.
///
/// A helper macro to conveniently iterate over all opcodes recognized by this
/// crate. This can be used to work with either the [`Operator`] enumeration or
/// the [`VisitOperator`] trait if your use case uniformly handles all operators
/// the same way.
///
/// It is also possible to specialize handling of operators depending on the
/// Wasm proposal from which they are originating.
///
/// This is an "iterator macro" where this macro is invoked with the name of
/// another macro, and then that macro is invoked with the list of all
/// operators.
///
/// The list of specializable Wasm proposals is as follows:
///
/// - `@mvp`: Denoting a Wasm operator from the initial Wasm MVP version.
/// - `@exceptions`: [Wasm `exception-handling` proposal]
/// - `@tail_call`: [Wasm `tail-calls` proposal]
/// - `@reference_types`: [Wasm `reference-types` proposal]
/// - `@sign_extension`: [Wasm `sign-extension-ops` proposal]
/// - `@saturating_float_to_int`: [Wasm `non_trapping_float-to-int-conversions` proposal]
/// - `@bulk_memory `:[Wasm `bulk-memory` proposal]
/// - `@simd`: [Wasm `simd` proposal]
/// - `@relaxed_simd`: [Wasm `relaxed-simd` proposal]
/// - `@threads`: [Wasm `threads` proposal]
/// - `@gc`: [Wasm `gc` proposal]
/// - `@stack_switching`: [Wasm `stack-switching` proposal]
/// - `@wide_arithmetic`: [Wasm `wide-arithmetic` proposal]
/// - `@custom_descriptors` : [Wasm `custom-descriptors` proposal]
///
/// [Wasm `exception-handling` proposal]:
/// https://github.com/WebAssembly/exception-handling
///
/// [Wasm `tail-calls` proposal]:
/// https://github.com/WebAssembly/tail-call
///
/// [Wasm `reference-types` proposal]:
/// https://github.com/WebAssembly/reference-types
///
/// [Wasm `sign-extension-ops` proposal]:
/// https://github.com/WebAssembly/sign-extension-ops
///
/// [Wasm `non_trapping_float-to-int-conversions` proposal]:
/// https://github.com/WebAssembly/nontrapping-float-to-int-conversions
///
/// [Wasm `bulk-memory` proposal]:
/// https://github.com/WebAssembly/bulk-memory-operations
///
/// [Wasm `simd` proposal]:
/// https://github.com/webassembly/simd
///
/// [Wasm `relaxed-simd` proposal]:
/// https://github.com/WebAssembly/relaxed-simd
///
/// [Wasm `threads` proposal]:
/// https://github.com/webassembly/threads
///
/// [Wasm `gc` proposal]:
/// https://github.com/WebAssembly/gc
///
/// [Wasm `stack-switching` proposal]:
/// https://github.com/WebAssembly/stack-switching
///
/// [Wasm `wide-arithmetic` proposal]:
/// https://github.com/WebAssembly/wide-arithmetic
///
/// ```
/// fn do_nothing(op: &wasmparser::Operator) {
///     macro_rules! define_match_operator {
///         // The outer layer of repetition represents how all operators are
///         // provided to the macro at the same time.
///         //
///         // The `$proposal` identifier indicates the Wasm proposals from which
///         // the Wasm operator is originating.
///         // For example to specialize the macro match arm for Wasm SIMD proposal
///         // operators you could write `@simd` instead of `@$proposal:ident` to
///         // only catch those operators.
///         //
///         // The `$op` name is bound to the `Operator` variant name. The
///         // payload of the operator is optionally specified (the `$(...)?`
///         // clause) since not all instructions have payloads. Within the payload
///         // each argument is named and has its type specified.
///         //
///         // The `$visit` name is bound to the corresponding name in the
///         // `VisitOperator` trait that this corresponds to.
///         //
///         // The `$ann` annotations give information about the operator's type (e.g. binary i32 or arity 2 -> 1).
///         ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
///             match op {
///                 $(
///                     wasmparser::Operator::$op $( { $($arg),* } )? => {
///                         // do nothing for this example
///                     }
///                 )*
///                 _ => unreachable!(), // required because `Operator` enum is non-exhaustive
///             }
///         }
///     }
///     wasmparser::for_each_operator!(define_match_operator);
/// }
/// ```
///
/// If you only wanted to visit the initial base set of wasm instructions, for
/// example, you could do:
///
/// ```
/// fn is_mvp_operator(op: &wasmparser::Operator) -> bool {
///     macro_rules! define_match_operator {
///         // delegate the macro invocation to sub-invocations of this macro to
///         // deal with each instruction on a case-by-case basis.
///         ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
///             match op {
///                 $(
///                     wasmparser::Operator::$op $( { $($arg),* } )? => {
///                         define_match_operator!(impl_one @$proposal)
///                     }
///                 )*
///                 _ => unreachable!(), // required because `Operator` enum is non-exhaustive
///             }
///         };
///
///         (impl_one @mvp) => { true };
///         (impl_one @$proposal:ident) => { false };
///     }
///     wasmparser::for_each_operator!(define_match_operator)
/// }
/// ```
#[doc(inline)]
pub use _for_each_operator_impl as for_each_operator;

/// Used to implement the [`VisitOperator`] trait.
///
/// A helper macro to conveniently iterate over all opcodes recognized by this
/// crate. This can be used to work with either the [`Operator`] enumeration or
/// the [`VisitOperator`] trait if your use case uniformly handles all operators
/// the same way.
///
/// It is also possible to specialize handling of operators depending on the
/// Wasm proposal from which they are originating.
///
/// This is an "iterator macro" where this macro is invoked with the name of
/// another macro, and then that macro is invoked with the list of all
/// operators.
///
/// The list of specializable Wasm proposals is as follows:
///
/// - `@mvp`: Denoting a Wasm operator from the initial Wasm MVP version.
/// - `@exceptions`: [Wasm `exception-handling` proposal]
/// - `@tail_call`: [Wasm `tail-calls` proposal]
/// - `@reference_types`: [Wasm `reference-types` proposal]
/// - `@sign_extension`: [Wasm `sign-extension-ops` proposal]
/// - `@saturating_float_to_int`: [Wasm `non_trapping_float-to-int-conversions` proposal]
/// - `@bulk_memory `:[Wasm `bulk-memory` proposal]
/// - `@threads`: [Wasm `threads` proposal]
/// - `@gc`: [Wasm `gc` proposal]
/// - `@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.
///
/// [Wasm `exception-handling` proposal]:
/// https://github.com/WebAssembly/exception-handling
///
/// [Wasm `tail-calls` proposal]:
/// https://github.com/WebAssembly/tail-call
///
/// [Wasm `reference-types` proposal]:
/// https://github.com/WebAssembly/reference-types
///
/// [Wasm `sign-extension-ops` proposal]:
/// https://github.com/WebAssembly/sign-extension-ops
///
/// [Wasm `non_trapping_float-to-int-conversions` proposal]:
/// https://github.com/WebAssembly/nontrapping-float-to-int-conversions
///
/// [Wasm `bulk-memory` proposal]:
/// https://github.com/WebAssembly/bulk-memory-operations
/// [Wasm `simd` proposal]:
/// https://github.com/webassembly/simd
///
/// [Wasm `relaxed-simd` proposal]:
/// https://github.com/WebAssembly/relaxed-simd
///
/// [Wasm `threads` proposal]:
/// https://github.com/webassembly/threads
///
/// [Wasm `gc` proposal]:
/// https://github.com/WebAssembly/gc
///
/// [Wasm `stack-switching` proposal]:
/// https://github.com/WebAssembly/stack-switching
///
/// [Wasm `wide-arithmetic` proposal]:
/// https://github.com/WebAssembly/wide-arithmetic
///
/// ```
/// macro_rules! define_visit_operator {
///     // The outer layer of repetition represents how all operators are
///     // provided to the macro at the same time.
///     //
///     // The `$proposal` identifier indicates the Wasm proposals from which
///     // the Wasm operator is originating.
///     // For example to specialize the macro match arm for Wasm `gc` proposal
///     // operators you could write `@gc` instead of `@$proposal:ident` to
///     // only catch those operators.
///     //
///     // The `$op` name is bound to the `Operator` variant name. The
///     // payload of the operator is optionally specified (the `$(...)?`
///     // clause) since not all instructions have payloads. Within the payload
///     // each argument is named and has its type specified.
///     //
///     // The `$visit` name is bound to the corresponding name in the
///     // `VisitOperator` trait that this corresponds to.
///     //
///     // The `$ann` annotations give information about the operator's type (e.g. binary i32 or arity 2 -> 1).
///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
///         $(
///             fn $visit(&mut self $($(,$arg: $argty)*)?) {
///                 // do nothing for this example
///             }
///         )*
///     }
/// }
///
/// pub struct VisitAndDoNothing;
///
/// impl<'a> wasmparser::VisitOperator<'a> for VisitAndDoNothing {
///     type Output = ();
///
///     wasmparser::for_each_visit_operator!(define_visit_operator);
/// }
/// ```
///
/// If you only wanted to visit the initial base set of wasm instructions, for
/// example, you could do:
///
/// ```
/// macro_rules! visit_only_mvp {
///     // delegate the macro invocation to sub-invocations of this macro to
///     // deal with each instruction on a case-by-case basis.
///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
///         $(
///             visit_only_mvp!(visit_one @$proposal $op $({ $($arg: $argty),* })? => $visit);
///         )*
///     };
///
///     // MVP instructions are defined manually, so do nothing.
///     (visit_one @mvp $($rest:tt)*) => {};
///
///     // Non-MVP instructions all return `false` here. The exact type depends
///     // on `type Output` in the trait implementation below. You could change
///     // it to `Result<()>` for example and return an error here too.
///     (visit_one @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => {
///         fn $visit(&mut self $($(,$arg: $argty)*)?) -> bool {
///             false
///         }
///     }
/// }
/// # // to get this example to compile another macro is used here to define
/// # // visit methods for all mvp operators.
/// # macro_rules! visit_mvp {
/// #     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
/// #         $(
/// #             visit_mvp!(visit_one @$proposal $op $({ $($arg: $argty),* })? => $visit);
/// #         )*
/// #     };
/// #     (visit_one @mvp $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => {
/// #         fn $visit(&mut self $($(,$arg: $argty)*)?) -> bool {
/// #             true
/// #         }
/// #     };
/// #     (visit_one @$proposal:ident $($rest:tt)*) => {};
/// # }
///
/// pub struct VisitOnlyMvp;
///
/// impl<'a> wasmparser::VisitOperator<'a> for VisitOnlyMvp {
///     type Output = bool;
///
///     wasmparser::for_each_visit_operator!(visit_only_mvp);
/// #   wasmparser::for_each_visit_operator!(visit_mvp);
///
///     // manually define `visit_*` for all MVP operators here
/// }
/// ```
#[doc(inline)]
pub use _for_each_visit_operator_impl as for_each_visit_operator;

/// Used to implement the [`VisitSimdOperator`] trait.
///
/// The list of specializable Wasm proposals is as follows:
///
/// - `@simd`: [Wasm `simd` proposal]
/// - `@relaxed_simd`: [Wasm `relaxed-simd` proposal]
///
/// For more information about the structure and use of this macro please
/// refer to the documentation of the [`for_each_operator`] macro.
///
/// [Wasm `simd` proposal]:
/// https://github.com/webassembly/simd
///
/// [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
///     // provided to the macro at the same time.
///     //
///     // The `$proposal` identifier is either `@simd` or `@relaxed_simd`.
///     //
///     // The shape of this macro is identical to [`for_each_visit_operator`].
///     // Please refer to its documentation if you want to learn more.
///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
///         $(
///             fn $visit(&mut self $($(,$arg: $argty)*)?) {
///                 // do nothing for this example
///             }
///         )*
///     }
/// }
///
/// impl<'a> wasmparser::VisitSimdOperator<'a> for VisitAndDoNothing {
///     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;

macro_rules! format_err {
    ($offset:expr, $($arg:tt)*) => {
        crate::BinaryReaderError::fmt(format_args!($($arg)*), $offset)
    }
}

macro_rules! bail {
    ($($arg:tt)*) => {return Err(format_err!($($arg)*))}
}

#[cfg(all(feature = "component-model", feature = "validate"))] // Only used in component-model code right now.
macro_rules! ensure {
    ($cond:expr, $($arg:tt)*) => {
        if !$cond {
            bail!($($arg)*);
        }
    }
}

pub use crate::arity::*;
pub use crate::binary_reader::{BinaryReader, BinaryReaderError, Result};
pub use crate::features::*;
pub use crate::parser::*;
pub use crate::readers::*;

mod arity;
mod binary_reader;
mod features;
mod limits;
mod parser;
mod readers;

#[cfg(feature = "validate")]
mod resources;
#[cfg(feature = "validate")]
mod validator;
#[cfg(feature = "validate")]
pub use crate::resources::*;
#[cfg(feature = "validate")]
pub use crate::validator::*;

#[cfg(feature = "validate")]
pub mod collections;

Messung V0.5 in Prozent
C=75 H=95 G=85

¤ Dauer der Verarbeitung: 0.23 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.