inf_wasmparser/
lib.rs

1/* Copyright 2017 Mozilla Foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16//! A simple event-driven library for parsing WebAssembly binary files
17//! (or streams).
18//!
19//! The parser library reports events as they happen and only stores
20//! parsing information for a brief period of time, making it very fast
21//! and memory-efficient. The event-driven model, however, has some drawbacks.
22//! If you need random access to the entire WebAssembly data-structure,
23//! this is not the right library for you. You could however, build such
24//! a data-structure using this library.
25//!
26//! To get started, create a [`Parser`] using [`Parser::new`] and then follow
27//! the examples documented for [`Parser::parse`] or [`Parser::parse_all`].
28
29#![deny(missing_docs)]
30#![no_std]
31#![cfg_attr(docsrs, feature(doc_auto_cfg))]
32
33extern crate alloc;
34#[cfg(feature = "std")]
35#[macro_use]
36extern crate std;
37
38/// A small "prelude" to use throughout this crate.
39///
40/// This crate is tagged with `#![no_std]` meaning that we get libcore's prelude
41/// by default. This crate also uses `alloc`, however, and common types there
42/// like `String`. This custom prelude helps bring those types into scope to
43/// avoid having to import each of them manually.
44mod prelude {
45    pub use alloc::borrow::ToOwned;
46    pub use alloc::boxed::Box;
47    pub use alloc::format;
48    pub use alloc::string::{String, ToString};
49    pub use alloc::vec;
50    pub use alloc::vec::Vec;
51
52    #[cfg(all(feature = "validate", feature = "component-model"))]
53    pub use crate::collections::IndexSet;
54    #[cfg(feature = "validate")]
55    pub use crate::collections::{IndexMap, Map, Set};
56}
57
58/// A helper macro which is used to itself define further macros below.
59///
60/// This is a little complicated, so first off sorry about that. The idea here
61/// though is that there's one source of truth for the listing of instructions
62/// in `inf_wasmparser` and this is the one location. All other locations should be
63/// derivative from this. As this one source of truth it has all instructions
64/// from all proposals all grouped together. Down below though, for compile
65/// time, currently the simd instructions are split out into their own macro.
66/// The structure/syntax of this macro is to facilitate easily splitting out
67/// entire groups of instructions.
68///
69/// This is used below to define more macros.
70macro_rules! _for_each_operator_group {
71    ($mac:ident) => {
72        $mac! {
73            @mvp {
74                Unreachable => visit_unreachable (arity 0 -> 0)
75                Nop => visit_nop (arity 0 -> 0)
76                Block { blockty: $crate::BlockType } => visit_block (arity block -> ~block)
77                Loop { blockty: $crate::BlockType } => visit_loop (arity block -> ~block)
78                Forall { blockty: $crate::BlockType } => visit_forall (arity block -> ~block)
79                Exists { blockty: $crate::BlockType } => visit_exists (arity block -> ~block)
80                Assume { blockty: $crate::BlockType } => visit_assume (arity block -> ~block)
81                Unique { blockty: $crate::BlockType } => visit_unique (arity block -> ~block)
82                If { blockty: $crate::BlockType } => visit_if (arity 1 block -> ~block)
83                Else => visit_else (arity ~end -> ~end)
84                End => visit_end (arity implicit_else ~end -> implicit_else end)
85                Br { relative_depth: u32 } => visit_br (arity br -> 0)
86                BrIf { relative_depth: u32 } => visit_br_if (arity 1 br -> br)
87                BrTable { targets: $crate::BrTable<'a> } => visit_br_table (arity 1 br_table -> 0)
88                Return => visit_return (arity ~ret -> 0)
89                Call { function_index: u32 } => visit_call (arity func -> func)
90                CallIndirect { type_index: u32, table_index: u32 } => visit_call_indirect (arity 1 type -> type)
91                Drop => visit_drop (arity 1 -> 0)
92                Select => visit_select (arity 3 -> 1)
93                LocalGet { local_index: u32 } => visit_local_get (arity 0 -> 1)
94                LocalSet { local_index: u32 } => visit_local_set (arity 1 -> 0)
95                LocalTee { local_index: u32 } => visit_local_tee (arity 1 -> 1)
96                GlobalGet { global_index: u32 } => visit_global_get (arity 0 -> 1)
97                GlobalSet { global_index: u32 } => visit_global_set (arity 1 -> 0)
98                I32Load { memarg: $crate::MemArg } => visit_i32_load (load i32)
99                I64Load { memarg: $crate::MemArg } => visit_i64_load (load i64)
100                F32Load { memarg: $crate::MemArg } => visit_f32_load (load f32)
101                F64Load { memarg: $crate::MemArg } => visit_f64_load (load f64)
102                I32Load8S { memarg: $crate::MemArg } => visit_i32_load8_s (load i32)
103                I32Load8U { memarg: $crate::MemArg } => visit_i32_load8_u (load i32)
104                I32Load16S { memarg: $crate::MemArg } => visit_i32_load16_s (load i32)
105                I32Load16U { memarg: $crate::MemArg } => visit_i32_load16_u (load i32)
106                I64Load8S { memarg: $crate::MemArg } => visit_i64_load8_s (load i64)
107                I64Load8U { memarg: $crate::MemArg } => visit_i64_load8_u (load i64)
108                I64Load16S { memarg: $crate::MemArg } => visit_i64_load16_s (load i64)
109                I64Load16U { memarg: $crate::MemArg } => visit_i64_load16_u (load i64)
110                I64Load32S { memarg: $crate::MemArg } => visit_i64_load32_s (load i64)
111                I64Load32U { memarg: $crate::MemArg } => visit_i64_load32_u (load i64)
112                I32Store { memarg: $crate::MemArg } => visit_i32_store (store i32)
113                I64Store { memarg: $crate::MemArg } => visit_i64_store (store i64)
114                F32Store { memarg: $crate::MemArg } => visit_f32_store (store f32)
115                F64Store { memarg: $crate::MemArg } => visit_f64_store (store f64)
116                I32Store8 { memarg: $crate::MemArg } => visit_i32_store8 (store i32)
117                I32Store16 { memarg: $crate::MemArg } => visit_i32_store16 (store i32)
118                I64Store8 { memarg: $crate::MemArg } => visit_i64_store8 (store i64)
119                I64Store16 { memarg: $crate::MemArg } => visit_i64_store16 (store i64)
120                I64Store32 { memarg: $crate::MemArg } => visit_i64_store32 (store i64)
121                MemorySize { mem: u32 } => visit_memory_size (arity 0 -> 1)
122                MemoryGrow { mem: u32 } => visit_memory_grow (arity 1 -> 1)
123                I32Uzumaki { value: i32 } => visit_i32_uzumaki (push i32)
124                I32Const { value: i32 } => visit_i32_const (push i32)
125                I64Uzumaki { value: i64 } => visit_i64_uzumaki (push i64)
126                I64Const { value: i64 } => visit_i64_const (push i64)
127                F32Const { value: $crate::Ieee32 } => visit_f32_const (push f32)
128                F64Const { value: $crate::Ieee64 } => visit_f64_const (push f64)
129                I32Eqz => visit_i32_eqz (test i32)
130                I32Eq => visit_i32_eq (cmp i32)
131                I32Ne => visit_i32_ne (cmp i32)
132                I32LtS => visit_i32_lt_s (cmp i32)
133                I32LtU => visit_i32_lt_u (cmp i32)
134                I32GtS => visit_i32_gt_s (cmp i32)
135                I32GtU => visit_i32_gt_u (cmp i32)
136                I32LeS => visit_i32_le_s (cmp i32)
137                I32LeU => visit_i32_le_u (cmp i32)
138                I32GeS => visit_i32_ge_s (cmp i32)
139                I32GeU => visit_i32_ge_u (cmp i32)
140                I64Eqz => visit_i64_eqz (test i64)
141                I64Eq => visit_i64_eq (cmp i64)
142                I64Ne => visit_i64_ne (cmp i64)
143                I64LtS => visit_i64_lt_s (cmp i64)
144                I64LtU => visit_i64_lt_u (cmp i64)
145                I64GtS => visit_i64_gt_s (cmp i64)
146                I64GtU => visit_i64_gt_u (cmp i64)
147                I64LeS => visit_i64_le_s (cmp i64)
148                I64LeU => visit_i64_le_u (cmp i64)
149                I64GeS => visit_i64_ge_s (cmp i64)
150                I64GeU => visit_i64_ge_u (cmp i64)
151                F32Eq => visit_f32_eq (cmp f32)
152                F32Ne => visit_f32_ne (cmp f32)
153                F32Lt => visit_f32_lt (cmp f32)
154                F32Gt => visit_f32_gt (cmp f32)
155                F32Le => visit_f32_le (cmp f32)
156                F32Ge => visit_f32_ge (cmp f32)
157                F64Eq => visit_f64_eq (cmp f64)
158                F64Ne => visit_f64_ne (cmp f64)
159                F64Lt => visit_f64_lt (cmp f64)
160                F64Gt => visit_f64_gt (cmp f64)
161                F64Le => visit_f64_le (cmp f64)
162                F64Ge => visit_f64_ge (cmp f64)
163                I32Clz => visit_i32_clz (unary i32)
164                I32Ctz => visit_i32_ctz (unary i32)
165                I32Popcnt => visit_i32_popcnt (unary i32)
166                I32Add => visit_i32_add (binary i32)
167                I32Sub => visit_i32_sub (binary i32)
168                I32Mul => visit_i32_mul (binary i32)
169                I32DivS => visit_i32_div_s (binary i32)
170                I32DivU => visit_i32_div_u (binary i32)
171                I32RemS => visit_i32_rem_s (binary i32)
172                I32RemU => visit_i32_rem_u (binary i32)
173                I32And => visit_i32_and (binary i32)
174                I32Or => visit_i32_or (binary i32)
175                I32Xor => visit_i32_xor (binary i32)
176                I32Shl => visit_i32_shl (binary i32)
177                I32ShrS => visit_i32_shr_s (binary i32)
178                I32ShrU => visit_i32_shr_u (binary i32)
179                I32Rotl => visit_i32_rotl (binary i32)
180                I32Rotr => visit_i32_rotr (binary i32)
181                I64Clz => visit_i64_clz (unary i64)
182                I64Ctz => visit_i64_ctz (unary i64)
183                I64Popcnt => visit_i64_popcnt (unary i64)
184                I64Add => visit_i64_add (binary i64)
185                I64Sub => visit_i64_sub (binary i64)
186                I64Mul => visit_i64_mul (binary i64)
187                I64DivS => visit_i64_div_s (binary i64)
188                I64DivU => visit_i64_div_u (binary i64)
189                I64RemS => visit_i64_rem_s (binary i64)
190                I64RemU => visit_i64_rem_u (binary i64)
191                I64And => visit_i64_and (binary i64)
192                I64Or => visit_i64_or (binary i64)
193                I64Xor => visit_i64_xor (binary i64)
194                I64Shl => visit_i64_shl (binary i64)
195                I64ShrS => visit_i64_shr_s (binary i64)
196                I64ShrU => visit_i64_shr_u (binary i64)
197                I64Rotl => visit_i64_rotl (binary i64)
198                I64Rotr => visit_i64_rotr (binary i64)
199                F32Abs => visit_f32_abs (unary f32)
200                F32Neg => visit_f32_neg (unary f32)
201                F32Ceil => visit_f32_ceil (unary f32)
202                F32Floor => visit_f32_floor (unary f32)
203                F32Trunc => visit_f32_trunc (unary f32)
204                F32Nearest => visit_f32_nearest (unary f32)
205                F32Sqrt => visit_f32_sqrt (unary f32)
206                F32Add => visit_f32_add (binary f32)
207                F32Sub => visit_f32_sub (binary f32)
208                F32Mul => visit_f32_mul (binary f32)
209                F32Div => visit_f32_div (binary f32)
210                F32Min => visit_f32_min (binary f32)
211                F32Max => visit_f32_max (binary f32)
212                F32Copysign => visit_f32_copysign (binary f32)
213                F64Abs => visit_f64_abs (unary f64)
214                F64Neg => visit_f64_neg (unary f64)
215                F64Ceil => visit_f64_ceil (unary f64)
216                F64Floor => visit_f64_floor (unary f64)
217                F64Trunc => visit_f64_trunc (unary f64)
218                F64Nearest => visit_f64_nearest (unary f64)
219                F64Sqrt => visit_f64_sqrt (unary f64)
220                F64Add => visit_f64_add (binary f64)
221                F64Sub => visit_f64_sub (binary f64)
222                F64Mul => visit_f64_mul (binary f64)
223                F64Div => visit_f64_div (binary f64)
224                F64Min => visit_f64_min (binary f64)
225                F64Max => visit_f64_max (binary f64)
226                F64Copysign => visit_f64_copysign (binary f64)
227                I32WrapI64 => visit_i32_wrap_i64 (conversion i32 i64)
228                I32TruncF32S => visit_i32_trunc_f32_s (conversion i32 f32)
229                I32TruncF32U => visit_i32_trunc_f32_u (conversion i32 f32)
230                I32TruncF64S => visit_i32_trunc_f64_s (conversion i32 f64)
231                I32TruncF64U => visit_i32_trunc_f64_u (conversion i32 f64)
232                I64ExtendI32S => visit_i64_extend_i32_s (conversion i64 i32)
233                I64ExtendI32U => visit_i64_extend_i32_u (conversion i64 i32)
234                I64TruncF32S => visit_i64_trunc_f32_s (conversion i64 f32)
235                I64TruncF32U => visit_i64_trunc_f32_u (conversion i64 f32)
236                I64TruncF64S => visit_i64_trunc_f64_s (conversion i64 f64)
237                I64TruncF64U => visit_i64_trunc_f64_u (conversion i64 f64)
238                F32ConvertI32S => visit_f32_convert_i32_s (conversion f32 i32)
239                F32ConvertI32U => visit_f32_convert_i32_u (conversion f32 i32)
240                F32ConvertI64S => visit_f32_convert_i64_s (conversion f32 i64)
241                F32ConvertI64U => visit_f32_convert_i64_u (conversion f32 i64)
242                F32DemoteF64 => visit_f32_demote_f64 (conversion f32 f64)
243                F64ConvertI32S => visit_f64_convert_i32_s (conversion f64 i32)
244                F64ConvertI32U => visit_f64_convert_i32_u (conversion f64 i32)
245                F64ConvertI64S => visit_f64_convert_i64_s (conversion f64 i64)
246                F64ConvertI64U => visit_f64_convert_i64_u (conversion f64 i64)
247                F64PromoteF32 => visit_f64_promote_f32 (conversion f64 f32)
248                I32ReinterpretF32 => visit_i32_reinterpret_f32 (conversion i32 f32)
249                I64ReinterpretF64 => visit_i64_reinterpret_f64 (conversion i64 f64)
250                F32ReinterpretI32 => visit_f32_reinterpret_i32 (conversion f32 i32)
251                F64ReinterpretI64 => visit_f64_reinterpret_i64 (conversion f64 i64)
252            }
253
254            @sign_extension {
255                I32Extend8S => visit_i32_extend8_s (unary i32)
256                I32Extend16S => visit_i32_extend16_s (unary i32)
257                I64Extend8S => visit_i64_extend8_s (unary i64)
258                I64Extend16S => visit_i64_extend16_s (unary i64)
259                I64Extend32S => visit_i64_extend32_s (unary i64)
260            }
261
262            // 0xFB prefixed operators
263            // Garbage Collection
264            // http://github.com/WebAssembly/gc
265            @gc {
266                RefEq => visit_ref_eq (arity 2 -> 1)
267                StructNew { struct_type_index: u32 } => visit_struct_new (arity type -> 1)
268                StructNewDefault { struct_type_index: u32 } => visit_struct_new_default (arity 0 -> 1)
269                StructGet { struct_type_index: u32, field_index: u32 } => visit_struct_get (arity 1 -> 1)
270                StructGetS { struct_type_index: u32, field_index: u32 } => visit_struct_get_s (arity 1 -> 1)
271                StructGetU { struct_type_index: u32, field_index: u32 } => visit_struct_get_u (arity 1 -> 1)
272                StructSet { struct_type_index: u32, field_index: u32 } => visit_struct_set (arity 2 -> 0)
273                ArrayNew { array_type_index: u32 } => visit_array_new (arity 2 -> 1)
274                ArrayNewDefault { array_type_index: u32 } => visit_array_new_default (arity 1 -> 1)
275                ArrayNewFixed { array_type_index: u32, array_size: u32 } => visit_array_new_fixed (arity size -> 1)
276                ArrayNewData { array_type_index: u32, array_data_index: u32 } => visit_array_new_data (arity 2 -> 1)
277                ArrayNewElem { array_type_index: u32, array_elem_index: u32 } => visit_array_new_elem (arity 2 -> 1)
278                ArrayGet { array_type_index: u32 } => visit_array_get (arity 2 -> 1)
279                ArrayGetS { array_type_index: u32 } => visit_array_get_s (arity 2 -> 1)
280                ArrayGetU { array_type_index: u32 } => visit_array_get_u (arity 2 -> 1)
281                ArraySet { array_type_index: u32 } => visit_array_set (arity 3 -> 0)
282                ArrayLen => visit_array_len (arity 1 -> 1)
283                ArrayFill { array_type_index: u32 } => visit_array_fill (arity 4 -> 0)
284                ArrayCopy { array_type_index_dst: u32, array_type_index_src: u32 } => visit_array_copy (arity 5 -> 0)
285                ArrayInitData { array_type_index: u32, array_data_index: u32 } => visit_array_init_data (arity 4 -> 0)
286                ArrayInitElem { array_type_index: u32, array_elem_index: u32 } => visit_array_init_elem (arity 4 -> 0)
287                RefTestNonNull { hty: $crate::HeapType } => visit_ref_test_non_null (arity 1 -> 1)
288                RefTestNullable { hty: $crate::HeapType } => visit_ref_test_nullable (arity 1 -> 1)
289                RefCastNonNull { hty: $crate::HeapType } => visit_ref_cast_non_null (arity 1 -> 1)
290                RefCastNullable { hty: $crate::HeapType } => visit_ref_cast_nullable (arity 1 -> 1)
291                BrOnCast {
292                    relative_depth: u32,
293                    from_ref_type: $crate::RefType,
294                    to_ref_type: $crate::RefType
295                } => visit_br_on_cast (arity br -> br)
296                BrOnCastFail {
297                    relative_depth: u32,
298                    from_ref_type: $crate::RefType,
299                    to_ref_type: $crate::RefType
300                } => visit_br_on_cast_fail (arity br -> br)
301                AnyConvertExtern => visit_any_convert_extern  (arity 1 -> 1)
302                ExternConvertAny => visit_extern_convert_any (arity 1 -> 1)
303                RefI31 => visit_ref_i31 (arity 1 -> 1)
304                I31GetS => visit_i31_get_s (arity 1 -> 1)
305                I31GetU => visit_i31_get_u (arity 1 -> 1)
306            }
307
308            // 0xFC operators
309            // Non-trapping Float-to-int Conversions
310            // https://github.com/WebAssembly/nontrapping-float-to-int-conversions
311            @saturating_float_to_int {
312                I32TruncSatF32S => visit_i32_trunc_sat_f32_s (conversion i32 f32)
313                I32TruncSatF32U => visit_i32_trunc_sat_f32_u (conversion i32 f32)
314                I32TruncSatF64S => visit_i32_trunc_sat_f64_s (conversion i32 f64)
315                I32TruncSatF64U => visit_i32_trunc_sat_f64_u (conversion i32 f64)
316                I64TruncSatF32S => visit_i64_trunc_sat_f32_s (conversion i64 f32)
317                I64TruncSatF32U => visit_i64_trunc_sat_f32_u (conversion i64 f32)
318                I64TruncSatF64S => visit_i64_trunc_sat_f64_s (conversion i64 f64)
319                I64TruncSatF64U => visit_i64_trunc_sat_f64_u (conversion i64 f64)
320            }
321
322            // 0xFC prefixed operators
323            // bulk memory operations
324            // https://github.com/WebAssembly/bulk-memory-operations
325            @bulk_memory {
326                MemoryInit { data_index: u32, mem: u32 } => visit_memory_init (arity 3 -> 0)
327                DataDrop { data_index: u32 } => visit_data_drop (arity 0 -> 0)
328                MemoryCopy { dst_mem: u32, src_mem: u32 } => visit_memory_copy (arity 3 -> 0)
329                MemoryFill { mem: u32 } => visit_memory_fill (arity 3 -> 0)
330                TableInit { elem_index: u32, table: u32 } => visit_table_init (arity 3 -> 0)
331                ElemDrop { elem_index: u32 } => visit_elem_drop (arity 0 -> 0)
332                TableCopy { dst_table: u32, src_table: u32 } => visit_table_copy (arity 3 -> 0)
333            }
334
335            // 0xFC prefixed operators
336            // reference-types
337            // https://github.com/WebAssembly/reference-types
338            @reference_types {
339                TypedSelect { ty: $crate::ValType } => visit_typed_select (arity 3 -> 1)
340                RefNull { hty: $crate::HeapType } => visit_ref_null (arity 0 -> 1)
341                RefIsNull => visit_ref_is_null (arity 1 -> 1)
342                RefFunc { function_index: u32 } => visit_ref_func (arity 0 -> 1)
343                TableFill { table: u32 } => visit_table_fill (arity 3 -> 0)
344                TableGet { table: u32 } => visit_table_get (arity 1 -> 1)
345                TableSet { table: u32 } => visit_table_set (arity 2 -> 0)
346                TableGrow { table: u32 } => visit_table_grow (arity 2 -> 1)
347                TableSize { table: u32 } => visit_table_size (arity 0 -> 1)
348            }
349
350            // Wasm tail-call proposal
351            // https://github.com/WebAssembly/tail-call
352            @tail_call {
353                ReturnCall { function_index: u32 } => visit_return_call (arity func -> 0)
354                ReturnCallIndirect { type_index: u32, table_index: u32 } => visit_return_call_indirect (arity 1 type -> 0)
355            }
356
357            // OxFC prefixed operators
358            // memory control (experimental)
359            // https://github.com/WebAssembly/design/issues/1439
360            @memory_control {
361                MemoryDiscard { mem: u32 } => visit_memory_discard (arity 2 -> 0)
362            }
363
364            // 0xFE prefixed operators
365            // threads
366            // https://github.com/WebAssembly/threads
367            @threads {
368                MemoryAtomicNotify { memarg: $crate::MemArg } => visit_memory_atomic_notify (atomic rmw i32)
369                MemoryAtomicWait32 { memarg: $crate::MemArg } => visit_memory_atomic_wait32 (arity 3 -> 1)
370                MemoryAtomicWait64 { memarg: $crate::MemArg } => visit_memory_atomic_wait64 (arity 3 -> 1)
371                AtomicFence => visit_atomic_fence (arity 0 -> 0)
372                I32AtomicLoad { memarg: $crate::MemArg } => visit_i32_atomic_load (load atomic i32)
373                I64AtomicLoad { memarg: $crate::MemArg } => visit_i64_atomic_load (load atomic i64)
374                I32AtomicLoad8U { memarg: $crate::MemArg } => visit_i32_atomic_load8_u (load atomic i32)
375                I32AtomicLoad16U { memarg: $crate::MemArg } => visit_i32_atomic_load16_u (load atomic i32)
376                I64AtomicLoad8U { memarg: $crate::MemArg } => visit_i64_atomic_load8_u (load atomic i64)
377                I64AtomicLoad16U { memarg: $crate::MemArg } => visit_i64_atomic_load16_u (load atomic i64)
378                I64AtomicLoad32U { memarg: $crate::MemArg } => visit_i64_atomic_load32_u (load atomic i64)
379                I32AtomicStore { memarg: $crate::MemArg } => visit_i32_atomic_store (store atomic i32)
380                I64AtomicStore { memarg: $crate::MemArg } => visit_i64_atomic_store (store atomic i64)
381                I32AtomicStore8 { memarg: $crate::MemArg } => visit_i32_atomic_store8 (store atomic i32)
382                I32AtomicStore16 { memarg: $crate::MemArg } => visit_i32_atomic_store16 (store atomic i32)
383                I64AtomicStore8 { memarg: $crate::MemArg } => visit_i64_atomic_store8 (store atomic i64)
384                I64AtomicStore16 { memarg: $crate::MemArg } => visit_i64_atomic_store16 (store atomic i64)
385                I64AtomicStore32 { memarg: $crate::MemArg } => visit_i64_atomic_store32 (store atomic i64)
386                I32AtomicRmwAdd { memarg: $crate::MemArg } => visit_i32_atomic_rmw_add (atomic rmw i32)
387                I64AtomicRmwAdd { memarg: $crate::MemArg } => visit_i64_atomic_rmw_add (atomic rmw i64)
388                I32AtomicRmw8AddU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_add_u (atomic rmw i32)
389                I32AtomicRmw16AddU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_add_u (atomic rmw i32)
390                I64AtomicRmw8AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_add_u (atomic rmw i64)
391                I64AtomicRmw16AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_add_u (atomic rmw i64)
392                I64AtomicRmw32AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_add_u (atomic rmw i64)
393                I32AtomicRmwSub { memarg: $crate::MemArg } => visit_i32_atomic_rmw_sub (atomic rmw i32)
394                I64AtomicRmwSub { memarg: $crate::MemArg } => visit_i64_atomic_rmw_sub (atomic rmw i64)
395                I32AtomicRmw8SubU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_sub_u (atomic rmw i32)
396                I32AtomicRmw16SubU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_sub_u (atomic rmw i32)
397                I64AtomicRmw8SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_sub_u (atomic rmw i64)
398                I64AtomicRmw16SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_sub_u (atomic rmw i64)
399                I64AtomicRmw32SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_sub_u (atomic rmw i64)
400                I32AtomicRmwAnd { memarg: $crate::MemArg } => visit_i32_atomic_rmw_and (atomic rmw i32)
401                I64AtomicRmwAnd { memarg: $crate::MemArg } => visit_i64_atomic_rmw_and (atomic rmw i64)
402                I32AtomicRmw8AndU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_and_u (atomic rmw i32)
403                I32AtomicRmw16AndU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_and_u (atomic rmw i32)
404                I64AtomicRmw8AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_and_u (atomic rmw i64)
405                I64AtomicRmw16AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_and_u (atomic rmw i64)
406                I64AtomicRmw32AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_and_u (atomic rmw i64)
407                I32AtomicRmwOr { memarg: $crate::MemArg } => visit_i32_atomic_rmw_or (atomic rmw i32)
408                I64AtomicRmwOr { memarg: $crate::MemArg } => visit_i64_atomic_rmw_or (atomic rmw i64)
409                I32AtomicRmw8OrU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_or_u (atomic rmw i32)
410                I32AtomicRmw16OrU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_or_u (atomic rmw i32)
411                I64AtomicRmw8OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_or_u (atomic rmw i64)
412                I64AtomicRmw16OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_or_u (atomic rmw i64)
413                I64AtomicRmw32OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_or_u (atomic rmw i64)
414                I32AtomicRmwXor { memarg: $crate::MemArg } => visit_i32_atomic_rmw_xor (atomic rmw i32)
415                I64AtomicRmwXor { memarg: $crate::MemArg } => visit_i64_atomic_rmw_xor (atomic rmw i64)
416                I32AtomicRmw8XorU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_xor_u (atomic rmw i32)
417                I32AtomicRmw16XorU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_xor_u (atomic rmw i32)
418                I64AtomicRmw8XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_xor_u (atomic rmw i64)
419                I64AtomicRmw16XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_xor_u (atomic rmw i64)
420                I64AtomicRmw32XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_xor_u (atomic rmw i64)
421                I32AtomicRmwXchg { memarg: $crate::MemArg } => visit_i32_atomic_rmw_xchg (atomic rmw i32)
422                I64AtomicRmwXchg { memarg: $crate::MemArg } => visit_i64_atomic_rmw_xchg (atomic rmw i64)
423                I32AtomicRmw8XchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_xchg_u (atomic rmw i32)
424                I32AtomicRmw16XchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_xchg_u (atomic rmw i32)
425                I64AtomicRmw8XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_xchg_u (atomic rmw i64)
426                I64AtomicRmw16XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_xchg_u (atomic rmw i64)
427                I64AtomicRmw32XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_xchg_u (atomic rmw i64)
428                I32AtomicRmwCmpxchg { memarg: $crate::MemArg } => visit_i32_atomic_rmw_cmpxchg (atomic cmpxchg i32)
429                I64AtomicRmwCmpxchg { memarg: $crate::MemArg } => visit_i64_atomic_rmw_cmpxchg (atomic cmpxchg i64)
430                I32AtomicRmw8CmpxchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_cmpxchg_u (atomic cmpxchg i32)
431                I32AtomicRmw16CmpxchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_cmpxchg_u (atomic cmpxchg i32)
432                I64AtomicRmw8CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_cmpxchg_u (atomic cmpxchg i64)
433                I64AtomicRmw16CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_cmpxchg_u (atomic cmpxchg i64)
434                I64AtomicRmw32CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_cmpxchg_u (atomic cmpxchg i64)
435            }
436
437            // 0xFD operators
438            // 128-bit SIMD
439            // - https://github.com/webassembly/simd
440            // - https://webassembly.github.io/simd/core/binary/instructions.html
441            @simd {
442                V128Load { memarg: $crate::MemArg } => visit_v128_load (load v128)
443                V128Load8x8S { memarg: $crate::MemArg } => visit_v128_load8x8_s (load v128)
444                V128Load8x8U { memarg: $crate::MemArg } => visit_v128_load8x8_u (load v128)
445                V128Load16x4S { memarg: $crate::MemArg } => visit_v128_load16x4_s (load v128)
446                V128Load16x4U { memarg: $crate::MemArg } => visit_v128_load16x4_u (load v128)
447                V128Load32x2S { memarg: $crate::MemArg } => visit_v128_load32x2_s (load v128)
448                V128Load32x2U { memarg: $crate::MemArg } => visit_v128_load32x2_u (load v128)
449                V128Load8Splat { memarg: $crate::MemArg } => visit_v128_load8_splat (load v128)
450                V128Load16Splat { memarg: $crate::MemArg } => visit_v128_load16_splat (load v128)
451                V128Load32Splat { memarg: $crate::MemArg } => visit_v128_load32_splat (load v128)
452                V128Load64Splat { memarg: $crate::MemArg } => visit_v128_load64_splat (load v128)
453                V128Load32Zero { memarg: $crate::MemArg } => visit_v128_load32_zero (load v128)
454                V128Load64Zero { memarg: $crate::MemArg } => visit_v128_load64_zero (load v128)
455                V128Store { memarg: $crate::MemArg } => visit_v128_store (store v128)
456                V128Load8Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load8_lane (load lane 16)
457                V128Load16Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load16_lane (load lane 8)
458                V128Load32Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load32_lane (load lane 4)
459                V128Load64Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load64_lane (load lane 2)
460                V128Store8Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store8_lane (store lane 16)
461                V128Store16Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store16_lane (store lane 8)
462                V128Store32Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store32_lane (store lane 4)
463                V128Store64Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store64_lane (store lane 2)
464                V128Const { value: $crate::V128 } => visit_v128_const (push v128)
465                I8x16Shuffle { lanes: [u8; 16] } => visit_i8x16_shuffle (arity 2 -> 1)
466                I8x16ExtractLaneS { lane: u8 } => visit_i8x16_extract_lane_s (extract i32 16)
467                I8x16ExtractLaneU { lane: u8 } => visit_i8x16_extract_lane_u (extract i32 16)
468                I8x16ReplaceLane { lane: u8 } => visit_i8x16_replace_lane (replace i32 16)
469                I16x8ExtractLaneS { lane: u8 } => visit_i16x8_extract_lane_s (extract i32 8)
470                I16x8ExtractLaneU { lane: u8 } => visit_i16x8_extract_lane_u (extract i32 8)
471                I16x8ReplaceLane { lane: u8 } => visit_i16x8_replace_lane (replace i32 8)
472                I32x4ExtractLane { lane: u8 } => visit_i32x4_extract_lane (extract i32 4)
473                I32x4ReplaceLane { lane: u8 } => visit_i32x4_replace_lane (replace i32 4)
474                I64x2ExtractLane { lane: u8 } => visit_i64x2_extract_lane (extract i64 2)
475                I64x2ReplaceLane { lane: u8 } => visit_i64x2_replace_lane (replace i64 2)
476                F32x4ExtractLane { lane: u8 } => visit_f32x4_extract_lane (extract f32 4)
477                F32x4ReplaceLane { lane: u8 } => visit_f32x4_replace_lane (replace f32 4)
478                F64x2ExtractLane { lane: u8 } => visit_f64x2_extract_lane (extract f64 2)
479                F64x2ReplaceLane { lane: u8 } => visit_f64x2_replace_lane (replace f64 2)
480                I8x16Swizzle => visit_i8x16_swizzle (binary v128)
481                I8x16Splat => visit_i8x16_splat (splat i32)
482                I16x8Splat => visit_i16x8_splat (splat i32)
483                I32x4Splat => visit_i32x4_splat (splat i32)
484                I64x2Splat => visit_i64x2_splat (splat i64)
485                F32x4Splat => visit_f32x4_splat (splat f32)
486                F64x2Splat => visit_f64x2_splat (splat f64)
487                I8x16Eq => visit_i8x16_eq (binary v128)
488                I8x16Ne => visit_i8x16_ne (binary v128)
489                I8x16LtS => visit_i8x16_lt_s (binary v128)
490                I8x16LtU => visit_i8x16_lt_u (binary v128)
491                I8x16GtS => visit_i8x16_gt_s (binary v128)
492                I8x16GtU => visit_i8x16_gt_u (binary v128)
493                I8x16LeS => visit_i8x16_le_s (binary v128)
494                I8x16LeU => visit_i8x16_le_u (binary v128)
495                I8x16GeS => visit_i8x16_ge_s (binary v128)
496                I8x16GeU => visit_i8x16_ge_u (binary v128)
497                I16x8Eq => visit_i16x8_eq (binary v128)
498                I16x8Ne => visit_i16x8_ne (binary v128)
499                I16x8LtS => visit_i16x8_lt_s (binary v128)
500                I16x8LtU => visit_i16x8_lt_u (binary v128)
501                I16x8GtS => visit_i16x8_gt_s (binary v128)
502                I16x8GtU => visit_i16x8_gt_u (binary v128)
503                I16x8LeS => visit_i16x8_le_s (binary v128)
504                I16x8LeU => visit_i16x8_le_u (binary v128)
505                I16x8GeS => visit_i16x8_ge_s (binary v128)
506                I16x8GeU => visit_i16x8_ge_u (binary v128)
507                I32x4Eq => visit_i32x4_eq (binary v128)
508                I32x4Ne => visit_i32x4_ne (binary v128)
509                I32x4LtS => visit_i32x4_lt_s (binary v128)
510                I32x4LtU => visit_i32x4_lt_u (binary v128)
511                I32x4GtS => visit_i32x4_gt_s (binary v128)
512                I32x4GtU => visit_i32x4_gt_u (binary v128)
513                I32x4LeS => visit_i32x4_le_s (binary v128)
514                I32x4LeU => visit_i32x4_le_u (binary v128)
515                I32x4GeS => visit_i32x4_ge_s (binary v128)
516                I32x4GeU => visit_i32x4_ge_u (binary v128)
517                I64x2Eq => visit_i64x2_eq (binary v128)
518                I64x2Ne => visit_i64x2_ne (binary v128)
519                I64x2LtS => visit_i64x2_lt_s (binary v128)
520                I64x2GtS => visit_i64x2_gt_s (binary v128)
521                I64x2LeS => visit_i64x2_le_s (binary v128)
522                I64x2GeS => visit_i64x2_ge_s (binary v128)
523                F32x4Eq => visit_f32x4_eq (binary v128f)
524                F32x4Ne => visit_f32x4_ne (binary v128f)
525                F32x4Lt => visit_f32x4_lt (binary v128f)
526                F32x4Gt => visit_f32x4_gt (binary v128f)
527                F32x4Le => visit_f32x4_le (binary v128f)
528                F32x4Ge => visit_f32x4_ge (binary v128f)
529                F64x2Eq => visit_f64x2_eq (binary v128f)
530                F64x2Ne => visit_f64x2_ne (binary v128f)
531                F64x2Lt => visit_f64x2_lt (binary v128f)
532                F64x2Gt => visit_f64x2_gt (binary v128f)
533                F64x2Le => visit_f64x2_le (binary v128f)
534                F64x2Ge => visit_f64x2_ge (binary v128f)
535                V128Not => visit_v128_not (unary v128)
536                V128And => visit_v128_and (binary v128)
537                V128AndNot => visit_v128_andnot (binary v128)
538                V128Or => visit_v128_or (binary v128)
539                V128Xor => visit_v128_xor (binary v128)
540                V128Bitselect => visit_v128_bitselect (ternary v128)
541                V128AnyTrue => visit_v128_any_true (test v128)
542                I8x16Abs => visit_i8x16_abs (unary v128)
543                I8x16Neg => visit_i8x16_neg (unary v128)
544                I8x16Popcnt => visit_i8x16_popcnt (unary v128)
545                I8x16AllTrue => visit_i8x16_all_true (test v128)
546                I8x16Bitmask => visit_i8x16_bitmask (test v128)
547                I8x16NarrowI16x8S => visit_i8x16_narrow_i16x8_s (binary v128)
548                I8x16NarrowI16x8U => visit_i8x16_narrow_i16x8_u (binary v128)
549                I8x16Shl => visit_i8x16_shl (shift v128)
550                I8x16ShrS => visit_i8x16_shr_s (shift v128)
551                I8x16ShrU => visit_i8x16_shr_u (shift v128)
552                I8x16Add => visit_i8x16_add (binary v128)
553                I8x16AddSatS => visit_i8x16_add_sat_s (binary v128)
554                I8x16AddSatU => visit_i8x16_add_sat_u (binary v128)
555                I8x16Sub => visit_i8x16_sub (binary v128)
556                I8x16SubSatS => visit_i8x16_sub_sat_s (binary v128)
557                I8x16SubSatU => visit_i8x16_sub_sat_u (binary v128)
558                I8x16MinS => visit_i8x16_min_s (binary v128)
559                I8x16MinU => visit_i8x16_min_u (binary v128)
560                I8x16MaxS => visit_i8x16_max_s (binary v128)
561                I8x16MaxU => visit_i8x16_max_u (binary v128)
562                I8x16AvgrU => visit_i8x16_avgr_u (binary v128)
563                I16x8ExtAddPairwiseI8x16S => visit_i16x8_extadd_pairwise_i8x16_s (unary v128)
564                I16x8ExtAddPairwiseI8x16U => visit_i16x8_extadd_pairwise_i8x16_u (unary v128)
565                I16x8Abs => visit_i16x8_abs (unary v128)
566                I16x8Neg => visit_i16x8_neg (unary v128)
567                I16x8Q15MulrSatS => visit_i16x8_q15mulr_sat_s (binary v128)
568                I16x8AllTrue => visit_i16x8_all_true (test v128)
569                I16x8Bitmask => visit_i16x8_bitmask (test v128)
570                I16x8NarrowI32x4S => visit_i16x8_narrow_i32x4_s (binary v128)
571                I16x8NarrowI32x4U => visit_i16x8_narrow_i32x4_u (binary v128)
572                I16x8ExtendLowI8x16S => visit_i16x8_extend_low_i8x16_s (unary v128)
573                I16x8ExtendHighI8x16S => visit_i16x8_extend_high_i8x16_s (unary v128)
574                I16x8ExtendLowI8x16U => visit_i16x8_extend_low_i8x16_u (unary v128)
575                I16x8ExtendHighI8x16U => visit_i16x8_extend_high_i8x16_u (unary v128)
576                I16x8Shl => visit_i16x8_shl (shift v128)
577                I16x8ShrS => visit_i16x8_shr_s (shift v128)
578                I16x8ShrU => visit_i16x8_shr_u (shift v128)
579                I16x8Add => visit_i16x8_add (binary v128)
580                I16x8AddSatS => visit_i16x8_add_sat_s (binary v128)
581                I16x8AddSatU => visit_i16x8_add_sat_u (binary v128)
582                I16x8Sub => visit_i16x8_sub (binary v128)
583                I16x8SubSatS => visit_i16x8_sub_sat_s (binary v128)
584                I16x8SubSatU => visit_i16x8_sub_sat_u (binary v128)
585                I16x8Mul => visit_i16x8_mul (binary v128)
586                I16x8MinS => visit_i16x8_min_s (binary v128)
587                I16x8MinU => visit_i16x8_min_u (binary v128)
588                I16x8MaxS => visit_i16x8_max_s (binary v128)
589                I16x8MaxU => visit_i16x8_max_u (binary v128)
590                I16x8AvgrU => visit_i16x8_avgr_u (binary v128)
591                I16x8ExtMulLowI8x16S => visit_i16x8_extmul_low_i8x16_s (binary v128)
592                I16x8ExtMulHighI8x16S => visit_i16x8_extmul_high_i8x16_s (binary v128)
593                I16x8ExtMulLowI8x16U => visit_i16x8_extmul_low_i8x16_u (binary v128)
594                I16x8ExtMulHighI8x16U => visit_i16x8_extmul_high_i8x16_u (binary v128)
595                I32x4ExtAddPairwiseI16x8S => visit_i32x4_extadd_pairwise_i16x8_s (unary v128)
596                I32x4ExtAddPairwiseI16x8U => visit_i32x4_extadd_pairwise_i16x8_u (unary v128)
597                I32x4Abs => visit_i32x4_abs (unary v128)
598                I32x4Neg => visit_i32x4_neg (unary v128)
599                I32x4AllTrue => visit_i32x4_all_true (test v128)
600                I32x4Bitmask => visit_i32x4_bitmask (test v128)
601                I32x4ExtendLowI16x8S => visit_i32x4_extend_low_i16x8_s (unary v128)
602                I32x4ExtendHighI16x8S => visit_i32x4_extend_high_i16x8_s (unary v128)
603                I32x4ExtendLowI16x8U => visit_i32x4_extend_low_i16x8_u (unary v128)
604                I32x4ExtendHighI16x8U => visit_i32x4_extend_high_i16x8_u (unary v128)
605                I32x4Shl => visit_i32x4_shl (shift v128)
606                I32x4ShrS => visit_i32x4_shr_s (shift v128)
607                I32x4ShrU => visit_i32x4_shr_u (shift v128)
608                I32x4Add => visit_i32x4_add (binary v128)
609                I32x4Sub => visit_i32x4_sub (binary v128)
610                I32x4Mul => visit_i32x4_mul (binary v128)
611                I32x4MinS => visit_i32x4_min_s (binary v128)
612                I32x4MinU => visit_i32x4_min_u (binary v128)
613                I32x4MaxS => visit_i32x4_max_s (binary v128)
614                I32x4MaxU => visit_i32x4_max_u (binary v128)
615                I32x4DotI16x8S => visit_i32x4_dot_i16x8_s (binary v128)
616                I32x4ExtMulLowI16x8S => visit_i32x4_extmul_low_i16x8_s (binary v128)
617                I32x4ExtMulHighI16x8S => visit_i32x4_extmul_high_i16x8_s (binary v128)
618                I32x4ExtMulLowI16x8U => visit_i32x4_extmul_low_i16x8_u (binary v128)
619                I32x4ExtMulHighI16x8U => visit_i32x4_extmul_high_i16x8_u (binary v128)
620                I64x2Abs => visit_i64x2_abs (unary v128)
621                I64x2Neg => visit_i64x2_neg (unary v128)
622                I64x2AllTrue => visit_i64x2_all_true (test v128)
623                I64x2Bitmask => visit_i64x2_bitmask (test v128)
624                I64x2ExtendLowI32x4S => visit_i64x2_extend_low_i32x4_s (unary v128)
625                I64x2ExtendHighI32x4S => visit_i64x2_extend_high_i32x4_s (unary v128)
626                I64x2ExtendLowI32x4U => visit_i64x2_extend_low_i32x4_u (unary v128)
627                I64x2ExtendHighI32x4U => visit_i64x2_extend_high_i32x4_u (unary v128)
628                I64x2Shl => visit_i64x2_shl (shift v128)
629                I64x2ShrS => visit_i64x2_shr_s (shift v128)
630                I64x2ShrU => visit_i64x2_shr_u (shift v128)
631                I64x2Add => visit_i64x2_add (binary v128)
632                I64x2Sub => visit_i64x2_sub (binary v128)
633                I64x2Mul => visit_i64x2_mul (binary v128)
634                I64x2ExtMulLowI32x4S => visit_i64x2_extmul_low_i32x4_s (binary v128)
635                I64x2ExtMulHighI32x4S => visit_i64x2_extmul_high_i32x4_s (binary v128)
636                I64x2ExtMulLowI32x4U => visit_i64x2_extmul_low_i32x4_u (binary v128)
637                I64x2ExtMulHighI32x4U => visit_i64x2_extmul_high_i32x4_u (binary v128)
638                F32x4Ceil => visit_f32x4_ceil (unary v128f)
639                F32x4Floor => visit_f32x4_floor (unary v128f)
640                F32x4Trunc => visit_f32x4_trunc (unary v128f)
641                F32x4Nearest => visit_f32x4_nearest (unary v128f)
642                F32x4Abs => visit_f32x4_abs (unary v128f)
643                F32x4Neg => visit_f32x4_neg (unary v128f)
644                F32x4Sqrt => visit_f32x4_sqrt (unary v128f)
645                F32x4Add => visit_f32x4_add (binary v128f)
646                F32x4Sub => visit_f32x4_sub (binary v128f)
647                F32x4Mul => visit_f32x4_mul (binary v128f)
648                F32x4Div => visit_f32x4_div (binary v128f)
649                F32x4Min => visit_f32x4_min (binary v128f)
650                F32x4Max => visit_f32x4_max (binary v128f)
651                F32x4PMin => visit_f32x4_pmin (binary v128f)
652                F32x4PMax => visit_f32x4_pmax (binary v128f)
653                F64x2Ceil => visit_f64x2_ceil (unary v128f)
654                F64x2Floor => visit_f64x2_floor (unary v128f)
655                F64x2Trunc => visit_f64x2_trunc (unary v128f)
656                F64x2Nearest => visit_f64x2_nearest (unary v128f)
657                F64x2Abs => visit_f64x2_abs (unary v128f)
658                F64x2Neg => visit_f64x2_neg (unary v128f)
659                F64x2Sqrt => visit_f64x2_sqrt (unary v128f)
660                F64x2Add => visit_f64x2_add (binary v128f)
661                F64x2Sub => visit_f64x2_sub (binary v128f)
662                F64x2Mul => visit_f64x2_mul (binary v128f)
663                F64x2Div => visit_f64x2_div (binary v128f)
664                F64x2Min => visit_f64x2_min (binary v128f)
665                F64x2Max => visit_f64x2_max (binary v128f)
666                F64x2PMin => visit_f64x2_pmin (binary v128f)
667                F64x2PMax => visit_f64x2_pmax (binary v128f)
668                I32x4TruncSatF32x4S => visit_i32x4_trunc_sat_f32x4_s (unary v128f)
669                I32x4TruncSatF32x4U => visit_i32x4_trunc_sat_f32x4_u (unary v128f)
670                F32x4ConvertI32x4S => visit_f32x4_convert_i32x4_s (unary v128f)
671                F32x4ConvertI32x4U => visit_f32x4_convert_i32x4_u (unary v128f)
672                I32x4TruncSatF64x2SZero => visit_i32x4_trunc_sat_f64x2_s_zero (unary v128f)
673                I32x4TruncSatF64x2UZero => visit_i32x4_trunc_sat_f64x2_u_zero (unary v128f)
674                F64x2ConvertLowI32x4S => visit_f64x2_convert_low_i32x4_s (unary v128f)
675                F64x2ConvertLowI32x4U => visit_f64x2_convert_low_i32x4_u (unary v128f)
676                F32x4DemoteF64x2Zero => visit_f32x4_demote_f64x2_zero (unary v128f)
677                F64x2PromoteLowF32x4 => visit_f64x2_promote_low_f32x4 (unary v128f)
678            }
679
680            // Relaxed SIMD operators
681            // https://github.com/WebAssembly/relaxed-simd
682            @relaxed_simd {
683                I8x16RelaxedSwizzle => visit_i8x16_relaxed_swizzle (binary v128)
684                I32x4RelaxedTruncF32x4S => visit_i32x4_relaxed_trunc_f32x4_s (unary v128)
685                I32x4RelaxedTruncF32x4U => visit_i32x4_relaxed_trunc_f32x4_u (unary v128)
686                I32x4RelaxedTruncF64x2SZero => visit_i32x4_relaxed_trunc_f64x2_s_zero (unary v128)
687                I32x4RelaxedTruncF64x2UZero => visit_i32x4_relaxed_trunc_f64x2_u_zero (unary v128)
688                F32x4RelaxedMadd => visit_f32x4_relaxed_madd (ternary v128)
689                F32x4RelaxedNmadd => visit_f32x4_relaxed_nmadd (ternary v128)
690                F64x2RelaxedMadd => visit_f64x2_relaxed_madd  (ternary v128)
691                F64x2RelaxedNmadd => visit_f64x2_relaxed_nmadd (ternary v128)
692                I8x16RelaxedLaneselect => visit_i8x16_relaxed_laneselect (ternary v128)
693                I16x8RelaxedLaneselect => visit_i16x8_relaxed_laneselect (ternary v128)
694                I32x4RelaxedLaneselect => visit_i32x4_relaxed_laneselect (ternary v128)
695                I64x2RelaxedLaneselect => visit_i64x2_relaxed_laneselect (ternary v128)
696                F32x4RelaxedMin => visit_f32x4_relaxed_min (binary v128)
697                F32x4RelaxedMax => visit_f32x4_relaxed_max (binary v128)
698                F64x2RelaxedMin => visit_f64x2_relaxed_min (binary v128)
699                F64x2RelaxedMax => visit_f64x2_relaxed_max (binary v128)
700                I16x8RelaxedQ15mulrS => visit_i16x8_relaxed_q15mulr_s (binary v128)
701                I16x8RelaxedDotI8x16I7x16S => visit_i16x8_relaxed_dot_i8x16_i7x16_s (binary v128)
702                I32x4RelaxedDotI8x16I7x16AddS => visit_i32x4_relaxed_dot_i8x16_i7x16_add_s (ternary v128)
703            }
704
705            @exceptions {
706                TryTable { try_table: $crate::TryTable } => visit_try_table (arity try_table -> ~try_table)
707                Throw { tag_index: u32 } => visit_throw (arity tag -> 0)
708                ThrowRef => visit_throw_ref (arity 1 -> 0)
709            }
710            // Deprecated old instructions from the exceptions proposal
711            @legacy_exceptions {
712                Try { blockty: $crate::BlockType } => visit_try (arity block -> ~block)
713                Catch { tag_index: u32 } => visit_catch (arity ~end -> ~tag)
714                Rethrow { relative_depth: u32 } => visit_rethrow (arity 0 -> 0)
715                Delegate { relative_depth: u32 } => visit_delegate (arity ~end -> end)
716                CatchAll => visit_catch_all (arity ~end -> 0)
717            }
718
719            // Also 0xFE prefixed operators
720            // shared-everything threads
721            // https://github.com/WebAssembly/shared-everything-threads
722            @shared_everything_threads {
723                GlobalAtomicGet { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_get (arity 0 -> 1)
724                GlobalAtomicSet { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_set (arity 1 -> 0)
725                GlobalAtomicRmwAdd { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_add (unary atomic global)
726                GlobalAtomicRmwSub { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_sub (unary atomic global)
727                GlobalAtomicRmwAnd { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_and (unary atomic global)
728                GlobalAtomicRmwOr { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_or (unary atomic global)
729                GlobalAtomicRmwXor { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_xor (unary atomic global)
730                GlobalAtomicRmwXchg { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_xchg (arity 1 -> 1)
731                GlobalAtomicRmwCmpxchg { ordering: $crate::Ordering, global_index: u32 } => visit_global_atomic_rmw_cmpxchg (arity 2 -> 1)
732                TableAtomicGet { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_get (arity 1 -> 1)
733                TableAtomicSet { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_set (arity 2 -> 0)
734                TableAtomicRmwXchg { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_rmw_xchg (arity 2 -> 1)
735                TableAtomicRmwCmpxchg { ordering: $crate::Ordering, table_index: u32 } => visit_table_atomic_rmw_cmpxchg (arity 3 -> 1)
736                StructAtomicGet { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_get (arity 1 -> 1)
737                StructAtomicGetS { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_get_s (arity 1 -> 1)
738                StructAtomicGetU { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_get_u (arity 1 -> 1)
739                StructAtomicSet { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_set (arity 2 -> 0)
740                StructAtomicRmwAdd { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_add (atomic rmw struct add)
741                StructAtomicRmwSub { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_sub (atomic rmw struct sub)
742                StructAtomicRmwAnd { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_and (atomic rmw struct and)
743                StructAtomicRmwOr { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_or (atomic rmw struct or)
744                StructAtomicRmwXor { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_xor (atomic rmw struct xor)
745                StructAtomicRmwXchg { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_xchg (arity 2 -> 1)
746                StructAtomicRmwCmpxchg { ordering: $crate::Ordering, struct_type_index: u32, field_index: u32  } => visit_struct_atomic_rmw_cmpxchg (arity 3 -> 1)
747                ArrayAtomicGet { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get (arity 2 -> 1)
748                ArrayAtomicGetS { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get_s (arity 2 -> 1)
749                ArrayAtomicGetU { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_get_u (arity 2 -> 1)
750                ArrayAtomicSet { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_set (arity 3 -> 0)
751                ArrayAtomicRmwAdd { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_add (atomic rmw array add)
752                ArrayAtomicRmwSub { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_sub (atomic rmw array sub)
753                ArrayAtomicRmwAnd { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_and (atomic rmw array and)
754                ArrayAtomicRmwOr { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_or (atomic rmw array or)
755                ArrayAtomicRmwXor { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_xor (atomic rmw array xor)
756                ArrayAtomicRmwXchg { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_xchg (arity 3 -> 1)
757                ArrayAtomicRmwCmpxchg { ordering: $crate::Ordering, array_type_index: u32 } => visit_array_atomic_rmw_cmpxchg (arity 4 -> 1)
758                RefI31Shared => visit_ref_i31_shared (arity 1 -> 1)
759            }
760
761            // Typed Function references
762            @function_references {
763                CallRef { type_index: u32 } => visit_call_ref (arity 1 type -> type)
764                ReturnCallRef { type_index: u32 } => visit_return_call_ref (arity 1 type -> 0)
765                RefAsNonNull => visit_ref_as_non_null (arity 1 -> 1)
766                BrOnNull { relative_depth: u32 } => visit_br_on_null (arity 1 br -> 1 br)
767                BrOnNonNull { relative_depth: u32 } => visit_br_on_non_null (arity br -> br -1)
768            }
769
770            // Stack switching
771            @stack_switching {
772                ContNew { cont_type_index: u32 } => visit_cont_new (arity 1 -> 1)
773                ContBind { argument_index: u32, result_index: u32 } => visit_cont_bind (arity type_diff 1 -> 1)
774                Suspend { tag_index: u32 } => visit_suspend (arity tag -> tag)
775                Resume { cont_type_index: u32, resume_table: $crate::ResumeTable } => visit_resume (arity 1 type -> type)
776                ResumeThrow { cont_type_index: u32, tag_index: u32, resume_table: $crate::ResumeTable } => visit_resume_throw (arity 1 tag -> type)
777                Switch { cont_type_index: u32, tag_index: u32 } => visit_switch (arity type -> ~switch)
778            }
779
780            @wide_arithmetic {
781                I64Add128 => visit_i64_add128 (arity 4 -> 2)
782                I64Sub128 => visit_i64_sub128 (arity 4 -> 2)
783                I64MulWideS => visit_i64_mul_wide_s (arity 2 -> 2)
784                I64MulWideU => visit_i64_mul_wide_u (arity 2 -> 2)
785            }
786        }
787    };
788}
789
790/// Helper macro to define a `_for_each_non_simd_operator` which receives
791/// the syntax of each instruction individually, but only the non-simd
792/// operators.
793macro_rules! define_for_each_non_simd_operator {
794    // Switch from `_for_each_operator_group` syntax to this macro's syntax to
795    // be a "tt muncher macro"
796    (@ $($t:tt)*) => {define_for_each_non_simd_operator!(filter [] @ $($t)*);};
797
798    // filter out simd/relaxed-simd proposals
799    (filter $filter:tt @simd $simd:tt $($rest:tt)*) => {
800        define_for_each_non_simd_operator!(filter $filter $($rest)*);
801    };
802    (filter $filter:tt @relaxed_simd $simd:tt $($rest:tt)*) => {
803        define_for_each_non_simd_operator!(filter $filter $($rest)*);
804    };
805
806    // For all other proposals add in tokens where the `@proposal` is prepended
807    // before each instruction.
808    (
809        filter [$($t:tt)*]
810        @$proposal:ident {
811            $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
812        }
813        $($rest:tt)*
814    ) => {
815        define_for_each_non_simd_operator!(
816            filter [
817                $($t)*
818                $( @$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*) )*
819            ]
820            $($rest)*
821        );
822    };
823
824    // At the end the `$t` list here is how we want to define
825    // `_for_each_non_simd_operator`, so define the macro with these tokens.
826    (filter [$($t:tt)*]) => {
827        #[macro_export]
828        #[doc(hidden)]
829        macro_rules! _for_each_visit_operator_impl {
830            ($m:ident) => {
831                $m! { $($t)* }
832            }
833        }
834
835        // When simd is disabled then this macro is additionally the
836        // `for_each_operator!` macro implementation
837        #[cfg(not(feature = "simd"))]
838        #[doc(hidden)]
839        pub use _for_each_visit_operator_impl as _for_each_operator_impl;
840    };
841}
842_for_each_operator_group!(define_for_each_non_simd_operator);
843
844/// When the simd feature is enabled then `_for_each_operator_impl` is defined
845/// to be the same as the above `define_for_each_non_simd_operator` macro except
846/// with all proposals thrown in.
847#[cfg(feature = "simd")]
848macro_rules! define_for_each_operator_impl_with_simd {
849    (
850        $(
851            @$proposal:ident {
852                $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
853            }
854        )*
855    ) => {
856        #[macro_export]
857        #[doc(hidden)]
858        macro_rules! _for_each_operator_impl {
859            ($m:ident) => {
860                $m! {
861                    $(
862                        $(
863                            @$proposal $op $({$($arg: $argty),*})? => $visit ($($ann)*)
864                        )*
865                    )*
866                }
867            }
868        }
869    };
870}
871#[cfg(feature = "simd")]
872_for_each_operator_group!(define_for_each_operator_impl_with_simd);
873
874/// Helper macro to define the `_for_each_simd_operator_impl` macro.
875///
876/// This is basically the same as `define_for_each_non_simd_operator` above
877/// except that it's filtering on different proposals.
878#[cfg(feature = "simd")]
879macro_rules! define_for_each_simd_operator {
880    // Switch to "tt muncher" mode
881    (@ $($t:tt)*) => {define_for_each_simd_operator!(filter [] @ $($t)*);};
882
883    // Collect the `@simd` and `@relaxed_simd` proposals.
884    (
885        filter [$($t:tt)*]
886        @simd {
887            $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
888        }
889        $($rest:tt)*
890    ) => {
891        define_for_each_simd_operator!(
892            filter [
893                $($t)*
894                $( @simd $op $({ $($arg: $argty),* })? => $visit ($($ann)*) )*
895            ]
896            $($rest)*
897        );
898    };
899    (
900        filter [$($t:tt)*]
901        @relaxed_simd {
902            $( $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*
903        }
904        $($rest:tt)*
905    ) => {
906        define_for_each_simd_operator!(
907            filter [
908                $($t)*
909                $( @relaxed_simd $op $({ $($arg: $argty),* })? => $visit ($($ann)*) )*
910            ]
911            $($rest)*
912        );
913    };
914
915    // Skip all other proposals.
916    (filter $filter:tt @$proposal:ident $instrs:tt $($rest:tt)*) => {
917        define_for_each_simd_operator!(filter $filter $($rest)*);
918    };
919
920    // Base case to define the base macro.
921    (filter [$($t:tt)*]) => {
922        #[macro_export]
923        #[doc(hidden)]
924        macro_rules! _for_each_visit_simd_operator_impl {
925            ($m:ident) => {
926                $m! { $($t)* }
927            }
928        }
929    };
930}
931#[cfg(feature = "simd")]
932_for_each_operator_group!(define_for_each_simd_operator);
933
934/// Used to implement routines for the [`Operator`] enum.
935///
936/// A helper macro to conveniently iterate over all opcodes recognized by this
937/// crate. This can be used to work with either the [`Operator`] enumeration or
938/// the [`VisitOperator`] trait if your use case uniformly handles all operators
939/// the same way.
940///
941/// It is also possible to specialize handling of operators depending on the
942/// Wasm proposal from which they are originating.
943///
944/// This is an "iterator macro" where this macro is invoked with the name of
945/// another macro, and then that macro is invoked with the list of all
946/// operators.
947///
948/// The list of specializable Wasm proposals is as follows:
949///
950/// - `@mvp`: Denoting a Wasm operator from the initial Wasm MVP version.
951/// - `@exceptions`: [Wasm `exception-handling` proposal]
952/// - `@tail_call`: [Wasm `tail-calls` proposal]
953/// - `@reference_types`: [Wasm `reference-types` proposal]
954/// - `@sign_extension`: [Wasm `sign-extension-ops` proposal]
955/// - `@saturating_float_to_int`: [Wasm `non_trapping_float-to-int-conversions` proposal]
956/// - `@bulk_memory `:[Wasm `bulk-memory` proposal]
957/// - `@simd`: [Wasm `simd` proposal]
958/// - `@relaxed_simd`: [Wasm `relaxed-simd` proposal]
959/// - `@threads`: [Wasm `threads` proposal]
960/// - `@gc`: [Wasm `gc` proposal]
961/// - `@stack_switching`: [Wasm `stack-switching` proposal]
962/// - `@wide_arithmetic`: [Wasm `wide-arithmetic` proposal]
963///
964/// [Wasm `exception-handling` proposal]:
965/// https://github.com/WebAssembly/exception-handling
966///
967/// [Wasm `tail-calls` proposal]:
968/// https://github.com/WebAssembly/tail-call
969///
970/// [Wasm `reference-types` proposal]:
971/// https://github.com/WebAssembly/reference-types
972///
973/// [Wasm `sign-extension-ops` proposal]:
974/// https://github.com/WebAssembly/sign-extension-ops
975///
976/// [Wasm `non_trapping_float-to-int-conversions` proposal]:
977/// https://github.com/WebAssembly/nontrapping-float-to-int-conversions
978///
979/// [Wasm `bulk-memory` proposal]:
980/// https://github.com/WebAssembly/bulk-memory-operations
981///
982/// [Wasm `simd` proposal]:
983/// https://github.com/webassembly/simd
984///
985/// [Wasm `relaxed-simd` proposal]:
986/// https://github.com/WebAssembly/relaxed-simd
987///
988/// [Wasm `threads` proposal]:
989/// https://github.com/webassembly/threads
990///
991/// [Wasm `gc` proposal]:
992/// https://github.com/WebAssembly/gc
993///
994/// [Wasm `stack-switching` proposal]:
995/// https://github.com/WebAssembly/stack-switching
996///
997/// [Wasm `wide-arithmetic` proposal]:
998/// https://github.com/WebAssembly/wide-arithmetic
999///
1000/// ```
1001/// fn do_nothing(op: &inf_wasmparser::Operator) {
1002///     macro_rules! define_match_operator {
1003///         // The outer layer of repetition represents how all operators are
1004///         // provided to the macro at the same time.
1005///         //
1006///         // The `$proposal` identifier indicates the Wasm proposals from which
1007///         // the Wasm operator is originating.
1008///         // For example to specialize the macro match arm for Wasm SIMD proposal
1009///         // operators you could write `@simd` instead of `@$proposal:ident` to
1010///         // only catch those operators.
1011///         //
1012///         // The `$op` name is bound to the `Operator` variant name. The
1013///         // payload of the operator is optionally specified (the `$(...)?`
1014///         // clause) since not all instructions have payloads. Within the payload
1015///         // each argument is named and has its type specified.
1016///         //
1017///         // The `$visit` name is bound to the corresponding name in the
1018///         // `VisitOperator` trait that this corresponds to.
1019///         //
1020///         // The `$ann` annotations give information about the operator's type (e.g. binary i32 or arity 2 -> 1).
1021///         ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1022///             match op {
1023///                 $(
1024///                     inf_wasmparser::Operator::$op $( { $($arg),* } )? => {
1025///                         // do nothing for this example
1026///                     }
1027///                 )*
1028///                 _ => unreachable!(), // required because `Operator` enum is non-exhaustive
1029///             }
1030///         }
1031///     }
1032///     inf_wasmparser::for_each_operator!(define_match_operator);
1033/// }
1034/// ```
1035///
1036/// If you only wanted to visit the initial base set of wasm instructions, for
1037/// example, you could do:
1038///
1039/// ```
1040/// fn is_mvp_operator(op: &inf_wasmparser::Operator) -> bool {
1041///     macro_rules! define_match_operator {
1042///         // delegate the macro invocation to sub-invocations of this macro to
1043///         // deal with each instruction on a case-by-case basis.
1044///         ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1045///             match op {
1046///                 $(
1047///                     inf_wasmparser::Operator::$op $( { $($arg),* } )? => {
1048///                         define_match_operator!(impl_one @$proposal)
1049///                     }
1050///                 )*
1051///                 _ => unreachable!(), // required because `Operator` enum is non-exhaustive
1052///             }
1053///         };
1054///
1055///         (impl_one @mvp) => { true };
1056///         (impl_one @$proposal:ident) => { false };
1057///     }
1058///     inf_wasmparser::for_each_operator!(define_match_operator)
1059/// }
1060/// ```
1061#[doc(inline)]
1062pub use _for_each_operator_impl as for_each_operator;
1063
1064/// Used to implement the [`VisitOperator`] trait.
1065///
1066/// A helper macro to conveniently iterate over all opcodes recognized by this
1067/// crate. This can be used to work with either the [`Operator`] enumeration or
1068/// the [`VisitOperator`] trait if your use case uniformly handles all operators
1069/// the same way.
1070///
1071/// It is also possible to specialize handling of operators depending on the
1072/// Wasm proposal from which they are originating.
1073///
1074/// This is an "iterator macro" where this macro is invoked with the name of
1075/// another macro, and then that macro is invoked with the list of all
1076/// operators.
1077///
1078/// The list of specializable Wasm proposals is as follows:
1079///
1080/// - `@mvp`: Denoting a Wasm operator from the initial Wasm MVP version.
1081/// - `@exceptions`: [Wasm `exception-handling` proposal]
1082/// - `@tail_call`: [Wasm `tail-calls` proposal]
1083/// - `@reference_types`: [Wasm `reference-types` proposal]
1084/// - `@sign_extension`: [Wasm `sign-extension-ops` proposal]
1085/// - `@saturating_float_to_int`: [Wasm `non_trapping_float-to-int-conversions` proposal]
1086/// - `@bulk_memory `:[Wasm `bulk-memory` proposal]
1087/// - `@threads`: [Wasm `threads` proposal]
1088/// - `@gc`: [Wasm `gc` proposal]
1089/// - `@stack_switching`: [Wasm `stack-switching` proposal]
1090/// - `@wide_arithmetic`: [Wasm `wide-arithmetic` proposal]
1091///
1092/// Note that this macro does not iterate over the SIMD-related proposals. Those
1093/// are provided in [`VisitSimdOperator`] and [`for_each_visit_simd_operator`].
1094/// This macro only handles non-SIMD related operators and so users wanting to
1095/// handle the SIMD-class of operators need to use that trait/macro as well.
1096///
1097/// [Wasm `exception-handling` proposal]:
1098/// https://github.com/WebAssembly/exception-handling
1099///
1100/// [Wasm `tail-calls` proposal]:
1101/// https://github.com/WebAssembly/tail-call
1102///
1103/// [Wasm `reference-types` proposal]:
1104/// https://github.com/WebAssembly/reference-types
1105///
1106/// [Wasm `sign-extension-ops` proposal]:
1107/// https://github.com/WebAssembly/sign-extension-ops
1108///
1109/// [Wasm `non_trapping_float-to-int-conversions` proposal]:
1110/// https://github.com/WebAssembly/nontrapping-float-to-int-conversions
1111///
1112/// [Wasm `bulk-memory` proposal]:
1113/// https://github.com/WebAssembly/bulk-memory-operations
1114/// [Wasm `simd` proposal]:
1115/// https://github.com/webassembly/simd
1116///
1117/// [Wasm `relaxed-simd` proposal]:
1118/// https://github.com/WebAssembly/relaxed-simd
1119///
1120/// [Wasm `threads` proposal]:
1121/// https://github.com/webassembly/threads
1122///
1123/// [Wasm `gc` proposal]:
1124/// https://github.com/WebAssembly/gc
1125///
1126/// [Wasm `stack-switching` proposal]:
1127/// https://github.com/WebAssembly/stack-switching
1128///
1129/// [Wasm `wide-arithmetic` proposal]:
1130/// https://github.com/WebAssembly/wide-arithmetic
1131///
1132/// ```
1133/// macro_rules! define_visit_operator {
1134///     // The outer layer of repetition represents how all operators are
1135///     // provided to the macro at the same time.
1136///     //
1137///     // The `$proposal` identifier indicates the Wasm proposals from which
1138///     // the Wasm operator is originating.
1139///     // For example to specialize the macro match arm for Wasm `gc` proposal
1140///     // operators you could write `@gc` instead of `@$proposal:ident` to
1141///     // only catch those operators.
1142///     //
1143///     // The `$op` name is bound to the `Operator` variant name. The
1144///     // payload of the operator is optionally specified (the `$(...)?`
1145///     // clause) since not all instructions have payloads. Within the payload
1146///     // each argument is named and has its type specified.
1147///     //
1148///     // The `$visit` name is bound to the corresponding name in the
1149///     // `VisitOperator` trait that this corresponds to.
1150///     //
1151///     // The `$ann` annotations give information about the operator's type (e.g. binary i32 or arity 2 -> 1).
1152///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1153///         $(
1154///             fn $visit(&mut self $($(,$arg: $argty)*)?) {
1155///                 // do nothing for this example
1156///             }
1157///         )*
1158///     }
1159/// }
1160///
1161/// pub struct VisitAndDoNothing;
1162///
1163/// impl<'a> inf_wasmparser::VisitOperator<'a> for VisitAndDoNothing {
1164///     type Output = ();
1165///
1166///     inf_wasmparser::for_each_visit_operator!(define_visit_operator);
1167/// }
1168/// ```
1169///
1170/// If you only wanted to visit the initial base set of wasm instructions, for
1171/// example, you could do:
1172///
1173/// ```
1174/// macro_rules! visit_only_mvp {
1175///     // delegate the macro invocation to sub-invocations of this macro to
1176///     // deal with each instruction on a case-by-case basis.
1177///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1178///         $(
1179///             visit_only_mvp!(visit_one @$proposal $op $({ $($arg: $argty),* })? => $visit);
1180///         )*
1181///     };
1182///
1183///     // MVP instructions are defined manually, so do nothing.
1184///     (visit_one @mvp $($rest:tt)*) => {};
1185///
1186///     // Non-MVP instructions all return `false` here. The exact type depends
1187///     // on `type Output` in the trait implementation below. You could change
1188///     // it to `Result<()>` for example and return an error here too.
1189///     (visit_one @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => {
1190///         fn $visit(&mut self $($(,$arg: $argty)*)?) -> bool {
1191///             false
1192///         }
1193///     }
1194/// }
1195/// # // to get this example to compile another macro is used here to define
1196/// # // visit methods for all mvp oeprators.
1197/// # macro_rules! visit_mvp {
1198/// #     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1199/// #         $(
1200/// #             visit_mvp!(visit_one @$proposal $op $({ $($arg: $argty),* })? => $visit);
1201/// #         )*
1202/// #     };
1203/// #     (visit_one @mvp $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident) => {
1204/// #         fn $visit(&mut self $($(,$arg: $argty)*)?) -> bool {
1205/// #             true
1206/// #         }
1207/// #     };
1208/// #     (visit_one @$proposal:ident $($rest:tt)*) => {};
1209/// # }
1210///
1211/// pub struct VisitOnlyMvp;
1212///
1213/// impl<'a> inf_wasmparser::VisitOperator<'a> for VisitOnlyMvp {
1214///     type Output = bool;
1215///
1216///     inf_wasmparser::for_each_visit_operator!(visit_only_mvp);
1217/// #   inf_wasmparser::for_each_visit_operator!(visit_mvp);
1218///
1219///     // manually define `visit_*` for all MVP operators here
1220/// }
1221/// ```
1222#[doc(inline)]
1223pub use _for_each_visit_operator_impl as for_each_visit_operator;
1224
1225/// Used to implement the [`VisitSimdOperator`] trait.
1226///
1227/// The list of specializable Wasm proposals is as follows:
1228///
1229/// - `@simd`: [Wasm `simd` proposal]
1230/// - `@relaxed_simd`: [Wasm `relaxed-simd` proposal]
1231///
1232/// For more information about the structure and use of this macro please
1233/// refer to the documentation of the [`for_each_operator`] macro.
1234///
1235/// [Wasm `simd` proposal]:
1236/// https://github.com/webassembly/simd
1237///
1238/// [Wasm `relaxed-simd` proposal]:
1239/// https://github.com/WebAssembly/relaxed-simd
1240///
1241/// [`VisitSimdOperator`]: crate::VisitSimdOperator
1242///
1243/// ```
1244/// # macro_rules! define_visit_operator {
1245/// #     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1246/// #         $( fn $visit(&mut self $($(,$arg: $argty)*)?) {} )*
1247/// #     }
1248/// # }
1249/// pub struct VisitAndDoNothing;
1250///
1251/// impl<'a> inf_wasmparser::VisitOperator<'a> for VisitAndDoNothing {
1252///     type Output = ();
1253///
1254///     // implement all the visit methods ..
1255///     # inf_wasmparser::for_each_visit_operator!(define_visit_operator);
1256/// }
1257///
1258/// macro_rules! define_visit_simd_operator {
1259///     // The outer layer of repetition represents how all operators are
1260///     // provided to the macro at the same time.
1261///     //
1262///     // The `$proposal` identifier is either `@simd` or `@relaxed_simd`.
1263///     //
1264///     // The shape of this macro is identical to [`for_each_visit_operator`].
1265///     // Please refer to its documentation if you want to learn more.
1266///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
1267///         $(
1268///             fn $visit(&mut self $($(,$arg: $argty)*)?) {
1269///                 // do nothing for this example
1270///             }
1271///         )*
1272///     }
1273/// }
1274///
1275/// impl<'a> inf_wasmparser::VisitSimdOperator<'a> for VisitAndDoNothing {
1276///     inf_wasmparser::for_each_visit_simd_operator!(define_visit_simd_operator);
1277/// }
1278/// ```
1279#[cfg(feature = "simd")]
1280#[doc(inline)]
1281pub use _for_each_visit_simd_operator_impl as for_each_visit_simd_operator;
1282
1283macro_rules! format_err {
1284    ($offset:expr, $($arg:tt)*) => {
1285        crate::BinaryReaderError::fmt(format_args!($($arg)*), $offset)
1286    }
1287}
1288
1289macro_rules! bail {
1290    ($($arg:tt)*) => {return Err(format_err!($($arg)*))}
1291}
1292
1293pub use crate::arity::*;
1294pub use crate::binary_reader::{BinaryReader, BinaryReaderError, Result};
1295pub use crate::features::*;
1296pub use crate::parser::*;
1297pub use crate::readers::*;
1298
1299mod arity;
1300mod binary_reader;
1301mod features;
1302mod limits;
1303mod parser;
1304mod readers;
1305
1306#[cfg(feature = "validate")]
1307mod resources;
1308#[cfg(feature = "validate")]
1309mod validator;
1310#[cfg(feature = "validate")]
1311pub use crate::resources::*;
1312#[cfg(feature = "validate")]
1313pub use crate::validator::*;
1314
1315#[cfg(feature = "validate")]
1316pub mod collections;