1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
use super::{FuncBuilder, FuncValidator, TranslationError};
use wasmparser::{BinaryReaderError, VisitOperator};
macro_rules! for_each_supported_operator {
($mac:ident) => {
$mac! {
fn visit_unreachable() => fn translate_unreachable
fn visit_nop() => fn translate_nop
fn visit_block(ty: wasmparser::BlockType) => fn translate_block
fn visit_loop(ty: wasmparser::BlockType) => fn translate_loop
fn visit_if(ty: wasmparser::BlockType) => fn translate_if
fn visit_else() => fn translate_else
fn visit_end() => fn translate_end
fn visit_br(relative_depth: u32) => fn translate_br
fn visit_br_if(relative_depth: u32) => fn translate_br_if
fn visit_return() => fn translate_return
fn visit_call(function_index: u32) => fn translate_call
fn visit_call_indirect(index: u32, table_index: u32, table_byte: u8) => fn translate_call_indirect
fn visit_drop() => fn translate_drop
fn visit_select() => fn translate_select
fn visit_typed_select(ty: wasmparser::ValType) => fn translate_typed_select
fn visit_ref_null(ty: wasmparser::ValType) => fn translate_ref_null
fn visit_ref_is_null() => fn translate_ref_is_null
fn visit_ref_func(func_index: u32) => fn translate_ref_func
fn visit_local_get(local_index: u32) => fn translate_local_get
fn visit_local_set(local_index: u32) => fn translate_local_set
fn visit_local_tee(local_index: u32) => fn translate_local_tee
fn visit_global_get(global_index: u32) => fn translate_global_get
fn visit_global_set(global_index: u32) => fn translate_global_set
fn visit_i32_load(memarg: wasmparser::MemArg) => fn translate_i32_load
fn visit_i64_load(memarg: wasmparser::MemArg) => fn translate_i64_load
fn visit_f32_load(memarg: wasmparser::MemArg) => fn translate_f32_load
fn visit_f64_load(memarg: wasmparser::MemArg) => fn translate_f64_load
fn visit_i32_load8_s(memarg: wasmparser::MemArg) => fn translate_i32_load8_s
fn visit_i32_load8_u(memarg: wasmparser::MemArg) => fn translate_i32_load8_u
fn visit_i32_load16_s(memarg: wasmparser::MemArg) => fn translate_i32_load16_s
fn visit_i32_load16_u(memarg: wasmparser::MemArg) => fn translate_i32_load16_u
fn visit_i64_load8_s(memarg: wasmparser::MemArg) => fn translate_i64_load8_s
fn visit_i64_load8_u(memarg: wasmparser::MemArg) => fn translate_i64_load8_u
fn visit_i64_load16_s(memarg: wasmparser::MemArg) => fn translate_i64_load16_s
fn visit_i64_load16_u(memarg: wasmparser::MemArg) => fn translate_i64_load16_u
fn visit_i64_load32_s(memarg: wasmparser::MemArg) => fn translate_i64_load32_s
fn visit_i64_load32_u(memarg: wasmparser::MemArg) => fn translate_i64_load32_u
fn visit_i32_store(memarg: wasmparser::MemArg) => fn translate_i32_store
fn visit_i64_store(memarg: wasmparser::MemArg) => fn translate_i64_store
fn visit_f32_store(memarg: wasmparser::MemArg) => fn translate_f32_store
fn visit_f64_store(memarg: wasmparser::MemArg) => fn translate_f64_store
fn visit_i32_store8(memarg: wasmparser::MemArg) => fn translate_i32_store8
fn visit_i32_store16(memarg: wasmparser::MemArg) => fn translate_i32_store16
fn visit_i64_store8(memarg: wasmparser::MemArg) => fn translate_i64_store8
fn visit_i64_store16(memarg: wasmparser::MemArg) => fn translate_i64_store16
fn visit_i64_store32(memarg: wasmparser::MemArg) => fn translate_i64_store32
fn visit_memory_size(mem: u32, mem_byte: u8) => fn translate_memory_size
fn visit_memory_grow(mem: u32, mem_byte: u8) => fn translate_memory_grow
fn visit_memory_copy(dst_mem: u32, src_mem: u32) => fn translate_memory_copy
fn visit_memory_fill(mem: u32) => fn translate_memory_fill
fn visit_memory_init(seg: u32, mem: u32) => fn translate_memory_init
fn visit_data_drop(seg: u32) => fn translate_data_drop
fn visit_table_size(table: u32) => fn translate_table_size
fn visit_table_grow(table: u32) => fn translate_table_grow
fn visit_table_copy(dst_table: u32, src_table: u32) => fn translate_table_copy
fn visit_table_fill(table: u32) => fn translate_table_fill
fn visit_table_get(table: u32) => fn translate_table_get
fn visit_table_set(table: u32) => fn translate_table_set
fn visit_table_init(seg: u32, table: u32) => fn translate_table_init
fn visit_elem_drop(seg: u32) => fn translate_elem_drop
fn visit_i32_const(value: i32) => fn translate_i32_const
fn visit_i64_const(value: i64) => fn translate_i64_const
fn visit_f32_const(value: wasmparser::Ieee32) => fn translate_f32_const
fn visit_f64_const(value: wasmparser::Ieee64) => fn translate_f64_const
fn visit_i32_eqz() => fn translate_i32_eqz
fn visit_i32_eq() => fn translate_i32_eq
fn visit_i32_ne() => fn translate_i32_ne
fn visit_i32_lt_s() => fn translate_i32_lt_s
fn visit_i32_lt_u() => fn translate_i32_lt_u
fn visit_i32_gt_s() => fn translate_i32_gt_s
fn visit_i32_gt_u() => fn translate_i32_gt_u
fn visit_i32_le_s() => fn translate_i32_le_s
fn visit_i32_le_u() => fn translate_i32_le_u
fn visit_i32_ge_s() => fn translate_i32_ge_s
fn visit_i32_ge_u() => fn translate_i32_ge_u
fn visit_i64_eqz() => fn translate_i64_eqz
fn visit_i64_eq() => fn translate_i64_eq
fn visit_i64_ne() => fn translate_i64_ne
fn visit_i64_lt_s() => fn translate_i64_lt_s
fn visit_i64_lt_u() => fn translate_i64_lt_u
fn visit_i64_gt_s() => fn translate_i64_gt_s
fn visit_i64_gt_u() => fn translate_i64_gt_u
fn visit_i64_le_s() => fn translate_i64_le_s
fn visit_i64_le_u() => fn translate_i64_le_u
fn visit_i64_ge_s() => fn translate_i64_ge_s
fn visit_i64_ge_u() => fn translate_i64_ge_u
fn visit_f32_eq() => fn translate_f32_eq
fn visit_f32_ne() => fn translate_f32_ne
fn visit_f32_lt() => fn translate_f32_lt
fn visit_f32_gt() => fn translate_f32_gt
fn visit_f32_le() => fn translate_f32_le
fn visit_f32_ge() => fn translate_f32_ge
fn visit_f64_eq() => fn translate_f64_eq
fn visit_f64_ne() => fn translate_f64_ne
fn visit_f64_lt() => fn translate_f64_lt
fn visit_f64_gt() => fn translate_f64_gt
fn visit_f64_le() => fn translate_f64_le
fn visit_f64_ge() => fn translate_f64_ge
fn visit_i32_clz() => fn translate_i32_clz
fn visit_i32_ctz() => fn translate_i32_ctz
fn visit_i32_popcnt() => fn translate_i32_popcnt
fn visit_i32_add() => fn translate_i32_add
fn visit_i32_sub() => fn translate_i32_sub
fn visit_i32_mul() => fn translate_i32_mul
fn visit_i32_div_s() => fn translate_i32_div_s
fn visit_i32_div_u() => fn translate_i32_div_u
fn visit_i32_rem_s() => fn translate_i32_rem_s
fn visit_i32_rem_u() => fn translate_i32_rem_u
fn visit_i32_and() => fn translate_i32_and
fn visit_i32_or() => fn translate_i32_or
fn visit_i32_xor() => fn translate_i32_xor
fn visit_i32_shl() => fn translate_i32_shl
fn visit_i32_shr_s() => fn translate_i32_shr_s
fn visit_i32_shr_u() => fn translate_i32_shr_u
fn visit_i32_rotl() => fn translate_i32_rotl
fn visit_i32_rotr() => fn translate_i32_rotr
fn visit_i64_clz() => fn translate_i64_clz
fn visit_i64_ctz() => fn translate_i64_ctz
fn visit_i64_popcnt() => fn translate_i64_popcnt
fn visit_i64_add() => fn translate_i64_add
fn visit_i64_sub() => fn translate_i64_sub
fn visit_i64_mul() => fn translate_i64_mul
fn visit_i64_div_s() => fn translate_i64_div_s
fn visit_i64_div_u() => fn translate_i64_div_u
fn visit_i64_rem_s() => fn translate_i64_rem_s
fn visit_i64_rem_u() => fn translate_i64_rem_u
fn visit_i64_and() => fn translate_i64_and
fn visit_i64_or() => fn translate_i64_or
fn visit_i64_xor() => fn translate_i64_xor
fn visit_i64_shl() => fn translate_i64_shl
fn visit_i64_shr_s() => fn translate_i64_shr_s
fn visit_i64_shr_u() => fn translate_i64_shr_u
fn visit_i64_rotl() => fn translate_i64_rotl
fn visit_i64_rotr() => fn translate_i64_rotr
fn visit_f32_abs() => fn translate_f32_abs
fn visit_f32_neg() => fn translate_f32_neg
fn visit_f32_ceil() => fn translate_f32_ceil
fn visit_f32_floor() => fn translate_f32_floor
fn visit_f32_trunc() => fn translate_f32_trunc
fn visit_f32_nearest() => fn translate_f32_nearest
fn visit_f32_sqrt() => fn translate_f32_sqrt
fn visit_f32_add() => fn translate_f32_add
fn visit_f32_sub() => fn translate_f32_sub
fn visit_f32_mul() => fn translate_f32_mul
fn visit_f32_div() => fn translate_f32_div
fn visit_f32_min() => fn translate_f32_min
fn visit_f32_max() => fn translate_f32_max
fn visit_f32_copysign() => fn translate_f32_copysign
fn visit_f64_abs() => fn translate_f64_abs
fn visit_f64_neg() => fn translate_f64_neg
fn visit_f64_ceil() => fn translate_f64_ceil
fn visit_f64_floor() => fn translate_f64_floor
fn visit_f64_trunc() => fn translate_f64_trunc
fn visit_f64_nearest() => fn translate_f64_nearest
fn visit_f64_sqrt() => fn translate_f64_sqrt
fn visit_f64_add() => fn translate_f64_add
fn visit_f64_sub() => fn translate_f64_sub
fn visit_f64_mul() => fn translate_f64_mul
fn visit_f64_div() => fn translate_f64_div
fn visit_f64_min() => fn translate_f64_min
fn visit_f64_max() => fn translate_f64_max
fn visit_f64_copysign() => fn translate_f64_copysign
fn visit_i32_wrap_i64() => fn translate_i32_wrap_i64
fn visit_i32_trunc_f32_s() => fn translate_i32_trunc_f32_s
fn visit_i32_trunc_f32_u() => fn translate_i32_trunc_f32_u
fn visit_i32_trunc_f64_s() => fn translate_i32_trunc_f64_s
fn visit_i32_trunc_f64_u() => fn translate_i32_trunc_f64_u
fn visit_i64_extend_i32_s() => fn translate_i64_extend_i32_s
fn visit_i64_extend_i32_u() => fn translate_i64_extend_i32_u
fn visit_i64_trunc_f32_s() => fn translate_i64_trunc_f32_s
fn visit_i64_trunc_f32_u() => fn translate_i64_trunc_f32_u
fn visit_i64_trunc_f64_s() => fn translate_i64_trunc_f64_s
fn visit_i64_trunc_f64_u() => fn translate_i64_trunc_f64_u
fn visit_f32_convert_i32_s() => fn translate_f32_convert_i32_s
fn visit_f32_convert_i32_u() => fn translate_f32_convert_i32_u
fn visit_f32_convert_i64_s() => fn translate_f32_convert_i64_s
fn visit_f32_convert_i64_u() => fn translate_f32_convert_i64_u
fn visit_f32_demote_f64() => fn translate_f32_demote_f64
fn visit_f64_convert_i32_s() => fn translate_f64_convert_i32_s
fn visit_f64_convert_i32_u() => fn translate_f64_convert_i32_u
fn visit_f64_convert_i64_s() => fn translate_f64_convert_i64_s
fn visit_f64_convert_i64_u() => fn translate_f64_convert_i64_u
fn visit_f64_promote_f32() => fn translate_f64_promote_f32
fn visit_i32_reinterpret_f32() => fn translate_i32_reinterpret_f32
fn visit_i64_reinterpret_f64() => fn translate_i64_reinterpret_f64
fn visit_f32_reinterpret_i32() => fn translate_f32_reinterpret_i32
fn visit_f64_reinterpret_i64() => fn translate_f64_reinterpret_i64
fn visit_i32_extend8_s() => fn translate_i32_extend8_s
fn visit_i32_extend16_s() => fn translate_i32_extend16_s
fn visit_i64_extend8_s() => fn translate_i64_extend8_s
fn visit_i64_extend16_s() => fn translate_i64_extend16_s
fn visit_i64_extend32_s() => fn translate_i64_extend32_s
fn visit_i32_trunc_sat_f32_s() => fn translate_i32_trunc_sat_f32_s
fn visit_i32_trunc_sat_f32_u() => fn translate_i32_trunc_sat_f32_u
fn visit_i32_trunc_sat_f64_s() => fn translate_i32_trunc_sat_f64_s
fn visit_i32_trunc_sat_f64_u() => fn translate_i32_trunc_sat_f64_u
fn visit_i64_trunc_sat_f32_s() => fn translate_i64_trunc_sat_f32_s
fn visit_i64_trunc_sat_f32_u() => fn translate_i64_trunc_sat_f32_u
fn visit_i64_trunc_sat_f64_s() => fn translate_i64_trunc_sat_f64_s
fn visit_i64_trunc_sat_f64_u() => fn translate_i64_trunc_sat_f64_u
}
}
}
impl<'parser> FuncBuilder<'parser> {
fn validate_then_translate<V, F>(
&mut self,
validate: V,
translator: F,
) -> Result<(), TranslationError>
where
V: FnOnce(&mut FuncValidator) -> Result<(), BinaryReaderError>,
F: FnOnce(&mut Self) -> Result<(), TranslationError>,
{
validate(&mut self.validator)?;
translator(self)?;
Ok(())
}
}
macro_rules! define_supported_visit_operator {
($( fn $visit:ident $(( $($arg:ident: $argty:ty),* ))? => fn $translate:ident)*) => {
$(
fn $visit(&mut self, offset: usize $($(,$arg: $argty)*)?) -> Self::Output {
self.validate_then_translate(
|v| v.$visit(offset $($(,$arg)*)?),
|this| {
this.$translate($($($arg),*)?)
},
)
}
)*
};
}
macro_rules! define_unsupported_visit_operator {
( @mvp $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @sign_ext_ops $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @non_trapping_f2i_conversions $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @bulk_memory $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @reference_types $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
define_unsupported_visit_operator!($($rest)*);
};
( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident $($rest:tt)* ) => {
fn $visit(&mut self, offset: usize $($(,$arg: $argty)*)?) -> Self::Output {
self.validator.$visit(offset $($(,$arg)*)?).map_err(::core::convert::Into::into)
}
define_unsupported_visit_operator!($($rest)*);
};
() => {};
}
impl<'a> VisitOperator<'a> for FuncBuilder<'a> {
type Output = Result<(), TranslationError>;
for_each_supported_operator!(define_supported_visit_operator);
wasmparser::for_each_operator!(define_unsupported_visit_operator);
fn visit_br_table(&mut self, offset: usize, table: wasmparser::BrTable<'a>) -> Self::Output {
let table_cloned = table.clone();
self.validate_then_translate(
|v| v.visit_br_table(offset, table_cloned),
|this| this.translate_br_table(table),
)
}
}