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