| 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 |  | 
|---|
| 33 | extern crate alloc; | 
|---|
| 34 | #[ cfg(feature = "std")] | 
|---|
| 35 | #[ macro_use] | 
|---|
| 36 | extern 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. | 
|---|
| 44 | mod 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. | 
|---|
| 70 | macro_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. | 
|---|
| 787 | macro_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")] | 
|---|
| 842 | macro_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")] | 
|---|
| 873 | macro_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)] | 
|---|
| 1056 | pub 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)] | 
|---|
| 1217 | pub 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)] | 
|---|
| 1275 | pub use _for_each_visit_simd_operator_impl as for_each_visit_simd_operator; | 
|---|
| 1276 |  | 
|---|
| 1277 | macro_rules! format_err { | 
|---|
| 1278 | ($offset:expr, $($arg:tt)*) => { | 
|---|
| 1279 | crate::BinaryReaderError::fmt(format_args!($($arg)*), $offset) | 
|---|
| 1280 | } | 
|---|
| 1281 | } | 
|---|
| 1282 |  | 
|---|
| 1283 | macro_rules! bail { | 
|---|
| 1284 | ($($arg:tt)*) => {return Err(format_err!($($arg)*))} | 
|---|
| 1285 | } | 
|---|
| 1286 |  | 
|---|
| 1287 | pub use crate::arity::*; | 
|---|
| 1288 | pub use crate::binary_reader::{BinaryReader, BinaryReaderError, Result}; | 
|---|
| 1289 | pub use crate::features::*; | 
|---|
| 1290 | pub use crate::parser::*; | 
|---|
| 1291 | pub use crate::readers::*; | 
|---|
| 1292 |  | 
|---|
| 1293 | mod arity; | 
|---|
| 1294 | mod binary_reader; | 
|---|
| 1295 | mod features; | 
|---|
| 1296 | mod limits; | 
|---|
| 1297 | mod parser; | 
|---|
| 1298 | mod readers; | 
|---|
| 1299 |  | 
|---|
| 1300 | #[ cfg(feature = "validate")] | 
|---|
| 1301 | mod resources; | 
|---|
| 1302 | #[ cfg(feature = "validate")] | 
|---|
| 1303 | mod validator; | 
|---|
| 1304 | #[ cfg(feature = "validate")] | 
|---|
| 1305 | pub use crate::resources::*; | 
|---|
| 1306 | #[ cfg(feature = "validate")] | 
|---|
| 1307 | pub use crate::validator::*; | 
|---|
| 1308 |  | 
|---|
| 1309 | #[ cfg(feature = "validate")] | 
|---|
| 1310 | pub mod collections; | 
|---|
| 1311 |  | 
|---|