orca_wasm/
opcode.rs

1//! Traits that defines the injection behaviour for wasm opcodes
2
3// note: this should be implemented by FunctionBuilder, ModuleIterator, and ComponentIterator
4// note that the location of the injection is handled specific implementation
5// for iterators, we inject at the location the iterator is pointing at (curr_loc)
6// for FunctionBuilder, we inject at the end of the function
7use crate::ir::id::{DataSegmentID, ElementID, FieldID, FunctionID, GlobalID, LocalID, TypeID};
8use crate::ir::module::module_types::HeapType;
9use crate::ir::types::{BlockType, FuncInstrMode, InstrumentationMode};
10use crate::Location;
11use wasmparser::MemArg;
12use wasmparser::Operator;
13
14/// Defines instrumentation behaviour
15pub trait Instrumenter<'a> {
16    /// Can be called after finishing some instrumentation to reset the mode.
17    fn finish_instr(&mut self);
18    /// Get the InstrumentType of the current location
19    fn curr_instrument_mode(&self) -> &Option<InstrumentationMode>;
20
21    /// Sets the type of Instrumentation Type of the specified location
22    fn set_instrument_mode_at(&mut self, mode: InstrumentationMode, loc: Location);
23
24    /// Get the InstrumentType of the current function
25    fn curr_func_instrument_mode(&self) -> &Option<FuncInstrMode>;
26
27    /// Sets the type of Instrumentation Type of the current function
28    fn set_func_instrument_mode(&mut self, mode: FuncInstrMode);
29
30    // ==== FUNC INSTR INJECTION ====
31
32    /// Mark the current function to InstrumentFuncEntry
33    fn func_entry(&mut self) -> &mut Self {
34        self.set_func_instrument_mode(FuncInstrMode::Entry);
35        self
36    }
37
38    /// Mark the current function to InstrumentFuncExit
39    fn func_exit(&mut self) -> &mut Self {
40        self.set_func_instrument_mode(FuncInstrMode::Exit);
41        self
42    }
43
44    // ==== INSTR INJECTION ====
45    /// Clears the instruction at a given Location
46    fn clear_instr_at(&mut self, loc: Location, mode: InstrumentationMode);
47
48    /// Splice a new instruction into a specific location
49    fn add_instr_at(&mut self, loc: Location, instr: Operator<'a>);
50
51    /// Injects an Instruction with InstrumentationMode `Before` at a given location
52    fn before_at(&mut self, loc: Location) -> &mut Self {
53        self.set_instrument_mode_at(InstrumentationMode::Before, loc);
54        self
55    }
56
57    /// Injects an Instruction with InstrumentationMode `After` at a given location
58    fn after_at(&mut self, loc: Location) -> &mut Self {
59        self.set_instrument_mode_at(InstrumentationMode::After, loc);
60        self
61    }
62
63    /// Injects an Instruction with InstrumentationMode `Alternate` at a given location
64    fn alternate_at(&mut self, loc: Location) -> &mut Self {
65        self.set_instrument_mode_at(InstrumentationMode::Alternate, loc);
66        self
67    }
68
69    /// Injects an empty InstrumentationMode `Alternate` at a given location
70    fn empty_alternate_at(&mut self, loc: Location) -> &mut Self;
71
72    /// Injects a Semantic After at a given location
73    fn semantic_after_at(&mut self, loc: Location) -> &mut Self {
74        self.set_instrument_mode_at(InstrumentationMode::SemanticAfter, loc);
75        self
76    }
77
78    /// Injects a block entry at a given location
79    fn block_entry_at(&mut self, loc: Location) -> &mut Self {
80        self.set_instrument_mode_at(InstrumentationMode::BlockEntry, loc);
81        self
82    }
83
84    /// Injects a block exit at a given location
85    fn block_exit_at(&mut self, loc: Location) -> &mut Self {
86        self.set_instrument_mode_at(InstrumentationMode::BlockExit, loc);
87        self
88    }
89
90    /// Injects a block alternate at a given location
91    fn block_alt_at(&mut self, loc: Location) -> &mut Self {
92        self.set_instrument_mode_at(InstrumentationMode::BlockAlt, loc);
93        self
94    }
95
96    /// Injects an empty block alternate at a given location
97    fn empty_block_alt_at(&mut self, loc: Location) -> &mut Self;
98
99    /// Get the instruction injected at index idx
100    fn get_injected_val(&self, idx: usize) -> &Operator;
101}
102
103/// Defines Injection behaviour at the current location of the Iterator
104pub trait Inject<'a> {
105    /// Inject an operator at the current location
106    fn inject(&mut self, instr: Operator<'a>);
107
108    /// Inject multiple operators at the current location
109    fn inject_all(&mut self, instrs: &[Operator<'a>]) -> &mut Self {
110        instrs.iter().for_each(|instr| {
111            self.inject(instr.to_owned());
112        });
113        self
114    }
115}
116
117/// Defines Injection Behaviour at a given location
118pub trait InjectAt<'a> {
119    /// Inject an Instruction at a given Location with a given `InstrumentationMode`
120    fn inject_at(&mut self, idx: usize, mode: InstrumentationMode, instr: Operator<'a>);
121}
122
123#[allow(dead_code)]
124/// Defines injection behaviour. Takes a [`wasmparser::Operator`] and instructions are defined [here].
125///
126/// [`wasmparser::Operator`]: https://docs.rs/wasmparser/latest/wasmparser/enum.Operator.html
127/// [here]: https://webassembly.github.io/spec/core/binary/instructions.html
128pub trait Opcode<'a>: Inject<'a> {
129    // Control Flow
130    /// Inject a call instruction
131    fn call(&mut self, idx: FunctionID) -> &mut Self {
132        self.inject(Operator::Call {
133            function_index: *idx,
134        });
135        self
136    }
137
138    /// Inject a return statement
139    fn return_stmt(&mut self) -> &mut Self {
140        self.inject(Operator::Return);
141        self
142    }
143
144    /// Inject a no op instruction
145    fn nop(&mut self) -> &mut Self {
146        self.inject(Operator::Nop);
147        self
148    }
149
150    /// Inject an unreachable instruction
151    fn unreachable(&mut self) -> &mut Self {
152        self.inject(Operator::Unreachable);
153        self
154    }
155
156    /// Inject a select statement
157    fn select(&mut self) -> &mut Self {
158        self.inject(Operator::Select);
159        self
160    }
161
162    /// Inject an if statement
163    fn if_stmt(&mut self, block_type: BlockType) -> &mut Self {
164        self.inject(Operator::If {
165            blockty: wasmparser::BlockType::from(block_type),
166        });
167        self
168    }
169
170    /// Inject an else statement
171    fn else_stmt(&mut self) -> &mut Self {
172        self.inject(Operator::Else);
173        self
174    }
175
176    /// Inject an end statement. Indicates the end of the current scope
177    fn end(&mut self) -> &mut Self {
178        self.inject(Operator::End);
179        self
180    }
181
182    /// Inject a block statement. Indicates the start of a block
183    fn block(&mut self, block_type: BlockType) -> &mut Self {
184        self.inject(Operator::Block {
185            blockty: wasmparser::BlockType::from(block_type),
186        });
187        self
188    }
189
190    /// Inject a loop statement
191    fn loop_stmt(&mut self, block_type: BlockType) -> &mut Self {
192        self.inject(Operator::Loop {
193            blockty: wasmparser::BlockType::from(block_type),
194        });
195        self
196    }
197
198    /// Inject a break statement
199    fn br(&mut self, relative_depth: u32) -> &mut Self {
200        self.inject(Operator::Br { relative_depth });
201        self
202    }
203
204    /// Inject a conditional break statement
205    fn br_if(&mut self, relative_depth: u32) -> &mut Self {
206        self.inject(Operator::BrIf { relative_depth });
207        self
208    }
209
210    // Numerics
211    /// Inject a local.get
212    fn local_get(&mut self, idx: LocalID) -> &mut Self {
213        self.inject(Operator::LocalGet { local_index: *idx });
214        self
215    }
216
217    /// Inject a local.set
218    fn local_set(&mut self, idx: LocalID) -> &mut Self {
219        self.inject(Operator::LocalSet { local_index: *idx });
220        self
221    }
222
223    fn local_tee(&mut self, idx: LocalID) -> &mut Self {
224        self.inject(Operator::LocalTee { local_index: *idx });
225        self
226    }
227
228    // Integers
229    /// Inject an i32.const instruction
230    fn i32_const(&mut self, value: i32) -> &mut Self {
231        self.inject(Operator::I32Const { value });
232        self
233    }
234
235    /// Inject an i32.add instruction
236    fn i32_add(&mut self) -> &mut Self {
237        self.inject(Operator::I32Add);
238        self
239    }
240
241    /// Inject an i32.sub instruction
242    fn i32_sub(&mut self) -> &mut Self {
243        self.inject(Operator::I32Sub);
244        self
245    }
246
247    /// Inject an i32.mul instruction
248    fn i32_mul(&mut self) -> &mut Self {
249        self.inject(Operator::I32Mul);
250        self
251    }
252
253    /// Inject an i32.divs instruction
254    fn i32_div_signed(&mut self) -> &mut Self {
255        self.inject(Operator::I32DivS);
256        self
257    }
258
259    /// Inject an i32.divu instruction
260    fn i32_div_unsigned(&mut self) -> &mut Self {
261        self.inject(Operator::I32DivU);
262        self
263    }
264
265    /// Inject an i32.remu instruction
266    fn i32_rem_unsigned(&mut self) -> &mut Self {
267        self.inject(Operator::I32RemU);
268        self
269    }
270
271    /// Inject an i32.rems instruction
272    fn i32_rem_signed(&mut self) -> &mut Self {
273        self.inject(Operator::I32RemS);
274        self
275    }
276
277    /// Inject an i32.and instruction
278    fn i32_and(&mut self) -> &mut Self {
279        self.inject(Operator::I32And);
280        self
281    }
282
283    /// Inject an i32.or instruction
284    fn i32_or(&mut self) -> &mut Self {
285        self.inject(Operator::I32Or);
286        self
287    }
288
289    /// Inject an i32.xor instruction
290    fn i32_xor(&mut self) -> &mut Self {
291        self.inject(Operator::I32Xor);
292        self
293    }
294
295    /// Inject an i32.shl instruction
296    fn i32_shl(&mut self) -> &mut Self {
297        self.inject(Operator::I32Shl);
298        self
299    }
300
301    /// Inject an i32.shrs instruction
302    fn i32_shr_signed(&mut self) -> &mut Self {
303        self.inject(Operator::I32ShrS);
304        self
305    }
306
307    /// Inject an i32.shru instruction
308    fn i32_shr_unsigned(&mut self) -> &mut Self {
309        self.inject(Operator::I32ShrU);
310        self
311    }
312
313    /// Inject an i32.rotl instruction
314    fn i32_rotl(&mut self) -> &mut Self {
315        self.inject(Operator::I32Rotl);
316        self
317    }
318
319    /// Inject and i32.rotr instruction
320    fn i32_rotr(&mut self) -> &mut Self {
321        self.inject(Operator::I32Rotr);
322        self
323    }
324
325    /// Inject an i32.eq instruction
326    fn i32_eq(&mut self) -> &mut Self {
327        self.inject(Operator::I32Eq);
328        self
329    }
330
331    /// Inject an i32.eqz instruction
332    fn i32_eqz(&mut self) -> &mut Self {
333        self.inject(Operator::I32Eqz);
334        self
335    }
336
337    /// Inject an i32.ne instruction
338    fn i32_ne(&mut self) -> &mut Self {
339        self.inject(Operator::I32Ne);
340        self
341    }
342
343    /// Inject an i32.ltu instruction
344    fn i32_lt_unsigned(&mut self) -> &mut Self {
345        self.inject(Operator::I32LtU);
346        self
347    }
348
349    /// Inject an i32.lts instruction
350    fn i32_lt_signed(&mut self) -> &mut Self {
351        self.inject(Operator::I32LtS);
352        self
353    }
354
355    /// Inject an i32.gtu instruction
356    fn i32_gt_unsigned(&mut self) -> &mut Self {
357        self.inject(Operator::I32GtU);
358        self
359    }
360
361    /// Inject an i32.gts instruction
362    fn i32_gt_signed(&mut self) -> &mut Self {
363        self.inject(Operator::I32GtS);
364        self
365    }
366
367    /// Inject an i32.lteu instruction
368    fn i32_lte_unsigned(&mut self) -> &mut Self {
369        self.inject(Operator::I32LeU);
370        self
371    }
372
373    /// Inject an i32.ltes instruction
374    fn i32_lte_signed(&mut self) -> &mut Self {
375        self.inject(Operator::I32LeS);
376        self
377    }
378
379    /// Inject an i32.gteu instruction
380    fn i32_gte_unsigned(&mut self) -> &mut Self {
381        self.inject(Operator::I32GeU);
382        self
383    }
384
385    /// Inject an i32.gtes instruction
386    fn i32_gte_signed(&mut self) -> &mut Self {
387        self.inject(Operator::I32GeS);
388        self
389    }
390
391    fn i32_wrap_i64(&mut self) -> &mut Self {
392        self.inject(Operator::I32WrapI64);
393        self
394    }
395
396    /// Inject a i32.extend_8s instruction
397    fn i32_extend_8s(&mut self) -> &mut Self {
398        self.inject(Operator::I32Extend8S);
399        self
400    }
401
402    /// Inject a i32.extend_16s instruction
403    fn i32_extend_16s(&mut self) -> &mut Self {
404        self.inject(Operator::I32Extend16S);
405        self
406    }
407
408    /// Inject a i32.trunc_f32s instruction
409    fn i32_trunc_f32s(&mut self) -> &mut Self {
410        self.inject(Operator::I32TruncF32S);
411        self
412    }
413
414    /// Inject a i32.trunc_f32u instruction
415    fn i32_trunc_f32u(&mut self) -> &mut Self {
416        self.inject(Operator::I32TruncF32U);
417        self
418    }
419
420    /// Inject a i32.trunc_f64s instruction
421    fn i32_trunc_f64s(&mut self) -> &mut Self {
422        self.inject(Operator::I32TruncF64S);
423        self
424    }
425
426    /// Inject a i32.trunc_f64u instruction
427    fn i32_trunc_f64u(&mut self) -> &mut Self {
428        self.inject(Operator::I32TruncF64U);
429        self
430    }
431
432    /// Inject a i32.reinterpret_f32 instruction
433    fn i32_reinterpret_f32(&mut self) -> &mut Self {
434        self.inject(Operator::I32ReinterpretF32);
435        self
436    }
437
438    /// Inject an i64.const
439    fn i64_const(&mut self, value: i64) -> &mut Self {
440        self.inject(Operator::I64Const { value });
441        self
442    }
443
444    /// Inject an i64.add instruction
445    fn i64_add(&mut self) -> &mut Self {
446        self.inject(Operator::I64Add);
447        self
448    }
449
450    /// Inject an i64.sub instruction
451    fn i64_sub(&mut self) -> &mut Self {
452        self.inject(Operator::I64Sub);
453        self
454    }
455
456    /// Inject an i64.mul instruction
457    fn i64_mul(&mut self) -> &mut Self {
458        self.inject(Operator::I64Mul);
459        self
460    }
461
462    /// Inject an i64.divs instruction
463    fn i64_div_signed(&mut self) -> &mut Self {
464        self.inject(Operator::I64DivS);
465        self
466    }
467
468    /// Inject an i64.divu instruction
469    fn i64_div_unsigned(&mut self) -> &mut Self {
470        self.inject(Operator::I64DivU);
471        self
472    }
473
474    /// Inject an i64.remu instruction
475    fn i64_rem_unsigned(&mut self) -> &mut Self {
476        self.inject(Operator::I64RemU);
477        self
478    }
479
480    /// Inject an i64.rems instruction
481    fn i64_rem_signed(&mut self) -> &mut Self {
482        self.inject(Operator::I64RemS);
483        self
484    }
485
486    /// Inject an i64.and instruction
487    fn i64_and(&mut self) -> &mut Self {
488        self.inject(Operator::I64And);
489        self
490    }
491
492    /// Inject an i64.or instruction
493    fn i64_or(&mut self) -> &mut Self {
494        self.inject(Operator::I64Or);
495        self
496    }
497
498    /// Inject an i64.xor instruction
499    fn i64_xor(&mut self) -> &mut Self {
500        self.inject(Operator::I64Xor);
501        self
502    }
503
504    /// Inject an i64.shl instruction
505    fn i64_shl(&mut self) -> &mut Self {
506        self.inject(Operator::I64Shl);
507        self
508    }
509
510    /// Inject an i64.shrs instruction
511    fn i64_shr_signed(&mut self) -> &mut Self {
512        self.inject(Operator::I64ShrS);
513        self
514    }
515
516    /// Inject an i64.shru instruction
517    fn i64_shr_unsigned(&mut self) -> &mut Self {
518        self.inject(Operator::I64ShrU);
519        self
520    }
521
522    /// Inject an i64.rotl instruction
523    fn i64_rotl(&mut self) -> &mut Self {
524        self.inject(Operator::I64Rotl);
525        self
526    }
527
528    /// Inject an i64.rotr instruction
529    fn i64_rotr(&mut self) -> &mut Self {
530        self.inject(Operator::I64Rotr);
531        self
532    }
533
534    /// Inject an i64.eq instruction
535    fn i64_eq(&mut self) -> &mut Self {
536        self.inject(Operator::I64Eq);
537        self
538    }
539
540    /// Inject an i64.eqz instruction
541    fn i64_eqz(&mut self) -> &mut Self {
542        self.inject(Operator::I64Eqz);
543        self
544    }
545
546    /// Inject an i64.ne instruction
547    fn i64_ne(&mut self) -> &mut Self {
548        self.inject(Operator::I64Ne);
549        self
550    }
551
552    /// Inject an i64.ltu instruction
553    fn i64_lt_unsigned(&mut self) -> &mut Self {
554        self.inject(Operator::I64LtU);
555        self
556    }
557
558    /// Inject an i64.lts instruction
559    fn i64_lt_signed(&mut self) -> &mut Self {
560        self.inject(Operator::I64LtS);
561        self
562    }
563
564    /// Inject an i64.gtu instruction
565    fn i64_gt_unsigned(&mut self) -> &mut Self {
566        self.inject(Operator::I64GtU);
567        self
568    }
569
570    /// Inject an i64.gts instruction
571    fn i64_gt_signed(&mut self) -> &mut Self {
572        self.inject(Operator::I64GtS);
573        self
574    }
575
576    /// Inject an i64.lteu instruction
577    fn i64_lte_unsigned(&mut self) -> &mut Self {
578        self.inject(Operator::I64LeU);
579        self
580    }
581
582    /// Inject an i64.ltes instruction
583    fn i64_lte_signed(&mut self) -> &mut Self {
584        self.inject(Operator::I64LeS);
585        self
586    }
587
588    /// Inject an i64.gteu instruction
589    fn i64_gte_unsigned(&mut self) -> &mut Self {
590        self.inject(Operator::I64GeU);
591        self
592    }
593
594    /// Inject an i64.gtes instruction
595    fn i64_gte_signed(&mut self) -> &mut Self {
596        self.inject(Operator::I64GeS);
597        self
598    }
599
600    /// Inject a i64.extend_i32_u instruction
601    fn i64_extend_i32u(&mut self) -> &mut Self {
602        self.inject(Operator::I64ExtendI32U);
603        self
604    }
605
606    /// Inject a i64.extend_i32_s instruction
607    fn i64_extend_i32s(&mut self) -> &mut Self {
608        self.inject(Operator::I64ExtendI32S);
609        self
610    }
611
612    /// Inject a i64.trunc_f32s instruction
613    fn i64_trunc_f32s(&mut self) -> &mut Self {
614        self.inject(Operator::I64TruncF32S);
615        self
616    }
617
618    /// Inject a i64.trunc_f32u instruction
619    fn i64_trunc_f32u(&mut self) -> &mut Self {
620        self.inject(Operator::I64TruncF32U);
621        self
622    }
623
624    /// Inject a i64.trunc_f64s instruction
625    fn i64_trunc_f64s(&mut self) -> &mut Self {
626        self.inject(Operator::I64TruncF64S);
627        self
628    }
629
630    /// Inject a i64.trunc_f64u instruction
631    fn i64_trunc_f64u(&mut self) -> &mut Self {
632        self.inject(Operator::I64TruncF64U);
633        self
634    }
635
636    /// Inject a i64.reinterpret_f64 instruction
637    fn i64_reinterpret_f64(&mut self) -> &mut Self {
638        self.inject(Operator::I64ReinterpretF64);
639        self
640    }
641
642    // Floating point
643    /// Inject a f32.const instruction
644    fn f32_const(&mut self, val: f32) -> &mut Self {
645        self.inject(Operator::F32Const {
646            value: wasmparser::Ieee32::from(val),
647        });
648        self
649    }
650
651    /// Inject a f32.abs instruction
652    fn f32_abs(&mut self) -> &mut Self {
653        self.inject(Operator::F32Abs);
654        self
655    }
656
657    /// Inject a f32.ceil instruction
658    fn f32_ceil(&mut self) -> &mut Self {
659        self.inject(Operator::F32Ceil);
660        self
661    }
662
663    /// Inject a f32.floor instruction
664    fn f32_floor(&mut self) -> &mut Self {
665        self.inject(Operator::F32Floor);
666        self
667    }
668
669    /// Inject a f32.trunc instruction
670    fn f32_trunc(&mut self) -> &mut Self {
671        self.inject(Operator::F32Trunc);
672        self
673    }
674
675    /// Inject a f32.sqrt instruction
676    fn f32_sqrt(&mut self) -> &mut Self {
677        self.inject(Operator::F32Sqrt);
678        self
679    }
680
681    /// Inject a f32.add instruction
682    fn f32_add(&mut self) -> &mut Self {
683        self.inject(Operator::F32Add);
684        self
685    }
686
687    /// Inject a f32.sub instruction
688    fn f32_sub(&mut self) -> &mut Self {
689        self.inject(Operator::F32Sub);
690        self
691    }
692
693    /// Inject a f32.mul instruction
694    fn f32_mul(&mut self) -> &mut Self {
695        self.inject(Operator::F32Mul);
696        self
697    }
698
699    /// Inject a f32.div instruction
700    fn f32_div(&mut self) -> &mut Self {
701        self.inject(Operator::F32Div);
702        self
703    }
704
705    /// Inject a f32.min instruction
706    fn f32_min(&mut self) -> &mut Self {
707        self.inject(Operator::F32Min);
708        self
709    }
710
711    /// Inject a f32.max instruction
712    fn f32_max(&mut self) -> &mut Self {
713        self.inject(Operator::F32Max);
714        self
715    }
716
717    /// Inject a f32.eq instruction
718    fn f32_eq(&mut self) -> &mut Self {
719        self.inject(Operator::F32Eq);
720        self
721    }
722
723    /// Inject a f32.ne instruction
724    fn f32_ne(&mut self) -> &mut Self {
725        self.inject(Operator::F32Ne);
726        self
727    }
728
729    /// Inject a f32.gt instruction
730    fn f32_gt(&mut self) -> &mut Self {
731        self.inject(Operator::F32Gt);
732        self
733    }
734
735    /// Inject a f32.ge instruction
736    fn f32_ge(&mut self) -> &mut Self {
737        self.inject(Operator::F32Ge);
738        self
739    }
740
741    /// Inject a f32.lt instruction
742    fn f32_lt(&mut self) -> &mut Self {
743        self.inject(Operator::F32Lt);
744        self
745    }
746
747    /// Inject a f32.le instruction
748    fn f32_le(&mut self) -> &mut Self {
749        self.inject(Operator::F32Le);
750        self
751    }
752
753    /// Inject a f32_convert_i32s instruction
754    fn f32_convert_i32s(&mut self) -> &mut Self {
755        self.inject(Operator::F32ConvertI32S);
756        self
757    }
758
759    /// Inject a f32_convert_i32u instruction
760    fn f32_convert_i32u(&mut self) -> &mut Self {
761        self.inject(Operator::F32ConvertI32U);
762        self
763    }
764
765    /// Inject a f32_convert_i64s instruction
766    fn f32_convert_i64s(&mut self) -> &mut Self {
767        self.inject(Operator::F32ConvertI64S);
768        self
769    }
770
771    /// Inject a f32_convert_i64u instruction
772    fn f32_convert_i64u(&mut self) -> &mut Self {
773        self.inject(Operator::F32ConvertI64U);
774        self
775    }
776
777    /// Inject a f32_demote_f64 instruction
778    fn f32_demote_f64(&mut self) -> &mut Self {
779        self.inject(Operator::F32DemoteF64);
780        self
781    }
782
783    /// Inject a f32.reinterpret_i32 instruction
784    fn f32_reinterpret_i32(&mut self) -> &mut Self {
785        self.inject(Operator::F32ReinterpretI32);
786        self
787    }
788
789    /// Inject a f32.copysign instruction
790    fn f32_copysign(&mut self) -> &mut Self {
791        self.inject(Operator::F32Copysign);
792        self
793    }
794
795    /// Inject a f64.const instruction
796    fn f64_const(&mut self, val: f64) -> &mut Self {
797        self.inject(Operator::F64Const {
798            value: wasmparser::Ieee64::from(val),
799        });
800        self
801    }
802
803    /// Inject a f64.abs instruction
804    fn f64_abs(&mut self) -> &mut Self {
805        self.inject(Operator::F64Abs);
806        self
807    }
808
809    /// Inject a f64.ceil instruction
810    fn f64_ceil(&mut self) -> &mut Self {
811        self.inject(Operator::F64Ceil);
812        self
813    }
814
815    /// Inject a f64.floor instruction
816    fn f64_floor(&mut self) -> &mut Self {
817        self.inject(Operator::F64Floor);
818        self
819    }
820
821    /// Inject a f64.trunc instruction
822    fn f64_trunc(&mut self) -> &mut Self {
823        self.inject(Operator::F64Trunc);
824        self
825    }
826
827    /// Inject a f64.sqrt instruction
828    fn f64_sqrt(&mut self) -> &mut Self {
829        self.inject(Operator::F64Sqrt);
830        self
831    }
832
833    /// Inject a f64.add instruction
834    fn f64_add(&mut self) -> &mut Self {
835        self.inject(Operator::F64Add);
836        self
837    }
838
839    /// Inject a f64.sub instruction
840    fn f64_sub(&mut self) -> &mut Self {
841        self.inject(Operator::F64Sub);
842        self
843    }
844
845    /// Inject a f64.mul instruction
846    fn f64_mul(&mut self) -> &mut Self {
847        self.inject(Operator::F64Mul);
848        self
849    }
850
851    /// Inject a f64.div instruction
852    fn f64_div(&mut self) -> &mut Self {
853        self.inject(Operator::F64Div);
854        self
855    }
856
857    /// Inject a f64.min instruction
858    fn f64_min(&mut self) -> &mut Self {
859        self.inject(Operator::F64Min);
860        self
861    }
862
863    /// Inject a f64.max instruction
864    fn f64_max(&mut self) -> &mut Self {
865        self.inject(Operator::F64Max);
866        self
867    }
868
869    /// Inject a f64.eq instruction
870    fn f64_eq(&mut self) -> &mut Self {
871        self.inject(Operator::F64Eq);
872        self
873    }
874
875    /// Inject a f64.ne instruction
876    fn f64_ne(&mut self) -> &mut Self {
877        self.inject(Operator::F64Ne);
878        self
879    }
880
881    /// Inject a f64.gt instruction
882    fn f64_gt(&mut self) -> &mut Self {
883        self.inject(Operator::F64Gt);
884        self
885    }
886
887    /// Inject a f64.ge instruction
888    fn f64_ge(&mut self) -> &mut Self {
889        self.inject(Operator::F64Ge);
890        self
891    }
892
893    /// Inject a f64.lt instruction
894    fn f64_lt(&mut self) -> &mut Self {
895        self.inject(Operator::F64Lt);
896        self
897    }
898
899    /// Inject a f64.le instruction
900    fn f64_le(&mut self) -> &mut Self {
901        self.inject(Operator::F64Le);
902        self
903    }
904
905    /// Inject a f64_reinterpret_i64 instruction
906    fn f64_reinterpret_i64(&mut self) -> &mut Self {
907        self.inject(Operator::F64ReinterpretI64);
908        self
909    }
910
911    /// Inject a f64_promote_f32 instruction
912    fn f64_promote_f32(&mut self) -> &mut Self {
913        self.inject(Operator::F64PromoteF32);
914        self
915    }
916
917    /// Inject a f64_convert_i32s instruction
918    fn f64_convert_i32s(&mut self) -> &mut Self {
919        self.inject(Operator::F64ConvertI32S);
920        self
921    }
922
923    /// Inject a f64_convert_i32u instruction
924    fn f64_convert_i32u(&mut self) -> &mut Self {
925        self.inject(Operator::F64ConvertI32U);
926        self
927    }
928
929    /// Inject a f64_convert_i64s instruction
930    fn f64_convert_i64s(&mut self) -> &mut Self {
931        self.inject(Operator::F64ConvertI64S);
932        self
933    }
934
935    /// Inject a f64_convert_i64u instruction
936    fn f64_convert_i64u(&mut self) -> &mut Self {
937        self.inject(Operator::F64ConvertI64U);
938        self
939    }
940
941    /// Inject a f64.copysign instruction
942    fn f64_copysign(&mut self) -> &mut Self {
943        self.inject(Operator::F64Copysign);
944        self
945    }
946
947    // Memory Instructions
948    /// Inject a memory.init instruction
949    fn memory_init(&mut self, data_index: u32, mem: u32) -> &mut Self {
950        self.inject(Operator::MemoryInit { data_index, mem });
951        self
952    }
953
954    /// Inject a memory.size instruction
955    fn memory_size(&mut self, mem: u32) -> &mut Self {
956        self.inject(Operator::MemorySize { mem });
957        self
958    }
959
960    /// Inject a memory.grow instruction
961    fn memory_grow(&mut self, mem: u32) -> &mut Self {
962        self.inject(Operator::MemoryGrow { mem });
963        self
964    }
965
966    /// Inject a memory.fill instruction
967    fn memory_fill(&mut self, mem: u32) -> &mut Self {
968        self.inject(Operator::MemoryFill { mem });
969        self
970    }
971
972    /// Inject a memory.copy instruction
973    fn memory_copy(&mut self, dst_mem: u32, src_mem: u32) -> &mut Self {
974        self.inject(Operator::MemoryCopy { dst_mem, src_mem });
975        self
976    }
977
978    /// Inject a memory.discard instruction
979    fn memory_discard(&mut self, mem: u32) -> &mut Self {
980        self.inject(Operator::MemoryDiscard { mem });
981        self
982    }
983    /// Inject a data drop instruction
984    fn data_drop(&mut self, data_index: u32) -> &mut Self {
985        self.inject(Operator::DataDrop { data_index });
986        self
987    }
988
989    // Parametric Instructions
990    /// Inject a drop instruction
991    fn drop(&mut self) -> &mut Self {
992        self.inject(Operator::Drop);
993        self
994    }
995
996    // Linear Memory Access
997    // note: walrus does not specify max_align (probably it's the same as align)
998
999    /// load 1 byte and sign-extend i8 to i32
1000    fn i32_load8_s(&mut self, memarg: MemArg) -> &mut Self {
1001        self.inject(Operator::I32Load8S { memarg });
1002        self
1003    }
1004
1005    /// load 1 byte and zero-extend i8 to i32
1006    fn i32_load8_u(&mut self, memarg: MemArg) -> &mut Self {
1007        self.inject(Operator::I32Load8U { memarg });
1008        self
1009    }
1010
1011    /// load 2 bytes and sign-extend i16 to i32
1012    fn i32_load16_s(&mut self, memarg: MemArg) -> &mut Self {
1013        self.inject(Operator::I32Load16S { memarg });
1014        self
1015    }
1016
1017    /// load 2 bytes and zero-extend i16 to i32
1018    fn i32_load16_u(&mut self, memarg: MemArg) -> &mut Self {
1019        self.inject(Operator::I32Load16U { memarg });
1020        self
1021    }
1022
1023    /// load 4 bytes as i32
1024    fn i32_load(&mut self, memarg: MemArg) -> &mut Self {
1025        self.inject(Operator::I32Load { memarg });
1026        self
1027    }
1028
1029    fn i32_store(&mut self, memarg: MemArg) -> &mut Self {
1030        self.inject(Operator::I32Store { memarg });
1031        self
1032    }
1033    fn i32_store8(&mut self, memarg: MemArg) -> &mut Self {
1034        self.inject(Operator::I32Store8 { memarg });
1035        self
1036    }
1037    fn i32_store16(&mut self, memarg: MemArg) -> &mut Self {
1038        self.inject(Operator::I32Store16 { memarg });
1039        self
1040    }
1041
1042    /// load 1 byte and sign-extend i8 to i64
1043    fn i64_load8_s(&mut self, memarg: MemArg) -> &mut Self {
1044        self.inject(Operator::I64Load8S { memarg });
1045        self
1046    }
1047
1048    /// load 1 byte and zero-extend i8 to i64
1049    fn i64_load8_u(&mut self, memarg: MemArg) -> &mut Self {
1050        self.inject(Operator::I64Load8U { memarg });
1051        self
1052    }
1053
1054    /// load 2 bytes and sign-extend i16 to i64
1055    fn i64_load16_s(&mut self, memarg: MemArg) -> &mut Self {
1056        self.inject(Operator::I64Load16S { memarg });
1057        self
1058    }
1059
1060    /// load 2 bytes and zero-extend i16 to i64
1061    fn i64_load16_u(&mut self, memarg: MemArg) -> &mut Self {
1062        self.inject(Operator::I64Load16U { memarg });
1063        self
1064    }
1065
1066    /// load 4 bytes and sign-extend i32 to i64
1067    fn i64_load32_s(&mut self, memarg: MemArg) -> &mut Self {
1068        self.inject(Operator::I64Load32S { memarg });
1069        self
1070    }
1071
1072    /// load 4 bytes and zero-extend i32 to i64
1073    fn i64_load32_u(&mut self, memarg: MemArg) -> &mut Self {
1074        self.inject(Operator::I64Load32U { memarg });
1075        self
1076    }
1077
1078    /// load 4 bytes as i64
1079    fn i64_load(&mut self, memarg: MemArg) -> &mut Self {
1080        self.inject(Operator::I64Load { memarg });
1081        self
1082    }
1083
1084    fn i64_store(&mut self, memarg: MemArg) -> &mut Self {
1085        self.inject(Operator::I64Store { memarg });
1086        self
1087    }
1088
1089    /// load 4 bytes as f32
1090    fn f32_load(&mut self, memarg: MemArg) -> &mut Self {
1091        self.inject(Operator::F32Load { memarg });
1092        self
1093    }
1094
1095    fn f32_store(&mut self, memarg: MemArg) -> &mut Self {
1096        self.inject(Operator::F32Store { memarg });
1097        self
1098    }
1099
1100    /// load 8 bytes as f64
1101    fn f64_load(&mut self, memarg: MemArg) -> &mut Self {
1102        self.inject(Operator::F64Load { memarg });
1103        self
1104    }
1105
1106    /// Inject an f64_store instruction
1107    fn f64_store(&mut self, memarg: MemArg) -> &mut Self {
1108        self.inject(Operator::F64Store { memarg });
1109        self
1110    }
1111
1112    /// Inject a global.get
1113    fn global_get(&mut self, idx: GlobalID) -> &mut Self {
1114        self.inject(Operator::GlobalGet { global_index: *idx });
1115        self
1116    }
1117
1118    /// Inject a global.set
1119    fn global_set(&mut self, idx: GlobalID) -> &mut Self {
1120        self.inject(Operator::GlobalSet { global_index: *idx });
1121        self
1122    }
1123
1124    // GC Instructions
1125    fn ref_null(&mut self, heap_type: HeapType) -> &mut Self {
1126        self.inject(Operator::RefNull {
1127            hty: wasmparser::HeapType::from(heap_type),
1128        });
1129        self
1130    }
1131
1132    fn ref_is_null(&mut self) -> &mut Self {
1133        self.inject(Operator::RefIsNull);
1134        self
1135    }
1136
1137    fn ref_func(&mut self, function_index: u32) -> &mut Self {
1138        self.inject(Operator::RefFunc { function_index });
1139        self
1140    }
1141
1142    fn ref_eq(&mut self) -> &mut Self {
1143        self.inject(Operator::RefEq);
1144        self
1145    }
1146
1147    fn ref_as_non_null(&mut self) -> &mut Self {
1148        self.inject(Operator::RefAsNonNull);
1149        self
1150    }
1151
1152    fn struct_new(&mut self, struct_type_index: TypeID) -> &mut Self {
1153        self.inject(Operator::StructNew {
1154            struct_type_index: *struct_type_index,
1155        });
1156        self
1157    }
1158
1159    fn struct_new_default(&mut self, struct_type_index: TypeID) -> &mut Self {
1160        self.inject(Operator::StructNewDefault {
1161            struct_type_index: *struct_type_index,
1162        });
1163        self
1164    }
1165
1166    fn struct_get(&mut self, struct_type_index: TypeID, field_index: FieldID) -> &mut Self {
1167        self.inject(Operator::StructGet {
1168            struct_type_index: *struct_type_index,
1169            field_index: *field_index,
1170        });
1171        self
1172    }
1173
1174    fn struct_get_s(&mut self, struct_type_index: TypeID, field_index: FieldID) -> &mut Self {
1175        self.inject(Operator::StructGetS {
1176            struct_type_index: *struct_type_index,
1177            field_index: *field_index,
1178        });
1179        self
1180    }
1181
1182    fn struct_get_u(&mut self, struct_type_index: TypeID, field_index: FieldID) -> &mut Self {
1183        self.inject(Operator::StructGetU {
1184            struct_type_index: *struct_type_index,
1185            field_index: *field_index,
1186        });
1187        self
1188    }
1189
1190    fn struct_set(&mut self, struct_type_index: TypeID, field_index: FieldID) -> &mut Self {
1191        self.inject(Operator::StructSet {
1192            struct_type_index: *struct_type_index,
1193            field_index: *field_index,
1194        });
1195        self
1196    }
1197
1198    fn array_new(&mut self, array_type_index: TypeID) -> &mut Self {
1199        self.inject(Operator::ArrayNew {
1200            array_type_index: *array_type_index,
1201        });
1202        self
1203    }
1204
1205    fn array_new_default(&mut self, array_type_index: TypeID) -> &mut Self {
1206        self.inject(Operator::ArrayNewDefault {
1207            array_type_index: *array_type_index,
1208        });
1209        self
1210    }
1211
1212    fn array_new_fixed(&mut self, array_type_index: TypeID, array_size: u32) -> &mut Self {
1213        self.inject(Operator::ArrayNewFixed {
1214            array_type_index: *array_type_index,
1215            array_size,
1216        });
1217        self
1218    }
1219
1220    // TODO: Check the arguments
1221    fn array_new_data(
1222        &mut self,
1223        array_type_index: TypeID,
1224        array_data_index: DataSegmentID,
1225    ) -> &mut Self {
1226        self.inject(Operator::ArrayNewData {
1227            array_type_index: *array_type_index,
1228            array_data_index: *array_data_index,
1229        });
1230        self
1231    }
1232
1233    fn array_new_elem(
1234        &mut self,
1235        array_type_index: TypeID,
1236        array_elem_index: ElementID,
1237    ) -> &mut Self {
1238        self.inject(Operator::ArrayNewElem {
1239            array_type_index: *array_type_index,
1240            array_elem_index: *array_elem_index,
1241        });
1242        self
1243    }
1244
1245    fn array_get(&mut self, array_type_index: TypeID) -> &mut Self {
1246        self.inject(Operator::ArrayGet {
1247            array_type_index: *array_type_index,
1248        });
1249        self
1250    }
1251
1252    fn array_get_s(&mut self, array_type_index: TypeID) -> &mut Self {
1253        self.inject(Operator::ArrayGetS {
1254            array_type_index: *array_type_index,
1255        });
1256        self
1257    }
1258
1259    fn array_get_u(&mut self, array_type_index: TypeID) -> &mut Self {
1260        self.inject(Operator::ArrayGetU {
1261            array_type_index: *array_type_index,
1262        });
1263        self
1264    }
1265
1266    fn array_set(&mut self, array_type_index: TypeID) -> &mut Self {
1267        self.inject(Operator::ArraySet {
1268            array_type_index: *array_type_index,
1269        });
1270        self
1271    }
1272
1273    fn array_len(&mut self) -> &mut Self {
1274        self.inject(Operator::ArrayLen);
1275        self
1276    }
1277
1278    fn array_fill(&mut self, array_type_index: TypeID) -> &mut Self {
1279        self.inject(Operator::ArrayFill {
1280            array_type_index: *array_type_index,
1281        });
1282        self
1283    }
1284
1285    fn array_copy(
1286        &mut self,
1287        array_type_index_dest: TypeID,
1288        array_type_index_src: TypeID,
1289    ) -> &mut Self {
1290        self.inject(Operator::ArrayCopy {
1291            array_type_index_dst: *array_type_index_dest,
1292            array_type_index_src: *array_type_index_src,
1293        });
1294        self
1295    }
1296
1297    fn array_init_data(
1298        &mut self,
1299        array_type_index: TypeID,
1300        array_data_index: DataSegmentID,
1301    ) -> &mut Self {
1302        self.inject(Operator::ArrayInitData {
1303            array_type_index: *array_type_index,
1304            array_data_index: *array_data_index,
1305        });
1306        self
1307    }
1308
1309    fn array_init_elem(
1310        &mut self,
1311        array_type_index: TypeID,
1312        array_elem_index: ElementID,
1313    ) -> &mut Self {
1314        self.inject(Operator::ArrayInitElem {
1315            array_type_index: *array_type_index,
1316            array_elem_index: *array_elem_index,
1317        });
1318        self
1319    }
1320
1321    fn ref_test(&mut self, heap_type: HeapType) -> &mut Self {
1322        self.inject(Operator::RefTestNonNull {
1323            hty: wasmparser::HeapType::from(heap_type),
1324        });
1325        self
1326    }
1327
1328    fn ref_test_null(&mut self, heap_type: HeapType) -> &mut Self {
1329        self.inject(Operator::RefTestNullable {
1330            hty: wasmparser::HeapType::from(heap_type),
1331        });
1332        self
1333    }
1334
1335    fn ref_cast(&mut self, heap_type: HeapType) -> &mut Self {
1336        self.inject(Operator::RefCastNonNull {
1337            hty: wasmparser::HeapType::from(heap_type),
1338        });
1339        self
1340    }
1341
1342    fn ref_cast_null(&mut self, heap_type: HeapType) -> &mut Self {
1343        self.inject(Operator::RefCastNullable {
1344            hty: wasmparser::HeapType::from(heap_type),
1345        });
1346        self
1347    }
1348
1349    fn any_convert_extern(&mut self) -> &mut Self {
1350        self.inject(Operator::AnyConvertExtern);
1351        self
1352    }
1353
1354    fn extern_convert_any(&mut self) -> &mut Self {
1355        self.inject(Operator::ExternConvertAny);
1356        self
1357    }
1358
1359    fn ref_i31(&mut self) -> &mut Self {
1360        self.inject(Operator::RefI31);
1361        self
1362    }
1363
1364    fn i31_get_s(&mut self) -> &mut Self {
1365        self.inject(Operator::I31GetS);
1366        self
1367    }
1368
1369    fn i31_get_u(&mut self) -> &mut Self {
1370        self.inject(Operator::I31GetU);
1371        self
1372    }
1373}
1374
1375#[allow(dead_code)]
1376/// Defines injection behaviour. Takes a [`wasmparser::Operator`] and instructions are defined [here].
1377///
1378/// [`wasmparser::Operator`]: https://docs.rs/wasmparser/latest/wasmparser/enum.Operator.html
1379/// [here]: https://webassembly.github.io/spec/core/binary/instructions.html
1380pub trait MacroOpcode<'a>: Inject<'a> {
1381    /// Helper function to reinterpret an u32 as an i32 and inject an i32.const instruction with that reinterpreted value.
1382    /// (Useful to emitting memory addresses.)
1383    /// We cast using the `as` keyword to accomplish this.
1384    /// See <https://github.com/thesuhas/orca/issues/133> for an explanation.
1385    fn u32_const(&mut self, value: u32) -> &mut Self {
1386        let i32_val = value as i32;
1387        self.inject(Operator::I32Const { value: i32_val });
1388        self
1389    }
1390    /// Helper function to reinterpret an u64 as an i64 and inject an i64.const instruction with that reinterpreted value.
1391    /// (Useful to emitting memory addresses.)
1392    /// We cast using the `as` keyword to accomplish this.
1393    /// See <https://github.com/thesuhas/orca/issues/133> for an explanation.
1394    fn u64_const(&mut self, value: u64) -> &mut Self {
1395        let i64_val = value as i64;
1396        self.inject(Operator::I64Const { value: i64_val });
1397        self
1398    }
1399}