Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
wasm_sysio_injection.hpp
Go to the documentation of this file.
1#pragma once
2
8#include <iostream>
9#include <functional>
10#include <vector>
11#include <map>
12#include <stack>
13#include <queue>
14#include <unordered_set>
15#include "IR/Module.h"
16#include "IR/Operators.h"
17#include "WASM/WASM.h"
18
19
20namespace sysio { namespace chain { namespace wasm_injections {
21 using namespace IR;
22 // helper functions for injection
23
25 static std::map<std::vector<uint16_t>, uint32_t> type_slots;
26 static std::map<std::string, uint32_t> registered_injected;
27 static std::map<uint32_t, uint32_t> injected_index_mapping;
29
30 static void init( Module& mod ) {
31 type_slots.clear();
32 registered_injected.clear();
34 build_type_slots( mod );
36 }
37
38 static void build_type_slots( Module& mod ) {
39 // add the module types to the type_slots map
40 for ( size_t i=0; i < mod.types.size(); i++ ) {
41 std::vector<uint16_t> type_slot_list = { static_cast<uint16_t>(mod.types[i]->ret) };
42 for ( auto param : mod.types[i]->parameters )
43 type_slot_list.push_back( static_cast<uint16_t>(param) );
44 type_slots.emplace( type_slot_list, i );
45 }
46 }
47
48 template <ResultType Result, ValueType... Params>
49 static void add_type_slot( Module& mod ) {
50 if ( type_slots.find({FromResultType<Result>::value, FromValueType<Params>::value...}) == type_slots.end() ) {
51 type_slots.emplace( std::vector<uint16_t>{FromResultType<Result>::value, FromValueType<Params>::value...}, mod.types.size() );
52 mod.types.push_back( FunctionType::get( Result, { Params... } ) );
53 }
54 }
55
56 // get the next available index that is greater than the last exported function
57 static void get_next_indices( Module& module, int& next_function_index, int& next_actual_index ) {
58 next_function_index = module.functions.imports.size() + module.functions.defs.size() + registered_injected.size();
59 next_actual_index = next_injected_index++;
60 }
61
62 template <ResultType Result, ValueType... Params>
63 static void add_import(Module& module, const char* func_name, int32_t& index ) {
64 if (module.functions.imports.size() == 0 || registered_injected.find(func_name) == registered_injected.end() ) {
65 add_type_slot<Result, Params...>( module );
67 int actual_index;
68 get_next_indices( module, index, actual_index );
69 registered_injected.emplace( func_name, index );
70 decltype(module.functions.imports) new_import = { {{func_type_index}, sysio_injected_module_name, std::move(func_name)} };
71 // prepend to the head of the imports
72 module.functions.imports.insert( module.functions.imports.begin()+(registered_injected.size()-1), new_import.begin(), new_import.end() );
73 injected_index_mapping.emplace( index, actual_index );
74
75 // shift all exported functions by 1
76 for ( size_t i=0; i < module.exports.size(); i++ ) {
77 if ( module.exports[i].kind == IR::ObjectKind::function ) {
78 module.exports[i].index++;
79 }
80 }
81
82 // update the start function
83 if ( module.startFunctionIndex != UINTPTR_MAX ) {
84 module.startFunctionIndex++;
85 }
86
87 // shift all table entries for call indirect
88 for(TableSegment& ts : module.tableSegments) {
89 for(auto& idx : ts.indices)
90 idx++;
91 }
92 }
93 else {
94 index = registered_injected[func_name];
95 }
96 }
97 };
98
100 static void inject( IR::Module& m );
101 static void initializer();
102 };
103
105 static void inject( IR::Module& m );
106 static void initializer();
107 };
108
110 static void inject( IR::Module& m );
111 static void initializer();
112 };
113
115 static void inject( IR::Module& m );
116 static void initializer();
117 };
118
120 static void inject( IR::Module& m );
121 static void initializer();
122 };
123
125 static void inject( IR::Module& m );
126 static void initializer();
127 };
128
129 using wasm_validate_func = std::function<void(IR::Module&)>;
130
131
132 // just pass
134 static void inject( IR::Module& m ) {}
135 };
136
137 // simple mutator that doesn't actually mutate anything
138 // used to verify that a given instruction is valid for execution on our platform
139 // injector 'interface' :
140 // `kills` -> should this injector kill the original instruction
141 // `post` -> should this injector inject after the original instruction
143 static constexpr bool kills = false;
144 static constexpr bool post = false;
145 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
146 }
147 };
148
150 static constexpr bool kills = false;
151 static constexpr bool post = false;
152 static void init() {}
153 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
154 wasm_ops::op_types<>::call_t* call_inst = reinterpret_cast<wasm_ops::op_types<>::call_t*>(inst);
155 auto mapped_index = injector_utils::injected_index_mapping.find(call_inst->field);
156
157 if ( mapped_index != injector_utils::injected_index_mapping.end() ) {
158 call_inst->field = mapped_index->second;
159 }
160 else {
161 call_inst->field += injector_utils::registered_injected.size();
162 }
163 }
164
165 };
166
167 // float injections
168 constexpr const char* inject_which_op( uint16_t opcode ) {
169 switch ( opcode ) {
171 return u8"_sysio_f32_add";
173 return u8"_sysio_f32_sub";
175 return u8"_sysio_f32_mul";
177 return u8"_sysio_f32_div";
179 return u8"_sysio_f32_min";
181 return u8"_sysio_f32_max";
183 return u8"_sysio_f32_copysign";
185 return u8"_sysio_f32_abs";
187 return u8"_sysio_f32_neg";
189 return u8"_sysio_f32_sqrt";
191 return u8"_sysio_f32_ceil";
193 return u8"_sysio_f32_floor";
195 return u8"_sysio_f32_trunc";
197 return u8"_sysio_f32_nearest";
199 return u8"_sysio_f32_eq";
201 return u8"_sysio_f32_ne";
203 return u8"_sysio_f32_lt";
205 return u8"_sysio_f32_le";
207 return u8"_sysio_f32_gt";
209 return u8"_sysio_f32_ge";
211 return u8"_sysio_f64_add";
213 return u8"_sysio_f64_sub";
215 return u8"_sysio_f64_mul";
217 return u8"_sysio_f64_div";
219 return u8"_sysio_f64_min";
221 return u8"_sysio_f64_max";
223 return u8"_sysio_f64_copysign";
225 return u8"_sysio_f64_abs";
227 return u8"_sysio_f64_neg";
229 return u8"_sysio_f64_sqrt";
231 return u8"_sysio_f64_ceil";
233 return u8"_sysio_f64_floor";
235 return u8"_sysio_f64_trunc";
237 return u8"_sysio_f64_nearest";
239 return u8"_sysio_f64_eq";
241 return u8"_sysio_f64_ne";
243 return u8"_sysio_f64_lt";
245 return u8"_sysio_f64_le";
247 return u8"_sysio_f64_gt";
249 return u8"_sysio_f64_ge";
251 return u8"_sysio_f32_promote";
253 return u8"_sysio_f64_demote";
255 return u8"_sysio_f32_trunc_i32u";
257 return u8"_sysio_f32_trunc_i32s";
259 return u8"_sysio_f64_trunc_i32u";
261 return u8"_sysio_f64_trunc_i32s";
263 return u8"_sysio_f32_trunc_i64u";
265 return u8"_sysio_f32_trunc_i64s";
267 return u8"_sysio_f64_trunc_i64u";
269 return u8"_sysio_f64_trunc_i64s";
271 return u8"_sysio_i32_to_f32";
273 return u8"_sysio_ui32_to_f32";
275 return u8"_sysio_i64_f32";
277 return u8"_sysio_ui64_to_f32";
279 return u8"_sysio_i32_to_f64";
281 return u8"_sysio_ui32_to_f64";
283 return u8"_sysio_i64_to_f64";
285 return u8"_sysio_ui64_to_f64";
286
287 default:
288 FC_THROW_EXCEPTION( sysio::chain::wasm_execution_error, "Error, unknown opcode in injection ${op}", ("op", opcode));
289 }
290 }
291
292 template <uint16_t Opcode>
294 static constexpr bool kills = true;
295 static constexpr bool post = false;
296 static void init() {}
297 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
298 int32_t idx;
301 f32op.field = idx;
302 f32op.pack(arg.new_code);
303 }
304 };
305
306 template <uint16_t Opcode>
308 static constexpr bool kills = true;
309 static constexpr bool post = false;
310 static void init() {}
311 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
312 int32_t idx;
315 f32op.field = idx;
316 f32op.pack(arg.new_code);
317 }
318 };
319
320 template <uint16_t Opcode>
322 static constexpr bool kills = true;
323 static constexpr bool post = false;
324 static void init() {}
325 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
326 int32_t idx;
329 f32op.field = idx;
330 f32op.pack(arg.new_code);
331 }
332 };
333 template <uint16_t Opcode>
335 static constexpr bool kills = true;
336 static constexpr bool post = false;
337 static void init() {}
338 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
339 int32_t idx;
342 f64op.field = idx;
343 f64op.pack(arg.new_code);
344 }
345 };
346
347 template <uint16_t Opcode>
349 static constexpr bool kills = true;
350 static constexpr bool post = false;
351 static void init() {}
352 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
353 int32_t idx;
356 f64op.field = idx;
357 f64op.pack(arg.new_code);
358 }
359 };
360
361 template <uint16_t Opcode>
363 static constexpr bool kills = true;
364 static constexpr bool post = false;
365 static void init() {}
366 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
367 int32_t idx;
370 f64op.field = idx;
371 f64op.pack(arg.new_code);
372 }
373 };
374
375 template <uint16_t Opcode>
377 static constexpr bool kills = true;
378 static constexpr bool post = false;
379 static void init() {}
380 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
381 int32_t idx;
384 f32op.field = idx;
385 f32op.pack(arg.new_code);
386 }
387 };
388 template <uint16_t Opcode>
390 static constexpr bool kills = true;
391 static constexpr bool post = false;
392 static void init() {}
393 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
394 int32_t idx;
397 f32op.field = idx;
398 f32op.pack(arg.new_code);
399 }
400 };
401 template <uint16_t Opcode>
403 static constexpr bool kills = true;
404 static constexpr bool post = false;
405 static void init() {}
406 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
407 int32_t idx;
410 f32op.field = idx;
411 f32op.pack(arg.new_code);
412 }
413 };
414 template <uint16_t Opcode>
416 static constexpr bool kills = true;
417 static constexpr bool post = false;
418 static void init() {}
419 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
420 int32_t idx;
423 f32op.field = idx;
424 f32op.pack(arg.new_code);
425 }
426 };
427 template <uint64_t Opcode>
429 static constexpr bool kills = true;
430 static constexpr bool post = false;
431 static void init() {}
432 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
433 int32_t idx;
436 f32op.field = idx;
437 f32op.pack(arg.new_code);
438 }
439 };
440 template <uint64_t Opcode>
442 static constexpr bool kills = true;
443 static constexpr bool post = false;
444 static void init() {}
445 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
446 int32_t idx;
449 f32op.field = idx;
450 f32op.pack(arg.new_code);
451 }
452 };
453 template <uint64_t Opcode>
455 static constexpr bool kills = true;
456 static constexpr bool post = false;
457 static void init() {}
458 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
459 int32_t idx;
462 f64op.field = idx;
463 f64op.pack(arg.new_code);
464 }
465 };
466 template <uint64_t Opcode>
468 static constexpr bool kills = true;
469 static constexpr bool post = false;
470 static void init() {}
471 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
472 int32_t idx;
475 f64op.field = idx;
476 f64op.pack(arg.new_code);
477 }
478 };
479
481 static constexpr bool kills = true;
482 static constexpr bool post = false;
483 static void init() {}
484 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
485 int32_t idx;
486 injector_utils::add_import<ResultType::f64, ValueType::f32>( *(arg.module), u8"_sysio_f32_promote", idx );
488 f32promote.field = idx;
489 f32promote.pack(arg.new_code);
490 }
491 };
492
494 static constexpr bool kills = true;
495 static constexpr bool post = false;
496 static void init() {}
497 static void accept( wasm_ops::instr* inst, wasm_ops::visitor_arg& arg ) {
498 int32_t idx;
499 injector_utils::add_import<ResultType::f32, ValueType::f64>( *(arg.module), u8"_sysio_f64_demote", idx );
501 f32promote.field = idx;
502 f32promote.pack(arg.new_code);
503 }
504 };
505
506 struct pre_op_injectors : wasm_ops::op_types<pass_injector> {
507 // float binops
508 using f32_add_t = wasm_ops::f32_add <f32_binop_injector<wasm_ops::f32_add_code>>;
509 using f32_sub_t = wasm_ops::f32_sub <f32_binop_injector<wasm_ops::f32_sub_code>>;
510 using f32_div_t = wasm_ops::f32_div <f32_binop_injector<wasm_ops::f32_div_code>>;
511 using f32_mul_t = wasm_ops::f32_mul <f32_binop_injector<wasm_ops::f32_mul_code>>;
512 using f32_min_t = wasm_ops::f32_min <f32_binop_injector<wasm_ops::f32_min_code>>;
513 using f32_max_t = wasm_ops::f32_max <f32_binop_injector<wasm_ops::f32_max_code>>;
514 using f32_copysign_t = wasm_ops::f32_copysign <f32_binop_injector<wasm_ops::f32_copysign_code>>;
515 // float unops
516 using f32_abs_t = wasm_ops::f32_abs <f32_unop_injector<wasm_ops::f32_abs_code>>;
517 using f32_neg_t = wasm_ops::f32_neg <f32_unop_injector<wasm_ops::f32_neg_code>>;
518 using f32_sqrt_t = wasm_ops::f32_sqrt <f32_unop_injector<wasm_ops::f32_sqrt_code>>;
519 using f32_floor_t = wasm_ops::f32_floor <f32_unop_injector<wasm_ops::f32_floor_code>>;
520 using f32_ceil_t = wasm_ops::f32_ceil <f32_unop_injector<wasm_ops::f32_ceil_code>>;
521 using f32_trunc_t = wasm_ops::f32_trunc <f32_unop_injector<wasm_ops::f32_trunc_code>>;
522 using f32_nearest_t = wasm_ops::f32_nearest <f32_unop_injector<wasm_ops::f32_nearest_code>>;
523 // float relops
524 using f32_eq_t = wasm_ops::f32_eq <f32_relop_injector<wasm_ops::f32_eq_code>>;
525 using f32_ne_t = wasm_ops::f32_ne <f32_relop_injector<wasm_ops::f32_ne_code>>;
526 using f32_lt_t = wasm_ops::f32_lt <f32_relop_injector<wasm_ops::f32_lt_code>>;
527 using f32_le_t = wasm_ops::f32_le <f32_relop_injector<wasm_ops::f32_le_code>>;
528 using f32_gt_t = wasm_ops::f32_gt <f32_relop_injector<wasm_ops::f32_gt_code>>;
529 using f32_ge_t = wasm_ops::f32_ge <f32_relop_injector<wasm_ops::f32_ge_code>>;
530
531 // float binops
532 using f64_add_t = wasm_ops::f64_add <f64_binop_injector<wasm_ops::f64_add_code>>;
533 using f64_sub_t = wasm_ops::f64_sub <f64_binop_injector<wasm_ops::f64_sub_code>>;
534 using f64_div_t = wasm_ops::f64_div <f64_binop_injector<wasm_ops::f64_div_code>>;
535 using f64_mul_t = wasm_ops::f64_mul <f64_binop_injector<wasm_ops::f64_mul_code>>;
536 using f64_min_t = wasm_ops::f64_min <f64_binop_injector<wasm_ops::f64_min_code>>;
537 using f64_max_t = wasm_ops::f64_max <f64_binop_injector<wasm_ops::f64_max_code>>;
538 using f64_copysign_t = wasm_ops::f64_copysign <f64_binop_injector<wasm_ops::f64_copysign_code>>;
539 // float unops
540 using f64_abs_t = wasm_ops::f64_abs <f64_unop_injector<wasm_ops::f64_abs_code>>;
541 using f64_neg_t = wasm_ops::f64_neg <f64_unop_injector<wasm_ops::f64_neg_code>>;
542 using f64_sqrt_t = wasm_ops::f64_sqrt <f64_unop_injector<wasm_ops::f64_sqrt_code>>;
543 using f64_floor_t = wasm_ops::f64_floor <f64_unop_injector<wasm_ops::f64_floor_code>>;
544 using f64_ceil_t = wasm_ops::f64_ceil <f64_unop_injector<wasm_ops::f64_ceil_code>>;
545 using f64_trunc_t = wasm_ops::f64_trunc <f64_unop_injector<wasm_ops::f64_trunc_code>>;
546 using f64_nearest_t = wasm_ops::f64_nearest <f64_unop_injector<wasm_ops::f64_nearest_code>>;
547 // float relops
548 using f64_eq_t = wasm_ops::f64_eq <f64_relop_injector<wasm_ops::f64_eq_code>>;
549 using f64_ne_t = wasm_ops::f64_ne <f64_relop_injector<wasm_ops::f64_ne_code>>;
550 using f64_lt_t = wasm_ops::f64_lt <f64_relop_injector<wasm_ops::f64_lt_code>>;
551 using f64_le_t = wasm_ops::f64_le <f64_relop_injector<wasm_ops::f64_le_code>>;
552 using f64_gt_t = wasm_ops::f64_gt <f64_relop_injector<wasm_ops::f64_gt_code>>;
553 using f64_ge_t = wasm_ops::f64_ge <f64_relop_injector<wasm_ops::f64_ge_code>>;
554
555
556 using f64_promote_f32_t = wasm_ops::f64_promote_f32 <f32_promote_injector>;
557 using f32_demote_f64_t = wasm_ops::f32_demote_f64 <f64_demote_injector>;
558
559
560 using i32_trunc_s_f32_t = wasm_ops::i32_trunc_s_f32 <f32_trunc_i32_injector<wasm_ops::i32_trunc_s_f32_code>>;
561 using i32_trunc_u_f32_t = wasm_ops::i32_trunc_u_f32 <f32_trunc_i32_injector<wasm_ops::i32_trunc_u_f32_code>>;
562 using i32_trunc_s_f64_t = wasm_ops::i32_trunc_s_f64 <f64_trunc_i32_injector<wasm_ops::i32_trunc_s_f64_code>>;
563 using i32_trunc_u_f64_t = wasm_ops::i32_trunc_u_f64 <f64_trunc_i32_injector<wasm_ops::i32_trunc_u_f64_code>>;
564 using i64_trunc_s_f32_t = wasm_ops::i64_trunc_s_f32 <f32_trunc_i64_injector<wasm_ops::i64_trunc_s_f32_code>>;
565 using i64_trunc_u_f32_t = wasm_ops::i64_trunc_u_f32 <f32_trunc_i64_injector<wasm_ops::i64_trunc_u_f32_code>>;
566 using i64_trunc_s_f64_t = wasm_ops::i64_trunc_s_f64 <f64_trunc_i64_injector<wasm_ops::i64_trunc_s_f64_code>>;
567 using i64_trunc_u_f64_t = wasm_ops::i64_trunc_u_f64 <f64_trunc_i64_injector<wasm_ops::i64_trunc_u_f64_code>>;
568
569 using f32_convert_s_i32 = wasm_ops::f32_convert_s_i32 <i32_convert_f32_injector<wasm_ops::f32_convert_s_i32_code>>;
570 using f32_convert_s_i64 = wasm_ops::f32_convert_s_i64 <i64_convert_f32_injector<wasm_ops::f32_convert_s_i64_code>>;
571 using f32_convert_u_i32 = wasm_ops::f32_convert_u_i32 <i32_convert_f32_injector<wasm_ops::f32_convert_u_i32_code>>;
572 using f32_convert_u_i64 = wasm_ops::f32_convert_u_i64 <i64_convert_f32_injector<wasm_ops::f32_convert_u_i64_code>>;
573 using f64_convert_s_i32 = wasm_ops::f64_convert_s_i32 <i32_convert_f64_injector<wasm_ops::f64_convert_s_i32_code>>;
574 using f64_convert_s_i64 = wasm_ops::f64_convert_s_i64 <i64_convert_f64_injector<wasm_ops::f64_convert_s_i64_code>>;
575 using f64_convert_u_i32 = wasm_ops::f64_convert_u_i32 <i32_convert_f64_injector<wasm_ops::f64_convert_u_i32_code>>;
576 using f64_convert_u_i64 = wasm_ops::f64_convert_u_i64 <i64_convert_f64_injector<wasm_ops::f64_convert_u_i64_code>>;
577 }; // pre_op_injectors
578
579 struct post_op_injectors : wasm_ops::op_types<pass_injector> {
580 using call_t = wasm_ops::call <fix_call_index>;
581 };
582
583 template <typename ... Visitors>
585 static void inject( IR::Module& m ) {
586 for ( auto injector : { Visitors::inject... } ) {
587 injector( m );
588 }
589 }
590 static void init() {
591 // place initial values for static fields of injectors here
592 for ( auto initializer : { Visitors::initializer... } ) {
593 initializer();
594 }
595 }
596 };
597
599 public:
600 wasm_binary_injection( IR::Module& mod ) : _module( &mod ) {
601 // initialize static fields of injectors
603 }
604
605 void inject() {
606
607 for ( auto& fd : _module->functions.defs ) {
609 wasm_ops::instruction_stream pre_code(fd.code.size()*2);
610
611 while ( pre_decoder ) {
612 auto op = pre_decoder.decodeOp();
613 if (op->is_post()) {
614 op->pack(&pre_code);
615 op->visit( { _module, &pre_code, &fd, pre_decoder.index() } );
616 }
617 else {
618 op->visit( { _module, &pre_code, &fd, pre_decoder.index() } );
619 if (!(op->is_kill()))
620 op->pack(&pre_code);
621 }
622 }
623 fd.code = pre_code.get();
624 }
625 for ( auto& fd : _module->functions.defs ) {
627 wasm_ops::instruction_stream post_code(fd.code.size()*2);
628
629 while ( post_decoder ) {
630 auto op = post_decoder.decodeOp();
631 if (op->is_post()) {
632 op->pack(&post_code);
633 op->visit( { _module, &post_code, &fd, post_decoder.index() } );
634 }
635 else {
636 op->visit( { _module, &post_code, &fd, post_decoder.index() } );
637 if (!(op->is_kill()))
638 op->pack(&post_code);
639 }
640 }
641 fd.code = post_code.get();
642 }
643 }
644 private:
645 IR::Module* _module;
646 };
647
648}}} // namespace wasm_constraints, chain, sysio
Defines exception's used by fc.
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Opcode
Definition Operators.h:576
ValueType
Definition Types.h:14
ResultType
Definition Types.h:134
constexpr const char * inject_which_op(uint16_t opcode)
std::function< void(IR::Module &)> wasm_validate_func
unsigned short uint16_t
Definition stdint.h:125
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
#define UINTPTR_MAX
Definition stdint.h:227
static IR_API const FunctionType * get(ResultType ret, const std::initializer_list< ValueType > &parameters)
Definition Types.cpp:38
IndexSpace< FunctionDef, IndexedFunctionType > functions
Definition Module.h:133
std::vector< const FunctionType * > types
Definition Module.h:131
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
static void add_import(Module &module, const char *func_name, int32_t &index)
static std::map< std::vector< uint16_t >, uint32_t > type_slots
static void get_next_indices(Module &module, int &next_function_index, int &next_actual_index)
static std::map< uint32_t, uint32_t > injected_index_mapping
static std::map< std::string, uint32_t > registered_injected
static void accept(wasm_ops::instr *inst, wasm_ops::visitor_arg &arg)
wasm_ops::f32_le< f32_relop_injector< wasm_ops::f32_le_code > > f32_le_t
wasm_ops::f32_nearest< f32_unop_injector< wasm_ops::f32_nearest_code > > f32_nearest_t
wasm_ops::f32_max< f32_binop_injector< wasm_ops::f32_max_code > > f32_max_t
wasm_ops::f32_abs< f32_unop_injector< wasm_ops::f32_abs_code > > f32_abs_t
wasm_ops::f32_neg< f32_unop_injector< wasm_ops::f32_neg_code > > f32_neg_t
wasm_ops::f64_convert_s_i64< i64_convert_f64_injector< wasm_ops::f64_convert_s_i64_code > > f64_convert_s_i64
wasm_ops::f64_le< f64_relop_injector< wasm_ops::f64_le_code > > f64_le_t
wasm_ops::f32_div< f32_binop_injector< wasm_ops::f32_div_code > > f32_div_t
wasm_ops::f32_sqrt< f32_unop_injector< wasm_ops::f32_sqrt_code > > f32_sqrt_t
wasm_ops::f32_copysign< f32_binop_injector< wasm_ops::f32_copysign_code > > f32_copysign_t
wasm_ops::f32_ge< f32_relop_injector< wasm_ops::f32_ge_code > > f32_ge_t
wasm_ops::i32_trunc_s_f64< f64_trunc_i32_injector< wasm_ops::i32_trunc_s_f64_code > > i32_trunc_s_f64_t
wasm_ops::f32_convert_s_i32< i32_convert_f32_injector< wasm_ops::f32_convert_s_i32_code > > f32_convert_s_i32
wasm_ops::i64_trunc_u_f32< f32_trunc_i64_injector< wasm_ops::i64_trunc_u_f32_code > > i64_trunc_u_f32_t
wasm_ops::i32_trunc_u_f64< f64_trunc_i32_injector< wasm_ops::i32_trunc_u_f64_code > > i32_trunc_u_f64_t
wasm_ops::f64_ne< f64_relop_injector< wasm_ops::f64_ne_code > > f64_ne_t
wasm_ops::f64_mul< f64_binop_injector< wasm_ops::f64_mul_code > > f64_mul_t
wasm_ops::f64_trunc< f64_unop_injector< wasm_ops::f64_trunc_code > > f64_trunc_t
wasm_ops::f32_floor< f32_unop_injector< wasm_ops::f32_floor_code > > f32_floor_t
wasm_ops::f64_neg< f64_unop_injector< wasm_ops::f64_neg_code > > f64_neg_t
wasm_ops::i32_trunc_s_f32< f32_trunc_i32_injector< wasm_ops::i32_trunc_s_f32_code > > i32_trunc_s_f32_t
wasm_ops::f32_trunc< f32_unop_injector< wasm_ops::f32_trunc_code > > f32_trunc_t
wasm_ops::f32_convert_s_i64< i64_convert_f32_injector< wasm_ops::f32_convert_s_i64_code > > f32_convert_s_i64
wasm_ops::f64_sub< f64_binop_injector< wasm_ops::f64_sub_code > > f64_sub_t
wasm_ops::f64_div< f64_binop_injector< wasm_ops::f64_div_code > > f64_div_t
wasm_ops::f32_mul< f32_binop_injector< wasm_ops::f32_mul_code > > f32_mul_t
wasm_ops::f64_ge< f64_relop_injector< wasm_ops::f64_ge_code > > f64_ge_t
wasm_ops::f64_convert_s_i32< i32_convert_f64_injector< wasm_ops::f64_convert_s_i32_code > > f64_convert_s_i32
wasm_ops::f64_nearest< f64_unop_injector< wasm_ops::f64_nearest_code > > f64_nearest_t
wasm_ops::f64_copysign< f64_binop_injector< wasm_ops::f64_copysign_code > > f64_copysign_t
wasm_ops::f32_ceil< f32_unop_injector< wasm_ops::f32_ceil_code > > f32_ceil_t
wasm_ops::f32_lt< f32_relop_injector< wasm_ops::f32_lt_code > > f32_lt_t
wasm_ops::f64_min< f64_binop_injector< wasm_ops::f64_min_code > > f64_min_t
wasm_ops::i64_trunc_u_f64< f64_trunc_i64_injector< wasm_ops::i64_trunc_u_f64_code > > i64_trunc_u_f64_t
wasm_ops::f64_promote_f32< f32_promote_injector > f64_promote_f32_t
wasm_ops::f64_max< f64_binop_injector< wasm_ops::f64_max_code > > f64_max_t
wasm_ops::f32_min< f32_binop_injector< wasm_ops::f32_min_code > > f32_min_t
wasm_ops::f32_add< f32_binop_injector< wasm_ops::f32_add_code > > f32_add_t
wasm_ops::f64_add< f64_binop_injector< wasm_ops::f64_add_code > > f64_add_t
wasm_ops::f64_floor< f64_unop_injector< wasm_ops::f64_floor_code > > f64_floor_t
wasm_ops::f32_sub< f32_binop_injector< wasm_ops::f32_sub_code > > f32_sub_t
wasm_ops::f32_gt< f32_relop_injector< wasm_ops::f32_gt_code > > f32_gt_t
wasm_ops::i32_trunc_u_f32< f32_trunc_i32_injector< wasm_ops::i32_trunc_u_f32_code > > i32_trunc_u_f32_t
wasm_ops::f64_abs< f64_unop_injector< wasm_ops::f64_abs_code > > f64_abs_t
wasm_ops::f64_ceil< f64_unop_injector< wasm_ops::f64_ceil_code > > f64_ceil_t
wasm_ops::f64_convert_u_i64< i64_convert_f64_injector< wasm_ops::f64_convert_u_i64_code > > f64_convert_u_i64
wasm_ops::f32_convert_u_i32< i32_convert_f32_injector< wasm_ops::f32_convert_u_i32_code > > f32_convert_u_i32
wasm_ops::f32_eq< f32_relop_injector< wasm_ops::f32_eq_code > > f32_eq_t
wasm_ops::f64_gt< f64_relop_injector< wasm_ops::f64_gt_code > > f64_gt_t
wasm_ops::f64_lt< f64_relop_injector< wasm_ops::f64_lt_code > > f64_lt_t
wasm_ops::f64_convert_u_i32< i32_convert_f64_injector< wasm_ops::f64_convert_u_i32_code > > f64_convert_u_i32
wasm_ops::f32_convert_u_i64< i64_convert_f32_injector< wasm_ops::f32_convert_u_i64_code > > f32_convert_u_i64
wasm_ops::i64_trunc_s_f32< f32_trunc_i64_injector< wasm_ops::i64_trunc_s_f32_code > > i64_trunc_s_f32_t
wasm_ops::f32_demote_f64< f64_demote_injector > f32_demote_f64_t
wasm_ops::i64_trunc_s_f64< f64_trunc_i64_injector< wasm_ops::i64_trunc_s_f64_code > > i64_trunc_s_f64_t
wasm_ops::f64_sqrt< f64_unop_injector< wasm_ops::f64_sqrt_code > > f64_sqrt_t
wasm_ops::f64_eq< f64_relop_injector< wasm_ops::f64_eq_code > > f64_eq_t
wasm_ops::f32_ne< f32_relop_injector< wasm_ops::f32_ne_code > > f32_ne_t