tinywasm_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#![no_std]
30#![deny(missing_docs)]
31extern crate alloc;
32mod std;
33
34/// A helper macro to conveniently iterate over all opcodes recognized by this
35/// crate. This can be used to work with either the [`Operator`] enumeration or
36/// the [`VisitOperator`] trait if your use case uniformly handles all operators
37/// the same way.
38///
39/// It is also possible to specialize handling of operators depending on the
40/// Wasm proposal from which they are originating.
41///
42/// This is an "iterator macro" where this macro is invoked with the name of
43/// another macro, and then that macro is invoked with the list of all
44/// operators. An example invocation of this looks like:
45///
46/// The list of specializable Wasm proposals is as follows:
47///
48/// - `@mvp`: Denoting a Wasm operator from the initial Wasm MVP version.
49/// - `@exceptions`: [Wasm `expection-handling` proposal]
50/// - `@tail_call`: [Wasm `tail-calls` proposal]
51/// - `@reference_types`: [Wasm `reference-types` proposal]
52/// - `@sign_extension`: [Wasm `sign-extension-ops` proposal]
53/// - `@saturating_float_to_int`: [Wasm `non_trapping_float-to-int-conversions` proposal]
54/// - `@bulk_memory `:[Wasm `bulk-memory` proposal]
55/// - `@threads`: [Wasm `threads` proposal]
56/// - `@simd`: [Wasm `simd` proposal]
57/// - `@relaxed_simd`: [Wasm `relaxed-simd` proposal]
58/// - `@gc`: [Wasm `gc` proposal]
59///
60/// [Wasm `expection-handling` proposal]:
61/// https://github.com/WebAssembly/exception-handling
62///
63/// [Wasm `tail-calls` proposal]:
64/// https://github.com/WebAssembly/tail-call
65///
66/// [Wasm `reference-types` proposal]:
67/// https://github.com/WebAssembly/reference-types
68///
69/// [Wasm `sign-extension-ops` proposal]:
70/// https://github.com/WebAssembly/sign-extension-ops
71///
72/// [Wasm `non_trapping_float-to-int-conversions` proposal]:
73/// https://github.com/WebAssembly/nontrapping-float-to-int-conversions
74///
75/// [Wasm `bulk-memory` proposal]:
76/// https://github.com/WebAssembly/bulk-memory-operations
77///
78/// [Wasm `threads` proposal]:
79/// https://github.com/webassembly/threads
80///
81/// [Wasm `simd` proposal]:
82/// https://github.com/webassembly/simd
83///
84/// [Wasm `relaxed-simd` proposal]:
85/// https://github.com/WebAssembly/relaxed-simd
86///
87/// [Wasm `gc` proposal]:
88/// https://github.com/WebAssembly/gc
89///
90/// ```
91/// macro_rules! define_visit_operator {
92///     // The outer layer of repetition represents how all operators are
93///     // provided to the macro at the same time.
94///     //
95///     // The `$proposal` identifier indicates the Wasm proposals from which
96///     // the Wasm operator is originating.
97///     // For example to specialize the macro match arm for Wasm SIMD proposal
98///     // operators you could write `@simd` instead of `@$proposal:ident` to
99///     // only catch those operators.
100///     //
101///     // The `$op` name is bound to the `Operator` variant name. The
102///     // payload of the operator is optionally specified (the `$(...)?`
103///     // clause) since not all instructions have payloads. Within the payload
104///     // each argument is named and has its type specified.
105///     //
106///     // The `$visit` name is bound to the corresponding name in the
107///     // `VisitOperator` trait that this corresponds to.
108///     ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => {
109///         $(
110///             fn $visit(&mut self $($(,$arg: $argty)*)?) {
111///                 // do nothing for this example
112///             }
113///         )*
114///     }
115/// }
116///
117/// pub struct VisitAndDoNothing;
118///
119/// impl<'a> tinywasm_wasmparser::VisitOperator<'a> for VisitAndDoNothing {
120///     type Output = ();
121///
122///     tinywasm_wasmparser::for_each_operator!(define_visit_operator);
123/// }
124/// ```
125#[macro_export]
126macro_rules! for_each_operator {
127    ($mac:ident) => {
128        $mac! {
129            @mvp Unreachable => visit_unreachable
130            @mvp Nop => visit_nop
131            @mvp Block { blockty: $crate::BlockType } => visit_block
132            @mvp Loop { blockty: $crate::BlockType } => visit_loop
133            @mvp If { blockty: $crate::BlockType } => visit_if
134            @mvp Else => visit_else
135            @exceptions TryTable { try_table: $crate::TryTable } => visit_try_table
136            @exceptions Throw { tag_index: u32 } => visit_throw
137            @exceptions ThrowRef => visit_throw_ref
138            // Deprecated old instructions from the exceptions proposal
139            @exceptions Try { blockty: $crate::BlockType } => visit_try
140            @exceptions Catch { tag_index: u32 } => visit_catch
141            @exceptions Rethrow { relative_depth: u32 } => visit_rethrow
142            @exceptions Delegate { relative_depth: u32 } => visit_delegate
143            @exceptions CatchAll => visit_catch_all
144            @mvp End => visit_end
145            @mvp Br { relative_depth: u32 } => visit_br
146            @mvp BrIf { relative_depth: u32 } => visit_br_if
147            @mvp BrTable { targets: $crate::BrTable<'a> } => visit_br_table
148            @mvp Return => visit_return
149            @mvp Call { function_index: u32 } => visit_call
150            @mvp CallIndirect { type_index: u32, table_index: u32, table_byte: u8 } => visit_call_indirect
151            @tail_call ReturnCall { function_index: u32 } => visit_return_call
152            @tail_call ReturnCallIndirect { type_index: u32, table_index: u32 } => visit_return_call_indirect
153            @mvp Drop => visit_drop
154            @mvp Select => visit_select
155            @reference_types TypedSelect { ty: $crate::ValType } => visit_typed_select
156            @mvp LocalGet { local_index: u32 } => visit_local_get
157            @mvp LocalSet { local_index: u32 } => visit_local_set
158            @mvp LocalTee { local_index: u32 } => visit_local_tee
159            @mvp GlobalGet { global_index: u32 } => visit_global_get
160            @mvp GlobalSet { global_index: u32 } => visit_global_set
161            @mvp I32Load { memarg: $crate::MemArg } => visit_i32_load
162            @mvp I64Load { memarg: $crate::MemArg } => visit_i64_load
163            @mvp F32Load { memarg: $crate::MemArg } => visit_f32_load
164            @mvp F64Load { memarg: $crate::MemArg } => visit_f64_load
165            @mvp I32Load8S { memarg: $crate::MemArg } => visit_i32_load8_s
166            @mvp I32Load8U { memarg: $crate::MemArg } => visit_i32_load8_u
167            @mvp I32Load16S { memarg: $crate::MemArg } => visit_i32_load16_s
168            @mvp I32Load16U { memarg: $crate::MemArg } => visit_i32_load16_u
169            @mvp I64Load8S { memarg: $crate::MemArg } => visit_i64_load8_s
170            @mvp I64Load8U { memarg: $crate::MemArg } => visit_i64_load8_u
171            @mvp I64Load16S { memarg: $crate::MemArg } => visit_i64_load16_s
172            @mvp I64Load16U { memarg: $crate::MemArg } => visit_i64_load16_u
173            @mvp I64Load32S { memarg: $crate::MemArg } => visit_i64_load32_s
174            @mvp I64Load32U { memarg: $crate::MemArg } => visit_i64_load32_u
175            @mvp I32Store { memarg: $crate::MemArg } => visit_i32_store
176            @mvp I64Store { memarg: $crate::MemArg } => visit_i64_store
177            @mvp F32Store { memarg: $crate::MemArg } => visit_f32_store
178            @mvp F64Store { memarg: $crate::MemArg } => visit_f64_store
179            @mvp I32Store8 { memarg: $crate::MemArg } => visit_i32_store8
180            @mvp I32Store16 { memarg: $crate::MemArg } => visit_i32_store16
181            @mvp I64Store8 { memarg: $crate::MemArg } => visit_i64_store8
182            @mvp I64Store16 { memarg: $crate::MemArg } => visit_i64_store16
183            @mvp I64Store32 { memarg: $crate::MemArg } => visit_i64_store32
184            @mvp MemorySize { mem: u32, mem_byte: u8 } => visit_memory_size
185            @mvp MemoryGrow { mem: u32, mem_byte: u8 } => visit_memory_grow
186            @mvp I32Const { value: i32 } => visit_i32_const
187            @mvp I64Const { value: i64 } => visit_i64_const
188            @mvp F32Const { value: $crate::Ieee32 } => visit_f32_const
189            @mvp F64Const { value: $crate::Ieee64 } => visit_f64_const
190            @reference_types RefNull { hty: $crate::HeapType } => visit_ref_null
191            @reference_types RefIsNull => visit_ref_is_null
192            @reference_types RefFunc { function_index: u32 } => visit_ref_func
193            @gc RefEq => visit_ref_eq
194            @mvp I32Eqz => visit_i32_eqz
195            @mvp I32Eq => visit_i32_eq
196            @mvp I32Ne => visit_i32_ne
197            @mvp I32LtS => visit_i32_lt_s
198            @mvp I32LtU => visit_i32_lt_u
199            @mvp I32GtS => visit_i32_gt_s
200            @mvp I32GtU => visit_i32_gt_u
201            @mvp I32LeS => visit_i32_le_s
202            @mvp I32LeU => visit_i32_le_u
203            @mvp I32GeS => visit_i32_ge_s
204            @mvp I32GeU => visit_i32_ge_u
205            @mvp I64Eqz => visit_i64_eqz
206            @mvp I64Eq => visit_i64_eq
207            @mvp I64Ne => visit_i64_ne
208            @mvp I64LtS => visit_i64_lt_s
209            @mvp I64LtU => visit_i64_lt_u
210            @mvp I64GtS => visit_i64_gt_s
211            @mvp I64GtU => visit_i64_gt_u
212            @mvp I64LeS => visit_i64_le_s
213            @mvp I64LeU => visit_i64_le_u
214            @mvp I64GeS => visit_i64_ge_s
215            @mvp I64GeU => visit_i64_ge_u
216            @mvp F32Eq => visit_f32_eq
217            @mvp F32Ne => visit_f32_ne
218            @mvp F32Lt => visit_f32_lt
219            @mvp F32Gt => visit_f32_gt
220            @mvp F32Le => visit_f32_le
221            @mvp F32Ge => visit_f32_ge
222            @mvp F64Eq => visit_f64_eq
223            @mvp F64Ne => visit_f64_ne
224            @mvp F64Lt => visit_f64_lt
225            @mvp F64Gt => visit_f64_gt
226            @mvp F64Le => visit_f64_le
227            @mvp F64Ge => visit_f64_ge
228            @mvp I32Clz => visit_i32_clz
229            @mvp I32Ctz => visit_i32_ctz
230            @mvp I32Popcnt => visit_i32_popcnt
231            @mvp I32Add => visit_i32_add
232            @mvp I32Sub => visit_i32_sub
233            @mvp I32Mul => visit_i32_mul
234            @mvp I32DivS => visit_i32_div_s
235            @mvp I32DivU => visit_i32_div_u
236            @mvp I32RemS => visit_i32_rem_s
237            @mvp I32RemU => visit_i32_rem_u
238            @mvp I32And => visit_i32_and
239            @mvp I32Or => visit_i32_or
240            @mvp I32Xor => visit_i32_xor
241            @mvp I32Shl => visit_i32_shl
242            @mvp I32ShrS => visit_i32_shr_s
243            @mvp I32ShrU => visit_i32_shr_u
244            @mvp I32Rotl => visit_i32_rotl
245            @mvp I32Rotr => visit_i32_rotr
246            @mvp I64Clz => visit_i64_clz
247            @mvp I64Ctz => visit_i64_ctz
248            @mvp I64Popcnt => visit_i64_popcnt
249            @mvp I64Add => visit_i64_add
250            @mvp I64Sub => visit_i64_sub
251            @mvp I64Mul => visit_i64_mul
252            @mvp I64DivS => visit_i64_div_s
253            @mvp I64DivU => visit_i64_div_u
254            @mvp I64RemS => visit_i64_rem_s
255            @mvp I64RemU => visit_i64_rem_u
256            @mvp I64And => visit_i64_and
257            @mvp I64Or => visit_i64_or
258            @mvp I64Xor => visit_i64_xor
259            @mvp I64Shl => visit_i64_shl
260            @mvp I64ShrS => visit_i64_shr_s
261            @mvp I64ShrU => visit_i64_shr_u
262            @mvp I64Rotl => visit_i64_rotl
263            @mvp I64Rotr => visit_i64_rotr
264            @mvp F32Abs => visit_f32_abs
265            @mvp F32Neg => visit_f32_neg
266            @mvp F32Ceil => visit_f32_ceil
267            @mvp F32Floor => visit_f32_floor
268            @mvp F32Trunc => visit_f32_trunc
269            @mvp F32Nearest => visit_f32_nearest
270            @mvp F32Sqrt => visit_f32_sqrt
271            @mvp F32Add => visit_f32_add
272            @mvp F32Sub => visit_f32_sub
273            @mvp F32Mul => visit_f32_mul
274            @mvp F32Div => visit_f32_div
275            @mvp F32Min => visit_f32_min
276            @mvp F32Max => visit_f32_max
277            @mvp F32Copysign => visit_f32_copysign
278            @mvp F64Abs => visit_f64_abs
279            @mvp F64Neg => visit_f64_neg
280            @mvp F64Ceil => visit_f64_ceil
281            @mvp F64Floor => visit_f64_floor
282            @mvp F64Trunc => visit_f64_trunc
283            @mvp F64Nearest => visit_f64_nearest
284            @mvp F64Sqrt => visit_f64_sqrt
285            @mvp F64Add => visit_f64_add
286            @mvp F64Sub => visit_f64_sub
287            @mvp F64Mul => visit_f64_mul
288            @mvp F64Div => visit_f64_div
289            @mvp F64Min => visit_f64_min
290            @mvp F64Max => visit_f64_max
291            @mvp F64Copysign => visit_f64_copysign
292            @mvp I32WrapI64 => visit_i32_wrap_i64
293            @mvp I32TruncF32S => visit_i32_trunc_f32_s
294            @mvp I32TruncF32U => visit_i32_trunc_f32_u
295            @mvp I32TruncF64S => visit_i32_trunc_f64_s
296            @mvp I32TruncF64U => visit_i32_trunc_f64_u
297            @mvp I64ExtendI32S => visit_i64_extend_i32_s
298            @mvp I64ExtendI32U => visit_i64_extend_i32_u
299            @mvp I64TruncF32S => visit_i64_trunc_f32_s
300            @mvp I64TruncF32U => visit_i64_trunc_f32_u
301            @mvp I64TruncF64S => visit_i64_trunc_f64_s
302            @mvp I64TruncF64U => visit_i64_trunc_f64_u
303            @mvp F32ConvertI32S => visit_f32_convert_i32_s
304            @mvp F32ConvertI32U => visit_f32_convert_i32_u
305            @mvp F32ConvertI64S => visit_f32_convert_i64_s
306            @mvp F32ConvertI64U => visit_f32_convert_i64_u
307            @mvp F32DemoteF64 => visit_f32_demote_f64
308            @mvp F64ConvertI32S => visit_f64_convert_i32_s
309            @mvp F64ConvertI32U => visit_f64_convert_i32_u
310            @mvp F64ConvertI64S => visit_f64_convert_i64_s
311            @mvp F64ConvertI64U => visit_f64_convert_i64_u
312            @mvp F64PromoteF32 => visit_f64_promote_f32
313            @mvp I32ReinterpretF32 => visit_i32_reinterpret_f32
314            @mvp I64ReinterpretF64 => visit_i64_reinterpret_f64
315            @mvp F32ReinterpretI32 => visit_f32_reinterpret_i32
316            @mvp F64ReinterpretI64 => visit_f64_reinterpret_i64
317            @sign_extension I32Extend8S => visit_i32_extend8_s
318            @sign_extension I32Extend16S => visit_i32_extend16_s
319            @sign_extension I64Extend8S => visit_i64_extend8_s
320            @sign_extension I64Extend16S => visit_i64_extend16_s
321            @sign_extension I64Extend32S => visit_i64_extend32_s
322
323            // 0xFB prefixed operators
324            // Garbage Collection
325            // http://github.com/WebAssembly/gc
326            @gc StructNew { struct_type_index: u32 } => visit_struct_new
327            @gc StructNewDefault { struct_type_index: u32 } => visit_struct_new_default
328            @gc StructGet { struct_type_index: u32, field_index: u32 } => visit_struct_get
329            @gc StructGetS { struct_type_index: u32, field_index: u32 } => visit_struct_get_s
330            @gc StructGetU { struct_type_index: u32, field_index: u32 } => visit_struct_get_u
331                @gc StructSet { struct_type_index: u32, field_index: u32 } => visit_struct_set
332            @gc ArrayNew { array_type_index: u32 } => visit_array_new
333            @gc ArrayNewDefault { array_type_index: u32 } => visit_array_new_default
334            @gc ArrayNewFixed { array_type_index: u32, array_size: u32 } => visit_array_new_fixed
335            @gc ArrayNewData { array_type_index: u32, array_data_index: u32 } => visit_array_new_data
336            @gc ArrayNewElem { array_type_index: u32, array_elem_index: u32 } => visit_array_new_elem
337            @gc ArrayGet { array_type_index: u32 } => visit_array_get
338            @gc ArrayGetS { array_type_index: u32 } => visit_array_get_s
339            @gc ArrayGetU { array_type_index: u32 } => visit_array_get_u
340            @gc ArraySet { array_type_index: u32 } => visit_array_set
341            @gc ArrayLen => visit_array_len
342            @gc ArrayFill { array_type_index: u32 } => visit_array_fill
343            @gc ArrayCopy { array_type_index_dst: u32, array_type_index_src: u32 } => visit_array_copy
344            @gc ArrayInitData { array_type_index: u32, array_data_index: u32 } => visit_array_init_data
345            @gc ArrayInitElem { array_type_index: u32, array_elem_index: u32 } => visit_array_init_elem
346            @gc RefTestNonNull { hty: $crate::HeapType } => visit_ref_test_non_null
347            @gc RefTestNullable { hty: $crate::HeapType } => visit_ref_test_nullable
348            @gc RefCastNonNull { hty: $crate::HeapType } => visit_ref_cast_non_null
349            @gc RefCastNullable { hty: $crate::HeapType } => visit_ref_cast_nullable
350            @gc BrOnCast {
351                relative_depth: u32,
352                from_ref_type: $crate::RefType,
353                to_ref_type: $crate::RefType
354            } => visit_br_on_cast
355            @gc BrOnCastFail {
356                relative_depth: u32,
357                from_ref_type: $crate::RefType,
358                to_ref_type: $crate::RefType
359            } => visit_br_on_cast_fail
360            @gc AnyConvertExtern => visit_any_convert_extern
361            @gc ExternConvertAny => visit_extern_convert_any
362            @gc RefI31 => visit_ref_i31
363            @gc I31GetS => visit_i31_get_s
364            @gc I31GetU => visit_i31_get_u
365
366            // 0xFC operators
367            // Non-trapping Float-to-int Conversions
368            // https://github.com/WebAssembly/nontrapping-float-to-int-conversions
369            @saturating_float_to_int I32TruncSatF32S => visit_i32_trunc_sat_f32_s
370            @saturating_float_to_int I32TruncSatF32U => visit_i32_trunc_sat_f32_u
371            @saturating_float_to_int I32TruncSatF64S => visit_i32_trunc_sat_f64_s
372            @saturating_float_to_int I32TruncSatF64U => visit_i32_trunc_sat_f64_u
373            @saturating_float_to_int I64TruncSatF32S => visit_i64_trunc_sat_f32_s
374            @saturating_float_to_int I64TruncSatF32U => visit_i64_trunc_sat_f32_u
375            @saturating_float_to_int I64TruncSatF64S => visit_i64_trunc_sat_f64_s
376            @saturating_float_to_int I64TruncSatF64U => visit_i64_trunc_sat_f64_u
377
378            // 0xFC prefixed operators
379            // bulk memory operations
380            // https://github.com/WebAssembly/bulk-memory-operations
381            @bulk_memory MemoryInit { data_index: u32, mem: u32 } => visit_memory_init
382            @bulk_memory DataDrop { data_index: u32 } => visit_data_drop
383            @bulk_memory MemoryCopy { dst_mem: u32, src_mem: u32 } => visit_memory_copy
384            @bulk_memory MemoryFill { mem: u32 } => visit_memory_fill
385            @bulk_memory TableInit { elem_index: u32, table: u32 } => visit_table_init
386            @bulk_memory ElemDrop { elem_index: u32 } => visit_elem_drop
387            @bulk_memory TableCopy { dst_table: u32, src_table: u32 } => visit_table_copy
388
389            // 0xFC prefixed operators
390            // reference-types
391            // https://github.com/WebAssembly/reference-types
392            @reference_types TableFill { table: u32 } => visit_table_fill
393            @reference_types TableGet { table: u32 } => visit_table_get
394            @reference_types TableSet { table: u32 } => visit_table_set
395            @reference_types TableGrow { table: u32 } => visit_table_grow
396            @reference_types TableSize { table: u32 } => visit_table_size
397
398            // OxFC prefixed operators
399            // memory control (experimental)
400            // https://github.com/WebAssembly/design/issues/1439
401            @memory_control MemoryDiscard { mem: u32 } => visit_memory_discard
402
403            // 0xFE prefixed operators
404            // threads
405            // https://github.com/WebAssembly/threads
406            @threads MemoryAtomicNotify { memarg: $crate::MemArg } => visit_memory_atomic_notify
407            @threads MemoryAtomicWait32 { memarg: $crate::MemArg } => visit_memory_atomic_wait32
408            @threads MemoryAtomicWait64 { memarg: $crate::MemArg } => visit_memory_atomic_wait64
409            @threads AtomicFence => visit_atomic_fence
410            @threads I32AtomicLoad { memarg: $crate::MemArg } => visit_i32_atomic_load
411            @threads I64AtomicLoad { memarg: $crate::MemArg } => visit_i64_atomic_load
412            @threads I32AtomicLoad8U { memarg: $crate::MemArg } => visit_i32_atomic_load8_u
413            @threads I32AtomicLoad16U { memarg: $crate::MemArg } => visit_i32_atomic_load16_u
414            @threads I64AtomicLoad8U { memarg: $crate::MemArg } => visit_i64_atomic_load8_u
415            @threads I64AtomicLoad16U { memarg: $crate::MemArg } => visit_i64_atomic_load16_u
416            @threads I64AtomicLoad32U { memarg: $crate::MemArg } => visit_i64_atomic_load32_u
417            @threads I32AtomicStore { memarg: $crate::MemArg } => visit_i32_atomic_store
418            @threads I64AtomicStore { memarg: $crate::MemArg } => visit_i64_atomic_store
419            @threads I32AtomicStore8 { memarg: $crate::MemArg } => visit_i32_atomic_store8
420            @threads I32AtomicStore16 { memarg: $crate::MemArg } => visit_i32_atomic_store16
421            @threads I64AtomicStore8 { memarg: $crate::MemArg } => visit_i64_atomic_store8
422            @threads I64AtomicStore16 { memarg: $crate::MemArg } => visit_i64_atomic_store16
423            @threads I64AtomicStore32 { memarg: $crate::MemArg } => visit_i64_atomic_store32
424            @threads I32AtomicRmwAdd { memarg: $crate::MemArg } => visit_i32_atomic_rmw_add
425            @threads I64AtomicRmwAdd { memarg: $crate::MemArg } => visit_i64_atomic_rmw_add
426            @threads I32AtomicRmw8AddU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_add_u
427            @threads I32AtomicRmw16AddU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_add_u
428            @threads I64AtomicRmw8AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_add_u
429            @threads I64AtomicRmw16AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_add_u
430            @threads I64AtomicRmw32AddU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_add_u
431            @threads I32AtomicRmwSub { memarg: $crate::MemArg } => visit_i32_atomic_rmw_sub
432            @threads I64AtomicRmwSub { memarg: $crate::MemArg } => visit_i64_atomic_rmw_sub
433            @threads I32AtomicRmw8SubU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_sub_u
434            @threads I32AtomicRmw16SubU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_sub_u
435            @threads I64AtomicRmw8SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_sub_u
436            @threads I64AtomicRmw16SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_sub_u
437            @threads I64AtomicRmw32SubU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_sub_u
438            @threads I32AtomicRmwAnd { memarg: $crate::MemArg } => visit_i32_atomic_rmw_and
439            @threads I64AtomicRmwAnd { memarg: $crate::MemArg } => visit_i64_atomic_rmw_and
440            @threads I32AtomicRmw8AndU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_and_u
441            @threads I32AtomicRmw16AndU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_and_u
442            @threads I64AtomicRmw8AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_and_u
443            @threads I64AtomicRmw16AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_and_u
444            @threads I64AtomicRmw32AndU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_and_u
445            @threads I32AtomicRmwOr { memarg: $crate::MemArg } => visit_i32_atomic_rmw_or
446            @threads I64AtomicRmwOr { memarg: $crate::MemArg } => visit_i64_atomic_rmw_or
447            @threads I32AtomicRmw8OrU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_or_u
448            @threads I32AtomicRmw16OrU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_or_u
449            @threads I64AtomicRmw8OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_or_u
450            @threads I64AtomicRmw16OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_or_u
451            @threads I64AtomicRmw32OrU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_or_u
452            @threads I32AtomicRmwXor { memarg: $crate::MemArg } => visit_i32_atomic_rmw_xor
453            @threads I64AtomicRmwXor { memarg: $crate::MemArg } => visit_i64_atomic_rmw_xor
454            @threads I32AtomicRmw8XorU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_xor_u
455            @threads I32AtomicRmw16XorU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_xor_u
456            @threads I64AtomicRmw8XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_xor_u
457            @threads I64AtomicRmw16XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_xor_u
458            @threads I64AtomicRmw32XorU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_xor_u
459            @threads I32AtomicRmwXchg { memarg: $crate::MemArg } => visit_i32_atomic_rmw_xchg
460            @threads I64AtomicRmwXchg { memarg: $crate::MemArg } => visit_i64_atomic_rmw_xchg
461            @threads I32AtomicRmw8XchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_xchg_u
462            @threads I32AtomicRmw16XchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_xchg_u
463            @threads I64AtomicRmw8XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_xchg_u
464            @threads I64AtomicRmw16XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_xchg_u
465            @threads I64AtomicRmw32XchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_xchg_u
466            @threads I32AtomicRmwCmpxchg { memarg: $crate::MemArg } => visit_i32_atomic_rmw_cmpxchg
467            @threads I64AtomicRmwCmpxchg { memarg: $crate::MemArg } => visit_i64_atomic_rmw_cmpxchg
468            @threads I32AtomicRmw8CmpxchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw8_cmpxchg_u
469            @threads I32AtomicRmw16CmpxchgU { memarg: $crate::MemArg } => visit_i32_atomic_rmw16_cmpxchg_u
470            @threads I64AtomicRmw8CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw8_cmpxchg_u
471            @threads I64AtomicRmw16CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw16_cmpxchg_u
472            @threads I64AtomicRmw32CmpxchgU { memarg: $crate::MemArg } => visit_i64_atomic_rmw32_cmpxchg_u
473
474            // 0xFD operators
475            // 128-bit SIMD
476            // - https://github.com/webassembly/simd
477            // - https://webassembly.github.io/simd/core/binary/instructions.html
478            @simd V128Load { memarg: $crate::MemArg } => visit_v128_load
479            @simd V128Load8x8S { memarg: $crate::MemArg } => visit_v128_load8x8_s
480            @simd V128Load8x8U { memarg: $crate::MemArg } => visit_v128_load8x8_u
481            @simd V128Load16x4S { memarg: $crate::MemArg } => visit_v128_load16x4_s
482            @simd V128Load16x4U { memarg: $crate::MemArg } => visit_v128_load16x4_u
483            @simd V128Load32x2S { memarg: $crate::MemArg } => visit_v128_load32x2_s
484            @simd V128Load32x2U { memarg: $crate::MemArg } => visit_v128_load32x2_u
485            @simd V128Load8Splat { memarg: $crate::MemArg } => visit_v128_load8_splat
486            @simd V128Load16Splat { memarg: $crate::MemArg } => visit_v128_load16_splat
487            @simd V128Load32Splat { memarg: $crate::MemArg } => visit_v128_load32_splat
488            @simd V128Load64Splat { memarg: $crate::MemArg } => visit_v128_load64_splat
489            @simd V128Load32Zero { memarg: $crate::MemArg } => visit_v128_load32_zero
490            @simd V128Load64Zero { memarg: $crate::MemArg } => visit_v128_load64_zero
491            @simd V128Store { memarg: $crate::MemArg } => visit_v128_store
492            @simd V128Load8Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load8_lane
493            @simd V128Load16Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load16_lane
494            @simd V128Load32Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load32_lane
495            @simd V128Load64Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_load64_lane
496            @simd V128Store8Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store8_lane
497            @simd V128Store16Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store16_lane
498            @simd V128Store32Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store32_lane
499            @simd V128Store64Lane { memarg: $crate::MemArg, lane: u8 } => visit_v128_store64_lane
500            @simd V128Const { value: $crate::V128 } => visit_v128_const
501            @simd I8x16Shuffle { lanes: [u8; 16] } => visit_i8x16_shuffle
502            @simd I8x16ExtractLaneS { lane: u8 } => visit_i8x16_extract_lane_s
503            @simd I8x16ExtractLaneU { lane: u8 } => visit_i8x16_extract_lane_u
504            @simd I8x16ReplaceLane { lane: u8 } => visit_i8x16_replace_lane
505            @simd I16x8ExtractLaneS { lane: u8 } => visit_i16x8_extract_lane_s
506            @simd I16x8ExtractLaneU { lane: u8 } => visit_i16x8_extract_lane_u
507            @simd I16x8ReplaceLane { lane: u8 } => visit_i16x8_replace_lane
508            @simd I32x4ExtractLane { lane: u8 } => visit_i32x4_extract_lane
509            @simd I32x4ReplaceLane { lane: u8 } => visit_i32x4_replace_lane
510            @simd I64x2ExtractLane { lane: u8 } => visit_i64x2_extract_lane
511            @simd I64x2ReplaceLane { lane: u8 } => visit_i64x2_replace_lane
512            @simd F32x4ExtractLane { lane: u8 } => visit_f32x4_extract_lane
513            @simd F32x4ReplaceLane { lane: u8 } => visit_f32x4_replace_lane
514            @simd F64x2ExtractLane { lane: u8 } => visit_f64x2_extract_lane
515            @simd F64x2ReplaceLane { lane: u8 } => visit_f64x2_replace_lane
516            @simd I8x16Swizzle => visit_i8x16_swizzle
517            @simd I8x16Splat => visit_i8x16_splat
518            @simd I16x8Splat => visit_i16x8_splat
519            @simd I32x4Splat => visit_i32x4_splat
520            @simd I64x2Splat => visit_i64x2_splat
521            @simd F32x4Splat => visit_f32x4_splat
522            @simd F64x2Splat => visit_f64x2_splat
523            @simd I8x16Eq => visit_i8x16_eq
524            @simd I8x16Ne => visit_i8x16_ne
525            @simd I8x16LtS => visit_i8x16_lt_s
526            @simd I8x16LtU => visit_i8x16_lt_u
527            @simd I8x16GtS => visit_i8x16_gt_s
528            @simd I8x16GtU => visit_i8x16_gt_u
529            @simd I8x16LeS => visit_i8x16_le_s
530            @simd I8x16LeU => visit_i8x16_le_u
531            @simd I8x16GeS => visit_i8x16_ge_s
532            @simd I8x16GeU => visit_i8x16_ge_u
533            @simd I16x8Eq => visit_i16x8_eq
534            @simd I16x8Ne => visit_i16x8_ne
535            @simd I16x8LtS => visit_i16x8_lt_s
536            @simd I16x8LtU => visit_i16x8_lt_u
537            @simd I16x8GtS => visit_i16x8_gt_s
538            @simd I16x8GtU => visit_i16x8_gt_u
539            @simd I16x8LeS => visit_i16x8_le_s
540            @simd I16x8LeU => visit_i16x8_le_u
541            @simd I16x8GeS => visit_i16x8_ge_s
542            @simd I16x8GeU => visit_i16x8_ge_u
543            @simd I32x4Eq => visit_i32x4_eq
544            @simd I32x4Ne => visit_i32x4_ne
545            @simd I32x4LtS => visit_i32x4_lt_s
546            @simd I32x4LtU => visit_i32x4_lt_u
547            @simd I32x4GtS => visit_i32x4_gt_s
548            @simd I32x4GtU => visit_i32x4_gt_u
549            @simd I32x4LeS => visit_i32x4_le_s
550            @simd I32x4LeU => visit_i32x4_le_u
551            @simd I32x4GeS => visit_i32x4_ge_s
552            @simd I32x4GeU => visit_i32x4_ge_u
553            @simd I64x2Eq => visit_i64x2_eq
554            @simd I64x2Ne => visit_i64x2_ne
555            @simd I64x2LtS => visit_i64x2_lt_s
556            @simd I64x2GtS => visit_i64x2_gt_s
557            @simd I64x2LeS => visit_i64x2_le_s
558            @simd I64x2GeS => visit_i64x2_ge_s
559            @simd F32x4Eq => visit_f32x4_eq
560            @simd F32x4Ne => visit_f32x4_ne
561            @simd F32x4Lt => visit_f32x4_lt
562            @simd F32x4Gt => visit_f32x4_gt
563            @simd F32x4Le => visit_f32x4_le
564            @simd F32x4Ge => visit_f32x4_ge
565            @simd F64x2Eq => visit_f64x2_eq
566            @simd F64x2Ne => visit_f64x2_ne
567            @simd F64x2Lt => visit_f64x2_lt
568            @simd F64x2Gt => visit_f64x2_gt
569            @simd F64x2Le => visit_f64x2_le
570            @simd F64x2Ge => visit_f64x2_ge
571            @simd V128Not => visit_v128_not
572            @simd V128And => visit_v128_and
573            @simd V128AndNot => visit_v128_andnot
574            @simd V128Or => visit_v128_or
575            @simd V128Xor => visit_v128_xor
576            @simd V128Bitselect => visit_v128_bitselect
577            @simd V128AnyTrue => visit_v128_any_true
578            @simd I8x16Abs => visit_i8x16_abs
579            @simd I8x16Neg => visit_i8x16_neg
580            @simd I8x16Popcnt => visit_i8x16_popcnt
581            @simd I8x16AllTrue => visit_i8x16_all_true
582            @simd I8x16Bitmask => visit_i8x16_bitmask
583            @simd I8x16NarrowI16x8S => visit_i8x16_narrow_i16x8_s
584            @simd I8x16NarrowI16x8U => visit_i8x16_narrow_i16x8_u
585            @simd I8x16Shl => visit_i8x16_shl
586            @simd I8x16ShrS => visit_i8x16_shr_s
587            @simd I8x16ShrU => visit_i8x16_shr_u
588            @simd I8x16Add => visit_i8x16_add
589            @simd I8x16AddSatS => visit_i8x16_add_sat_s
590            @simd I8x16AddSatU => visit_i8x16_add_sat_u
591            @simd I8x16Sub => visit_i8x16_sub
592            @simd I8x16SubSatS => visit_i8x16_sub_sat_s
593            @simd I8x16SubSatU => visit_i8x16_sub_sat_u
594            @simd I8x16MinS => visit_i8x16_min_s
595            @simd I8x16MinU => visit_i8x16_min_u
596            @simd I8x16MaxS => visit_i8x16_max_s
597            @simd I8x16MaxU => visit_i8x16_max_u
598            @simd I8x16AvgrU => visit_i8x16_avgr_u
599            @simd I16x8ExtAddPairwiseI8x16S => visit_i16x8_extadd_pairwise_i8x16_s
600            @simd I16x8ExtAddPairwiseI8x16U => visit_i16x8_extadd_pairwise_i8x16_u
601            @simd I16x8Abs => visit_i16x8_abs
602            @simd I16x8Neg => visit_i16x8_neg
603            @simd I16x8Q15MulrSatS => visit_i16x8_q15mulr_sat_s
604            @simd I16x8AllTrue => visit_i16x8_all_true
605            @simd I16x8Bitmask => visit_i16x8_bitmask
606            @simd I16x8NarrowI32x4S => visit_i16x8_narrow_i32x4_s
607            @simd I16x8NarrowI32x4U => visit_i16x8_narrow_i32x4_u
608            @simd I16x8ExtendLowI8x16S => visit_i16x8_extend_low_i8x16_s
609            @simd I16x8ExtendHighI8x16S => visit_i16x8_extend_high_i8x16_s
610            @simd I16x8ExtendLowI8x16U => visit_i16x8_extend_low_i8x16_u
611            @simd I16x8ExtendHighI8x16U => visit_i16x8_extend_high_i8x16_u
612            @simd I16x8Shl => visit_i16x8_shl
613            @simd I16x8ShrS => visit_i16x8_shr_s
614            @simd I16x8ShrU => visit_i16x8_shr_u
615            @simd I16x8Add => visit_i16x8_add
616            @simd I16x8AddSatS => visit_i16x8_add_sat_s
617            @simd I16x8AddSatU => visit_i16x8_add_sat_u
618            @simd I16x8Sub => visit_i16x8_sub
619            @simd I16x8SubSatS => visit_i16x8_sub_sat_s
620            @simd I16x8SubSatU => visit_i16x8_sub_sat_u
621            @simd I16x8Mul => visit_i16x8_mul
622            @simd I16x8MinS => visit_i16x8_min_s
623            @simd I16x8MinU => visit_i16x8_min_u
624            @simd I16x8MaxS => visit_i16x8_max_s
625            @simd I16x8MaxU => visit_i16x8_max_u
626            @simd I16x8AvgrU => visit_i16x8_avgr_u
627            @simd I16x8ExtMulLowI8x16S => visit_i16x8_extmul_low_i8x16_s
628            @simd I16x8ExtMulHighI8x16S => visit_i16x8_extmul_high_i8x16_s
629            @simd I16x8ExtMulLowI8x16U => visit_i16x8_extmul_low_i8x16_u
630            @simd I16x8ExtMulHighI8x16U => visit_i16x8_extmul_high_i8x16_u
631            @simd I32x4ExtAddPairwiseI16x8S => visit_i32x4_extadd_pairwise_i16x8_s
632            @simd I32x4ExtAddPairwiseI16x8U => visit_i32x4_extadd_pairwise_i16x8_u
633            @simd I32x4Abs => visit_i32x4_abs
634            @simd I32x4Neg => visit_i32x4_neg
635            @simd I32x4AllTrue => visit_i32x4_all_true
636            @simd I32x4Bitmask => visit_i32x4_bitmask
637            @simd I32x4ExtendLowI16x8S => visit_i32x4_extend_low_i16x8_s
638            @simd I32x4ExtendHighI16x8S => visit_i32x4_extend_high_i16x8_s
639            @simd I32x4ExtendLowI16x8U => visit_i32x4_extend_low_i16x8_u
640            @simd I32x4ExtendHighI16x8U => visit_i32x4_extend_high_i16x8_u
641            @simd I32x4Shl => visit_i32x4_shl
642            @simd I32x4ShrS => visit_i32x4_shr_s
643            @simd I32x4ShrU => visit_i32x4_shr_u
644            @simd I32x4Add => visit_i32x4_add
645            @simd I32x4Sub => visit_i32x4_sub
646            @simd I32x4Mul => visit_i32x4_mul
647            @simd I32x4MinS => visit_i32x4_min_s
648            @simd I32x4MinU => visit_i32x4_min_u
649            @simd I32x4MaxS => visit_i32x4_max_s
650            @simd I32x4MaxU => visit_i32x4_max_u
651            @simd I32x4DotI16x8S => visit_i32x4_dot_i16x8_s
652            @simd I32x4ExtMulLowI16x8S => visit_i32x4_extmul_low_i16x8_s
653            @simd I32x4ExtMulHighI16x8S => visit_i32x4_extmul_high_i16x8_s
654            @simd I32x4ExtMulLowI16x8U => visit_i32x4_extmul_low_i16x8_u
655            @simd I32x4ExtMulHighI16x8U => visit_i32x4_extmul_high_i16x8_u
656            @simd I64x2Abs => visit_i64x2_abs
657            @simd I64x2Neg => visit_i64x2_neg
658            @simd I64x2AllTrue => visit_i64x2_all_true
659            @simd I64x2Bitmask => visit_i64x2_bitmask
660            @simd I64x2ExtendLowI32x4S => visit_i64x2_extend_low_i32x4_s
661            @simd I64x2ExtendHighI32x4S => visit_i64x2_extend_high_i32x4_s
662            @simd I64x2ExtendLowI32x4U => visit_i64x2_extend_low_i32x4_u
663            @simd I64x2ExtendHighI32x4U => visit_i64x2_extend_high_i32x4_u
664            @simd I64x2Shl => visit_i64x2_shl
665            @simd I64x2ShrS => visit_i64x2_shr_s
666            @simd I64x2ShrU => visit_i64x2_shr_u
667            @simd I64x2Add => visit_i64x2_add
668            @simd I64x2Sub => visit_i64x2_sub
669            @simd I64x2Mul => visit_i64x2_mul
670            @simd I64x2ExtMulLowI32x4S => visit_i64x2_extmul_low_i32x4_s
671            @simd I64x2ExtMulHighI32x4S => visit_i64x2_extmul_high_i32x4_s
672            @simd I64x2ExtMulLowI32x4U => visit_i64x2_extmul_low_i32x4_u
673            @simd I64x2ExtMulHighI32x4U => visit_i64x2_extmul_high_i32x4_u
674            @simd F32x4Ceil => visit_f32x4_ceil
675            @simd F32x4Floor => visit_f32x4_floor
676            @simd F32x4Trunc => visit_f32x4_trunc
677            @simd F32x4Nearest => visit_f32x4_nearest
678            @simd F32x4Abs => visit_f32x4_abs
679            @simd F32x4Neg => visit_f32x4_neg
680            @simd F32x4Sqrt => visit_f32x4_sqrt
681            @simd F32x4Add => visit_f32x4_add
682            @simd F32x4Sub => visit_f32x4_sub
683            @simd F32x4Mul => visit_f32x4_mul
684            @simd F32x4Div => visit_f32x4_div
685            @simd F32x4Min => visit_f32x4_min
686            @simd F32x4Max => visit_f32x4_max
687            @simd F32x4PMin => visit_f32x4_pmin
688            @simd F32x4PMax => visit_f32x4_pmax
689            @simd F64x2Ceil => visit_f64x2_ceil
690            @simd F64x2Floor => visit_f64x2_floor
691            @simd F64x2Trunc => visit_f64x2_trunc
692            @simd F64x2Nearest => visit_f64x2_nearest
693            @simd F64x2Abs => visit_f64x2_abs
694            @simd F64x2Neg => visit_f64x2_neg
695            @simd F64x2Sqrt => visit_f64x2_sqrt
696            @simd F64x2Add => visit_f64x2_add
697            @simd F64x2Sub => visit_f64x2_sub
698            @simd F64x2Mul => visit_f64x2_mul
699            @simd F64x2Div => visit_f64x2_div
700            @simd F64x2Min => visit_f64x2_min
701            @simd F64x2Max => visit_f64x2_max
702            @simd F64x2PMin => visit_f64x2_pmin
703            @simd F64x2PMax => visit_f64x2_pmax
704            @simd I32x4TruncSatF32x4S => visit_i32x4_trunc_sat_f32x4_s
705            @simd I32x4TruncSatF32x4U => visit_i32x4_trunc_sat_f32x4_u
706            @simd F32x4ConvertI32x4S => visit_f32x4_convert_i32x4_s
707            @simd F32x4ConvertI32x4U => visit_f32x4_convert_i32x4_u
708            @simd I32x4TruncSatF64x2SZero => visit_i32x4_trunc_sat_f64x2_s_zero
709            @simd I32x4TruncSatF64x2UZero => visit_i32x4_trunc_sat_f64x2_u_zero
710            @simd F64x2ConvertLowI32x4S => visit_f64x2_convert_low_i32x4_s
711            @simd F64x2ConvertLowI32x4U => visit_f64x2_convert_low_i32x4_u
712            @simd F32x4DemoteF64x2Zero => visit_f32x4_demote_f64x2_zero
713            @simd F64x2PromoteLowF32x4 => visit_f64x2_promote_low_f32x4
714
715            // Relaxed SIMD operators
716            // https://github.com/WebAssembly/relaxed-simd
717            @relaxed_simd I8x16RelaxedSwizzle => visit_i8x16_relaxed_swizzle
718            @relaxed_simd I32x4RelaxedTruncF32x4S => visit_i32x4_relaxed_trunc_f32x4_s
719            @relaxed_simd I32x4RelaxedTruncF32x4U => visit_i32x4_relaxed_trunc_f32x4_u
720            @relaxed_simd I32x4RelaxedTruncF64x2SZero => visit_i32x4_relaxed_trunc_f64x2_s_zero
721            @relaxed_simd I32x4RelaxedTruncF64x2UZero => visit_i32x4_relaxed_trunc_f64x2_u_zero
722            @relaxed_simd F32x4RelaxedMadd => visit_f32x4_relaxed_madd
723            @relaxed_simd F32x4RelaxedNmadd => visit_f32x4_relaxed_nmadd
724            @relaxed_simd F64x2RelaxedMadd => visit_f64x2_relaxed_madd
725            @relaxed_simd F64x2RelaxedNmadd => visit_f64x2_relaxed_nmadd
726            @relaxed_simd I8x16RelaxedLaneselect => visit_i8x16_relaxed_laneselect
727            @relaxed_simd I16x8RelaxedLaneselect => visit_i16x8_relaxed_laneselect
728            @relaxed_simd I32x4RelaxedLaneselect => visit_i32x4_relaxed_laneselect
729            @relaxed_simd I64x2RelaxedLaneselect => visit_i64x2_relaxed_laneselect
730            @relaxed_simd F32x4RelaxedMin => visit_f32x4_relaxed_min
731            @relaxed_simd F32x4RelaxedMax => visit_f32x4_relaxed_max
732            @relaxed_simd F64x2RelaxedMin => visit_f64x2_relaxed_min
733            @relaxed_simd F64x2RelaxedMax => visit_f64x2_relaxed_max
734            @relaxed_simd I16x8RelaxedQ15mulrS => visit_i16x8_relaxed_q15mulr_s
735            @relaxed_simd I16x8RelaxedDotI8x16I7x16S => visit_i16x8_relaxed_dot_i8x16_i7x16_s
736            @relaxed_simd I32x4RelaxedDotI8x16I7x16AddS => visit_i32x4_relaxed_dot_i8x16_i7x16_add_s
737
738            // Typed Function references
739            @function_references CallRef { type_index: u32 } => visit_call_ref
740            @function_references ReturnCallRef { type_index: u32 } => visit_return_call_ref
741            @function_references RefAsNonNull => visit_ref_as_non_null
742            @function_references BrOnNull { relative_depth: u32 } => visit_br_on_null
743            @function_references BrOnNonNull { relative_depth: u32 } => visit_br_on_non_null
744        }
745    };
746}
747
748macro_rules! format_err {
749    ($offset:expr, $($arg:tt)*) => {
750        crate::BinaryReaderError::fmt(format_args!($($arg)*), $offset)
751    }
752}
753
754macro_rules! bail {
755    ($($arg:tt)*) => {return Err(format_err!($($arg)*))}
756}
757
758pub use crate::binary_reader::{BinaryReader, BinaryReaderError, Result};
759pub use crate::parser::*;
760pub use crate::readers::*;
761pub use crate::resources::*;
762pub use crate::validator::*;
763
764mod binary_reader;
765mod limits;
766mod parser;
767mod readers;
768mod resources;
769mod validator;