@@ -23,6 +23,150 @@ handle_aot_recent_error(const char *tag)
2323 std::cout << tag << " " << error << std::endl;
2424}
2525
26+ static bool
27+ is_supported_val_kind (wasm_valkind_t kind)
28+ {
29+ return kind == WASM_I32 || kind == WASM_I64 || kind == WASM_F32
30+ || kind == WASM_F64 || kind == WASM_EXTERNREF
31+ || kind == WASM_FUNCREF ;
32+ }
33+
34+ static wasm_val_t
35+ pre_defined_val (wasm_valkind_t kind)
36+ {
37+ if (kind == WASM_I32 ) {
38+ return wasm_val_t { .kind = WASM_I32 , .of = { .i32 = 2025 } };
39+ }
40+ else if (kind == WASM_I64 ) {
41+ return wasm_val_t { .kind = WASM_I64 , .of = { .i64 = 168 } };
42+ }
43+ else if (kind == WASM_F32 ) {
44+ return wasm_val_t { .kind = WASM_F32 , .of = { .f32 = 3 .14159f } };
45+ }
46+ else if (kind == WASM_F64 ) {
47+ return wasm_val_t { .kind = WASM_F64 , .of = { .f64 = 2.71828 } };
48+ }
49+ else if (kind == WASM_EXTERNREF ) {
50+ return wasm_val_t { .kind = WASM_EXTERNREF ,
51+ .of = { .foreign = 0xabcddead } };
52+ }
53+ // because aft is_supported_val_kind() check, so we can safely return as
54+ // WASM_FUNCREF
55+ else {
56+ return wasm_val_t { .kind = WASM_FUNCREF , .of = { .ref = nullptr } };
57+ }
58+ }
59+ void
60+ print_execution_args (const wasm_export_t &export_type,
61+ const std::vector<wasm_val_t > &args, unsigned param_count)
62+ {
63+ std::cout << " [EXECUTION] " << export_type.name << " (" ;
64+ for (unsigned p_i = 0 ; p_i < param_count; p_i++) {
65+ if (p_i != 0 ) {
66+ std::cout << " , " ;
67+ }
68+
69+ switch (args[p_i].kind ) {
70+ case WASM_I32 :
71+ std::cout << " i32:" << args[p_i].of .i32 ;
72+ break ;
73+ case WASM_I64 :
74+ std::cout << " i64:" << args[p_i].of .i64 ;
75+ break ;
76+ case WASM_F32 :
77+ std::cout << " f32:" << args[p_i].of .f32 ;
78+ break ;
79+ case WASM_F64 :
80+ std::cout << " f64:" << args[p_i].of .f64 ;
81+ break ;
82+ case WASM_EXTERNREF :
83+ std::cout << " externref:" << args[p_i].of .foreign ;
84+ break ;
85+ default :
86+ // because aft is_supported_val_kind() check, so we can safely
87+ // return as WASM_FUNCREF
88+ std::cout << " funcref:" << args[p_i].of .ref ;
89+ break ;
90+ }
91+ }
92+ std::cout << " )" << std::endl;
93+ }
94+
95+ static bool
96+ execute_export_functions (wasm_module_t module , wasm_module_inst_t inst)
97+ {
98+ int32_t export_count = wasm_runtime_get_export_count (module );
99+
100+ for (int e_i = 0 ; e_i < export_count; e_i++) {
101+ wasm_export_t export_type = { 0 };
102+ wasm_runtime_get_export_type (module , e_i, &export_type);
103+
104+ if (export_type.kind != WASM_IMPORT_EXPORT_KIND_FUNC ) {
105+ continue ;
106+ }
107+
108+ wasm_function_inst_t func =
109+ wasm_runtime_lookup_function (inst, export_type.name );
110+ if (!func) {
111+ std::cout << " Failed to lookup function: " << export_type.name
112+ << std::endl;
113+ continue ;
114+ }
115+
116+ wasm_func_type_t func_type = export_type.u .func_type ;
117+ uint32_t param_count = wasm_func_type_get_param_count (func_type);
118+
119+ /* build arguments */
120+ std::vector<wasm_val_t > args;
121+ for (unsigned p_i = 0 ; p_i < param_count; p_i++) {
122+ wasm_valkind_t param_type =
123+ wasm_func_type_get_param_valkind (func_type, p_i);
124+
125+ if (!is_supported_val_kind (param_type)) {
126+ std::cout
127+ << " Bypass execution because of unsupported value kind: "
128+ << param_type << std::endl;
129+ return true ;
130+ }
131+
132+ wasm_val_t arg = pre_defined_val (param_type);
133+ args.push_back (arg);
134+ }
135+
136+ /* build results storage */
137+ uint32_t result_count = wasm_func_type_get_result_count (func_type);
138+ std::vector<wasm_val_t > results = std::vector<wasm_val_t >(result_count);
139+
140+ print_execution_args (export_type, args, param_count);
141+
142+ /* execute the function */
143+ wasm_exec_env_t exec_env = wasm_runtime_get_exec_env_singleton (inst);
144+ if (!exec_env) {
145+ std::cout << " Failed to get exec env" << std::endl;
146+ return false ;
147+ }
148+
149+ bool ret =
150+ wasm_runtime_call_wasm_a (exec_env, func, result_count,
151+ results.data (), param_count, args.data ());
152+ if (!ret) {
153+ const char *exception = wasm_runtime_get_exception (inst);
154+ if (!exception) {
155+ std::cout << " [EXECUTION] " << export_type.name
156+ << " () failed. No exception info." << std::endl;
157+ }
158+ else {
159+ std::cout << " [EXECUTION] " << export_type.name << " () failed. "
160+ << exception << std::endl;
161+ }
162+ }
163+
164+ wasm_runtime_clear_exception (inst);
165+ }
166+
167+ return true ;
168+ }
169+
26170extern " C" int
27171LLVMFuzzerTestOneInput (const uint8_t *Data, size_t Size)
28172{
@@ -101,6 +245,8 @@ LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
101245 goto UNLOAD_AOT_MODULE ;
102246 }
103247
248+ execute_export_functions (module , inst);
249+
104250DEINSTANTIZE_AOT_MODULE :
105251 wasm_runtime_deinstantiate (inst);
106252UNLOAD_AOT_MODULE :
0 commit comments