1 use super::{BlockType, Elements, FuncType, Instruction, MemArg, Module, ValType};
2 use arbitrary::{Result, Unstructured};
3 use std::collections::{BTreeMap, BTreeSet};
4 use std::convert::TryFrom;
5 
6 macro_rules! instructions {
7 	(
8         $(
9             ($predicate:expr, $generator_fn:ident $(, $cost:tt)?),
10         )*
11     ) => {
12         static NUM_OPTIONS: usize = instructions!(
13             @count;
14             $( $generator_fn )*
15         );
16 
17         fn choose_instruction(
18             u: &mut Unstructured<'_>,
19             module: &Module,
20             builder: &mut CodeBuilder,
21         ) -> Option<
22             fn(&mut Unstructured<'_>, &Module, &mut CodeBuilder) -> Result<Instruction>
23         > {
24             builder.allocs.options.clear();
25             let mut cost = 0;
26             // Unroll the loop that checks whether each instruction is valid in
27             // the current context and, if it is valid, pushes it onto our
28             // options. Unrolling this loops lets us avoid dynamic calls through
29             // function pointers and, furthermore, each call site can be branch
30             // predicted and even inlined. This saved us about 30% of time in
31             // the `corpus` benchmark.
32             $(
33                 let predicate: Option<fn(&Module, &mut CodeBuilder) -> bool> = $predicate;
34                 if predicate.map_or(true, |f| f(module, builder)) {
35 
36                     builder.allocs.options.push(($generator_fn, cost));
37                     cost += 1000 $(- $cost)?;
38                 }
39             )*
40 
41             debug_assert!(cost > 0);
42 
43             let i = u.int_in_range(0..=cost).ok()?;
44             let idx = builder
45                 .allocs
46                 .options
47                 .binary_search_by_key(&i,|p| p.1)
48                 .unwrap_or_else(|i| i - 1);
49             Some(builder.allocs.options[idx].0)
50         }
51 	};
52 
53     ( @count; ) => {
54         0
55     };
56     ( @count; $x:ident $( $xs:ident )* ) => {
57         1 + instructions!( @count; $( $xs )* )
58     };
59 }
60 
61 // The static set of options of instruction to generate that could be valid at
62 // some given time. One entry per Wasm instruction.
63 //
64 // Each entry is made up of up to three parts:
65 //
66 // 1. A predicate for whether this is a valid choice, if any. `None` means that
67 //    the choice is always applicable.
68 //
69 // 2. The function to generate the instruction, given that we've made this
70 //    choice.
71 //
72 // 3. An optional number used to weight how often this instruction is chosen.
73 //    Higher numbers are less likely to be chosen, and number specified must be
74 //    less than 1000.
75 instructions! {
76     // Control instructions.
77     (None, unreachable, 990),
78     (None, nop, 800),
79     (None, block),
80     (None, r#loop),
81     (Some(try_valid), r#try),
82     (Some(delegate_valid), delegate),
83     (Some(catch_valid), catch),
84     (Some(catch_all_valid), catch_all),
85     (Some(if_valid), r#if),
86     (Some(else_valid), r#else),
87     (Some(end_valid), end),
88     (Some(br_valid), br),
89     (Some(br_if_valid), br_if),
90     (Some(br_table_valid), br_table),
91     (Some(return_valid), r#return, 900),
92     (Some(call_valid), call),
93     (Some(call_indirect_valid), call_indirect),
94     (Some(throw_valid), throw, 850),
95     (Some(rethrow_valid), rethrow),
96     // Parametric instructions.
97     (Some(drop_valid), drop),
98     (Some(select_valid), select),
99     // Variable instructions.
100     (Some(local_get_valid), local_get),
101     (Some(local_set_valid), local_set),
102     (Some(local_set_valid), local_tee),
103     (Some(global_get_valid), global_get),
104     (Some(global_set_valid), global_set),
105     // Memory instructions.
106     (Some(have_memory_and_offset), i32_load),
107     (Some(have_memory_and_offset), i64_load),
108     (Some(have_memory_and_offset), f32_load),
109     (Some(have_memory_and_offset), f64_load),
110     (Some(have_memory_and_offset), i32_load_8_s),
111     (Some(have_memory_and_offset), i32_load_8_u),
112     (Some(have_memory_and_offset), i32_load_16_s),
113     (Some(have_memory_and_offset), i32_load_16_u),
114     (Some(have_memory_and_offset), i64_load_8_s),
115     (Some(have_memory_and_offset), i64_load_16_s),
116     (Some(have_memory_and_offset), i64_load_32_s),
117     (Some(have_memory_and_offset), i64_load_8_u),
118     (Some(have_memory_and_offset), i64_load_16_u),
119     (Some(have_memory_and_offset), i64_load_32_u),
120     (Some(i32_store_valid), i32_store),
121     (Some(i64_store_valid), i64_store),
122     (Some(f32_store_valid), f32_store),
123     (Some(f64_store_valid), f64_store),
124     (Some(i32_store_valid), i32_store_8),
125     (Some(i32_store_valid), i32_store_16),
126     (Some(i64_store_valid), i64_store_8),
127     (Some(i64_store_valid), i64_store_16),
128     (Some(i64_store_valid), i64_store_32),
129     (Some(have_memory), memory_size),
130     (Some(memory_grow_valid), memory_grow),
131     (Some(memory_init_valid), memory_init),
132     (Some(data_drop_valid), data_drop),
133     (Some(memory_copy_valid), memory_copy),
134     (Some(memory_fill_valid), memory_fill),
135     // Numeric instructions.
136     (None, i32_const),
137     (None, i64_const),
138     (None, f32_const),
139     (None, f64_const),
140     (Some(i32_on_stack), i32_eqz),
141     (Some(i32_i32_on_stack), i32_eq),
142     (Some(i32_i32_on_stack), i32_neq),
143     (Some(i32_i32_on_stack), i32_lt_s),
144     (Some(i32_i32_on_stack), i32_lt_u),
145     (Some(i32_i32_on_stack), i32_gt_s),
146     (Some(i32_i32_on_stack), i32_gt_u),
147     (Some(i32_i32_on_stack), i32_le_s),
148     (Some(i32_i32_on_stack), i32_le_u),
149     (Some(i32_i32_on_stack), i32_ge_s),
150     (Some(i32_i32_on_stack), i32_ge_u),
151     (Some(i64_on_stack), i64_eqz),
152     (Some(i64_i64_on_stack), i64_eq),
153     (Some(i64_i64_on_stack), i64_neq),
154     (Some(i64_i64_on_stack), i64_lt_s),
155     (Some(i64_i64_on_stack), i64_lt_u),
156     (Some(i64_i64_on_stack), i64_gt_s),
157     (Some(i64_i64_on_stack), i64_gt_u),
158     (Some(i64_i64_on_stack), i64_le_s),
159     (Some(i64_i64_on_stack), i64_le_u),
160     (Some(i64_i64_on_stack), i64_ge_s),
161     (Some(i64_i64_on_stack), i64_ge_u),
162     (Some(f32_f32_on_stack), f32_eq),
163     (Some(f32_f32_on_stack), f32_neq),
164     (Some(f32_f32_on_stack), f32_lt),
165     (Some(f32_f32_on_stack), f32_gt),
166     (Some(f32_f32_on_stack), f32_le),
167     (Some(f32_f32_on_stack), f32_ge),
168     (Some(f64_f64_on_stack), f64_eq),
169     (Some(f64_f64_on_stack), f64_neq),
170     (Some(f64_f64_on_stack), f64_lt),
171     (Some(f64_f64_on_stack), f64_gt),
172     (Some(f64_f64_on_stack), f64_le),
173     (Some(f64_f64_on_stack), f64_ge),
174     (Some(i32_on_stack), i32_clz),
175     (Some(i32_on_stack), i32_ctz),
176     (Some(i32_on_stack), i32_popcnt),
177     (Some(i32_i32_on_stack), i32_add),
178     (Some(i32_i32_on_stack), i32_sub),
179     (Some(i32_i32_on_stack), i32_mul),
180     (Some(i32_i32_on_stack), i32_div_s),
181     (Some(i32_i32_on_stack), i32_div_u),
182     (Some(i32_i32_on_stack), i32_rem_s),
183     (Some(i32_i32_on_stack), i32_rem_u),
184     (Some(i32_i32_on_stack), i32_and),
185     (Some(i32_i32_on_stack), i32_or),
186     (Some(i32_i32_on_stack), i32_xor),
187     (Some(i32_i32_on_stack), i32_shl),
188     (Some(i32_i32_on_stack), i32_shr_s),
189     (Some(i32_i32_on_stack), i32_shr_u),
190     (Some(i32_i32_on_stack), i32_rotl),
191     (Some(i32_i32_on_stack), i32_rotr),
192     (Some(i64_on_stack), i64_clz),
193     (Some(i64_on_stack), i64_ctz),
194     (Some(i64_on_stack), i64_popcnt),
195     (Some(i64_i64_on_stack), i64_add),
196     (Some(i64_i64_on_stack), i64_sub),
197     (Some(i64_i64_on_stack), i64_mul),
198     (Some(i64_i64_on_stack), i64_div_s),
199     (Some(i64_i64_on_stack), i64_div_u),
200     (Some(i64_i64_on_stack), i64_rem_s),
201     (Some(i64_i64_on_stack), i64_rem_u),
202     (Some(i64_i64_on_stack), i64_and),
203     (Some(i64_i64_on_stack), i64_or),
204     (Some(i64_i64_on_stack), i64_xor),
205     (Some(i64_i64_on_stack), i64_shl),
206     (Some(i64_i64_on_stack), i64_shr_s),
207     (Some(i64_i64_on_stack), i64_shr_u),
208     (Some(i64_i64_on_stack), i64_rotl),
209     (Some(i64_i64_on_stack), i64_rotr),
210     (Some(f32_on_stack), f32_abs),
211     (Some(f32_on_stack), f32_neg),
212     (Some(f32_on_stack), f32_ceil),
213     (Some(f32_on_stack), f32_floor),
214     (Some(f32_on_stack), f32_trunc),
215     (Some(f32_on_stack), f32_nearest),
216     (Some(f32_on_stack), f32_sqrt),
217     (Some(f32_f32_on_stack), f32_add),
218     (Some(f32_f32_on_stack), f32_sub),
219     (Some(f32_f32_on_stack), f32_mul),
220     (Some(f32_f32_on_stack), f32_div),
221     (Some(f32_f32_on_stack), f32_min),
222     (Some(f32_f32_on_stack), f32_max),
223     (Some(f32_f32_on_stack), f32_copysign),
224     (Some(f64_on_stack), f64_abs),
225     (Some(f64_on_stack), f64_neg),
226     (Some(f64_on_stack), f64_ceil),
227     (Some(f64_on_stack), f64_floor),
228     (Some(f64_on_stack), f64_trunc),
229     (Some(f64_on_stack), f64_nearest),
230     (Some(f64_on_stack), f64_sqrt),
231     (Some(f64_f64_on_stack), f64_add),
232     (Some(f64_f64_on_stack), f64_sub),
233     (Some(f64_f64_on_stack), f64_mul),
234     (Some(f64_f64_on_stack), f64_div),
235     (Some(f64_f64_on_stack), f64_min),
236     (Some(f64_f64_on_stack), f64_max),
237     (Some(f64_f64_on_stack), f64_copysign),
238     (Some(i64_on_stack), i32_wrap_i64),
239     (Some(f32_on_stack), i32_trunc_f32_s),
240     (Some(f32_on_stack), i32_trunc_f32_u),
241     (Some(f64_on_stack), i32_trunc_f64_s),
242     (Some(f64_on_stack), i32_trunc_f64_u),
243     (Some(i32_on_stack), i64_extend_i32_s),
244     (Some(i32_on_stack), i64_extend_i32_u),
245     (Some(f32_on_stack), i64_trunc_f32_s),
246     (Some(f32_on_stack), i64_trunc_f32_u),
247     (Some(f64_on_stack), i64_trunc_f64_s),
248     (Some(f64_on_stack), i64_trunc_f64_u),
249     (Some(i32_on_stack), f32_convert_i32_s),
250     (Some(i32_on_stack), f32_convert_i32_u),
251     (Some(i64_on_stack), f32_convert_i64_s),
252     (Some(i64_on_stack), f32_convert_i64_u),
253     (Some(f64_on_stack), f32_demote_f64),
254     (Some(i32_on_stack), f64_convert_i32_s),
255     (Some(i32_on_stack), f64_convert_i32_u),
256     (Some(i64_on_stack), f64_convert_i64_s),
257     (Some(i64_on_stack), f64_convert_i64_u),
258     (Some(f32_on_stack), f64_promote_f32),
259     (Some(f32_on_stack), i32_reinterpret_f32),
260     (Some(f64_on_stack), i64_reinterpret_f64),
261     (Some(i32_on_stack), f32_reinterpret_i32),
262     (Some(i64_on_stack), f64_reinterpret_i64),
263     (Some(i32_on_stack), i32_extend_8_s),
264     (Some(i32_on_stack), i32_extend_16_s),
265     (Some(i64_on_stack), i64_extend_8_s),
266     (Some(i64_on_stack), i64_extend_16_s),
267     (Some(i64_on_stack), i64_extend_32_s),
268     (Some(f32_on_stack), i32_trunc_sat_f32_s),
269     (Some(f32_on_stack), i32_trunc_sat_f32_u),
270     (Some(f64_on_stack), i32_trunc_sat_f64_s),
271     (Some(f64_on_stack), i32_trunc_sat_f64_u),
272     (Some(f32_on_stack), i64_trunc_sat_f32_s),
273     (Some(f32_on_stack), i64_trunc_sat_f32_u),
274     (Some(f64_on_stack), i64_trunc_sat_f64_s),
275     (Some(f64_on_stack), i64_trunc_sat_f64_u),
276     // reference types proposal
277     (Some(ref_null_valid), ref_null),
278     (Some(ref_func_valid), ref_func),
279     (Some(ref_is_null_valid), ref_is_null),
280     (Some(table_fill_valid), table_fill),
281     (Some(table_set_valid), table_set),
282     (Some(table_get_valid), table_get),
283     (Some(table_size_valid), table_size),
284     (Some(table_grow_valid), table_grow),
285     (Some(table_copy_valid), table_copy),
286     (Some(table_init_valid), table_init),
287     (Some(elem_drop_valid), elem_drop),
288     // SIMD instructions.
289     (Some(simd_have_memory_and_offset), v128_load),
290     (Some(simd_have_memory_and_offset), v128_load8x8s),
291     (Some(simd_have_memory_and_offset), v128_load8x8u),
292     (Some(simd_have_memory_and_offset), v128_load16x4s),
293     (Some(simd_have_memory_and_offset), v128_load16x4u),
294     (Some(simd_have_memory_and_offset), v128_load32x2s),
295     (Some(simd_have_memory_and_offset), v128_load32x2u),
296     (Some(simd_have_memory_and_offset), v128_load8_splat),
297     (Some(simd_have_memory_and_offset), v128_load16_splat),
298     (Some(simd_have_memory_and_offset), v128_load32_splat),
299     (Some(simd_have_memory_and_offset), v128_load64_splat),
300     (Some(simd_have_memory_and_offset), v128_load32_zero),
301     (Some(simd_have_memory_and_offset), v128_load64_zero),
302     (Some(simd_v128_store_valid), v128_store),
303     (Some(simd_have_memory_and_offset_and_v128), v128_load8_lane),
304     (Some(simd_have_memory_and_offset_and_v128), v128_load16_lane),
305     (Some(simd_have_memory_and_offset_and_v128), v128_load32_lane),
306     (Some(simd_have_memory_and_offset_and_v128), v128_load64_lane),
307     (Some(simd_v128_store_valid), v128_store8_lane),
308     (Some(simd_v128_store_valid), v128_store16_lane),
309     (Some(simd_v128_store_valid), v128_store32_lane),
310     (Some(simd_v128_store_valid), v128_store64_lane),
311     (Some(simd_enabled), v128_const),
312     (Some(simd_v128_v128_on_stack), i8x16_shuffle),
313     (Some(simd_v128_on_stack), i8x16_extract_lane_s),
314     (Some(simd_v128_on_stack), i8x16_extract_lane_u),
315     (Some(simd_v128_i32_on_stack), i8x16_replace_lane),
316     (Some(simd_v128_on_stack), i16x8_extract_lane_s),
317     (Some(simd_v128_on_stack), i16x8_extract_lane_u),
318     (Some(simd_v128_i32_on_stack), i16x8_replace_lane),
319     (Some(simd_v128_on_stack), i32x4_extract_lane),
320     (Some(simd_v128_i32_on_stack), i32x4_replace_lane),
321     (Some(simd_v128_on_stack), i64x2_extract_lane),
322     (Some(simd_v128_i64_on_stack), i64x2_replace_lane),
323     (Some(simd_v128_on_stack), f32x4_extract_lane),
324     (Some(simd_v128_f32_on_stack), f32x4_replace_lane),
325     (Some(simd_v128_on_stack), f64x2_extract_lane),
326     (Some(simd_v128_f64_on_stack), f64x2_replace_lane),
327     (Some(simd_v128_v128_on_stack), i8x16_swizzle),
328     (Some(simd_i32_on_stack), i8x16_splat),
329     (Some(simd_i32_on_stack), i16x8_splat),
330     (Some(simd_i32_on_stack), i32x4_splat),
331     (Some(simd_i64_on_stack), i64x2_splat),
332     (Some(simd_f32_on_stack), f32x4_splat),
333     (Some(simd_f64_on_stack), f64x2_splat),
334     (Some(simd_v128_v128_on_stack), i8x16_swizzle),
335     (Some(simd_v128_v128_v128_on_stack), v128_bitselect),
336     (Some(simd_v128_v128_on_stack), i8x16_eq),
337     (Some(simd_v128_v128_on_stack), i8x16_ne),
338     (Some(simd_v128_v128_on_stack), i8x16_lt_s),
339     (Some(simd_v128_v128_on_stack), i8x16_lt_u),
340     (Some(simd_v128_v128_on_stack), i8x16_gt_s),
341     (Some(simd_v128_v128_on_stack), i8x16_gt_u),
342     (Some(simd_v128_v128_on_stack), i8x16_le_s),
343     (Some(simd_v128_v128_on_stack), i8x16_le_u),
344     (Some(simd_v128_v128_on_stack), i8x16_ge_s),
345     (Some(simd_v128_v128_on_stack), i8x16_ge_u),
346     (Some(simd_v128_v128_on_stack), i16x8_eq),
347     (Some(simd_v128_v128_on_stack), i16x8_ne),
348     (Some(simd_v128_v128_on_stack), i16x8_lt_s),
349     (Some(simd_v128_v128_on_stack), i16x8_lt_u),
350     (Some(simd_v128_v128_on_stack), i16x8_gt_s),
351     (Some(simd_v128_v128_on_stack), i16x8_gt_u),
352     (Some(simd_v128_v128_on_stack), i16x8_le_s),
353     (Some(simd_v128_v128_on_stack), i16x8_le_u),
354     (Some(simd_v128_v128_on_stack), i16x8_ge_s),
355     (Some(simd_v128_v128_on_stack), i16x8_ge_u),
356     (Some(simd_v128_v128_on_stack), i32x4_eq),
357     (Some(simd_v128_v128_on_stack), i32x4_ne),
358     (Some(simd_v128_v128_on_stack), i32x4_lt_s),
359     (Some(simd_v128_v128_on_stack), i32x4_lt_u),
360     (Some(simd_v128_v128_on_stack), i32x4_gt_s),
361     (Some(simd_v128_v128_on_stack), i32x4_gt_u),
362     (Some(simd_v128_v128_on_stack), i32x4_le_s),
363     (Some(simd_v128_v128_on_stack), i32x4_le_u),
364     (Some(simd_v128_v128_on_stack), i32x4_ge_s),
365     (Some(simd_v128_v128_on_stack), i32x4_ge_u),
366     (Some(simd_v128_v128_on_stack), i64x2_eq),
367     (Some(simd_v128_v128_on_stack), i64x2_ne),
368     (Some(simd_v128_v128_on_stack), i64x2_lt_s),
369     (Some(simd_v128_v128_on_stack), i64x2_gt_s),
370     (Some(simd_v128_v128_on_stack), i64x2_le_s),
371     (Some(simd_v128_v128_on_stack), i64x2_ge_s),
372     (Some(simd_v128_v128_on_stack), f32x4_eq),
373     (Some(simd_v128_v128_on_stack), f32x4_ne),
374     (Some(simd_v128_v128_on_stack), f32x4_lt),
375     (Some(simd_v128_v128_on_stack), f32x4_gt),
376     (Some(simd_v128_v128_on_stack), f32x4_le),
377     (Some(simd_v128_v128_on_stack), f32x4_ge),
378     (Some(simd_v128_v128_on_stack), f64x2_eq),
379     (Some(simd_v128_v128_on_stack), f64x2_ne),
380     (Some(simd_v128_v128_on_stack), f64x2_lt),
381     (Some(simd_v128_v128_on_stack), f64x2_gt),
382     (Some(simd_v128_v128_on_stack), f64x2_le),
383     (Some(simd_v128_v128_on_stack), f64x2_ge),
384     (Some(simd_v128_on_stack), v128_not),
385     (Some(simd_v128_v128_on_stack), v128_and),
386     (Some(simd_v128_v128_on_stack), v128_and_not),
387     (Some(simd_v128_v128_on_stack), v128_or),
388     (Some(simd_v128_v128_on_stack), v128_xor),
389     (Some(simd_v128_v128_on_stack), v128_any_true),
390     (Some(simd_v128_on_stack), i8x16_abs),
391     (Some(simd_v128_on_stack), i8x16_neg),
392     (Some(simd_v128_on_stack), i8x16_popcnt),
393     (Some(simd_v128_on_stack), i8x16_all_true),
394     (Some(simd_v128_on_stack), i8x16_bitmask),
395     (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8s),
396     (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8u),
397     (Some(simd_v128_i32_on_stack), i8x16_shl),
398     (Some(simd_v128_i32_on_stack), i8x16_shr_s),
399     (Some(simd_v128_i32_on_stack), i8x16_shr_u),
400     (Some(simd_v128_v128_on_stack), i8x16_add),
401     (Some(simd_v128_v128_on_stack), i8x16_add_sat_s),
402     (Some(simd_v128_v128_on_stack), i8x16_add_sat_u),
403     (Some(simd_v128_v128_on_stack), i8x16_sub),
404     (Some(simd_v128_v128_on_stack), i8x16_sub_sat_s),
405     (Some(simd_v128_v128_on_stack), i8x16_sub_sat_u),
406     (Some(simd_v128_v128_on_stack), i8x16_min_s),
407     (Some(simd_v128_v128_on_stack), i8x16_min_u),
408     (Some(simd_v128_v128_on_stack), i8x16_max_s),
409     (Some(simd_v128_v128_on_stack), i8x16_max_u),
410     (Some(simd_v128_v128_on_stack), i8x16_rounding_average_u),
411     (Some(simd_v128_on_stack), i16x8_ext_add_pairwise_i8x16s),
412     (Some(simd_v128_on_stack), i16x8_ext_add_pairwise_i8x16u),
413     (Some(simd_v128_on_stack), i16x8_abs),
414     (Some(simd_v128_on_stack), i16x8_neg),
415     (Some(simd_v128_v128_on_stack), i16x8q15_mulr_sat_s),
416     (Some(simd_v128_on_stack), i16x8_all_true),
417     (Some(simd_v128_on_stack), i16x8_bitmask),
418     (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4s),
419     (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4u),
420     (Some(simd_v128_on_stack), i16x8_extend_low_i8x16s),
421     (Some(simd_v128_on_stack), i16x8_extend_high_i8x16s),
422     (Some(simd_v128_on_stack), i16x8_extend_low_i8x16u),
423     (Some(simd_v128_on_stack), i16x8_extend_high_i8x16u),
424     (Some(simd_v128_i32_on_stack), i16x8_shl),
425     (Some(simd_v128_i32_on_stack), i16x8_shr_s),
426     (Some(simd_v128_i32_on_stack), i16x8_shr_u),
427     (Some(simd_v128_v128_on_stack), i16x8_add),
428     (Some(simd_v128_v128_on_stack), i16x8_add_sat_s),
429     (Some(simd_v128_v128_on_stack), i16x8_add_sat_u),
430     (Some(simd_v128_v128_on_stack), i16x8_sub),
431     (Some(simd_v128_v128_on_stack), i16x8_sub_sat_s),
432     (Some(simd_v128_v128_on_stack), i16x8_sub_sat_u),
433     (Some(simd_v128_v128_on_stack), i16x8_mul),
434     (Some(simd_v128_v128_on_stack), i16x8_min_s),
435     (Some(simd_v128_v128_on_stack), i16x8_min_u),
436     (Some(simd_v128_v128_on_stack), i16x8_max_s),
437     (Some(simd_v128_v128_on_stack), i16x8_max_u),
438     (Some(simd_v128_v128_on_stack), i16x8_rounding_average_u),
439     (Some(simd_v128_v128_on_stack), i16x8_ext_mul_low_i8x16s),
440     (Some(simd_v128_v128_on_stack), i16x8_ext_mul_high_i8x16s),
441     (Some(simd_v128_v128_on_stack), i16x8_ext_mul_low_i8x16u),
442     (Some(simd_v128_v128_on_stack), i16x8_ext_mul_high_i8x16u),
443     (Some(simd_v128_on_stack), i32x4_ext_add_pairwise_i16x8s),
444     (Some(simd_v128_on_stack), i32x4_ext_add_pairwise_i16x8u),
445     (Some(simd_v128_on_stack), i32x4_abs),
446     (Some(simd_v128_on_stack), i32x4_neg),
447     (Some(simd_v128_on_stack), i32x4_all_true),
448     (Some(simd_v128_on_stack), i32x4_bitmask),
449     (Some(simd_v128_on_stack), i32x4_extend_low_i16x8s),
450     (Some(simd_v128_on_stack), i32x4_extend_high_i16x8s),
451     (Some(simd_v128_on_stack), i32x4_extend_low_i16x8u),
452     (Some(simd_v128_on_stack), i32x4_extend_high_i16x8u),
453     (Some(simd_v128_i32_on_stack), i32x4_shl),
454     (Some(simd_v128_i32_on_stack), i32x4_shr_s),
455     (Some(simd_v128_i32_on_stack), i32x4_shr_u),
456     (Some(simd_v128_v128_on_stack), i32x4_add),
457     (Some(simd_v128_v128_on_stack), i32x4_sub),
458     (Some(simd_v128_v128_on_stack), i32x4_mul),
459     (Some(simd_v128_v128_on_stack), i32x4_min_s),
460     (Some(simd_v128_v128_on_stack), i32x4_min_u),
461     (Some(simd_v128_v128_on_stack), i32x4_max_s),
462     (Some(simd_v128_v128_on_stack), i32x4_max_u),
463     (Some(simd_v128_v128_on_stack), i32x4_dot_i16x8s),
464     (Some(simd_v128_v128_on_stack), i32x4_ext_mul_low_i16x8s),
465     (Some(simd_v128_v128_on_stack), i32x4_ext_mul_high_i16x8s),
466     (Some(simd_v128_v128_on_stack), i32x4_ext_mul_low_i16x8u),
467     (Some(simd_v128_v128_on_stack), i32x4_ext_mul_high_i16x8u),
468     (Some(simd_v128_on_stack), i64x2_abs),
469     (Some(simd_v128_on_stack), i64x2_neg),
470     (Some(simd_v128_on_stack), i64x2_all_true),
471     (Some(simd_v128_on_stack), i64x2_bitmask),
472     (Some(simd_v128_on_stack), i64x2_extend_low_i32x4s),
473     (Some(simd_v128_on_stack), i64x2_extend_high_i32x4s),
474     (Some(simd_v128_on_stack), i64x2_extend_low_i32x4u),
475     (Some(simd_v128_on_stack), i64x2_extend_high_i32x4u),
476     (Some(simd_v128_i32_on_stack), i64x2_shl),
477     (Some(simd_v128_i32_on_stack), i64x2_shr_s),
478     (Some(simd_v128_i32_on_stack), i64x2_shr_u),
479     (Some(simd_v128_v128_on_stack), i64x2_add),
480     (Some(simd_v128_v128_on_stack), i64x2_sub),
481     (Some(simd_v128_v128_on_stack), i64x2_mul),
482     (Some(simd_v128_v128_on_stack), i64x2_ext_mul_low_i32x4s),
483     (Some(simd_v128_v128_on_stack), i64x2_ext_mul_high_i32x4s),
484     (Some(simd_v128_v128_on_stack), i64x2_ext_mul_low_i32x4u),
485     (Some(simd_v128_v128_on_stack), i64x2_ext_mul_high_i32x4u),
486     (Some(simd_v128_on_stack), f32x4_ceil),
487     (Some(simd_v128_on_stack), f32x4_floor),
488     (Some(simd_v128_on_stack), f32x4_trunc),
489     (Some(simd_v128_on_stack), f32x4_nearest),
490     (Some(simd_v128_on_stack), f32x4_abs),
491     (Some(simd_v128_on_stack), f32x4_neg),
492     (Some(simd_v128_on_stack), f32x4_sqrt),
493     (Some(simd_v128_v128_on_stack), f32x4_add),
494     (Some(simd_v128_v128_on_stack), f32x4_sub),
495     (Some(simd_v128_v128_on_stack), f32x4_mul),
496     (Some(simd_v128_v128_on_stack), f32x4_div),
497     (Some(simd_v128_v128_on_stack), f32x4_min),
498     (Some(simd_v128_v128_on_stack), f32x4_max),
499     (Some(simd_v128_v128_on_stack), f32x4p_min),
500     (Some(simd_v128_v128_on_stack), f32x4p_max),
501     (Some(simd_v128_on_stack), f64x2_ceil),
502     (Some(simd_v128_on_stack), f64x2_floor),
503     (Some(simd_v128_on_stack), f64x2_trunc),
504     (Some(simd_v128_on_stack), f64x2_nearest),
505     (Some(simd_v128_on_stack), f64x2_abs),
506     (Some(simd_v128_on_stack), f64x2_neg),
507     (Some(simd_v128_on_stack), f64x2_sqrt),
508     (Some(simd_v128_v128_on_stack), f64x2_add),
509     (Some(simd_v128_v128_on_stack), f64x2_sub),
510     (Some(simd_v128_v128_on_stack), f64x2_mul),
511     (Some(simd_v128_v128_on_stack), f64x2_div),
512     (Some(simd_v128_v128_on_stack), f64x2_min),
513     (Some(simd_v128_v128_on_stack), f64x2_max),
514     (Some(simd_v128_v128_on_stack), f64x2p_min),
515     (Some(simd_v128_v128_on_stack), f64x2p_max),
516     (Some(simd_v128_on_stack), i32x4_trunc_sat_f32x4s),
517     (Some(simd_v128_on_stack), i32x4_trunc_sat_f32x4u),
518     (Some(simd_v128_on_stack), f32x4_convert_i32x4s),
519     (Some(simd_v128_on_stack), f32x4_convert_i32x4u),
520     (Some(simd_v128_on_stack), i32x4_trunc_sat_f64x2s_zero),
521     (Some(simd_v128_on_stack), i32x4_trunc_sat_f64x2u_zero),
522     (Some(simd_v128_on_stack), f64x2_convert_low_i32x4s),
523     (Some(simd_v128_on_stack), f64x2_convert_low_i32x4u),
524     (Some(simd_v128_on_stack), f32x4_demote_f64x2_zero),
525     (Some(simd_v128_on_stack), f64x2_promote_low_f32x4),
526 }
527 
528 pub(crate) struct CodeBuilderAllocations {
529     // The control labels in scope right now.
530     controls: Vec<Control>,
531 
532     // The types on the operand stack right now.
533     operands: Vec<Option<ValType>>,
534 
535     // Dynamic set of options of instruction we can generate that are known to
536     // be valid right now.
537     options: Vec<(
538         fn(&mut Unstructured, &Module, &mut CodeBuilder) -> Result<Instruction>,
539         u32,
540     )>,
541 
542     // Cached information about the module that we're generating functions for,
543     // used to speed up validity checks. The mutable globals map is a map of the
544     // type of global to the global indices which have that type (and they're
545     // all mutable).
546     mutable_globals: BTreeMap<ValType, Vec<u32>>,
547 
548     // Like mutable globals above this is a map from function types to the list
549     // of functions that have that function type.
550     functions: BTreeMap<Vec<ValType>, Vec<u32>>,
551 
552     // Like functions above this is a map from tag types to the list of tags
553     // have that tag type.
554     tags: BTreeMap<Vec<ValType>, Vec<u32>>,
555 
556     // Tables in this module which have a funcref element type.
557     funcref_tables: Vec<u32>,
558 
559     // Functions that are referenced in the module through globals and segments.
560     referenced_functions: Vec<u32>,
561 
562     // Flag that indicates if any element segments have the same type as any
563     // table
564     table_init_possible: bool,
565 
566     // Lists of memory indices which are either 32-bit or 64-bit. This is used
567     // for faster lookup in validating instructions to know which memories have
568     // which types. For example if there are no 64-bit memories then we
569     // shouldn't ever look for i64 on the stack for `i32.load`.
570     memory32: Vec<u32>,
571     memory64: Vec<u32>,
572 }
573 
574 pub(crate) struct CodeBuilder<'a> {
575     func_ty: &'a FuncType,
576     locals: &'a mut Vec<ValType>,
577     allocs: &'a mut CodeBuilderAllocations,
578 
579     // Temporary locals injected and used by nan canonicalization. Note that
580     // this list of extra locals is appended to `self.locals` at the end of code
581     // generation, and it's kept separate here to avoid using these locals in
582     // `local.get` and similar instructions.
583     extra_locals: Vec<ValType>,
584     f32_scratch: Option<usize>,
585     f64_scratch: Option<usize>,
586     v128_scratch: Option<usize>,
587 }
588 
589 /// A control frame.
590 #[derive(Debug, Clone)]
591 struct Control {
592     kind: ControlKind,
593     /// Value types that must be on the stack when entering this control frame.
594     params: Vec<ValType>,
595     /// Value types that are left on the stack when exiting this control frame.
596     results: Vec<ValType>,
597     /// How far down the operand stack instructions inside this control frame
598     /// can reach.
599     height: usize,
600 }
601 
602 impl Control {
label_types(&self) -> &[ValType]603     fn label_types(&self) -> &[ValType] {
604         if self.kind == ControlKind::Loop {
605             &self.params
606         } else {
607             &self.results
608         }
609     }
610 }
611 
612 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
613 enum ControlKind {
614     Block,
615     If,
616     Loop,
617     Try,
618     Catch,
619     CatchAll,
620 }
621 
622 enum Float {
623     F32,
624     F64,
625     F32x4,
626     F64x2,
627 }
628 
629 impl CodeBuilderAllocations {
new(module: &Module) -> Self630     pub(crate) fn new(module: &Module) -> Self {
631         let mut mutable_globals = BTreeMap::new();
632         for (i, global) in module.globals.iter().enumerate() {
633             if global.mutable {
634                 mutable_globals
635                     .entry(global.val_type)
636                     .or_insert(Vec::new())
637                     .push(i as u32);
638             }
639         }
640 
641         let mut tags = BTreeMap::new();
642         for (idx, tag_type) in module.tags() {
643             tags.entry(tag_type.func_type.params.clone())
644                 .or_insert(Vec::new())
645                 .push(idx);
646         }
647 
648         let mut functions = BTreeMap::new();
649         for (idx, func) in module.funcs() {
650             functions
651                 .entry(func.params.clone())
652                 .or_insert(Vec::new())
653                 .push(idx);
654         }
655 
656         let mut funcref_tables = Vec::new();
657         let mut table_tys = Vec::new();
658         for (i, table) in module.tables.iter().enumerate() {
659             table_tys.push(table.elem_ty);
660             if table.elem_ty == ValType::FuncRef {
661                 funcref_tables.push(i as u32);
662             }
663         }
664 
665         let mut referenced_functions = BTreeSet::new();
666         for (_, expr) in module.defined_globals.iter() {
667             if let Instruction::RefFunc(i) = *expr {
668                 referenced_functions.insert(i);
669             }
670         }
671         for g in module.elems.iter() {
672             match &g.items {
673                 Elements::Expressions(e) => {
674                     let iter = e.iter().filter_map(|i| *i);
675                     referenced_functions.extend(iter);
676                 }
677                 Elements::Functions(e) => {
678                     referenced_functions.extend(e.iter().cloned());
679                 }
680             }
681         }
682 
683         let table_init_possible = module.elems.iter().any(|e| table_tys.contains(&e.ty));
684 
685         let mut memory32 = Vec::new();
686         let mut memory64 = Vec::new();
687         for (i, mem) in module.memories.iter().enumerate() {
688             if mem.memory64 {
689                 memory64.push(i as u32);
690             } else {
691                 memory32.push(i as u32);
692             }
693         }
694 
695         CodeBuilderAllocations {
696             controls: Vec::with_capacity(4),
697             operands: Vec::with_capacity(16),
698             options: Vec::with_capacity(NUM_OPTIONS),
699             functions,
700             tags,
701             mutable_globals,
702             funcref_tables,
703             referenced_functions: referenced_functions.into_iter().collect(),
704             table_init_possible,
705             memory32,
706             memory64,
707         }
708     }
709 
builder<'a>( &'a mut self, func_ty: &'a FuncType, locals: &'a mut Vec<ValType>, ) -> CodeBuilder<'a>710     pub(crate) fn builder<'a>(
711         &'a mut self,
712         func_ty: &'a FuncType,
713         locals: &'a mut Vec<ValType>,
714     ) -> CodeBuilder<'a> {
715         self.controls.clear();
716         self.controls.push(Control {
717             kind: ControlKind::Block,
718             params: vec![],
719             results: func_ty.results.clone(),
720             height: 0,
721         });
722 
723         self.operands.clear();
724         self.options.clear();
725 
726         CodeBuilder {
727             func_ty,
728             locals,
729             allocs: self,
730             extra_locals: Vec::new(),
731             f32_scratch: None,
732             f64_scratch: None,
733             v128_scratch: None,
734         }
735     }
736 }
737 
738 impl CodeBuilder<'_> {
739     /// Get the operands that are in-scope within the current control frame.
operands(&self) -> &[Option<ValType>]740     fn operands(&self) -> &[Option<ValType>] {
741         let height = self.allocs.controls.last().map_or(0, |c| c.height);
742         &self.allocs.operands[height..]
743     }
744 
pop_operands(&mut self, to_pop: &[ValType])745     fn pop_operands(&mut self, to_pop: &[ValType]) {
746         debug_assert!(self.types_on_stack(to_pop));
747         self.allocs
748             .operands
749             .truncate(self.allocs.operands.len() - to_pop.len());
750     }
751 
push_operands(&mut self, to_push: &[ValType])752     fn push_operands(&mut self, to_push: &[ValType]) {
753         self.allocs
754             .operands
755             .extend(to_push.iter().copied().map(Some));
756     }
757 
label_types_on_stack(&self, to_check: &Control) -> bool758     fn label_types_on_stack(&self, to_check: &Control) -> bool {
759         self.types_on_stack(to_check.label_types())
760     }
761 
type_on_stack(&self, ty: ValType) -> bool762     fn type_on_stack(&self, ty: ValType) -> bool {
763         match self.operands().last() {
764             None => false,
765             Some(None) => true,
766             Some(Some(x)) => *x == ty,
767         }
768     }
769 
types_on_stack(&self, types: &[ValType]) -> bool770     fn types_on_stack(&self, types: &[ValType]) -> bool {
771         self.operands().len() >= types.len()
772             && self
773                 .operands()
774                 .iter()
775                 .rev()
776                 .zip(types.iter().rev())
777                 .all(|(a, b)| match (a, b) {
778                     (None, _) => true,
779                     (Some(x), y) => x == y,
780                 })
781     }
782 
783     #[inline(never)]
arbitrary_block_type(&self, u: &mut Unstructured, module: &Module) -> Result<BlockType>784     fn arbitrary_block_type(&self, u: &mut Unstructured, module: &Module) -> Result<BlockType> {
785         let mut options: Vec<Box<dyn Fn(&mut Unstructured) -> Result<BlockType>>> = vec![
786             Box::new(|_| Ok(BlockType::Empty)),
787             Box::new(|u| Ok(BlockType::Result(module.arbitrary_valtype(u)?))),
788         ];
789 
790         for (i, ty) in module.func_types() {
791             if self.types_on_stack(&ty.params) {
792                 options.push(Box::new(move |_| Ok(BlockType::FuncType(i as u32))));
793             }
794         }
795 
796         let f = u.choose(&options)?;
797         f(u)
798     }
799 
arbitrary( mut self, u: &mut Unstructured, module: &Module, ) -> Result<Vec<Instruction>>800     pub(crate) fn arbitrary(
801         mut self,
802         u: &mut Unstructured,
803         module: &Module,
804     ) -> Result<Vec<Instruction>> {
805         let max_instructions = module.config.max_instructions();
806         let mut instructions = vec![];
807 
808         while !self.allocs.controls.is_empty() {
809             let keep_going = instructions.len() < max_instructions
810                 && u.arbitrary().map_or(false, |b: u8| b != 0);
811             if !keep_going {
812                 self.end_active_control_frames(u, &mut instructions);
813                 break;
814             }
815 
816             match choose_instruction(u, module, &mut self) {
817                 Some(f) => {
818                     let inst = f(u, module, &mut self)?;
819                     instructions.push(inst);
820                 }
821                 // Choosing an instruction can fail because there is not enough
822                 // underlying data, so we really cannot generate any more
823                 // instructions. In this case we swallow that error and instead
824                 // just terminate our wasm function's frames.
825                 None => {
826                     self.end_active_control_frames(u, &mut instructions);
827                     break;
828                 }
829             }
830 
831             // If the configuration for this module requests nan
832             // canonicalization then perform that here based on whether or not
833             // the previous instruction needs canonicalization. Note that this
834             // is based off Cranelift's pass for nan canonicalization for which
835             // instructions to canonicalize, but the general idea is most
836             // floating-point operations.
837             if module.config.canonicalize_nans() {
838                 match instructions.last().unwrap() {
839                     Instruction::F32Ceil
840                     | Instruction::F32Floor
841                     | Instruction::F32Nearest
842                     | Instruction::F32Sqrt
843                     | Instruction::F32Trunc
844                     | Instruction::F32Div
845                     | Instruction::F32Max
846                     | Instruction::F32Min
847                     | Instruction::F32Mul
848                     | Instruction::F32Sub
849                     | Instruction::F32Add => self.canonicalize_nan(Float::F32, &mut instructions),
850                     Instruction::F64Ceil
851                     | Instruction::F64Floor
852                     | Instruction::F64Nearest
853                     | Instruction::F64Sqrt
854                     | Instruction::F64Trunc
855                     | Instruction::F64Div
856                     | Instruction::F64Max
857                     | Instruction::F64Min
858                     | Instruction::F64Mul
859                     | Instruction::F64Sub
860                     | Instruction::F64Add => self.canonicalize_nan(Float::F64, &mut instructions),
861                     Instruction::F32x4Ceil
862                     | Instruction::F32x4Floor
863                     | Instruction::F32x4Nearest
864                     | Instruction::F32x4Sqrt
865                     | Instruction::F32x4Trunc
866                     | Instruction::F32x4Div
867                     | Instruction::F32x4Max
868                     | Instruction::F32x4Min
869                     | Instruction::F32x4Mul
870                     | Instruction::F32x4Sub
871                     | Instruction::F32x4Add => {
872                         self.canonicalize_nan(Float::F32x4, &mut instructions)
873                     }
874                     Instruction::F64x2Ceil
875                     | Instruction::F64x2Floor
876                     | Instruction::F64x2Nearest
877                     | Instruction::F64x2Sqrt
878                     | Instruction::F64x2Trunc
879                     | Instruction::F64x2Div
880                     | Instruction::F64x2Max
881                     | Instruction::F64x2Min
882                     | Instruction::F64x2Mul
883                     | Instruction::F64x2Sub
884                     | Instruction::F64x2Add => {
885                         self.canonicalize_nan(Float::F64x2, &mut instructions)
886                     }
887                     _ => {}
888                 }
889             }
890         }
891 
892         self.locals.extend(self.extra_locals.drain(..));
893 
894         Ok(instructions)
895     }
896 
canonicalize_nan(&mut self, ty: Float, ins: &mut Vec<Instruction>)897     fn canonicalize_nan(&mut self, ty: Float, ins: &mut Vec<Instruction>) {
898         // We'll need to temporarily save the top of the stack into a local, so
899         // figure out that local here. Note that this tries to use the same
900         // local if canonicalization happens more than once in a function.
901         let local = match ty {
902             Float::F32 => &mut self.f32_scratch,
903             Float::F64 => &mut self.f64_scratch,
904             Float::F32x4 | Float::F64x2 => &mut self.v128_scratch,
905         };
906         let local = match *local {
907             Some(i) => i,
908             None => {
909                 let val = self.locals.len() + self.func_ty.params.len() + self.extra_locals.len();
910                 *local = Some(val);
911                 self.extra_locals.push(match ty {
912                     Float::F32 => ValType::F32,
913                     Float::F64 => ValType::F64,
914                     Float::F32x4 | Float::F64x2 => ValType::V128,
915                 });
916                 val
917             }
918         };
919         let local = local as u32;
920 
921         // Save the previous instruction's result into a local. This also leaves
922         // a value on the stack as `val1` for the `select` instruction.
923         ins.push(Instruction::LocalTee(local));
924 
925         // The `val2` value input to the `select` below, our nan pattern.
926         //
927         // The nan patterns here are chosen to be a canonical representation
928         // which is still NaN but the wasm will always produce the same bits of
929         // a nan so if the wasm takes a look at the nan inside it'll always see
930         // the same representation.
931         const CANON_32BIT_NAN: u32 = 0b01111111110000000000000000000000;
932         const CANON_64BIT_NAN: u64 =
933             0b0111111111111000000000000000000000000000000000000000000000000000;
934         ins.push(match ty {
935             Float::F32 => Instruction::F32Const(f32::from_bits(CANON_32BIT_NAN)),
936             Float::F64 => Instruction::F64Const(f64::from_bits(CANON_64BIT_NAN)),
937             Float::F32x4 => {
938                 let nan = CANON_32BIT_NAN as i128;
939                 let nan = nan | (nan << 32) | (nan << 64) | (nan << 96);
940                 Instruction::V128Const(nan)
941             }
942             Float::F64x2 => {
943                 let nan = CANON_64BIT_NAN as i128;
944                 let nan = nan | (nan << 64);
945                 Instruction::V128Const(nan)
946             }
947         });
948 
949         // the condition of the `select`, which is the float's equality test
950         // with itself.
951         ins.push(Instruction::LocalGet(local));
952         ins.push(Instruction::LocalGet(local));
953         ins.push(match ty {
954             Float::F32 => Instruction::F32Eq,
955             Float::F64 => Instruction::F64Eq,
956             Float::F32x4 => Instruction::F32x4Eq,
957             Float::F64x2 => Instruction::F64x2Eq,
958         });
959 
960         // Select the result. If the condition is nonzero (aka the float is
961         // equal to itself) it picks `val1`, otherwise if zero (aka the float
962         // is nan) it picks `val2`.
963         ins.push(match ty {
964             Float::F32 | Float::F64 => Instruction::Select,
965             Float::F32x4 | Float::F64x2 => Instruction::V128Bitselect,
966         });
967     }
968 
end_active_control_frames( &mut self, u: &mut Unstructured<'_>, instructions: &mut Vec<Instruction>, )969     fn end_active_control_frames(
970         &mut self,
971         u: &mut Unstructured<'_>,
972         instructions: &mut Vec<Instruction>,
973     ) {
974         while !self.allocs.controls.is_empty() {
975             // Ensure that this label is valid by placing the right types onto
976             // the operand stack for the end of the label.
977             self.guarantee_label_results(u, instructions);
978 
979             // Remove the label and clear the operand stack since the label has
980             // been removed.
981             let label = self.allocs.controls.pop().unwrap();
982             self.allocs.operands.truncate(label.height);
983 
984             // If this is an `if` that is not stack neutral, then it
985             // must have an `else`. Generate synthetic results here in the same
986             // manner we did above.
987             if label.kind == ControlKind::If && label.params != label.results {
988                 instructions.push(Instruction::Else);
989                 self.allocs.controls.push(label.clone());
990                 self.allocs
991                     .operands
992                     .extend(label.params.into_iter().map(Some));
993                 self.guarantee_label_results(u, instructions);
994                 self.allocs.controls.pop();
995                 self.allocs.operands.truncate(label.height);
996             }
997 
998             // The last control frame for the function return does not
999             // need an `end` instruction.
1000             if !self.allocs.controls.is_empty() {
1001                 instructions.push(Instruction::End);
1002             }
1003 
1004             // Place the results of the label onto the operand stack for use
1005             // after the label.
1006             self.allocs
1007                 .operands
1008                 .extend(label.results.into_iter().map(Some));
1009         }
1010     }
1011 
1012     /// Modifies the instruction stream to guarantee that the current control
1013     /// label's results are on the stack and ready for the control label to return.
guarantee_label_results( &mut self, u: &mut Unstructured<'_>, instructions: &mut Vec<Instruction>, )1014     fn guarantee_label_results(
1015         &mut self,
1016         u: &mut Unstructured<'_>,
1017         instructions: &mut Vec<Instruction>,
1018     ) {
1019         let mut operands = self.operands();
1020         let label = self.allocs.controls.last().unwrap();
1021 
1022         // Already done, yay!
1023         if label.results.len() == operands.len() && self.types_on_stack(&label.results) {
1024             return;
1025         }
1026 
1027         // Generating an unreachable instruction is always a valid way to
1028         // generate any types for a label, but it's not too interesting, so
1029         // don't favor it.
1030         if u.arbitrary::<u16>().unwrap_or(0) == 1 {
1031             instructions.push(Instruction::Unreachable);
1032             return;
1033         }
1034 
1035         // Arbitrarily massage the stack to get the expected results. First we
1036         // drop all extraneous results to we're only dealing with those we want
1037         // to deal with. Afterwards we start at the bottom of the stack and move
1038         // up, figuring out what matches and what doesn't. As soon as something
1039         // doesn't match we throw out that and everything else remaining,
1040         // filling in results with dummy values.
1041         while operands.len() > label.results.len() {
1042             instructions.push(Instruction::Drop);
1043             operands = &operands[..operands.len() - 1];
1044         }
1045         for (i, expected) in label.results.iter().enumerate() {
1046             if let Some(actual) = operands.get(i) {
1047                 if Some(*expected) == *actual {
1048                     continue;
1049                 }
1050                 for _ in operands[i..].iter() {
1051                     instructions.push(Instruction::Drop);
1052                 }
1053                 operands = &[];
1054             }
1055             instructions.push(arbitrary_val(*expected, u));
1056         }
1057     }
1058 }
1059 
arbitrary_val(ty: ValType, u: &mut Unstructured<'_>) -> Instruction1060 fn arbitrary_val(ty: ValType, u: &mut Unstructured<'_>) -> Instruction {
1061     match ty {
1062         ValType::I32 => Instruction::I32Const(u.arbitrary().unwrap_or(0)),
1063         ValType::I64 => Instruction::I64Const(u.arbitrary().unwrap_or(0)),
1064         ValType::F32 => Instruction::F32Const(u.arbitrary().unwrap_or(0.0)),
1065         ValType::F64 => Instruction::F64Const(u.arbitrary().unwrap_or(0.0)),
1066         ValType::V128 => Instruction::V128Const(u.arbitrary().unwrap_or(0)),
1067         ValType::ExternRef => Instruction::RefNull(ValType::ExternRef),
1068         ValType::FuncRef => Instruction::RefNull(ValType::FuncRef),
1069     }
1070 }
1071 
unreachable(_: &mut Unstructured, _: &Module, _: &mut CodeBuilder) -> Result<Instruction>1072 fn unreachable(_: &mut Unstructured, _: &Module, _: &mut CodeBuilder) -> Result<Instruction> {
1073     Ok(Instruction::Unreachable)
1074 }
1075 
nop(_: &mut Unstructured, _: &Module, _: &mut CodeBuilder) -> Result<Instruction>1076 fn nop(_: &mut Unstructured, _: &Module, _: &mut CodeBuilder) -> Result<Instruction> {
1077     Ok(Instruction::Nop)
1078 }
1079 
block(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1080 fn block(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1081     let block_ty = builder.arbitrary_block_type(u, module)?;
1082     let (params, results) = block_ty.params_results(module);
1083     let height = builder.allocs.operands.len() - params.len();
1084     builder.allocs.controls.push(Control {
1085         kind: ControlKind::Block,
1086         params,
1087         results,
1088         height,
1089     });
1090     Ok(Instruction::Block(block_ty))
1091 }
1092 
1093 #[inline]
try_valid(module: &Module, _: &mut CodeBuilder) -> bool1094 fn try_valid(module: &Module, _: &mut CodeBuilder) -> bool {
1095     module.config.exceptions_enabled()
1096 }
1097 
1098 fn r#try(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1099     let block_ty = builder.arbitrary_block_type(u, module)?;
1100     let (params, results) = block_ty.params_results(module);
1101     let height = builder.allocs.operands.len() - params.len();
1102     builder.allocs.controls.push(Control {
1103         kind: ControlKind::Try,
1104         params,
1105         results,
1106         height,
1107     });
1108     Ok(Instruction::Try(block_ty))
1109 }
1110 
1111 #[inline]
delegate_valid(module: &Module, builder: &mut CodeBuilder) -> bool1112 fn delegate_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1113     let control_kind = builder.allocs.controls.last().unwrap().kind;
1114     // delegate is only valid if end could be used in a try control frame
1115     module.config.exceptions_enabled()
1116         && control_kind == ControlKind::Try
1117         && end_valid(module, builder)
1118 }
1119 
delegate(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1120 fn delegate(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1121     // There will always be at least the function's return frame and try
1122     // control frame if we are emitting delegate
1123     let n = builder.allocs.controls.iter().count();
1124     debug_assert!(n >= 2);
1125     // Delegate must target an outer control from the try block, and is
1126     // encoded with relative depth from the outer control
1127     let target_relative_from_last = u.int_in_range(1..=n - 1)?;
1128     let target_relative_from_outer = target_relative_from_last - 1;
1129     // Delegate ends the try block
1130     builder.allocs.controls.pop();
1131     Ok(Instruction::Delegate(target_relative_from_outer as u32))
1132 }
1133 
1134 #[inline]
catch_valid(module: &Module, builder: &mut CodeBuilder) -> bool1135 fn catch_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1136     let control_kind = builder.allocs.controls.last().unwrap().kind;
1137     // catch is only valid if end could be used in a try or catch (not
1138     // catch_all) control frame. There must also be a tag that we can catch.
1139     module.config.exceptions_enabled()
1140         && (control_kind == ControlKind::Try || control_kind == ControlKind::Catch)
1141         && end_valid(module, builder)
1142         && module.tags.len() > 0
1143 }
1144 
catch(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1145 fn catch(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1146     let tag_idx = u.int_in_range(0..=(module.tags.len() - 1))?;
1147     let tag_type = &module.tags[tag_idx];
1148     let control = builder.allocs.controls.pop().unwrap();
1149     // Pop the results for the previous try or catch
1150     builder.pop_operands(&control.results);
1151     // Push the params of the tag we're catching
1152     builder.push_operands(&tag_type.func_type.params);
1153     builder.allocs.controls.push(Control {
1154         kind: ControlKind::Catch,
1155         ..control
1156     });
1157     Ok(Instruction::Catch(tag_idx as u32))
1158 }
1159 
1160 #[inline]
catch_all_valid(module: &Module, builder: &mut CodeBuilder) -> bool1161 fn catch_all_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1162     let control_kind = builder.allocs.controls.last().unwrap().kind;
1163     // catch_all is only valid if end could be used in a try or catch (not
1164     // catch_all) control frame.
1165     module.config.exceptions_enabled()
1166         && (control_kind == ControlKind::Try || control_kind == ControlKind::Catch)
1167         && end_valid(module, builder)
1168 }
1169 
catch_all(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1170 fn catch_all(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1171     let control = builder.allocs.controls.pop().unwrap();
1172     // Pop the results for the previous try or catch
1173     builder.pop_operands(&control.results);
1174     builder.allocs.controls.push(Control {
1175         kind: ControlKind::CatchAll,
1176         ..control
1177     });
1178     Ok(Instruction::CatchAll)
1179 }
1180 
1181 fn r#loop(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1182     let block_ty = builder.arbitrary_block_type(u, module)?;
1183     let (params, results) = block_ty.params_results(module);
1184     let height = builder.allocs.operands.len() - params.len();
1185     builder.allocs.controls.push(Control {
1186         kind: ControlKind::Loop,
1187         params,
1188         results,
1189         height,
1190     });
1191     Ok(Instruction::Loop(block_ty))
1192 }
1193 
1194 #[inline]
if_valid(_: &Module, builder: &mut CodeBuilder) -> bool1195 fn if_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1196     builder.type_on_stack(ValType::I32)
1197 }
1198 
1199 fn r#if(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1200     builder.pop_operands(&[ValType::I32]);
1201 
1202     let block_ty = builder.arbitrary_block_type(u, module)?;
1203     let (params, results) = block_ty.params_results(module);
1204     let height = builder.allocs.operands.len() - params.len();
1205     builder.allocs.controls.push(Control {
1206         kind: ControlKind::If,
1207         params,
1208         results,
1209         height,
1210     });
1211     Ok(Instruction::If(block_ty))
1212 }
1213 
1214 #[inline]
else_valid(_: &Module, builder: &mut CodeBuilder) -> bool1215 fn else_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1216     let last_control = builder.allocs.controls.last().unwrap();
1217     last_control.kind == ControlKind::If
1218         && builder.operands().len() == last_control.results.len()
1219         && builder.types_on_stack(&last_control.results)
1220 }
1221 
1222 fn r#else(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1223     let control = builder.allocs.controls.pop().unwrap();
1224     builder.pop_operands(&control.results);
1225     builder.push_operands(&control.params);
1226     builder.allocs.controls.push(Control {
1227         kind: ControlKind::Block,
1228         ..control
1229     });
1230     Ok(Instruction::Else)
1231 }
1232 
1233 #[inline]
end_valid(_: &Module, builder: &mut CodeBuilder) -> bool1234 fn end_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1235     // Note: first control frame is the function return's control frame, which
1236     // does not have an associated `end`.
1237     if builder.allocs.controls.len() <= 1 {
1238         return false;
1239     }
1240     let control = builder.allocs.controls.last().unwrap();
1241     builder.operands().len() == control.results.len()
1242         && builder.types_on_stack(&control.results)
1243         // `if`s that don't leave the stack as they found it must have an
1244         // `else`.
1245         && !(control.kind == ControlKind::If && control.params != control.results)
1246 }
1247 
end(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1248 fn end(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1249     builder.allocs.controls.pop();
1250     Ok(Instruction::End)
1251 }
1252 
1253 #[inline]
br_valid(_: &Module, builder: &mut CodeBuilder) -> bool1254 fn br_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1255     builder
1256         .allocs
1257         .controls
1258         .iter()
1259         .any(|l| builder.label_types_on_stack(l))
1260 }
1261 
br(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1262 fn br(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1263     let n = builder
1264         .allocs
1265         .controls
1266         .iter()
1267         .filter(|l| builder.label_types_on_stack(l))
1268         .count();
1269     debug_assert!(n > 0);
1270     let i = u.int_in_range(0..=n - 1)?;
1271     let (target, _) = builder
1272         .allocs
1273         .controls
1274         .iter()
1275         .rev()
1276         .enumerate()
1277         .filter(|(_, l)| builder.label_types_on_stack(l))
1278         .nth(i)
1279         .unwrap();
1280     let control = &builder.allocs.controls[builder.allocs.controls.len() - 1 - target];
1281     let tys = control.label_types().to_vec();
1282     builder.pop_operands(&tys);
1283     Ok(Instruction::Br(target as u32))
1284 }
1285 
1286 #[inline]
br_if_valid(_: &Module, builder: &mut CodeBuilder) -> bool1287 fn br_if_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1288     if !builder.type_on_stack(ValType::I32) {
1289         return false;
1290     }
1291     let ty = builder.allocs.operands.pop().unwrap();
1292     let is_valid = builder
1293         .allocs
1294         .controls
1295         .iter()
1296         .any(|l| builder.label_types_on_stack(l));
1297     builder.allocs.operands.push(ty);
1298     is_valid
1299 }
1300 
br_if(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1301 fn br_if(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1302     builder.pop_operands(&[ValType::I32]);
1303 
1304     let n = builder
1305         .allocs
1306         .controls
1307         .iter()
1308         .filter(|l| builder.label_types_on_stack(l))
1309         .count();
1310     debug_assert!(n > 0);
1311     let i = u.int_in_range(0..=n - 1)?;
1312     let (target, _) = builder
1313         .allocs
1314         .controls
1315         .iter()
1316         .rev()
1317         .enumerate()
1318         .filter(|(_, l)| builder.label_types_on_stack(l))
1319         .nth(i)
1320         .unwrap();
1321     Ok(Instruction::BrIf(target as u32))
1322 }
1323 
1324 #[inline]
br_table_valid(module: &Module, builder: &mut CodeBuilder) -> bool1325 fn br_table_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1326     if !builder.type_on_stack(ValType::I32) {
1327         return false;
1328     }
1329     let ty = builder.allocs.operands.pop().unwrap();
1330     let is_valid = br_valid(module, builder);
1331     builder.allocs.operands.push(ty);
1332     is_valid
1333 }
1334 
br_table(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1335 fn br_table(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1336     builder.pop_operands(&[ValType::I32]);
1337 
1338     let n = builder
1339         .allocs
1340         .controls
1341         .iter()
1342         .filter(|l| builder.label_types_on_stack(l))
1343         .count();
1344     debug_assert!(n > 0);
1345 
1346     let i = u.int_in_range(0..=n - 1)?;
1347     let (default_target, _) = builder
1348         .allocs
1349         .controls
1350         .iter()
1351         .rev()
1352         .enumerate()
1353         .filter(|(_, l)| builder.label_types_on_stack(l))
1354         .nth(i)
1355         .unwrap();
1356     let control = &builder.allocs.controls[builder.allocs.controls.len() - 1 - default_target];
1357 
1358     let targets = builder
1359         .allocs
1360         .controls
1361         .iter()
1362         .rev()
1363         .enumerate()
1364         .filter(|(_, l)| l.label_types() == control.label_types())
1365         .map(|(t, _)| t as u32)
1366         .collect();
1367 
1368     let tys = control.label_types().to_vec();
1369     builder.pop_operands(&tys);
1370 
1371     Ok(Instruction::BrTable(targets, default_target as u32))
1372 }
1373 
1374 #[inline]
return_valid(_: &Module, builder: &mut CodeBuilder) -> bool1375 fn return_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1376     builder.label_types_on_stack(&builder.allocs.controls[0])
1377 }
1378 
1379 fn r#return(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1380     let results = builder.allocs.controls[0].results.clone();
1381     builder.pop_operands(&results);
1382     Ok(Instruction::Return)
1383 }
1384 
1385 #[inline]
call_valid(_: &Module, builder: &mut CodeBuilder) -> bool1386 fn call_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1387     builder
1388         .allocs
1389         .functions
1390         .keys()
1391         .any(|k| builder.types_on_stack(k))
1392 }
1393 
call(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1394 fn call(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1395     let candidates = builder
1396         .allocs
1397         .functions
1398         .iter()
1399         .filter(|(k, _)| builder.types_on_stack(k))
1400         .flat_map(|(_, v)| v.iter().copied())
1401         .collect::<Vec<_>>();
1402     assert!(candidates.len() > 0);
1403     let i = u.int_in_range(0..=candidates.len() - 1)?;
1404     let (func_idx, ty) = module.funcs().nth(candidates[i] as usize).unwrap();
1405     builder.pop_operands(&ty.params);
1406     builder.push_operands(&ty.results);
1407     Ok(Instruction::Call(func_idx as u32))
1408 }
1409 
1410 #[inline]
call_indirect_valid(module: &Module, builder: &mut CodeBuilder) -> bool1411 fn call_indirect_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1412     if builder.allocs.funcref_tables.is_empty() || !builder.type_on_stack(ValType::I32) {
1413         return false;
1414     }
1415     let ty = builder.allocs.operands.pop().unwrap();
1416     let is_valid = module
1417         .func_types()
1418         .any(|(_, ty)| builder.types_on_stack(&ty.params));
1419     builder.allocs.operands.push(ty);
1420     is_valid
1421 }
1422 
call_indirect( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1423 fn call_indirect(
1424     u: &mut Unstructured,
1425     module: &Module,
1426     builder: &mut CodeBuilder,
1427 ) -> Result<Instruction> {
1428     builder.pop_operands(&[ValType::I32]);
1429 
1430     let choices = module
1431         .func_types()
1432         .filter(|(_, ty)| builder.types_on_stack(&ty.params))
1433         .collect::<Vec<_>>();
1434     let (type_idx, ty) = u.choose(&choices)?;
1435     builder.pop_operands(&ty.params);
1436     builder.push_operands(&ty.results);
1437     let table = *u.choose(&builder.allocs.funcref_tables)?;
1438     Ok(Instruction::CallIndirect {
1439         ty: *type_idx as u32,
1440         table,
1441     })
1442 }
1443 
1444 #[inline]
throw_valid(module: &Module, builder: &mut CodeBuilder) -> bool1445 fn throw_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1446     module.config.exceptions_enabled()
1447         && builder
1448             .allocs
1449             .tags
1450             .keys()
1451             .any(|k| builder.types_on_stack(k))
1452 }
1453 
throw(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1454 fn throw(u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1455     let candidates = builder
1456         .allocs
1457         .tags
1458         .iter()
1459         .filter(|(k, _)| builder.types_on_stack(k))
1460         .flat_map(|(_, v)| v.iter().copied())
1461         .collect::<Vec<_>>();
1462     assert!(candidates.len() > 0);
1463     let i = u.int_in_range(0..=candidates.len() - 1)?;
1464     let (tag_idx, tag_type) = module.tags().nth(candidates[i] as usize).unwrap();
1465     // Tags have no results, throwing cannot return
1466     assert!(tag_type.func_type.results.len() == 0);
1467     builder.pop_operands(&tag_type.func_type.params);
1468     Ok(Instruction::Throw(tag_idx as u32))
1469 }
1470 
1471 #[inline]
rethrow_valid(module: &Module, builder: &mut CodeBuilder) -> bool1472 fn rethrow_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1473     // There must be a catch or catch_all control on the stack
1474     module.config.exceptions_enabled()
1475         && builder
1476             .allocs
1477             .controls
1478             .iter()
1479             .any(|l| l.kind == ControlKind::Catch || l.kind == ControlKind::CatchAll)
1480 }
1481 
rethrow(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1482 fn rethrow(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1483     let n = builder
1484         .allocs
1485         .controls
1486         .iter()
1487         .filter(|l| l.kind == ControlKind::Catch || l.kind == ControlKind::CatchAll)
1488         .count();
1489     debug_assert!(n > 0);
1490     let i = u.int_in_range(0..=n - 1)?;
1491     let (target, _) = builder
1492         .allocs
1493         .controls
1494         .iter()
1495         .rev()
1496         .enumerate()
1497         .filter(|(_, l)| l.kind == ControlKind::Catch || l.kind == ControlKind::CatchAll)
1498         .nth(i)
1499         .unwrap();
1500     Ok(Instruction::Rethrow(target as u32))
1501 }
1502 
1503 #[inline]
drop_valid(_: &Module, builder: &mut CodeBuilder) -> bool1504 fn drop_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1505     !builder.operands().is_empty()
1506 }
1507 
drop(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1508 fn drop(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1509     builder.allocs.operands.pop();
1510     Ok(Instruction::Drop)
1511 }
1512 
1513 #[inline]
select_valid(_: &Module, builder: &mut CodeBuilder) -> bool1514 fn select_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1515     if !(builder.operands().len() >= 3 && builder.type_on_stack(ValType::I32)) {
1516         return false;
1517     }
1518     let t = builder.operands()[builder.operands().len() - 2];
1519     let u = builder.operands()[builder.operands().len() - 3];
1520     t.is_none() || u.is_none() || t == u
1521 }
1522 
select(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1523 fn select(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1524     builder.allocs.operands.pop();
1525     let t = builder.allocs.operands.pop().unwrap();
1526     let u = builder.allocs.operands.pop().unwrap();
1527     let ty = t.or(u);
1528     builder.allocs.operands.push(ty);
1529     match ty {
1530         Some(ty @ ValType::ExternRef) | Some(ty @ ValType::FuncRef) => {
1531             Ok(Instruction::TypedSelect(ty))
1532         }
1533         Some(ValType::I32) | Some(ValType::I64) | Some(ValType::F32) | Some(ValType::F64)
1534         | Some(ValType::V128) | None => Ok(Instruction::Select),
1535     }
1536 }
1537 
1538 #[inline]
local_get_valid(_: &Module, builder: &mut CodeBuilder) -> bool1539 fn local_get_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1540     !builder.func_ty.params.is_empty() || !builder.locals.is_empty()
1541 }
1542 
local_get(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1543 fn local_get(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1544     let num_params = builder.func_ty.params.len();
1545     let n = num_params + builder.locals.len();
1546     debug_assert!(n > 0);
1547     let i = u.int_in_range(0..=n - 1)?;
1548     builder.allocs.operands.push(Some(if i < num_params {
1549         builder.func_ty.params[i]
1550     } else {
1551         builder.locals[i - num_params]
1552     }));
1553     Ok(Instruction::LocalGet(i as u32))
1554 }
1555 
1556 #[inline]
local_set_valid(_: &Module, builder: &mut CodeBuilder) -> bool1557 fn local_set_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1558     builder
1559         .func_ty
1560         .params
1561         .iter()
1562         .chain(builder.locals.iter())
1563         .any(|ty| builder.type_on_stack(*ty))
1564 }
1565 
local_set(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1566 fn local_set(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1567     let n = builder
1568         .func_ty
1569         .params
1570         .iter()
1571         .chain(builder.locals.iter())
1572         .filter(|ty| builder.type_on_stack(**ty))
1573         .count();
1574     debug_assert!(n > 0);
1575     let i = u.int_in_range(0..=n - 1)?;
1576     let (j, _) = builder
1577         .func_ty
1578         .params
1579         .iter()
1580         .chain(builder.locals.iter())
1581         .enumerate()
1582         .filter(|(_, ty)| builder.type_on_stack(**ty))
1583         .nth(i)
1584         .unwrap();
1585     builder.allocs.operands.pop();
1586     Ok(Instruction::LocalSet(j as u32))
1587 }
1588 
local_tee(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1589 fn local_tee(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1590     let n = builder
1591         .func_ty
1592         .params
1593         .iter()
1594         .chain(builder.locals.iter())
1595         .filter(|ty| builder.type_on_stack(**ty))
1596         .count();
1597     debug_assert!(n > 0);
1598     let i = u.int_in_range(0..=n - 1)?;
1599     let (j, _) = builder
1600         .func_ty
1601         .params
1602         .iter()
1603         .chain(builder.locals.iter())
1604         .enumerate()
1605         .filter(|(_, ty)| builder.type_on_stack(**ty))
1606         .nth(i)
1607         .unwrap();
1608     Ok(Instruction::LocalTee(j as u32))
1609 }
1610 
1611 #[inline]
global_get_valid(module: &Module, _: &mut CodeBuilder) -> bool1612 fn global_get_valid(module: &Module, _: &mut CodeBuilder) -> bool {
1613     module.globals.len() > 0
1614 }
1615 
global_get( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1616 fn global_get(
1617     u: &mut Unstructured,
1618     module: &Module,
1619     builder: &mut CodeBuilder,
1620 ) -> Result<Instruction> {
1621     debug_assert!(module.globals.len() > 0);
1622     let global_idx = u.int_in_range(0..=module.globals.len() - 1)?;
1623     builder
1624         .allocs
1625         .operands
1626         .push(Some(module.globals[global_idx].val_type));
1627     Ok(Instruction::GlobalGet(global_idx as u32))
1628 }
1629 
1630 #[inline]
global_set_valid(_: &Module, builder: &mut CodeBuilder) -> bool1631 fn global_set_valid(_: &Module, builder: &mut CodeBuilder) -> bool {
1632     builder
1633         .allocs
1634         .mutable_globals
1635         .iter()
1636         .any(|(ty, _)| builder.type_on_stack(*ty))
1637 }
1638 
global_set(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>1639 fn global_set(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
1640     let candidates = builder
1641         .allocs
1642         .mutable_globals
1643         .iter()
1644         .find(|(ty, _)| builder.type_on_stack(**ty))
1645         .unwrap()
1646         .1;
1647     let i = u.int_in_range(0..=candidates.len() - 1)?;
1648     builder.allocs.operands.pop();
1649     Ok(Instruction::GlobalSet(candidates[i]))
1650 }
1651 
1652 #[inline]
have_memory(module: &Module, _: &mut CodeBuilder) -> bool1653 fn have_memory(module: &Module, _: &mut CodeBuilder) -> bool {
1654     module.memories.len() > 0
1655 }
1656 
1657 #[inline]
have_memory_and_offset(_module: &Module, builder: &mut CodeBuilder) -> bool1658 fn have_memory_and_offset(_module: &Module, builder: &mut CodeBuilder) -> bool {
1659     (builder.allocs.memory32.len() > 0 && builder.type_on_stack(ValType::I32))
1660         || (builder.allocs.memory64.len() > 0 && builder.type_on_stack(ValType::I64))
1661 }
1662 
1663 #[inline]
have_data(module: &Module, _: &mut CodeBuilder) -> bool1664 fn have_data(module: &Module, _: &mut CodeBuilder) -> bool {
1665     module.data.len() > 0
1666 }
1667 
i32_load( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1668 fn i32_load(
1669     u: &mut Unstructured,
1670     module: &Module,
1671     builder: &mut CodeBuilder,
1672 ) -> Result<Instruction> {
1673     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1674     builder.allocs.operands.push(Some(ValType::I32));
1675     Ok(Instruction::I32Load(memarg))
1676 }
1677 
i64_load( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1678 fn i64_load(
1679     u: &mut Unstructured,
1680     module: &Module,
1681     builder: &mut CodeBuilder,
1682 ) -> Result<Instruction> {
1683     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1684     builder.allocs.operands.push(Some(ValType::I64));
1685     Ok(Instruction::I64Load(memarg))
1686 }
1687 
f32_load( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1688 fn f32_load(
1689     u: &mut Unstructured,
1690     module: &Module,
1691     builder: &mut CodeBuilder,
1692 ) -> Result<Instruction> {
1693     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1694     builder.allocs.operands.push(Some(ValType::F32));
1695     Ok(Instruction::F32Load(memarg))
1696 }
1697 
f64_load( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1698 fn f64_load(
1699     u: &mut Unstructured,
1700     module: &Module,
1701     builder: &mut CodeBuilder,
1702 ) -> Result<Instruction> {
1703     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1704     builder.allocs.operands.push(Some(ValType::F64));
1705     Ok(Instruction::F64Load(memarg))
1706 }
1707 
i32_load_8_s( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1708 fn i32_load_8_s(
1709     u: &mut Unstructured,
1710     module: &Module,
1711     builder: &mut CodeBuilder,
1712 ) -> Result<Instruction> {
1713     let memarg = mem_arg(u, module, builder, &[0])?;
1714     builder.allocs.operands.push(Some(ValType::I32));
1715     Ok(Instruction::I32Load8_S(memarg))
1716 }
1717 
i32_load_8_u( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1718 fn i32_load_8_u(
1719     u: &mut Unstructured,
1720     module: &Module,
1721     builder: &mut CodeBuilder,
1722 ) -> Result<Instruction> {
1723     let memarg = mem_arg(u, module, builder, &[0])?;
1724     builder.allocs.operands.push(Some(ValType::I32));
1725     Ok(Instruction::I32Load8_U(memarg))
1726 }
1727 
i32_load_16_s( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1728 fn i32_load_16_s(
1729     u: &mut Unstructured,
1730     module: &Module,
1731     builder: &mut CodeBuilder,
1732 ) -> Result<Instruction> {
1733     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1734     builder.allocs.operands.push(Some(ValType::I32));
1735     Ok(Instruction::I32Load16_S(memarg))
1736 }
1737 
i32_load_16_u( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1738 fn i32_load_16_u(
1739     u: &mut Unstructured,
1740     module: &Module,
1741     builder: &mut CodeBuilder,
1742 ) -> Result<Instruction> {
1743     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1744     builder.allocs.operands.push(Some(ValType::I32));
1745     Ok(Instruction::I32Load16_U(memarg))
1746 }
1747 
i64_load_8_s( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1748 fn i64_load_8_s(
1749     u: &mut Unstructured,
1750     module: &Module,
1751     builder: &mut CodeBuilder,
1752 ) -> Result<Instruction> {
1753     let memarg = mem_arg(u, module, builder, &[0])?;
1754     builder.allocs.operands.push(Some(ValType::I64));
1755     Ok(Instruction::I64Load8_S(memarg))
1756 }
1757 
i64_load_16_s( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1758 fn i64_load_16_s(
1759     u: &mut Unstructured,
1760     module: &Module,
1761     builder: &mut CodeBuilder,
1762 ) -> Result<Instruction> {
1763     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1764     builder.allocs.operands.push(Some(ValType::I64));
1765     Ok(Instruction::I64Load16_S(memarg))
1766 }
1767 
i64_load_32_s( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1768 fn i64_load_32_s(
1769     u: &mut Unstructured,
1770     module: &Module,
1771     builder: &mut CodeBuilder,
1772 ) -> Result<Instruction> {
1773     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1774     builder.allocs.operands.push(Some(ValType::I64));
1775     Ok(Instruction::I64Load32_S(memarg))
1776 }
1777 
i64_load_8_u( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1778 fn i64_load_8_u(
1779     u: &mut Unstructured,
1780     module: &Module,
1781     builder: &mut CodeBuilder,
1782 ) -> Result<Instruction> {
1783     let memarg = mem_arg(u, module, builder, &[0])?;
1784     builder.allocs.operands.push(Some(ValType::I64));
1785     Ok(Instruction::I64Load8_U(memarg))
1786 }
1787 
i64_load_16_u( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1788 fn i64_load_16_u(
1789     u: &mut Unstructured,
1790     module: &Module,
1791     builder: &mut CodeBuilder,
1792 ) -> Result<Instruction> {
1793     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1794     builder.allocs.operands.push(Some(ValType::I64));
1795     Ok(Instruction::I64Load16_U(memarg))
1796 }
1797 
i64_load_32_u( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1798 fn i64_load_32_u(
1799     u: &mut Unstructured,
1800     module: &Module,
1801     builder: &mut CodeBuilder,
1802 ) -> Result<Instruction> {
1803     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1804     builder.allocs.operands.push(Some(ValType::I64));
1805     Ok(Instruction::I64Load32_U(memarg))
1806 }
1807 
1808 #[inline]
store_valid(_module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool1809 fn store_valid(_module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool {
1810     (builder.allocs.memory32.len() > 0 && builder.types_on_stack(&[ValType::I32, f()]))
1811         || (builder.allocs.memory64.len() > 0 && builder.types_on_stack(&[ValType::I64, f()]))
1812 }
1813 
1814 #[inline]
i32_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool1815 fn i32_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1816     store_valid(module, builder, || ValType::I32)
1817 }
1818 
i32_store( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1819 fn i32_store(
1820     u: &mut Unstructured,
1821     module: &Module,
1822     builder: &mut CodeBuilder,
1823 ) -> Result<Instruction> {
1824     builder.pop_operands(&[ValType::I32]);
1825     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1826     Ok(Instruction::I32Store(memarg))
1827 }
1828 
1829 #[inline]
i64_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool1830 fn i64_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1831     store_valid(module, builder, || ValType::I64)
1832 }
1833 
i64_store( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1834 fn i64_store(
1835     u: &mut Unstructured,
1836     module: &Module,
1837     builder: &mut CodeBuilder,
1838 ) -> Result<Instruction> {
1839     builder.pop_operands(&[ValType::I64]);
1840     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1841     Ok(Instruction::I64Store(memarg))
1842 }
1843 
1844 #[inline]
f32_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool1845 fn f32_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1846     store_valid(module, builder, || ValType::F32)
1847 }
1848 
f32_store( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1849 fn f32_store(
1850     u: &mut Unstructured,
1851     module: &Module,
1852     builder: &mut CodeBuilder,
1853 ) -> Result<Instruction> {
1854     builder.pop_operands(&[ValType::F32]);
1855     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1856     Ok(Instruction::F32Store(memarg))
1857 }
1858 
1859 #[inline]
f64_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool1860 fn f64_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1861     store_valid(module, builder, || ValType::F64)
1862 }
1863 
f64_store( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1864 fn f64_store(
1865     u: &mut Unstructured,
1866     module: &Module,
1867     builder: &mut CodeBuilder,
1868 ) -> Result<Instruction> {
1869     builder.pop_operands(&[ValType::F64]);
1870     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1871     Ok(Instruction::F64Store(memarg))
1872 }
1873 
i32_store_8( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1874 fn i32_store_8(
1875     u: &mut Unstructured,
1876     module: &Module,
1877     builder: &mut CodeBuilder,
1878 ) -> Result<Instruction> {
1879     builder.pop_operands(&[ValType::I32]);
1880     let memarg = mem_arg(u, module, builder, &[0])?;
1881     Ok(Instruction::I32Store8(memarg))
1882 }
1883 
i32_store_16( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1884 fn i32_store_16(
1885     u: &mut Unstructured,
1886     module: &Module,
1887     builder: &mut CodeBuilder,
1888 ) -> Result<Instruction> {
1889     builder.pop_operands(&[ValType::I32]);
1890     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1891     Ok(Instruction::I32Store16(memarg))
1892 }
1893 
i64_store_8( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1894 fn i64_store_8(
1895     u: &mut Unstructured,
1896     module: &Module,
1897     builder: &mut CodeBuilder,
1898 ) -> Result<Instruction> {
1899     builder.pop_operands(&[ValType::I64]);
1900     let memarg = mem_arg(u, module, builder, &[0])?;
1901     Ok(Instruction::I64Store8(memarg))
1902 }
1903 
i64_store_16( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1904 fn i64_store_16(
1905     u: &mut Unstructured,
1906     module: &Module,
1907     builder: &mut CodeBuilder,
1908 ) -> Result<Instruction> {
1909     builder.pop_operands(&[ValType::I64]);
1910     let memarg = mem_arg(u, module, builder, &[0, 1])?;
1911     Ok(Instruction::I64Store16(memarg))
1912 }
1913 
i64_store_32( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1914 fn i64_store_32(
1915     u: &mut Unstructured,
1916     module: &Module,
1917     builder: &mut CodeBuilder,
1918 ) -> Result<Instruction> {
1919     builder.pop_operands(&[ValType::I64]);
1920     let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
1921     Ok(Instruction::I64Store32(memarg))
1922 }
1923 
memory_size( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1924 fn memory_size(
1925     u: &mut Unstructured,
1926     module: &Module,
1927     builder: &mut CodeBuilder,
1928 ) -> Result<Instruction> {
1929     let i = u.int_in_range(0..=module.memories.len() - 1)?;
1930     let ty = if module.memories[i].memory64 {
1931         ValType::I64
1932     } else {
1933         ValType::I32
1934     };
1935     builder.push_operands(&[ty]);
1936     Ok(Instruction::MemorySize(i as u32))
1937 }
1938 
1939 #[inline]
memory_grow_valid(_module: &Module, builder: &mut CodeBuilder) -> bool1940 fn memory_grow_valid(_module: &Module, builder: &mut CodeBuilder) -> bool {
1941     (builder.allocs.memory32.len() > 0 && builder.type_on_stack(ValType::I32))
1942         || (builder.allocs.memory64.len() > 0 && builder.type_on_stack(ValType::I64))
1943 }
1944 
memory_grow( u: &mut Unstructured, _module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1945 fn memory_grow(
1946     u: &mut Unstructured,
1947     _module: &Module,
1948     builder: &mut CodeBuilder,
1949 ) -> Result<Instruction> {
1950     let ty = if builder.type_on_stack(ValType::I32) {
1951         ValType::I32
1952     } else {
1953         ValType::I64
1954     };
1955     let index = memory_index(u, builder, ty)?;
1956     builder.pop_operands(&[ty]);
1957     builder.push_operands(&[ty]);
1958     Ok(Instruction::MemoryGrow(index))
1959 }
1960 
1961 #[inline]
memory_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool1962 fn memory_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1963     module.config.bulk_memory_enabled()
1964         && have_data(module, builder)
1965         && (builder.allocs.memory32.len() > 0
1966             && builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
1967             || (builder.allocs.memory64.len() > 0
1968                 && builder.types_on_stack(&[ValType::I64, ValType::I32, ValType::I32])))
1969 }
1970 
memory_init( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1971 fn memory_init(
1972     u: &mut Unstructured,
1973     module: &Module,
1974     builder: &mut CodeBuilder,
1975 ) -> Result<Instruction> {
1976     builder.pop_operands(&[ValType::I32, ValType::I32]);
1977     let ty = if builder.type_on_stack(ValType::I32) {
1978         ValType::I32
1979     } else {
1980         ValType::I64
1981     };
1982     let mem = memory_index(u, builder, ty)?;
1983     let data = data_index(u, module)?;
1984     builder.pop_operands(&[ty]);
1985     Ok(Instruction::MemoryInit { mem, data })
1986 }
1987 
1988 #[inline]
memory_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool1989 fn memory_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1990     module.config.bulk_memory_enabled()
1991         && (builder.allocs.memory32.len() > 0
1992             && builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
1993             || (builder.allocs.memory64.len() > 0
1994                 && builder.types_on_stack(&[ValType::I64, ValType::I32, ValType::I64])))
1995 }
1996 
memory_fill( u: &mut Unstructured, _module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>1997 fn memory_fill(
1998     u: &mut Unstructured,
1999     _module: &Module,
2000     builder: &mut CodeBuilder,
2001 ) -> Result<Instruction> {
2002     let ty = if builder.type_on_stack(ValType::I32) {
2003         ValType::I32
2004     } else {
2005         ValType::I64
2006     };
2007     let mem = memory_index(u, builder, ty)?;
2008     builder.pop_operands(&[ty, ValType::I32, ty]);
2009     Ok(Instruction::MemoryFill(mem))
2010 }
2011 
2012 #[inline]
memory_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool2013 fn memory_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2014     if !module.config.bulk_memory_enabled() {
2015         return false;
2016     }
2017 
2018     if builder.types_on_stack(&[ValType::I64, ValType::I64, ValType::I64])
2019         && builder.allocs.memory64.len() > 0
2020     {
2021         return true;
2022     }
2023     if builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
2024         && builder.allocs.memory32.len() > 0
2025     {
2026         return true;
2027     }
2028     if builder.types_on_stack(&[ValType::I64, ValType::I32, ValType::I32])
2029         && builder.allocs.memory32.len() > 0
2030         && builder.allocs.memory64.len() > 0
2031     {
2032         return true;
2033     }
2034     if builder.types_on_stack(&[ValType::I32, ValType::I64, ValType::I32])
2035         && builder.allocs.memory32.len() > 0
2036         && builder.allocs.memory64.len() > 0
2037     {
2038         return true;
2039     }
2040     false
2041 }
2042 
memory_copy( u: &mut Unstructured, _module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2043 fn memory_copy(
2044     u: &mut Unstructured,
2045     _module: &Module,
2046     builder: &mut CodeBuilder,
2047 ) -> Result<Instruction> {
2048     let (src, dst) = if builder.types_on_stack(&[ValType::I64, ValType::I64, ValType::I64]) {
2049         builder.pop_operands(&[ValType::I64, ValType::I64, ValType::I64]);
2050         (
2051             memory_index(u, builder, ValType::I64)?,
2052             memory_index(u, builder, ValType::I64)?,
2053         )
2054     } else if builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32]) {
2055         builder.pop_operands(&[ValType::I32, ValType::I32, ValType::I32]);
2056         (
2057             memory_index(u, builder, ValType::I32)?,
2058             memory_index(u, builder, ValType::I32)?,
2059         )
2060     } else if builder.types_on_stack(&[ValType::I64, ValType::I32, ValType::I32]) {
2061         builder.pop_operands(&[ValType::I64, ValType::I32, ValType::I32]);
2062         (
2063             memory_index(u, builder, ValType::I32)?,
2064             memory_index(u, builder, ValType::I64)?,
2065         )
2066     } else if builder.types_on_stack(&[ValType::I32, ValType::I64, ValType::I32]) {
2067         builder.pop_operands(&[ValType::I32, ValType::I64, ValType::I32]);
2068         (
2069             memory_index(u, builder, ValType::I64)?,
2070             memory_index(u, builder, ValType::I32)?,
2071         )
2072     } else {
2073         unreachable!()
2074     };
2075     Ok(Instruction::MemoryCopy { dst, src })
2076 }
2077 
2078 #[inline]
data_drop_valid(module: &Module, builder: &mut CodeBuilder) -> bool2079 fn data_drop_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2080     have_data(module, builder) && module.config.bulk_memory_enabled()
2081 }
2082 
data_drop( u: &mut Unstructured, module: &Module, _builder: &mut CodeBuilder, ) -> Result<Instruction>2083 fn data_drop(
2084     u: &mut Unstructured,
2085     module: &Module,
2086     _builder: &mut CodeBuilder,
2087 ) -> Result<Instruction> {
2088     Ok(Instruction::DataDrop(data_index(u, module)?))
2089 }
2090 
i32_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2091 fn i32_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2092     let x = u.arbitrary()?;
2093     builder.push_operands(&[ValType::I32]);
2094     Ok(Instruction::I32Const(x))
2095 }
2096 
i64_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2097 fn i64_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2098     let x = u.arbitrary()?;
2099     builder.push_operands(&[ValType::I64]);
2100     Ok(Instruction::I64Const(x))
2101 }
2102 
f32_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2103 fn f32_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2104     let x = u.arbitrary()?;
2105     builder.push_operands(&[ValType::F32]);
2106     Ok(Instruction::F32Const(x))
2107 }
2108 
f64_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2109 fn f64_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2110     let x = u.arbitrary()?;
2111     builder.push_operands(&[ValType::F64]);
2112     Ok(Instruction::F64Const(x))
2113 }
2114 
2115 #[inline]
i32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2116 fn i32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2117     builder.type_on_stack(ValType::I32)
2118 }
2119 
i32_eqz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2120 fn i32_eqz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2121     builder.pop_operands(&[ValType::I32]);
2122     builder.push_operands(&[ValType::I32]);
2123     Ok(Instruction::I32Eqz)
2124 }
2125 
2126 #[inline]
i32_i32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2127 fn i32_i32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2128     builder.types_on_stack(&[ValType::I32, ValType::I32])
2129 }
2130 
i32_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2131 fn i32_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2132     builder.pop_operands(&[ValType::I32, ValType::I32]);
2133     builder.push_operands(&[ValType::I32]);
2134     Ok(Instruction::I32Eq)
2135 }
2136 
i32_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2137 fn i32_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2138     builder.pop_operands(&[ValType::I32, ValType::I32]);
2139     builder.push_operands(&[ValType::I32]);
2140     Ok(Instruction::I32Neq)
2141 }
2142 
i32_lt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2143 fn i32_lt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2144     builder.pop_operands(&[ValType::I32, ValType::I32]);
2145     builder.push_operands(&[ValType::I32]);
2146     Ok(Instruction::I32LtS)
2147 }
2148 
i32_lt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2149 fn i32_lt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2150     builder.pop_operands(&[ValType::I32, ValType::I32]);
2151     builder.push_operands(&[ValType::I32]);
2152     Ok(Instruction::I32LtU)
2153 }
2154 
i32_gt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2155 fn i32_gt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2156     builder.pop_operands(&[ValType::I32, ValType::I32]);
2157     builder.push_operands(&[ValType::I32]);
2158     Ok(Instruction::I32GtS)
2159 }
2160 
i32_gt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2161 fn i32_gt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2162     builder.pop_operands(&[ValType::I32, ValType::I32]);
2163     builder.push_operands(&[ValType::I32]);
2164     Ok(Instruction::I32GtU)
2165 }
2166 
i32_le_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2167 fn i32_le_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2168     builder.pop_operands(&[ValType::I32, ValType::I32]);
2169     builder.push_operands(&[ValType::I32]);
2170     Ok(Instruction::I32LeS)
2171 }
2172 
i32_le_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2173 fn i32_le_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2174     builder.pop_operands(&[ValType::I32, ValType::I32]);
2175     builder.push_operands(&[ValType::I32]);
2176     Ok(Instruction::I32LeU)
2177 }
2178 
i32_ge_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2179 fn i32_ge_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2180     builder.pop_operands(&[ValType::I32, ValType::I32]);
2181     builder.push_operands(&[ValType::I32]);
2182     Ok(Instruction::I32GeS)
2183 }
2184 
i32_ge_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2185 fn i32_ge_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2186     builder.pop_operands(&[ValType::I32, ValType::I32]);
2187     builder.push_operands(&[ValType::I32]);
2188     Ok(Instruction::I32GeU)
2189 }
2190 
2191 #[inline]
i64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2192 fn i64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2193     builder.types_on_stack(&[ValType::I64])
2194 }
2195 
i64_eqz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2196 fn i64_eqz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2197     builder.pop_operands(&[ValType::I64]);
2198     builder.push_operands(&[ValType::I32]);
2199     Ok(Instruction::I64Eqz)
2200 }
2201 
2202 #[inline]
i64_i64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2203 fn i64_i64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2204     builder.types_on_stack(&[ValType::I64, ValType::I64])
2205 }
2206 
i64_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2207 fn i64_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2208     builder.pop_operands(&[ValType::I64, ValType::I64]);
2209     builder.push_operands(&[ValType::I32]);
2210     Ok(Instruction::I64Eq)
2211 }
2212 
i64_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2213 fn i64_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2214     builder.pop_operands(&[ValType::I64, ValType::I64]);
2215     builder.push_operands(&[ValType::I32]);
2216     Ok(Instruction::I64Neq)
2217 }
2218 
i64_lt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2219 fn i64_lt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2220     builder.pop_operands(&[ValType::I64, ValType::I64]);
2221     builder.push_operands(&[ValType::I32]);
2222     Ok(Instruction::I64LtS)
2223 }
2224 
i64_lt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2225 fn i64_lt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2226     builder.pop_operands(&[ValType::I64, ValType::I64]);
2227     builder.push_operands(&[ValType::I32]);
2228     Ok(Instruction::I64LtU)
2229 }
2230 
i64_gt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2231 fn i64_gt_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2232     builder.pop_operands(&[ValType::I64, ValType::I64]);
2233     builder.push_operands(&[ValType::I32]);
2234     Ok(Instruction::I64GtS)
2235 }
2236 
i64_gt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2237 fn i64_gt_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2238     builder.pop_operands(&[ValType::I64, ValType::I64]);
2239     builder.push_operands(&[ValType::I32]);
2240     Ok(Instruction::I64GtU)
2241 }
2242 
i64_le_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2243 fn i64_le_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2244     builder.pop_operands(&[ValType::I64, ValType::I64]);
2245     builder.push_operands(&[ValType::I32]);
2246     Ok(Instruction::I64LeS)
2247 }
2248 
i64_le_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2249 fn i64_le_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2250     builder.pop_operands(&[ValType::I64, ValType::I64]);
2251     builder.push_operands(&[ValType::I32]);
2252     Ok(Instruction::I64LeU)
2253 }
2254 
i64_ge_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2255 fn i64_ge_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2256     builder.pop_operands(&[ValType::I64, ValType::I64]);
2257     builder.push_operands(&[ValType::I32]);
2258     Ok(Instruction::I64GeS)
2259 }
2260 
i64_ge_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2261 fn i64_ge_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2262     builder.pop_operands(&[ValType::I64, ValType::I64]);
2263     builder.push_operands(&[ValType::I32]);
2264     Ok(Instruction::I64GeU)
2265 }
2266 
f32_f32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2267 fn f32_f32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2268     builder.types_on_stack(&[ValType::F32, ValType::F32])
2269 }
2270 
f32_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2271 fn f32_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2272     builder.pop_operands(&[ValType::F32, ValType::F32]);
2273     builder.push_operands(&[ValType::I32]);
2274     Ok(Instruction::F32Eq)
2275 }
2276 
f32_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2277 fn f32_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2278     builder.pop_operands(&[ValType::F32, ValType::F32]);
2279     builder.push_operands(&[ValType::I32]);
2280     Ok(Instruction::F32Neq)
2281 }
2282 
f32_lt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2283 fn f32_lt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2284     builder.pop_operands(&[ValType::F32, ValType::F32]);
2285     builder.push_operands(&[ValType::I32]);
2286     Ok(Instruction::F32Lt)
2287 }
2288 
f32_gt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2289 fn f32_gt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2290     builder.pop_operands(&[ValType::F32, ValType::F32]);
2291     builder.push_operands(&[ValType::I32]);
2292     Ok(Instruction::F32Gt)
2293 }
2294 
f32_le(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2295 fn f32_le(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2296     builder.pop_operands(&[ValType::F32, ValType::F32]);
2297     builder.push_operands(&[ValType::I32]);
2298     Ok(Instruction::F32Le)
2299 }
2300 
f32_ge(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2301 fn f32_ge(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2302     builder.pop_operands(&[ValType::F32, ValType::F32]);
2303     builder.push_operands(&[ValType::I32]);
2304     Ok(Instruction::F32Ge)
2305 }
2306 
f64_f64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2307 fn f64_f64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2308     builder.types_on_stack(&[ValType::F64, ValType::F64])
2309 }
2310 
f64_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2311 fn f64_eq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2312     builder.pop_operands(&[ValType::F64, ValType::F64]);
2313     builder.push_operands(&[ValType::I32]);
2314     Ok(Instruction::F64Eq)
2315 }
2316 
f64_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2317 fn f64_neq(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2318     builder.pop_operands(&[ValType::F64, ValType::F64]);
2319     builder.push_operands(&[ValType::I32]);
2320     Ok(Instruction::F64Neq)
2321 }
2322 
f64_lt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2323 fn f64_lt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2324     builder.pop_operands(&[ValType::F64, ValType::F64]);
2325     builder.push_operands(&[ValType::I32]);
2326     Ok(Instruction::F64Lt)
2327 }
2328 
f64_gt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2329 fn f64_gt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2330     builder.pop_operands(&[ValType::F64, ValType::F64]);
2331     builder.push_operands(&[ValType::I32]);
2332     Ok(Instruction::F64Gt)
2333 }
2334 
f64_le(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2335 fn f64_le(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2336     builder.pop_operands(&[ValType::F64, ValType::F64]);
2337     builder.push_operands(&[ValType::I32]);
2338     Ok(Instruction::F64Le)
2339 }
2340 
f64_ge(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2341 fn f64_ge(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2342     builder.pop_operands(&[ValType::F64, ValType::F64]);
2343     builder.push_operands(&[ValType::I32]);
2344     Ok(Instruction::F64Ge)
2345 }
2346 
i32_clz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2347 fn i32_clz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2348     builder.pop_operands(&[ValType::I32]);
2349     builder.push_operands(&[ValType::I32]);
2350     Ok(Instruction::I32Clz)
2351 }
2352 
i32_ctz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2353 fn i32_ctz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2354     builder.pop_operands(&[ValType::I32]);
2355     builder.push_operands(&[ValType::I32]);
2356     Ok(Instruction::I32Ctz)
2357 }
2358 
i32_popcnt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2359 fn i32_popcnt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2360     builder.pop_operands(&[ValType::I32]);
2361     builder.push_operands(&[ValType::I32]);
2362     Ok(Instruction::I32Popcnt)
2363 }
2364 
i32_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2365 fn i32_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2366     builder.pop_operands(&[ValType::I32, ValType::I32]);
2367     builder.push_operands(&[ValType::I32]);
2368     Ok(Instruction::I32Add)
2369 }
2370 
i32_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2371 fn i32_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2372     builder.pop_operands(&[ValType::I32, ValType::I32]);
2373     builder.push_operands(&[ValType::I32]);
2374     Ok(Instruction::I32Sub)
2375 }
2376 
i32_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2377 fn i32_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2378     builder.pop_operands(&[ValType::I32, ValType::I32]);
2379     builder.push_operands(&[ValType::I32]);
2380     Ok(Instruction::I32Mul)
2381 }
2382 
i32_div_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2383 fn i32_div_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2384     builder.pop_operands(&[ValType::I32, ValType::I32]);
2385     builder.push_operands(&[ValType::I32]);
2386     Ok(Instruction::I32DivS)
2387 }
2388 
i32_div_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2389 fn i32_div_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2390     builder.pop_operands(&[ValType::I32, ValType::I32]);
2391     builder.push_operands(&[ValType::I32]);
2392     Ok(Instruction::I32DivU)
2393 }
2394 
i32_rem_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2395 fn i32_rem_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2396     builder.pop_operands(&[ValType::I32, ValType::I32]);
2397     builder.push_operands(&[ValType::I32]);
2398     Ok(Instruction::I32RemS)
2399 }
2400 
i32_rem_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2401 fn i32_rem_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2402     builder.pop_operands(&[ValType::I32, ValType::I32]);
2403     builder.push_operands(&[ValType::I32]);
2404     Ok(Instruction::I32RemU)
2405 }
2406 
i32_and(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2407 fn i32_and(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2408     builder.pop_operands(&[ValType::I32, ValType::I32]);
2409     builder.push_operands(&[ValType::I32]);
2410     Ok(Instruction::I32And)
2411 }
2412 
i32_or(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2413 fn i32_or(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2414     builder.pop_operands(&[ValType::I32, ValType::I32]);
2415     builder.push_operands(&[ValType::I32]);
2416     Ok(Instruction::I32Or)
2417 }
2418 
i32_xor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2419 fn i32_xor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2420     builder.pop_operands(&[ValType::I32, ValType::I32]);
2421     builder.push_operands(&[ValType::I32]);
2422     Ok(Instruction::I32Xor)
2423 }
2424 
i32_shl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2425 fn i32_shl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2426     builder.pop_operands(&[ValType::I32, ValType::I32]);
2427     builder.push_operands(&[ValType::I32]);
2428     Ok(Instruction::I32Shl)
2429 }
2430 
i32_shr_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2431 fn i32_shr_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2432     builder.pop_operands(&[ValType::I32, ValType::I32]);
2433     builder.push_operands(&[ValType::I32]);
2434     Ok(Instruction::I32ShrS)
2435 }
2436 
i32_shr_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2437 fn i32_shr_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2438     builder.pop_operands(&[ValType::I32, ValType::I32]);
2439     builder.push_operands(&[ValType::I32]);
2440     Ok(Instruction::I32ShrU)
2441 }
2442 
i32_rotl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2443 fn i32_rotl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2444     builder.pop_operands(&[ValType::I32, ValType::I32]);
2445     builder.push_operands(&[ValType::I32]);
2446     Ok(Instruction::I32Rotl)
2447 }
2448 
i32_rotr(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2449 fn i32_rotr(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2450     builder.pop_operands(&[ValType::I32, ValType::I32]);
2451     builder.push_operands(&[ValType::I32]);
2452     Ok(Instruction::I32Rotr)
2453 }
2454 
i64_clz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2455 fn i64_clz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2456     builder.pop_operands(&[ValType::I64]);
2457     builder.push_operands(&[ValType::I64]);
2458     Ok(Instruction::I64Clz)
2459 }
2460 
i64_ctz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2461 fn i64_ctz(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2462     builder.pop_operands(&[ValType::I64]);
2463     builder.push_operands(&[ValType::I64]);
2464     Ok(Instruction::I64Ctz)
2465 }
2466 
i64_popcnt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2467 fn i64_popcnt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2468     builder.pop_operands(&[ValType::I64]);
2469     builder.push_operands(&[ValType::I64]);
2470     Ok(Instruction::I64Popcnt)
2471 }
2472 
i64_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2473 fn i64_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2474     builder.pop_operands(&[ValType::I64, ValType::I64]);
2475     builder.push_operands(&[ValType::I64]);
2476     Ok(Instruction::I64Add)
2477 }
2478 
i64_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2479 fn i64_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2480     builder.pop_operands(&[ValType::I64, ValType::I64]);
2481     builder.push_operands(&[ValType::I64]);
2482     Ok(Instruction::I64Sub)
2483 }
2484 
i64_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2485 fn i64_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2486     builder.pop_operands(&[ValType::I64, ValType::I64]);
2487     builder.push_operands(&[ValType::I64]);
2488     Ok(Instruction::I64Mul)
2489 }
2490 
i64_div_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2491 fn i64_div_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2492     builder.pop_operands(&[ValType::I64, ValType::I64]);
2493     builder.push_operands(&[ValType::I64]);
2494     Ok(Instruction::I64DivS)
2495 }
2496 
i64_div_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2497 fn i64_div_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2498     builder.pop_operands(&[ValType::I64, ValType::I64]);
2499     builder.push_operands(&[ValType::I64]);
2500     Ok(Instruction::I64DivU)
2501 }
2502 
i64_rem_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2503 fn i64_rem_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2504     builder.pop_operands(&[ValType::I64, ValType::I64]);
2505     builder.push_operands(&[ValType::I64]);
2506     Ok(Instruction::I64RemS)
2507 }
2508 
i64_rem_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2509 fn i64_rem_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2510     builder.pop_operands(&[ValType::I64, ValType::I64]);
2511     builder.push_operands(&[ValType::I64]);
2512     Ok(Instruction::I64RemU)
2513 }
2514 
i64_and(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2515 fn i64_and(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2516     builder.pop_operands(&[ValType::I64, ValType::I64]);
2517     builder.push_operands(&[ValType::I64]);
2518     Ok(Instruction::I64And)
2519 }
2520 
i64_or(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2521 fn i64_or(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2522     builder.pop_operands(&[ValType::I64, ValType::I64]);
2523     builder.push_operands(&[ValType::I64]);
2524     Ok(Instruction::I64Or)
2525 }
2526 
i64_xor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2527 fn i64_xor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2528     builder.pop_operands(&[ValType::I64, ValType::I64]);
2529     builder.push_operands(&[ValType::I64]);
2530     Ok(Instruction::I64Xor)
2531 }
2532 
i64_shl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2533 fn i64_shl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2534     builder.pop_operands(&[ValType::I64, ValType::I64]);
2535     builder.push_operands(&[ValType::I64]);
2536     Ok(Instruction::I64Shl)
2537 }
2538 
i64_shr_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2539 fn i64_shr_s(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2540     builder.pop_operands(&[ValType::I64, ValType::I64]);
2541     builder.push_operands(&[ValType::I64]);
2542     Ok(Instruction::I64ShrS)
2543 }
2544 
i64_shr_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2545 fn i64_shr_u(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2546     builder.pop_operands(&[ValType::I64, ValType::I64]);
2547     builder.push_operands(&[ValType::I64]);
2548     Ok(Instruction::I64ShrU)
2549 }
2550 
i64_rotl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2551 fn i64_rotl(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2552     builder.pop_operands(&[ValType::I64, ValType::I64]);
2553     builder.push_operands(&[ValType::I64]);
2554     Ok(Instruction::I64Rotl)
2555 }
2556 
i64_rotr(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2557 fn i64_rotr(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2558     builder.pop_operands(&[ValType::I64, ValType::I64]);
2559     builder.push_operands(&[ValType::I64]);
2560     Ok(Instruction::I64Rotr)
2561 }
2562 
2563 #[inline]
f32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2564 fn f32_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2565     builder.types_on_stack(&[ValType::F32])
2566 }
2567 
f32_abs(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2568 fn f32_abs(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2569     builder.pop_operands(&[ValType::F32]);
2570     builder.push_operands(&[ValType::F32]);
2571     Ok(Instruction::F32Abs)
2572 }
2573 
f32_neg(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2574 fn f32_neg(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2575     builder.pop_operands(&[ValType::F32]);
2576     builder.push_operands(&[ValType::F32]);
2577     Ok(Instruction::F32Neg)
2578 }
2579 
f32_ceil(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2580 fn f32_ceil(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2581     builder.pop_operands(&[ValType::F32]);
2582     builder.push_operands(&[ValType::F32]);
2583     Ok(Instruction::F32Ceil)
2584 }
2585 
f32_floor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2586 fn f32_floor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2587     builder.pop_operands(&[ValType::F32]);
2588     builder.push_operands(&[ValType::F32]);
2589     Ok(Instruction::F32Floor)
2590 }
2591 
f32_trunc(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2592 fn f32_trunc(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2593     builder.pop_operands(&[ValType::F32]);
2594     builder.push_operands(&[ValType::F32]);
2595     Ok(Instruction::F32Trunc)
2596 }
2597 
f32_nearest(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2598 fn f32_nearest(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2599     builder.pop_operands(&[ValType::F32]);
2600     builder.push_operands(&[ValType::F32]);
2601     Ok(Instruction::F32Nearest)
2602 }
2603 
f32_sqrt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2604 fn f32_sqrt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2605     builder.pop_operands(&[ValType::F32]);
2606     builder.push_operands(&[ValType::F32]);
2607     Ok(Instruction::F32Sqrt)
2608 }
2609 
f32_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2610 fn f32_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2611     builder.pop_operands(&[ValType::F32, ValType::F32]);
2612     builder.push_operands(&[ValType::F32]);
2613     Ok(Instruction::F32Add)
2614 }
2615 
f32_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2616 fn f32_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2617     builder.pop_operands(&[ValType::F32, ValType::F32]);
2618     builder.push_operands(&[ValType::F32]);
2619     Ok(Instruction::F32Sub)
2620 }
2621 
f32_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2622 fn f32_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2623     builder.pop_operands(&[ValType::F32, ValType::F32]);
2624     builder.push_operands(&[ValType::F32]);
2625     Ok(Instruction::F32Mul)
2626 }
2627 
f32_div(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2628 fn f32_div(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2629     builder.pop_operands(&[ValType::F32, ValType::F32]);
2630     builder.push_operands(&[ValType::F32]);
2631     Ok(Instruction::F32Div)
2632 }
2633 
f32_min(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2634 fn f32_min(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2635     builder.pop_operands(&[ValType::F32, ValType::F32]);
2636     builder.push_operands(&[ValType::F32]);
2637     Ok(Instruction::F32Min)
2638 }
2639 
f32_max(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2640 fn f32_max(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2641     builder.pop_operands(&[ValType::F32, ValType::F32]);
2642     builder.push_operands(&[ValType::F32]);
2643     Ok(Instruction::F32Max)
2644 }
2645 
f32_copysign( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2646 fn f32_copysign(
2647     _: &mut Unstructured,
2648     _: &Module,
2649     builder: &mut CodeBuilder,
2650 ) -> Result<Instruction> {
2651     builder.pop_operands(&[ValType::F32, ValType::F32]);
2652     builder.push_operands(&[ValType::F32]);
2653     Ok(Instruction::F32Copysign)
2654 }
2655 
2656 #[inline]
f64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool2657 fn f64_on_stack(_: &Module, builder: &mut CodeBuilder) -> bool {
2658     builder.types_on_stack(&[ValType::F64])
2659 }
2660 
f64_abs(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2661 fn f64_abs(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2662     builder.pop_operands(&[ValType::F64]);
2663     builder.push_operands(&[ValType::F64]);
2664     Ok(Instruction::F64Abs)
2665 }
2666 
f64_neg(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2667 fn f64_neg(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2668     builder.pop_operands(&[ValType::F64]);
2669     builder.push_operands(&[ValType::F64]);
2670     Ok(Instruction::F64Neg)
2671 }
2672 
f64_ceil(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2673 fn f64_ceil(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2674     builder.pop_operands(&[ValType::F64]);
2675     builder.push_operands(&[ValType::F64]);
2676     Ok(Instruction::F64Ceil)
2677 }
2678 
f64_floor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2679 fn f64_floor(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2680     builder.pop_operands(&[ValType::F64]);
2681     builder.push_operands(&[ValType::F64]);
2682     Ok(Instruction::F64Floor)
2683 }
2684 
f64_trunc(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2685 fn f64_trunc(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2686     builder.pop_operands(&[ValType::F64]);
2687     builder.push_operands(&[ValType::F64]);
2688     Ok(Instruction::F64Trunc)
2689 }
2690 
f64_nearest(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2691 fn f64_nearest(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2692     builder.pop_operands(&[ValType::F64]);
2693     builder.push_operands(&[ValType::F64]);
2694     Ok(Instruction::F64Nearest)
2695 }
2696 
f64_sqrt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2697 fn f64_sqrt(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2698     builder.pop_operands(&[ValType::F64]);
2699     builder.push_operands(&[ValType::F64]);
2700     Ok(Instruction::F64Sqrt)
2701 }
2702 
f64_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2703 fn f64_add(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2704     builder.pop_operands(&[ValType::F64, ValType::F64]);
2705     builder.push_operands(&[ValType::F64]);
2706     Ok(Instruction::F64Add)
2707 }
2708 
f64_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2709 fn f64_sub(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2710     builder.pop_operands(&[ValType::F64, ValType::F64]);
2711     builder.push_operands(&[ValType::F64]);
2712     Ok(Instruction::F64Sub)
2713 }
2714 
f64_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2715 fn f64_mul(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2716     builder.pop_operands(&[ValType::F64, ValType::F64]);
2717     builder.push_operands(&[ValType::F64]);
2718     Ok(Instruction::F64Mul)
2719 }
2720 
f64_div(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2721 fn f64_div(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2722     builder.pop_operands(&[ValType::F64, ValType::F64]);
2723     builder.push_operands(&[ValType::F64]);
2724     Ok(Instruction::F64Div)
2725 }
2726 
f64_min(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2727 fn f64_min(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2728     builder.pop_operands(&[ValType::F64, ValType::F64]);
2729     builder.push_operands(&[ValType::F64]);
2730     Ok(Instruction::F64Min)
2731 }
2732 
f64_max(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>2733 fn f64_max(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
2734     builder.pop_operands(&[ValType::F64, ValType::F64]);
2735     builder.push_operands(&[ValType::F64]);
2736     Ok(Instruction::F64Max)
2737 }
2738 
f64_copysign( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2739 fn f64_copysign(
2740     _: &mut Unstructured,
2741     _: &Module,
2742     builder: &mut CodeBuilder,
2743 ) -> Result<Instruction> {
2744     builder.pop_operands(&[ValType::F64, ValType::F64]);
2745     builder.push_operands(&[ValType::F64]);
2746     Ok(Instruction::F64Copysign)
2747 }
2748 
i32_wrap_i64( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2749 fn i32_wrap_i64(
2750     _: &mut Unstructured,
2751     _: &Module,
2752     builder: &mut CodeBuilder,
2753 ) -> Result<Instruction> {
2754     builder.pop_operands(&[ValType::I64]);
2755     builder.push_operands(&[ValType::I32]);
2756     Ok(Instruction::I32WrapI64)
2757 }
2758 
i32_trunc_f32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2759 fn i32_trunc_f32_s(
2760     _: &mut Unstructured,
2761     _: &Module,
2762     builder: &mut CodeBuilder,
2763 ) -> Result<Instruction> {
2764     builder.pop_operands(&[ValType::F32]);
2765     builder.push_operands(&[ValType::I32]);
2766     Ok(Instruction::I32TruncF32S)
2767 }
2768 
i32_trunc_f32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2769 fn i32_trunc_f32_u(
2770     _: &mut Unstructured,
2771     _: &Module,
2772     builder: &mut CodeBuilder,
2773 ) -> Result<Instruction> {
2774     builder.pop_operands(&[ValType::F32]);
2775     builder.push_operands(&[ValType::I32]);
2776     Ok(Instruction::I32TruncF32U)
2777 }
2778 
i32_trunc_f64_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2779 fn i32_trunc_f64_s(
2780     _: &mut Unstructured,
2781     _: &Module,
2782     builder: &mut CodeBuilder,
2783 ) -> Result<Instruction> {
2784     builder.pop_operands(&[ValType::F64]);
2785     builder.push_operands(&[ValType::I32]);
2786     Ok(Instruction::I32TruncF64S)
2787 }
2788 
i32_trunc_f64_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2789 fn i32_trunc_f64_u(
2790     _: &mut Unstructured,
2791     _: &Module,
2792     builder: &mut CodeBuilder,
2793 ) -> Result<Instruction> {
2794     builder.pop_operands(&[ValType::F64]);
2795     builder.push_operands(&[ValType::I32]);
2796     Ok(Instruction::I32TruncF64U)
2797 }
2798 
i64_extend_i32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2799 fn i64_extend_i32_s(
2800     _: &mut Unstructured,
2801     _: &Module,
2802     builder: &mut CodeBuilder,
2803 ) -> Result<Instruction> {
2804     builder.pop_operands(&[ValType::I32]);
2805     builder.push_operands(&[ValType::I64]);
2806     Ok(Instruction::I64ExtendI32S)
2807 }
2808 
i64_extend_i32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2809 fn i64_extend_i32_u(
2810     _: &mut Unstructured,
2811     _: &Module,
2812     builder: &mut CodeBuilder,
2813 ) -> Result<Instruction> {
2814     builder.pop_operands(&[ValType::I32]);
2815     builder.push_operands(&[ValType::I64]);
2816     Ok(Instruction::I64ExtendI32U)
2817 }
2818 
i64_trunc_f32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2819 fn i64_trunc_f32_s(
2820     _: &mut Unstructured,
2821     _: &Module,
2822     builder: &mut CodeBuilder,
2823 ) -> Result<Instruction> {
2824     builder.pop_operands(&[ValType::F32]);
2825     builder.push_operands(&[ValType::I64]);
2826     Ok(Instruction::I64TruncF32S)
2827 }
2828 
i64_trunc_f32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2829 fn i64_trunc_f32_u(
2830     _: &mut Unstructured,
2831     _: &Module,
2832     builder: &mut CodeBuilder,
2833 ) -> Result<Instruction> {
2834     builder.pop_operands(&[ValType::F32]);
2835     builder.push_operands(&[ValType::I64]);
2836     Ok(Instruction::I64TruncF32U)
2837 }
2838 
i64_trunc_f64_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2839 fn i64_trunc_f64_s(
2840     _: &mut Unstructured,
2841     _: &Module,
2842     builder: &mut CodeBuilder,
2843 ) -> Result<Instruction> {
2844     builder.pop_operands(&[ValType::F64]);
2845     builder.push_operands(&[ValType::I64]);
2846     Ok(Instruction::I64TruncF64S)
2847 }
2848 
i64_trunc_f64_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2849 fn i64_trunc_f64_u(
2850     _: &mut Unstructured,
2851     _: &Module,
2852     builder: &mut CodeBuilder,
2853 ) -> Result<Instruction> {
2854     builder.pop_operands(&[ValType::F64]);
2855     builder.push_operands(&[ValType::I64]);
2856     Ok(Instruction::I64TruncF64U)
2857 }
2858 
f32_convert_i32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2859 fn f32_convert_i32_s(
2860     _: &mut Unstructured,
2861     _: &Module,
2862     builder: &mut CodeBuilder,
2863 ) -> Result<Instruction> {
2864     builder.pop_operands(&[ValType::I32]);
2865     builder.push_operands(&[ValType::F32]);
2866     Ok(Instruction::F32ConvertI32S)
2867 }
2868 
f32_convert_i32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2869 fn f32_convert_i32_u(
2870     _: &mut Unstructured,
2871     _: &Module,
2872     builder: &mut CodeBuilder,
2873 ) -> Result<Instruction> {
2874     builder.pop_operands(&[ValType::I32]);
2875     builder.push_operands(&[ValType::F32]);
2876     Ok(Instruction::F32ConvertI32U)
2877 }
2878 
f32_convert_i64_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2879 fn f32_convert_i64_s(
2880     _: &mut Unstructured,
2881     _: &Module,
2882     builder: &mut CodeBuilder,
2883 ) -> Result<Instruction> {
2884     builder.pop_operands(&[ValType::I64]);
2885     builder.push_operands(&[ValType::F32]);
2886     Ok(Instruction::F32ConvertI64S)
2887 }
2888 
f32_convert_i64_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2889 fn f32_convert_i64_u(
2890     _: &mut Unstructured,
2891     _: &Module,
2892     builder: &mut CodeBuilder,
2893 ) -> Result<Instruction> {
2894     builder.pop_operands(&[ValType::I64]);
2895     builder.push_operands(&[ValType::F32]);
2896     Ok(Instruction::F32ConvertI64U)
2897 }
2898 
f32_demote_f64( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2899 fn f32_demote_f64(
2900     _: &mut Unstructured,
2901     _: &Module,
2902     builder: &mut CodeBuilder,
2903 ) -> Result<Instruction> {
2904     builder.pop_operands(&[ValType::F64]);
2905     builder.push_operands(&[ValType::F32]);
2906     Ok(Instruction::F32DemoteF64)
2907 }
2908 
f64_convert_i32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2909 fn f64_convert_i32_s(
2910     _: &mut Unstructured,
2911     _: &Module,
2912     builder: &mut CodeBuilder,
2913 ) -> Result<Instruction> {
2914     builder.pop_operands(&[ValType::I32]);
2915     builder.push_operands(&[ValType::F64]);
2916     Ok(Instruction::F64ConvertI32S)
2917 }
2918 
f64_convert_i32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2919 fn f64_convert_i32_u(
2920     _: &mut Unstructured,
2921     _: &Module,
2922     builder: &mut CodeBuilder,
2923 ) -> Result<Instruction> {
2924     builder.pop_operands(&[ValType::I32]);
2925     builder.push_operands(&[ValType::F64]);
2926     Ok(Instruction::F64ConvertI32U)
2927 }
2928 
f64_convert_i64_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2929 fn f64_convert_i64_s(
2930     _: &mut Unstructured,
2931     _: &Module,
2932     builder: &mut CodeBuilder,
2933 ) -> Result<Instruction> {
2934     builder.pop_operands(&[ValType::I64]);
2935     builder.push_operands(&[ValType::F64]);
2936     Ok(Instruction::F64ConvertI64S)
2937 }
2938 
f64_convert_i64_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2939 fn f64_convert_i64_u(
2940     _: &mut Unstructured,
2941     _: &Module,
2942     builder: &mut CodeBuilder,
2943 ) -> Result<Instruction> {
2944     builder.pop_operands(&[ValType::I64]);
2945     builder.push_operands(&[ValType::F64]);
2946     Ok(Instruction::F64ConvertI64U)
2947 }
2948 
f64_promote_f32( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2949 fn f64_promote_f32(
2950     _: &mut Unstructured,
2951     _: &Module,
2952     builder: &mut CodeBuilder,
2953 ) -> Result<Instruction> {
2954     builder.pop_operands(&[ValType::F32]);
2955     builder.push_operands(&[ValType::F64]);
2956     Ok(Instruction::F64PromoteF32)
2957 }
2958 
i32_reinterpret_f32( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2959 fn i32_reinterpret_f32(
2960     _: &mut Unstructured,
2961     _: &Module,
2962     builder: &mut CodeBuilder,
2963 ) -> Result<Instruction> {
2964     builder.pop_operands(&[ValType::F32]);
2965     builder.push_operands(&[ValType::I32]);
2966     Ok(Instruction::I32ReinterpretF32)
2967 }
2968 
i64_reinterpret_f64( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2969 fn i64_reinterpret_f64(
2970     _: &mut Unstructured,
2971     _: &Module,
2972     builder: &mut CodeBuilder,
2973 ) -> Result<Instruction> {
2974     builder.pop_operands(&[ValType::F64]);
2975     builder.push_operands(&[ValType::I64]);
2976     Ok(Instruction::I64ReinterpretF64)
2977 }
2978 
f32_reinterpret_i32( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2979 fn f32_reinterpret_i32(
2980     _: &mut Unstructured,
2981     _: &Module,
2982     builder: &mut CodeBuilder,
2983 ) -> Result<Instruction> {
2984     builder.pop_operands(&[ValType::I32]);
2985     builder.push_operands(&[ValType::F32]);
2986     Ok(Instruction::F32ReinterpretI32)
2987 }
2988 
f64_reinterpret_i64( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2989 fn f64_reinterpret_i64(
2990     _: &mut Unstructured,
2991     _: &Module,
2992     builder: &mut CodeBuilder,
2993 ) -> Result<Instruction> {
2994     builder.pop_operands(&[ValType::I64]);
2995     builder.push_operands(&[ValType::F64]);
2996     Ok(Instruction::F64ReinterpretI64)
2997 }
2998 
i32_extend_8_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>2999 fn i32_extend_8_s(
3000     _: &mut Unstructured,
3001     _: &Module,
3002     builder: &mut CodeBuilder,
3003 ) -> Result<Instruction> {
3004     builder.pop_operands(&[ValType::I32]);
3005     builder.push_operands(&[ValType::I32]);
3006     Ok(Instruction::I32Extend8S)
3007 }
3008 
i32_extend_16_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3009 fn i32_extend_16_s(
3010     _: &mut Unstructured,
3011     _: &Module,
3012     builder: &mut CodeBuilder,
3013 ) -> Result<Instruction> {
3014     builder.pop_operands(&[ValType::I32]);
3015     builder.push_operands(&[ValType::I32]);
3016     Ok(Instruction::I32Extend16S)
3017 }
3018 
i64_extend_8_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3019 fn i64_extend_8_s(
3020     _: &mut Unstructured,
3021     _: &Module,
3022     builder: &mut CodeBuilder,
3023 ) -> Result<Instruction> {
3024     builder.pop_operands(&[ValType::I64]);
3025     builder.push_operands(&[ValType::I64]);
3026     Ok(Instruction::I64Extend8S)
3027 }
3028 
i64_extend_16_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3029 fn i64_extend_16_s(
3030     _: &mut Unstructured,
3031     _: &Module,
3032     builder: &mut CodeBuilder,
3033 ) -> Result<Instruction> {
3034     builder.pop_operands(&[ValType::I64]);
3035     builder.push_operands(&[ValType::I64]);
3036     Ok(Instruction::I64Extend16S)
3037 }
3038 
i64_extend_32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3039 fn i64_extend_32_s(
3040     _: &mut Unstructured,
3041     _: &Module,
3042     builder: &mut CodeBuilder,
3043 ) -> Result<Instruction> {
3044     builder.pop_operands(&[ValType::I64]);
3045     builder.push_operands(&[ValType::I64]);
3046     Ok(Instruction::I64Extend32S)
3047 }
3048 
i32_trunc_sat_f32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3049 fn i32_trunc_sat_f32_s(
3050     _: &mut Unstructured,
3051     _: &Module,
3052     builder: &mut CodeBuilder,
3053 ) -> Result<Instruction> {
3054     builder.pop_operands(&[ValType::F32]);
3055     builder.push_operands(&[ValType::I32]);
3056     Ok(Instruction::I32TruncSatF32S)
3057 }
3058 
i32_trunc_sat_f32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3059 fn i32_trunc_sat_f32_u(
3060     _: &mut Unstructured,
3061     _: &Module,
3062     builder: &mut CodeBuilder,
3063 ) -> Result<Instruction> {
3064     builder.pop_operands(&[ValType::F32]);
3065     builder.push_operands(&[ValType::I32]);
3066     Ok(Instruction::I32TruncSatF32U)
3067 }
3068 
i32_trunc_sat_f64_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3069 fn i32_trunc_sat_f64_s(
3070     _: &mut Unstructured,
3071     _: &Module,
3072     builder: &mut CodeBuilder,
3073 ) -> Result<Instruction> {
3074     builder.pop_operands(&[ValType::F64]);
3075     builder.push_operands(&[ValType::I32]);
3076     Ok(Instruction::I32TruncSatF64S)
3077 }
3078 
i32_trunc_sat_f64_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3079 fn i32_trunc_sat_f64_u(
3080     _: &mut Unstructured,
3081     _: &Module,
3082     builder: &mut CodeBuilder,
3083 ) -> Result<Instruction> {
3084     builder.pop_operands(&[ValType::F64]);
3085     builder.push_operands(&[ValType::I32]);
3086     Ok(Instruction::I32TruncSatF64U)
3087 }
3088 
i64_trunc_sat_f32_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3089 fn i64_trunc_sat_f32_s(
3090     _: &mut Unstructured,
3091     _: &Module,
3092     builder: &mut CodeBuilder,
3093 ) -> Result<Instruction> {
3094     builder.pop_operands(&[ValType::F32]);
3095     builder.push_operands(&[ValType::I64]);
3096     Ok(Instruction::I64TruncSatF32S)
3097 }
3098 
i64_trunc_sat_f32_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3099 fn i64_trunc_sat_f32_u(
3100     _: &mut Unstructured,
3101     _: &Module,
3102     builder: &mut CodeBuilder,
3103 ) -> Result<Instruction> {
3104     builder.pop_operands(&[ValType::F32]);
3105     builder.push_operands(&[ValType::I64]);
3106     Ok(Instruction::I64TruncSatF32U)
3107 }
3108 
i64_trunc_sat_f64_s( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3109 fn i64_trunc_sat_f64_s(
3110     _: &mut Unstructured,
3111     _: &Module,
3112     builder: &mut CodeBuilder,
3113 ) -> Result<Instruction> {
3114     builder.pop_operands(&[ValType::F64]);
3115     builder.push_operands(&[ValType::I64]);
3116     Ok(Instruction::I64TruncSatF64S)
3117 }
3118 
i64_trunc_sat_f64_u( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3119 fn i64_trunc_sat_f64_u(
3120     _: &mut Unstructured,
3121     _: &Module,
3122     builder: &mut CodeBuilder,
3123 ) -> Result<Instruction> {
3124     builder.pop_operands(&[ValType::F64]);
3125     builder.push_operands(&[ValType::I64]);
3126     Ok(Instruction::I64TruncSatF64U)
3127 }
3128 
memory_offset(u: &mut Unstructured, module: &Module, memory_index: u32) -> Result<u64>3129 fn memory_offset(u: &mut Unstructured, module: &Module, memory_index: u32) -> Result<u64> {
3130     let (a, b, c) = module.config.memory_offset_choices();
3131     assert!(a + b + c != 0);
3132 
3133     let memory_type = &module.memories[memory_index as usize];
3134     let min = memory_type.minimum.saturating_mul(65536);
3135     let max = memory_type
3136         .maximum
3137         .map(|max| max.saturating_mul(65536))
3138         .unwrap_or(u64::MAX);
3139     let (min, max, true_max) = if memory_type.memory64 {
3140         // 64-bit memories can use the limits calculated above as-is
3141         (min, max, u64::MAX)
3142     } else {
3143         // 32-bit memories can't represent a full 4gb offset, so if that's the
3144         // min/max sizes then we need to switch the m to `u32::MAX`.
3145         (
3146             u64::from(u32::try_from(min).unwrap_or(u32::MAX)),
3147             u64::from(u32::try_from(max).unwrap_or(u32::MAX)),
3148             u64::from(u32::MAX),
3149         )
3150     };
3151 
3152     let choice = u.int_in_range(0..=a + b + c - 1)?;
3153     if choice < a {
3154         u.int_in_range(0..=min)
3155     } else if choice < a + b {
3156         u.int_in_range(min..=max)
3157     } else {
3158         u.int_in_range(max..=true_max)
3159     }
3160 }
3161 
mem_arg( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, alignments: &[u32], ) -> Result<MemArg>3162 fn mem_arg(
3163     u: &mut Unstructured,
3164     module: &Module,
3165     builder: &mut CodeBuilder,
3166     alignments: &[u32],
3167 ) -> Result<MemArg> {
3168     let memory_index = if builder.type_on_stack(ValType::I32) {
3169         builder.pop_operands(&[ValType::I32]);
3170         memory_index(u, builder, ValType::I32)?
3171     } else {
3172         builder.pop_operands(&[ValType::I64]);
3173         memory_index(u, builder, ValType::I64)?
3174     };
3175     let offset = memory_offset(u, module, memory_index)?;
3176     let align = *u.choose(alignments)?;
3177     Ok(MemArg {
3178         memory_index,
3179         offset,
3180         align,
3181     })
3182 }
3183 
memory_index(u: &mut Unstructured, builder: &CodeBuilder, ty: ValType) -> Result<u32>3184 fn memory_index(u: &mut Unstructured, builder: &CodeBuilder, ty: ValType) -> Result<u32> {
3185     if ty == ValType::I32 {
3186         Ok(*u.choose(&builder.allocs.memory32)?)
3187     } else {
3188         Ok(*u.choose(&builder.allocs.memory64)?)
3189     }
3190 }
3191 
data_index(u: &mut Unstructured, module: &Module) -> Result<u32>3192 fn data_index(u: &mut Unstructured, module: &Module) -> Result<u32> {
3193     let data = module.data.len() as u32;
3194     assert!(data > 0);
3195     if data == 1 {
3196         Ok(0)
3197     } else {
3198         u.int_in_range(0..=data - 1)
3199     }
3200 }
3201 
3202 #[inline]
ref_null_valid(module: &Module, _: &mut CodeBuilder) -> bool3203 fn ref_null_valid(module: &Module, _: &mut CodeBuilder) -> bool {
3204     module.config.reference_types_enabled()
3205 }
3206 
ref_null(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>3207 fn ref_null(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
3208     let ty = *u.choose(&[ValType::ExternRef, ValType::FuncRef])?;
3209     builder.push_operands(&[ty]);
3210     Ok(Instruction::RefNull(ty))
3211 }
3212 
3213 #[inline]
ref_func_valid(module: &Module, builder: &mut CodeBuilder) -> bool3214 fn ref_func_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3215     module.config.reference_types_enabled() && builder.allocs.referenced_functions.len() > 0
3216 }
3217 
ref_func(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>3218 fn ref_func(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
3219     let i = *u.choose(&builder.allocs.referenced_functions)?;
3220     builder.push_operands(&[ValType::FuncRef]);
3221     Ok(Instruction::RefFunc(i))
3222 }
3223 
3224 #[inline]
ref_is_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool3225 fn ref_is_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3226     module.config.reference_types_enabled()
3227         && (builder.type_on_stack(ValType::ExternRef) || builder.type_on_stack(ValType::FuncRef))
3228 }
3229 
ref_is_null(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>3230 fn ref_is_null(_: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
3231     pop_reference_type(builder);
3232     builder.push_operands(&[ValType::I32]);
3233     Ok(Instruction::RefIsNull)
3234 }
3235 
3236 #[inline]
table_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool3237 fn table_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3238     module.config.reference_types_enabled()
3239         && module.config.bulk_memory_enabled()
3240         && [ValType::ExternRef, ValType::FuncRef].iter().any(|ty| {
3241             builder.types_on_stack(&[ValType::I32, *ty, ValType::I32])
3242                 && module.tables.iter().any(|t| t.elem_ty == *ty)
3243         })
3244 }
3245 
table_fill( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3246 fn table_fill(
3247     u: &mut Unstructured,
3248     module: &Module,
3249     builder: &mut CodeBuilder,
3250 ) -> Result<Instruction> {
3251     builder.pop_operands(&[ValType::I32]);
3252     let ty = pop_reference_type(builder);
3253     builder.pop_operands(&[ValType::I32]);
3254     let table = table_index(ty, u, module)?;
3255     Ok(Instruction::TableFill { table })
3256 }
3257 
3258 #[inline]
table_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool3259 fn table_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3260     module.config.reference_types_enabled()
3261         && [ValType::ExternRef, ValType::FuncRef].iter().any(|ty| {
3262             builder.types_on_stack(&[ValType::I32, *ty])
3263                 && module.tables.iter().any(|t| t.elem_ty == *ty)
3264         })
3265 }
3266 
table_set( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3267 fn table_set(
3268     u: &mut Unstructured,
3269     module: &Module,
3270     builder: &mut CodeBuilder,
3271 ) -> Result<Instruction> {
3272     let ty = pop_reference_type(builder);
3273     builder.pop_operands(&[ValType::I32]);
3274     let table = table_index(ty, u, module)?;
3275     Ok(Instruction::TableSet { table })
3276 }
3277 
3278 #[inline]
table_get_valid(module: &Module, builder: &mut CodeBuilder) -> bool3279 fn table_get_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3280     module.config.reference_types_enabled()
3281         && builder.type_on_stack(ValType::I32)
3282         && module.tables.len() > 0
3283 }
3284 
table_get( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3285 fn table_get(
3286     u: &mut Unstructured,
3287     module: &Module,
3288     builder: &mut CodeBuilder,
3289 ) -> Result<Instruction> {
3290     builder.pop_operands(&[ValType::I32]);
3291     let idx = u.int_in_range(0..=module.tables.len() - 1)?;
3292     let ty = module.tables[idx].elem_ty;
3293     builder.push_operands(&[ty]);
3294     Ok(Instruction::TableGet { table: idx as u32 })
3295 }
3296 
3297 #[inline]
table_size_valid(module: &Module, _: &mut CodeBuilder) -> bool3298 fn table_size_valid(module: &Module, _: &mut CodeBuilder) -> bool {
3299     module.config.reference_types_enabled() && module.tables.len() > 0
3300 }
3301 
table_size( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3302 fn table_size(
3303     u: &mut Unstructured,
3304     module: &Module,
3305     builder: &mut CodeBuilder,
3306 ) -> Result<Instruction> {
3307     let table = u.int_in_range(0..=module.tables.len() - 1)? as u32;
3308     builder.push_operands(&[ValType::I32]);
3309     Ok(Instruction::TableSize { table })
3310 }
3311 
3312 #[inline]
table_grow_valid(module: &Module, builder: &mut CodeBuilder) -> bool3313 fn table_grow_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3314     module.config.reference_types_enabled()
3315         && [ValType::ExternRef, ValType::FuncRef].iter().any(|ty| {
3316             builder.types_on_stack(&[*ty, ValType::I32])
3317                 && module.tables.iter().any(|t| t.elem_ty == *ty)
3318         })
3319 }
3320 
table_grow( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3321 fn table_grow(
3322     u: &mut Unstructured,
3323     module: &Module,
3324     builder: &mut CodeBuilder,
3325 ) -> Result<Instruction> {
3326     builder.pop_operands(&[ValType::I32]);
3327     let ty = pop_reference_type(builder);
3328     let table = table_index(ty, u, module)?;
3329     builder.push_operands(&[ValType::I32]);
3330     Ok(Instruction::TableGrow { table })
3331 }
3332 
3333 #[inline]
table_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool3334 fn table_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3335     module.config.reference_types_enabled()
3336         && module.tables.len() > 0
3337         && builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
3338 }
3339 
table_copy( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3340 fn table_copy(
3341     u: &mut Unstructured,
3342     module: &Module,
3343     builder: &mut CodeBuilder,
3344 ) -> Result<Instruction> {
3345     builder.pop_operands(&[ValType::I32, ValType::I32, ValType::I32]);
3346     let src = u.int_in_range(0..=module.tables.len() - 1)? as u32;
3347     let dst = table_index(module.tables[src as usize].elem_ty, u, module)?;
3348     Ok(Instruction::TableCopy { src, dst })
3349 }
3350 
3351 #[inline]
table_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool3352 fn table_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3353     module.config.reference_types_enabled()
3354         && builder.allocs.table_init_possible
3355         && builder.types_on_stack(&[ValType::I32, ValType::I32, ValType::I32])
3356 }
3357 
table_init( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3358 fn table_init(
3359     u: &mut Unstructured,
3360     module: &Module,
3361     builder: &mut CodeBuilder,
3362 ) -> Result<Instruction> {
3363     builder.pop_operands(&[ValType::I32, ValType::I32, ValType::I32]);
3364     let segments = module
3365         .elems
3366         .iter()
3367         .enumerate()
3368         .filter(|(_, e)| module.tables.iter().any(|t| t.elem_ty == e.ty))
3369         .map(|(i, _)| i)
3370         .collect::<Vec<_>>();
3371     let segment = *u.choose(&segments)?;
3372     let table = table_index(module.elems[segment].ty, u, module)?;
3373     Ok(Instruction::TableInit {
3374         segment: segment as u32,
3375         table,
3376     })
3377 }
3378 
3379 #[inline]
elem_drop_valid(module: &Module, _builder: &mut CodeBuilder) -> bool3380 fn elem_drop_valid(module: &Module, _builder: &mut CodeBuilder) -> bool {
3381     module.config.reference_types_enabled() && module.elems.len() > 0
3382 }
3383 
elem_drop( u: &mut Unstructured, module: &Module, _builder: &mut CodeBuilder, ) -> Result<Instruction>3384 fn elem_drop(
3385     u: &mut Unstructured,
3386     module: &Module,
3387     _builder: &mut CodeBuilder,
3388 ) -> Result<Instruction> {
3389     let segment = u.int_in_range(0..=module.elems.len() - 1)? as u32;
3390     Ok(Instruction::ElemDrop { segment })
3391 }
3392 
pop_reference_type(builder: &mut CodeBuilder) -> ValType3393 fn pop_reference_type(builder: &mut CodeBuilder) -> ValType {
3394     if builder.type_on_stack(ValType::ExternRef) {
3395         builder.pop_operands(&[ValType::ExternRef]);
3396         ValType::ExternRef
3397     } else {
3398         builder.pop_operands(&[ValType::FuncRef]);
3399         ValType::FuncRef
3400     }
3401 }
3402 
table_index(ty: ValType, u: &mut Unstructured, module: &Module) -> Result<u32>3403 fn table_index(ty: ValType, u: &mut Unstructured, module: &Module) -> Result<u32> {
3404     let tables = module
3405         .tables
3406         .iter()
3407         .enumerate()
3408         .filter(|(_, t)| t.elem_ty == ty)
3409         .map(|t| t.0 as u32)
3410         .collect::<Vec<_>>();
3411     Ok(*u.choose(&tables)?)
3412 }
3413 
lane_index(u: &mut Unstructured, number_of_lanes: u8) -> Result<u8>3414 fn lane_index(u: &mut Unstructured, number_of_lanes: u8) -> Result<u8> {
3415     u.int_in_range(0..=(number_of_lanes - 1))
3416 }
3417 
3418 #[inline]
simd_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3419 fn simd_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3420     module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128])
3421 }
3422 
3423 #[inline]
simd_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3424 fn simd_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3425     module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::V128])
3426 }
3427 
3428 #[inline]
simd_v128_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3429 fn simd_v128_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3430     module.config.simd_enabled()
3431         && builder.types_on_stack(&[ValType::V128, ValType::V128, ValType::V128])
3432 }
3433 
3434 #[inline]
simd_v128_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3435 fn simd_v128_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3436     module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::I32])
3437 }
3438 
3439 #[inline]
simd_v128_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3440 fn simd_v128_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3441     module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::I64])
3442 }
3443 
3444 #[inline]
simd_v128_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3445 fn simd_v128_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3446     module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::F32])
3447 }
3448 
3449 #[inline]
simd_v128_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3450 fn simd_v128_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3451     module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::F64])
3452 }
3453 
3454 #[inline]
simd_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3455 fn simd_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3456     module.config.simd_enabled() && builder.type_on_stack(ValType::I32)
3457 }
3458 
3459 #[inline]
simd_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3460 fn simd_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3461     module.config.simd_enabled() && builder.type_on_stack(ValType::I64)
3462 }
3463 
3464 #[inline]
simd_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3465 fn simd_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3466     module.config.simd_enabled() && builder.type_on_stack(ValType::F32)
3467 }
3468 
3469 #[inline]
simd_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool3470 fn simd_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3471     module.config.simd_enabled() && builder.type_on_stack(ValType::F64)
3472 }
3473 
3474 #[inline]
simd_have_memory_and_offset(module: &Module, builder: &mut CodeBuilder) -> bool3475 fn simd_have_memory_and_offset(module: &Module, builder: &mut CodeBuilder) -> bool {
3476     module.config.simd_enabled() && have_memory_and_offset(module, builder)
3477 }
3478 
3479 #[inline]
simd_have_memory_and_offset_and_v128(module: &Module, builder: &mut CodeBuilder) -> bool3480 fn simd_have_memory_and_offset_and_v128(module: &Module, builder: &mut CodeBuilder) -> bool {
3481     module.config.simd_enabled() && store_valid(module, builder, || ValType::V128)
3482 }
3483 
3484 #[inline]
simd_v128_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool3485 fn simd_v128_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3486     module.config.simd_enabled() && store_valid(module, builder, || ValType::V128)
3487 }
3488 
3489 #[inline]
simd_enabled(module: &Module, _: &mut CodeBuilder) -> bool3490 fn simd_enabled(module: &Module, _: &mut CodeBuilder) -> bool {
3491     module.config.simd_enabled()
3492 }
3493 
3494 macro_rules! simd_load {
3495     ($instruction:ident, $generator_fn_name:ident, $alignments:expr) => {
3496         fn $generator_fn_name(
3497             u: &mut Unstructured,
3498             module: &Module,
3499             builder: &mut CodeBuilder,
3500         ) -> Result<Instruction> {
3501             let memarg = mem_arg(u, module, builder, $alignments)?;
3502             builder.push_operands(&[ValType::V128]);
3503             Ok(Instruction::$instruction { memarg })
3504         }
3505     };
3506 }
3507 
3508 simd_load!(V128Load, v128_load, &[0, 1, 2, 3, 4]);
3509 simd_load!(V128Load8x8S, v128_load8x8s, &[0, 1, 2, 3]);
3510 simd_load!(V128Load8x8U, v128_load8x8u, &[0, 1, 2, 3]);
3511 simd_load!(V128Load16x4S, v128_load16x4s, &[0, 1, 2, 3]);
3512 simd_load!(V128Load16x4U, v128_load16x4u, &[0, 1, 2, 3]);
3513 simd_load!(V128Load32x2S, v128_load32x2s, &[0, 1, 2, 3]);
3514 simd_load!(V128Load32x2U, v128_load32x2u, &[0, 1, 2, 3]);
3515 simd_load!(V128Load8Splat, v128_load8_splat, &[0]);
3516 simd_load!(V128Load16Splat, v128_load16_splat, &[0, 1]);
3517 simd_load!(V128Load32Splat, v128_load32_splat, &[0, 1, 2]);
3518 simd_load!(V128Load64Splat, v128_load64_splat, &[0, 1, 2, 3]);
3519 simd_load!(V128Load32Zero, v128_load32_zero, &[0, 1, 2]);
3520 simd_load!(V128Load64Zero, v128_load64_zero, &[0, 1, 2, 3]);
3521 
v128_store( u: &mut Unstructured, module: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3522 fn v128_store(
3523     u: &mut Unstructured,
3524     module: &Module,
3525     builder: &mut CodeBuilder,
3526 ) -> Result<Instruction> {
3527     builder.pop_operands(&[ValType::V128]);
3528     let memarg = mem_arg(u, module, builder, &[0, 1, 2, 3, 4])?;
3529     Ok(Instruction::V128Store { memarg })
3530 }
3531 
3532 macro_rules! simd_load_lane {
3533     ($instruction:ident, $generator_fn_name:ident, $alignments:expr, $number_of_lanes:expr) => {
3534         fn $generator_fn_name(
3535             u: &mut Unstructured,
3536             module: &Module,
3537             builder: &mut CodeBuilder,
3538         ) -> Result<Instruction> {
3539             builder.pop_operands(&[ValType::V128]);
3540             let memarg = mem_arg(u, module, builder, $alignments)?;
3541             builder.push_operands(&[ValType::V128]);
3542             Ok(Instruction::$instruction {
3543                 memarg,
3544                 lane: lane_index(u, $number_of_lanes)?,
3545             })
3546         }
3547     };
3548 }
3549 
3550 simd_load_lane!(V128Load8Lane, v128_load8_lane, &[0], 16);
3551 simd_load_lane!(V128Load16Lane, v128_load16_lane, &[0, 1], 8);
3552 simd_load_lane!(V128Load32Lane, v128_load32_lane, &[0, 1, 2], 4);
3553 simd_load_lane!(V128Load64Lane, v128_load64_lane, &[0, 1, 2, 3], 2);
3554 
3555 macro_rules! simd_store_lane {
3556     ($instruction:ident, $generator_fn_name:ident, $alignments:expr, $number_of_lanes:expr) => {
3557         fn $generator_fn_name(
3558             u: &mut Unstructured,
3559             module: &Module,
3560             builder: &mut CodeBuilder,
3561         ) -> Result<Instruction> {
3562             builder.pop_operands(&[ValType::V128]);
3563             let memarg = mem_arg(u, module, builder, $alignments)?;
3564             Ok(Instruction::$instruction {
3565                 memarg,
3566                 lane: lane_index(u, $number_of_lanes)?,
3567             })
3568         }
3569     };
3570 }
3571 
3572 simd_store_lane!(V128Store8Lane, v128_store8_lane, &[0], 16);
3573 simd_store_lane!(V128Store16Lane, v128_store16_lane, &[0, 1], 8);
3574 simd_store_lane!(V128Store32Lane, v128_store32_lane, &[0, 1, 2], 4);
3575 simd_store_lane!(V128Store64Lane, v128_store64_lane, &[0, 1, 2, 3], 2);
3576 
v128_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction>3577 fn v128_const(u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder) -> Result<Instruction> {
3578     builder.push_operands(&[ValType::V128]);
3579     let c = i128::from_le_bytes(u.arbitrary()?);
3580     Ok(Instruction::V128Const(c))
3581 }
3582 
i8x16_shuffle( u: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3583 fn i8x16_shuffle(
3584     u: &mut Unstructured,
3585     _: &Module,
3586     builder: &mut CodeBuilder,
3587 ) -> Result<Instruction> {
3588     builder.pop_operands(&[ValType::V128, ValType::V128]);
3589     builder.push_operands(&[ValType::V128]);
3590     let mut lanes = [0; 16];
3591     for i in 0..16 {
3592         lanes[i] = u.int_in_range(0..=31)?;
3593     }
3594     Ok(Instruction::I8x16Shuffle { lanes: lanes })
3595 }
3596 
3597 macro_rules! simd_lane_access {
3598     ($instruction:ident, $generator_fn_name:ident, $in_types:expr => $out_types:expr, $number_of_lanes:expr) => {
3599         fn $generator_fn_name(
3600             u: &mut Unstructured,
3601             _: &Module,
3602             builder: &mut CodeBuilder,
3603         ) -> Result<Instruction> {
3604             builder.pop_operands($in_types);
3605             builder.push_operands($out_types);
3606             Ok(Instruction::$instruction {
3607                 lane: lane_index(u, $number_of_lanes)?,
3608             })
3609         }
3610     };
3611 }
3612 
3613 simd_lane_access!(I8x16ExtractLaneS, i8x16_extract_lane_s, &[ValType::V128] => &[ValType::I32], 16);
3614 simd_lane_access!(I8x16ExtractLaneU, i8x16_extract_lane_u, &[ValType::V128] => &[ValType::I32], 16);
3615 simd_lane_access!(I8x16ReplaceLane, i8x16_replace_lane, &[ValType::V128, ValType::I32] => &[ValType::V128], 16);
3616 simd_lane_access!(I16x8ExtractLaneS, i16x8_extract_lane_s, &[ValType::V128] => &[ValType::I32], 8);
3617 simd_lane_access!(I16x8ExtractLaneU, i16x8_extract_lane_u, &[ValType::V128] => &[ValType::I32], 8);
3618 simd_lane_access!(I16x8ReplaceLane, i16x8_replace_lane, &[ValType::V128, ValType::I32] => &[ValType::V128], 8);
3619 simd_lane_access!(I32x4ExtractLane, i32x4_extract_lane, &[ValType::V128] => &[ValType::I32], 4);
3620 simd_lane_access!(I32x4ReplaceLane, i32x4_replace_lane, &[ValType::V128, ValType::I32] => &[ValType::V128], 4);
3621 simd_lane_access!(I64x2ExtractLane, i64x2_extract_lane, &[ValType::V128] => &[ValType::I64], 2);
3622 simd_lane_access!(I64x2ReplaceLane, i64x2_replace_lane, &[ValType::V128, ValType::I64] => &[ValType::V128], 2);
3623 simd_lane_access!(F32x4ExtractLane, f32x4_extract_lane, &[ValType::V128] => &[ValType::F32], 4);
3624 simd_lane_access!(F32x4ReplaceLane, f32x4_replace_lane, &[ValType::V128, ValType::F32] => &[ValType::V128], 4);
3625 simd_lane_access!(F64x2ExtractLane, f64x2_extract_lane, &[ValType::V128] => &[ValType::F64], 2);
3626 simd_lane_access!(F64x2ReplaceLane, f64x2_replace_lane, &[ValType::V128, ValType::F64] => &[ValType::V128], 2);
3627 
3628 macro_rules! simd_binop {
3629     ($instruction:ident, $generator_fn_name:ident) => {
3630         fn $generator_fn_name(
3631             _: &mut Unstructured,
3632             _: &Module,
3633             builder: &mut CodeBuilder,
3634         ) -> Result<Instruction> {
3635             builder.pop_operands(&[ValType::V128, ValType::V128]);
3636             builder.push_operands(&[ValType::V128]);
3637             Ok(Instruction::$instruction)
3638         }
3639     };
3640 }
3641 
3642 macro_rules! simd_unop {
3643     ($instruction:ident, $generator_fn_name:ident) => {
3644         simd_unop!($instruction, $generator_fn_name, V128 -> V128);
3645     };
3646 
3647     ($instruction:ident, $generator_fn_name:ident, $in_type:ident -> $out_type:ident) => {
3648         fn $generator_fn_name(
3649             _: &mut Unstructured,
3650             _: &Module,
3651             builder: &mut CodeBuilder,
3652         ) -> Result<Instruction> {
3653             builder.pop_operands(&[ValType::$in_type]);
3654             builder.push_operands(&[ValType::$out_type]);
3655             Ok(Instruction::$instruction)
3656         }
3657     };
3658 }
3659 
3660 macro_rules! simd_shift {
3661     ($instruction:ident, $generator_fn_name:ident) => {
3662         fn $generator_fn_name(
3663             _: &mut Unstructured,
3664             _: &Module,
3665             builder: &mut CodeBuilder,
3666         ) -> Result<Instruction> {
3667             builder.pop_operands(&[ValType::V128, ValType::I32]);
3668             builder.push_operands(&[ValType::V128]);
3669             Ok(Instruction::$instruction)
3670         }
3671     };
3672 }
3673 
3674 simd_unop!(I8x16Splat, i8x16_splat, I32 -> V128);
3675 simd_unop!(I16x8Splat, i16x8_splat, I32 -> V128);
3676 simd_unop!(I32x4Splat, i32x4_splat, I32 -> V128);
3677 simd_unop!(I64x2Splat, i64x2_splat, I64 -> V128);
3678 simd_unop!(F32x4Splat, f32x4_splat, F32 -> V128);
3679 simd_unop!(F64x2Splat, f64x2_splat, F64 -> V128);
3680 simd_binop!(I8x16Swizzle, i8x16_swizzle);
3681 simd_binop!(I8x16Eq, i8x16_eq);
3682 simd_binop!(I8x16Ne, i8x16_ne);
3683 simd_binop!(I8x16LtS, i8x16_lt_s);
3684 simd_binop!(I8x16LtU, i8x16_lt_u);
3685 simd_binop!(I8x16GtS, i8x16_gt_s);
3686 simd_binop!(I8x16GtU, i8x16_gt_u);
3687 simd_binop!(I8x16LeS, i8x16_le_s);
3688 simd_binop!(I8x16LeU, i8x16_le_u);
3689 simd_binop!(I8x16GeS, i8x16_ge_s);
3690 simd_binop!(I8x16GeU, i8x16_ge_u);
3691 simd_binop!(I16x8Eq, i16x8_eq);
3692 simd_binop!(I16x8Ne, i16x8_ne);
3693 simd_binop!(I16x8LtS, i16x8_lt_s);
3694 simd_binop!(I16x8LtU, i16x8_lt_u);
3695 simd_binop!(I16x8GtS, i16x8_gt_s);
3696 simd_binop!(I16x8GtU, i16x8_gt_u);
3697 simd_binop!(I16x8LeS, i16x8_le_s);
3698 simd_binop!(I16x8LeU, i16x8_le_u);
3699 simd_binop!(I16x8GeS, i16x8_ge_s);
3700 simd_binop!(I16x8GeU, i16x8_ge_u);
3701 simd_binop!(I32x4Eq, i32x4_eq);
3702 simd_binop!(I32x4Ne, i32x4_ne);
3703 simd_binop!(I32x4LtS, i32x4_lt_s);
3704 simd_binop!(I32x4LtU, i32x4_lt_u);
3705 simd_binop!(I32x4GtS, i32x4_gt_s);
3706 simd_binop!(I32x4GtU, i32x4_gt_u);
3707 simd_binop!(I32x4LeS, i32x4_le_s);
3708 simd_binop!(I32x4LeU, i32x4_le_u);
3709 simd_binop!(I32x4GeS, i32x4_ge_s);
3710 simd_binop!(I32x4GeU, i32x4_ge_u);
3711 simd_binop!(I64x2Eq, i64x2_eq);
3712 simd_binop!(I64x2Ne, i64x2_ne);
3713 simd_binop!(I64x2LtS, i64x2_lt_s);
3714 simd_binop!(I64x2GtS, i64x2_gt_s);
3715 simd_binop!(I64x2LeS, i64x2_le_s);
3716 simd_binop!(I64x2GeS, i64x2_ge_s);
3717 simd_binop!(F32x4Eq, f32x4_eq);
3718 simd_binop!(F32x4Ne, f32x4_ne);
3719 simd_binop!(F32x4Lt, f32x4_lt);
3720 simd_binop!(F32x4Gt, f32x4_gt);
3721 simd_binop!(F32x4Le, f32x4_le);
3722 simd_binop!(F32x4Ge, f32x4_ge);
3723 simd_binop!(F64x2Eq, f64x2_eq);
3724 simd_binop!(F64x2Ne, f64x2_ne);
3725 simd_binop!(F64x2Lt, f64x2_lt);
3726 simd_binop!(F64x2Gt, f64x2_gt);
3727 simd_binop!(F64x2Le, f64x2_le);
3728 simd_binop!(F64x2Ge, f64x2_ge);
3729 simd_unop!(V128Not, v128_not);
3730 simd_binop!(V128And, v128_and);
3731 simd_binop!(V128AndNot, v128_and_not);
3732 simd_binop!(V128Or, v128_or);
3733 simd_binop!(V128Xor, v128_xor);
3734 simd_unop!(V128AnyTrue, v128_any_true, V128 -> I32);
3735 simd_unop!(I8x16Abs, i8x16_abs);
3736 simd_unop!(I8x16Neg, i8x16_neg);
3737 simd_unop!(I8x16Popcnt, i8x16_popcnt);
3738 simd_unop!(I8x16AllTrue, i8x16_all_true, V128 -> I32);
3739 simd_unop!(I8x16Bitmask, i8x16_bitmask, V128 -> I32);
3740 simd_binop!(I8x16NarrowI16x8S, i8x16_narrow_i16x8s);
3741 simd_binop!(I8x16NarrowI16x8U, i8x16_narrow_i16x8u);
3742 simd_shift!(I8x16Shl, i8x16_shl);
3743 simd_shift!(I8x16ShrS, i8x16_shr_s);
3744 simd_shift!(I8x16ShrU, i8x16_shr_u);
3745 simd_binop!(I8x16Add, i8x16_add);
3746 simd_binop!(I8x16AddSatS, i8x16_add_sat_s);
3747 simd_binop!(I8x16AddSatU, i8x16_add_sat_u);
3748 simd_binop!(I8x16Sub, i8x16_sub);
3749 simd_binop!(I8x16SubSatS, i8x16_sub_sat_s);
3750 simd_binop!(I8x16SubSatU, i8x16_sub_sat_u);
3751 simd_binop!(I8x16MinS, i8x16_min_s);
3752 simd_binop!(I8x16MinU, i8x16_min_u);
3753 simd_binop!(I8x16MaxS, i8x16_max_s);
3754 simd_binop!(I8x16MaxU, i8x16_max_u);
3755 simd_binop!(I8x16RoundingAverageU, i8x16_rounding_average_u);
3756 simd_unop!(I16x8ExtAddPairwiseI8x16S, i16x8_ext_add_pairwise_i8x16s);
3757 simd_unop!(I16x8ExtAddPairwiseI8x16U, i16x8_ext_add_pairwise_i8x16u);
3758 simd_unop!(I16x8Abs, i16x8_abs);
3759 simd_unop!(I16x8Neg, i16x8_neg);
3760 simd_binop!(I16x8Q15MulrSatS, i16x8q15_mulr_sat_s);
3761 simd_unop!(I16x8AllTrue, i16x8_all_true, V128 -> I32);
3762 simd_unop!(I16x8Bitmask, i16x8_bitmask, V128 -> I32);
3763 simd_binop!(I16x8NarrowI32x4S, i16x8_narrow_i32x4s);
3764 simd_binop!(I16x8NarrowI32x4U, i16x8_narrow_i32x4u);
3765 simd_unop!(I16x8ExtendLowI8x16S, i16x8_extend_low_i8x16s);
3766 simd_unop!(I16x8ExtendHighI8x16S, i16x8_extend_high_i8x16s);
3767 simd_unop!(I16x8ExtendLowI8x16U, i16x8_extend_low_i8x16u);
3768 simd_unop!(I16x8ExtendHighI8x16U, i16x8_extend_high_i8x16u);
3769 simd_shift!(I16x8Shl, i16x8_shl);
3770 simd_shift!(I16x8ShrS, i16x8_shr_s);
3771 simd_shift!(I16x8ShrU, i16x8_shr_u);
3772 simd_binop!(I16x8Add, i16x8_add);
3773 simd_binop!(I16x8AddSatS, i16x8_add_sat_s);
3774 simd_binop!(I16x8AddSatU, i16x8_add_sat_u);
3775 simd_binop!(I16x8Sub, i16x8_sub);
3776 simd_binop!(I16x8SubSatS, i16x8_sub_sat_s);
3777 simd_binop!(I16x8SubSatU, i16x8_sub_sat_u);
3778 simd_binop!(I16x8Mul, i16x8_mul);
3779 simd_binop!(I16x8MinS, i16x8_min_s);
3780 simd_binop!(I16x8MinU, i16x8_min_u);
3781 simd_binop!(I16x8MaxS, i16x8_max_s);
3782 simd_binop!(I16x8MaxU, i16x8_max_u);
3783 simd_binop!(I16x8RoundingAverageU, i16x8_rounding_average_u);
3784 simd_binop!(I16x8ExtMulLowI8x16S, i16x8_ext_mul_low_i8x16s);
3785 simd_binop!(I16x8ExtMulHighI8x16S, i16x8_ext_mul_high_i8x16s);
3786 simd_binop!(I16x8ExtMulLowI8x16U, i16x8_ext_mul_low_i8x16u);
3787 simd_binop!(I16x8ExtMulHighI8x16U, i16x8_ext_mul_high_i8x16u);
3788 simd_unop!(I32x4ExtAddPairwiseI16x8S, i32x4_ext_add_pairwise_i16x8s);
3789 simd_unop!(I32x4ExtAddPairwiseI16x8U, i32x4_ext_add_pairwise_i16x8u);
3790 simd_unop!(I32x4Abs, i32x4_abs);
3791 simd_unop!(I32x4Neg, i32x4_neg);
3792 simd_unop!(I32x4AllTrue, i32x4_all_true, V128 -> I32);
3793 simd_unop!(I32x4Bitmask, i32x4_bitmask, V128 -> I32);
3794 simd_unop!(I32x4ExtendLowI16x8S, i32x4_extend_low_i16x8s);
3795 simd_unop!(I32x4ExtendHighI16x8S, i32x4_extend_high_i16x8s);
3796 simd_unop!(I32x4ExtendLowI16x8U, i32x4_extend_low_i16x8u);
3797 simd_unop!(I32x4ExtendHighI16x8U, i32x4_extend_high_i16x8u);
3798 simd_shift!(I32x4Shl, i32x4_shl);
3799 simd_shift!(I32x4ShrS, i32x4_shr_s);
3800 simd_shift!(I32x4ShrU, i32x4_shr_u);
3801 simd_binop!(I32x4Add, i32x4_add);
3802 simd_binop!(I32x4Sub, i32x4_sub);
3803 simd_binop!(I32x4Mul, i32x4_mul);
3804 simd_binop!(I32x4MinS, i32x4_min_s);
3805 simd_binop!(I32x4MinU, i32x4_min_u);
3806 simd_binop!(I32x4MaxS, i32x4_max_s);
3807 simd_binop!(I32x4MaxU, i32x4_max_u);
3808 simd_binop!(I32x4DotI16x8S, i32x4_dot_i16x8s);
3809 simd_binop!(I32x4ExtMulLowI16x8S, i32x4_ext_mul_low_i16x8s);
3810 simd_binop!(I32x4ExtMulHighI16x8S, i32x4_ext_mul_high_i16x8s);
3811 simd_binop!(I32x4ExtMulLowI16x8U, i32x4_ext_mul_low_i16x8u);
3812 simd_binop!(I32x4ExtMulHighI16x8U, i32x4_ext_mul_high_i16x8u);
3813 simd_unop!(I64x2Abs, i64x2_abs);
3814 simd_unop!(I64x2Neg, i64x2_neg);
3815 simd_unop!(I64x2AllTrue, i64x2_all_true, V128 -> I32);
3816 simd_unop!(I64x2Bitmask, i64x2_bitmask, V128 -> I32);
3817 simd_unop!(I64x2ExtendLowI32x4S, i64x2_extend_low_i32x4s);
3818 simd_unop!(I64x2ExtendHighI32x4S, i64x2_extend_high_i32x4s);
3819 simd_unop!(I64x2ExtendLowI32x4U, i64x2_extend_low_i32x4u);
3820 simd_unop!(I64x2ExtendHighI32x4U, i64x2_extend_high_i32x4u);
3821 simd_shift!(I64x2Shl, i64x2_shl);
3822 simd_shift!(I64x2ShrS, i64x2_shr_s);
3823 simd_shift!(I64x2ShrU, i64x2_shr_u);
3824 simd_binop!(I64x2Add, i64x2_add);
3825 simd_binop!(I64x2Sub, i64x2_sub);
3826 simd_binop!(I64x2Mul, i64x2_mul);
3827 simd_binop!(I64x2ExtMulLowI32x4S, i64x2_ext_mul_low_i32x4s);
3828 simd_binop!(I64x2ExtMulHighI32x4S, i64x2_ext_mul_high_i32x4s);
3829 simd_binop!(I64x2ExtMulLowI32x4U, i64x2_ext_mul_low_i32x4u);
3830 simd_binop!(I64x2ExtMulHighI32x4U, i64x2_ext_mul_high_i32x4u);
3831 simd_unop!(F32x4Ceil, f32x4_ceil);
3832 simd_unop!(F32x4Floor, f32x4_floor);
3833 simd_unop!(F32x4Trunc, f32x4_trunc);
3834 simd_unop!(F32x4Nearest, f32x4_nearest);
3835 simd_unop!(F32x4Abs, f32x4_abs);
3836 simd_unop!(F32x4Neg, f32x4_neg);
3837 simd_unop!(F32x4Sqrt, f32x4_sqrt);
3838 simd_binop!(F32x4Add, f32x4_add);
3839 simd_binop!(F32x4Sub, f32x4_sub);
3840 simd_binop!(F32x4Mul, f32x4_mul);
3841 simd_binop!(F32x4Div, f32x4_div);
3842 simd_binop!(F32x4Min, f32x4_min);
3843 simd_binop!(F32x4Max, f32x4_max);
3844 simd_binop!(F32x4PMin, f32x4p_min);
3845 simd_binop!(F32x4PMax, f32x4p_max);
3846 simd_unop!(F64x2Ceil, f64x2_ceil);
3847 simd_unop!(F64x2Floor, f64x2_floor);
3848 simd_unop!(F64x2Trunc, f64x2_trunc);
3849 simd_unop!(F64x2Nearest, f64x2_nearest);
3850 simd_unop!(F64x2Abs, f64x2_abs);
3851 simd_unop!(F64x2Neg, f64x2_neg);
3852 simd_unop!(F64x2Sqrt, f64x2_sqrt);
3853 simd_binop!(F64x2Add, f64x2_add);
3854 simd_binop!(F64x2Sub, f64x2_sub);
3855 simd_binop!(F64x2Mul, f64x2_mul);
3856 simd_binop!(F64x2Div, f64x2_div);
3857 simd_binop!(F64x2Min, f64x2_min);
3858 simd_binop!(F64x2Max, f64x2_max);
3859 simd_binop!(F64x2PMin, f64x2p_min);
3860 simd_binop!(F64x2PMax, f64x2p_max);
3861 simd_unop!(I32x4TruncSatF32x4S, i32x4_trunc_sat_f32x4s);
3862 simd_unop!(I32x4TruncSatF32x4U, i32x4_trunc_sat_f32x4u);
3863 simd_unop!(F32x4ConvertI32x4S, f32x4_convert_i32x4s);
3864 simd_unop!(F32x4ConvertI32x4U, f32x4_convert_i32x4u);
3865 simd_unop!(I32x4TruncSatF64x2SZero, i32x4_trunc_sat_f64x2s_zero);
3866 simd_unop!(I32x4TruncSatF64x2UZero, i32x4_trunc_sat_f64x2u_zero);
3867 simd_unop!(F64x2ConvertLowI32x4S, f64x2_convert_low_i32x4s);
3868 simd_unop!(F64x2ConvertLowI32x4U, f64x2_convert_low_i32x4u);
3869 simd_unop!(F32x4DemoteF64x2Zero, f32x4_demote_f64x2_zero);
3870 simd_unop!(F64x2PromoteLowF32x4, f64x2_promote_low_f32x4);
3871 
v128_bitselect( _: &mut Unstructured, _: &Module, builder: &mut CodeBuilder, ) -> Result<Instruction>3872 fn v128_bitselect(
3873     _: &mut Unstructured,
3874     _: &Module,
3875     builder: &mut CodeBuilder,
3876 ) -> Result<Instruction> {
3877     builder.pop_operands(&[ValType::V128, ValType::V128, ValType::V128]);
3878     builder.push_operands(&[ValType::V128]);
3879     Ok(Instruction::V128Bitselect)
3880 }
3881