wasm_native.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_native.h"
  6. #include "wasm_runtime_common.h"
  7. #include "bh_log.h"
  8. #if WASM_ENABLE_INTERP != 0
  9. #include "../interpreter/wasm_runtime.h"
  10. #endif
  11. #if WASM_ENABLE_AOT != 0
  12. #include "../aot/aot_runtime.h"
  13. #endif
  14. #if WASM_ENABLE_THREAD_MGR != 0
  15. #include "../libraries/thread-mgr/thread_manager.h"
  16. #endif
  17. static NativeSymbolsList g_native_symbols_list = NULL;
  18. #if WASM_ENABLE_LIBC_WASI != 0
  19. static void *g_wasi_context_key;
  20. #endif /* WASM_ENABLE_LIBC_WASI */
  21. uint32
  22. get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
  23. #if WASM_ENABLE_SPEC_TEST != 0
  24. uint32
  25. get_spectest_export_apis(NativeSymbol **p_libc_builtin_apis);
  26. #endif
  27. uint32
  28. get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis);
  29. uint32
  30. get_base_lib_export_apis(NativeSymbol **p_base_lib_apis);
  31. uint32
  32. get_ext_lib_export_apis(NativeSymbol **p_ext_lib_apis);
  33. #if WASM_ENABLE_LIB_PTHREAD != 0
  34. bool
  35. lib_pthread_init();
  36. void
  37. lib_pthread_destroy();
  38. uint32
  39. get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis);
  40. #endif
  41. #if WASM_ENABLE_LIB_WASI_THREADS != 0
  42. bool
  43. lib_wasi_threads_init(void);
  44. void
  45. lib_wasi_threads_destroy(void);
  46. uint32
  47. get_lib_wasi_threads_export_apis(NativeSymbol **p_lib_wasi_threads_apis);
  48. #endif
  49. uint32
  50. get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);
  51. uint32
  52. get_lib_rats_export_apis(NativeSymbol **p_lib_rats_apis);
  53. static bool
  54. compare_type_with_signature(uint8 type, const char signature)
  55. {
  56. const char num_sig_map[] = { 'F', 'f', 'I', 'i' };
  57. if (VALUE_TYPE_F64 <= type && type <= VALUE_TYPE_I32
  58. && signature == num_sig_map[type - VALUE_TYPE_F64]) {
  59. return true;
  60. }
  61. #if WASM_ENABLE_REF_TYPES != 0
  62. if ('r' == signature
  63. #if WASM_ENABLE_GC != 0
  64. #if WASM_ENABLE_STRINGREF != 0
  65. && (type >= REF_TYPE_STRINGVIEWITER && type <= REF_TYPE_NULLFUNCREF)
  66. #else
  67. && (type >= REF_TYPE_HT_NULLABLE && type <= REF_TYPE_NULLFUNCREF)
  68. #endif
  69. #else
  70. && type == VALUE_TYPE_EXTERNREF
  71. #endif
  72. )
  73. return true;
  74. #endif
  75. /* TODO: a v128 parameter */
  76. return false;
  77. }
  78. static bool
  79. check_symbol_signature(const WASMFuncType *type, const char *signature)
  80. {
  81. const char *p = signature, *p_end;
  82. char sig;
  83. uint32 i = 0;
  84. if (!p || strlen(p) < 2)
  85. return false;
  86. p_end = p + strlen(signature);
  87. if (*p++ != '(')
  88. return false;
  89. if ((uint32)(p_end - p) < (uint32)(type->param_count + 1))
  90. /* signatures of parameters, and ')' */
  91. return false;
  92. for (i = 0; i < type->param_count; i++) {
  93. sig = *p++;
  94. /* a f64/f32/i64/i32/externref parameter */
  95. if (compare_type_with_signature(type->types[i], sig))
  96. continue;
  97. /* a pointer/string parameter */
  98. if (type->types[i] != VALUE_TYPE_I32)
  99. /* pointer and string must be i32 type */
  100. return false;
  101. if (sig == '*') {
  102. /* it is a pointer */
  103. if (i + 1 < type->param_count
  104. && type->types[i + 1] == VALUE_TYPE_I32 && *p == '~') {
  105. /* pointer length followed */
  106. i++;
  107. p++;
  108. }
  109. }
  110. else if (sig == '$') {
  111. /* it is a string */
  112. }
  113. else {
  114. /* invalid signature */
  115. return false;
  116. }
  117. }
  118. if (*p++ != ')')
  119. return false;
  120. if (type->result_count) {
  121. if (p >= p_end)
  122. return false;
  123. /* result types includes: f64,f32,i64,i32,externref */
  124. if (!compare_type_with_signature(type->types[i], *p))
  125. return false;
  126. p++;
  127. }
  128. if (*p != '\0')
  129. return false;
  130. return true;
  131. }
  132. static int
  133. native_symbol_cmp(const void *native_symbol1, const void *native_symbol2)
  134. {
  135. return strcmp(((const NativeSymbol *)native_symbol1)->symbol,
  136. ((const NativeSymbol *)native_symbol2)->symbol);
  137. }
  138. static void *
  139. lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
  140. const char *symbol, const char **p_signature, void **p_attachment)
  141. {
  142. NativeSymbol *native_symbol, key = { 0 };
  143. key.symbol = symbol;
  144. if ((native_symbol = bsearch(&key, native_symbols, n_native_symbols,
  145. sizeof(NativeSymbol), native_symbol_cmp))) {
  146. *p_signature = native_symbol->signature;
  147. *p_attachment = native_symbol->attachment;
  148. return native_symbol->func_ptr;
  149. }
  150. return NULL;
  151. }
  152. /**
  153. * allow func_type and all outputs, like p_signature, p_attachment and
  154. * p_call_conv_raw to be NULL
  155. */
  156. void *
  157. wasm_native_resolve_symbol(const char *module_name, const char *field_name,
  158. const WASMFuncType *func_type,
  159. const char **p_signature, void **p_attachment,
  160. bool *p_call_conv_raw)
  161. {
  162. NativeSymbolsNode *node, *node_next;
  163. const char *signature = NULL;
  164. void *func_ptr = NULL, *attachment = NULL;
  165. node = g_native_symbols_list;
  166. while (node) {
  167. node_next = node->next;
  168. if (!strcmp(node->module_name, module_name)) {
  169. if ((func_ptr =
  170. lookup_symbol(node->native_symbols, node->n_native_symbols,
  171. field_name, &signature, &attachment))
  172. || (field_name[0] == '_'
  173. && (func_ptr = lookup_symbol(
  174. node->native_symbols, node->n_native_symbols,
  175. field_name + 1, &signature, &attachment))))
  176. break;
  177. }
  178. node = node_next;
  179. }
  180. if (!p_signature || !p_attachment || !p_call_conv_raw)
  181. return func_ptr;
  182. if (func_ptr) {
  183. if (signature && signature[0] != '\0') {
  184. /* signature is not empty, check its format */
  185. if (!func_type || !check_symbol_signature(func_type, signature)) {
  186. #if WASM_ENABLE_WAMR_COMPILER == 0
  187. /* Output warning except running aot compiler */
  188. LOG_WARNING("failed to check signature '%s' and resolve "
  189. "pointer params for import function (%s %s)\n",
  190. signature, module_name, field_name);
  191. #endif
  192. return NULL;
  193. }
  194. else
  195. /* Save signature for runtime to do pointer check and
  196. address conversion */
  197. *p_signature = signature;
  198. }
  199. else
  200. /* signature is empty */
  201. *p_signature = NULL;
  202. *p_attachment = attachment;
  203. *p_call_conv_raw = node->call_conv_raw;
  204. }
  205. return func_ptr;
  206. }
  207. static bool
  208. register_natives(const char *module_name, NativeSymbol *native_symbols,
  209. uint32 n_native_symbols, bool call_conv_raw)
  210. {
  211. NativeSymbolsNode *node;
  212. if (!(node = wasm_runtime_malloc(sizeof(NativeSymbolsNode))))
  213. return false;
  214. #if WASM_ENABLE_MEMORY_TRACING != 0
  215. os_printf("Register native, size: %u\n", sizeof(NativeSymbolsNode));
  216. #endif
  217. node->module_name = module_name;
  218. node->native_symbols = native_symbols;
  219. node->n_native_symbols = n_native_symbols;
  220. node->call_conv_raw = call_conv_raw;
  221. /* Add to list head */
  222. node->next = g_native_symbols_list;
  223. g_native_symbols_list = node;
  224. qsort(native_symbols, n_native_symbols, sizeof(NativeSymbol),
  225. native_symbol_cmp);
  226. return true;
  227. }
  228. bool
  229. wasm_native_register_natives(const char *module_name,
  230. NativeSymbol *native_symbols,
  231. uint32 n_native_symbols)
  232. {
  233. return register_natives(module_name, native_symbols, n_native_symbols,
  234. false);
  235. }
  236. bool
  237. wasm_native_register_natives_raw(const char *module_name,
  238. NativeSymbol *native_symbols,
  239. uint32 n_native_symbols)
  240. {
  241. return register_natives(module_name, native_symbols, n_native_symbols,
  242. true);
  243. }
  244. bool
  245. wasm_native_unregister_natives(const char *module_name,
  246. NativeSymbol *native_symbols)
  247. {
  248. NativeSymbolsNode **prevp;
  249. NativeSymbolsNode *node;
  250. prevp = &g_native_symbols_list;
  251. while ((node = *prevp) != NULL) {
  252. if (node->native_symbols == native_symbols
  253. && !strcmp(node->module_name, module_name)) {
  254. *prevp = node->next;
  255. wasm_runtime_free(node);
  256. return true;
  257. }
  258. prevp = &node->next;
  259. }
  260. return false;
  261. }
  262. #if WASM_ENABLE_MODULE_INST_CONTEXT != 0
  263. static uint32
  264. context_key_to_idx(void *key)
  265. {
  266. bh_assert(key != NULL);
  267. uint32 idx = (uint32)(uintptr_t)key;
  268. bh_assert(idx > 0);
  269. bh_assert(idx <= WASM_MAX_INSTANCE_CONTEXTS);
  270. return idx - 1;
  271. }
  272. static void *
  273. context_idx_to_key(uint32 idx)
  274. {
  275. bh_assert(idx < WASM_MAX_INSTANCE_CONTEXTS);
  276. return (void *)(uintptr_t)(idx + 1);
  277. }
  278. typedef void (*dtor_t)(WASMModuleInstanceCommon *, void *);
  279. static dtor_t g_context_dtors[WASM_MAX_INSTANCE_CONTEXTS];
  280. static void
  281. dtor_noop(WASMModuleInstanceCommon *inst, void *ctx)
  282. {}
  283. void *
  284. wasm_native_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
  285. void *ctx))
  286. {
  287. uint32 i;
  288. for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
  289. if (g_context_dtors[i] == NULL) {
  290. if (dtor == NULL) {
  291. dtor = dtor_noop;
  292. }
  293. g_context_dtors[i] = dtor;
  294. return context_idx_to_key(i);
  295. }
  296. }
  297. LOG_ERROR("failed to allocate instance context key");
  298. return NULL;
  299. }
  300. void
  301. wasm_native_destroy_context_key(void *key)
  302. {
  303. uint32 idx = context_key_to_idx(key);
  304. bh_assert(g_context_dtors[idx] != NULL);
  305. g_context_dtors[idx] = NULL;
  306. }
  307. static WASMModuleInstanceExtraCommon *
  308. wasm_module_inst_extra_common(WASMModuleInstanceCommon *inst)
  309. {
  310. #if WASM_ENABLE_INTERP != 0
  311. if (inst->module_type == Wasm_Module_Bytecode) {
  312. return &((WASMModuleInstance *)inst)->e->common;
  313. }
  314. #endif
  315. #if WASM_ENABLE_AOT != 0
  316. if (inst->module_type == Wasm_Module_AoT) {
  317. return &((AOTModuleInstanceExtra *)((AOTModuleInstance *)inst)->e)
  318. ->common;
  319. }
  320. #endif
  321. bh_assert(false);
  322. return NULL;
  323. }
  324. void
  325. wasm_native_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
  326. {
  327. uint32 idx = context_key_to_idx(key);
  328. WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
  329. common->contexts[idx] = ctx;
  330. }
  331. void
  332. wasm_native_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
  333. void *ctx)
  334. {
  335. #if WASM_ENABLE_THREAD_MGR != 0
  336. wasm_cluster_set_context(inst, key, ctx);
  337. #else
  338. wasm_native_set_context(inst, key, ctx);
  339. #endif
  340. }
  341. void *
  342. wasm_native_get_context(WASMModuleInstanceCommon *inst, void *key)
  343. {
  344. uint32 idx = context_key_to_idx(key);
  345. WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
  346. return common->contexts[idx];
  347. }
  348. void
  349. wasm_native_call_context_dtors(WASMModuleInstanceCommon *inst)
  350. {
  351. WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
  352. uint32 i;
  353. for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
  354. dtor_t dtor = g_context_dtors[i];
  355. if (dtor != NULL) {
  356. dtor(inst, common->contexts[i]);
  357. }
  358. }
  359. }
  360. void
  361. wasm_native_inherit_contexts(WASMModuleInstanceCommon *child,
  362. WASMModuleInstanceCommon *parent)
  363. {
  364. WASMModuleInstanceExtraCommon *parent_common =
  365. wasm_module_inst_extra_common(parent);
  366. WASMModuleInstanceExtraCommon *child_common =
  367. wasm_module_inst_extra_common(child);
  368. bh_memcpy_s(child_common->contexts,
  369. sizeof(*child_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS,
  370. parent_common->contexts,
  371. sizeof(*parent_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS);
  372. }
  373. #endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
  374. #if WASM_ENABLE_LIBC_WASI != 0
  375. WASIContext *
  376. wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
  377. {
  378. return wasm_native_get_context(module_inst_comm, g_wasi_context_key);
  379. }
  380. void
  381. wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
  382. WASIContext *wasi_ctx)
  383. {
  384. wasm_native_set_context(module_inst_comm, g_wasi_context_key, wasi_ctx);
  385. }
  386. static void
  387. wasi_context_dtor(WASMModuleInstanceCommon *inst, void *ctx)
  388. {
  389. if (ctx == NULL) {
  390. return;
  391. }
  392. wasm_runtime_destroy_wasi(inst);
  393. }
  394. #endif /* end of WASM_ENABLE_LIBC_WASI */
  395. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  396. static bool
  397. quick_aot_entry_init();
  398. #endif
  399. bool
  400. wasm_native_init()
  401. {
  402. #if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \
  403. || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \
  404. || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \
  405. || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \
  406. || WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
  407. NativeSymbol *native_symbols;
  408. uint32 n_native_symbols;
  409. #endif
  410. #if WASM_ENABLE_LIBC_BUILTIN != 0
  411. n_native_symbols = get_libc_builtin_export_apis(&native_symbols);
  412. if (!wasm_native_register_natives("env", native_symbols, n_native_symbols))
  413. goto fail;
  414. #endif /* WASM_ENABLE_LIBC_BUILTIN */
  415. #if WASM_ENABLE_SPEC_TEST
  416. n_native_symbols = get_spectest_export_apis(&native_symbols);
  417. if (!wasm_native_register_natives("spectest", native_symbols,
  418. n_native_symbols))
  419. goto fail;
  420. #endif /* WASM_ENABLE_SPEC_TEST */
  421. #if WASM_ENABLE_LIBC_WASI != 0
  422. g_wasi_context_key = wasm_native_create_context_key(wasi_context_dtor);
  423. if (g_wasi_context_key == NULL) {
  424. goto fail;
  425. }
  426. n_native_symbols = get_libc_wasi_export_apis(&native_symbols);
  427. if (!wasm_native_register_natives("wasi_unstable", native_symbols,
  428. n_native_symbols))
  429. goto fail;
  430. if (!wasm_native_register_natives("wasi_snapshot_preview1", native_symbols,
  431. n_native_symbols))
  432. goto fail;
  433. #endif
  434. #if WASM_ENABLE_BASE_LIB != 0
  435. n_native_symbols = get_base_lib_export_apis(&native_symbols);
  436. if (n_native_symbols > 0
  437. && !wasm_native_register_natives("env", native_symbols,
  438. n_native_symbols))
  439. goto fail;
  440. #endif
  441. #if WASM_ENABLE_APP_FRAMEWORK != 0
  442. n_native_symbols = get_ext_lib_export_apis(&native_symbols);
  443. if (n_native_symbols > 0
  444. && !wasm_native_register_natives("env", native_symbols,
  445. n_native_symbols))
  446. goto fail;
  447. #endif
  448. #if WASM_ENABLE_LIB_PTHREAD != 0
  449. if (!lib_pthread_init())
  450. goto fail;
  451. n_native_symbols = get_lib_pthread_export_apis(&native_symbols);
  452. if (n_native_symbols > 0
  453. && !wasm_native_register_natives("env", native_symbols,
  454. n_native_symbols))
  455. goto fail;
  456. #endif
  457. #if WASM_ENABLE_LIB_WASI_THREADS != 0
  458. if (!lib_wasi_threads_init())
  459. goto fail;
  460. n_native_symbols = get_lib_wasi_threads_export_apis(&native_symbols);
  461. if (n_native_symbols > 0
  462. && !wasm_native_register_natives("wasi", native_symbols,
  463. n_native_symbols))
  464. goto fail;
  465. #endif
  466. #if WASM_ENABLE_LIBC_EMCC != 0
  467. n_native_symbols = get_libc_emcc_export_apis(&native_symbols);
  468. if (n_native_symbols > 0
  469. && !wasm_native_register_natives("env", native_symbols,
  470. n_native_symbols))
  471. goto fail;
  472. #endif /* WASM_ENABLE_LIBC_EMCC */
  473. #if WASM_ENABLE_LIB_RATS != 0
  474. n_native_symbols = get_lib_rats_export_apis(&native_symbols);
  475. if (n_native_symbols > 0
  476. && !wasm_native_register_natives("env", native_symbols,
  477. n_native_symbols))
  478. goto fail;
  479. #endif /* WASM_ENABLE_LIB_RATS */
  480. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  481. if (!quick_aot_entry_init()) {
  482. #if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \
  483. || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \
  484. || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \
  485. || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \
  486. || WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
  487. goto fail;
  488. #else
  489. return false;
  490. #endif
  491. }
  492. #endif
  493. return true;
  494. #if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_LIBC_BUILTIN != 0 \
  495. || WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \
  496. || WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \
  497. || WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \
  498. || WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
  499. fail:
  500. wasm_native_destroy();
  501. return false;
  502. #endif
  503. }
  504. void
  505. wasm_native_destroy()
  506. {
  507. NativeSymbolsNode *node, *node_next;
  508. #if WASM_ENABLE_LIBC_WASI != 0
  509. if (g_wasi_context_key != NULL) {
  510. wasm_native_destroy_context_key(g_wasi_context_key);
  511. g_wasi_context_key = NULL;
  512. }
  513. #endif
  514. #if WASM_ENABLE_LIB_PTHREAD != 0
  515. lib_pthread_destroy();
  516. #endif
  517. #if WASM_ENABLE_LIB_WASI_THREADS != 0
  518. lib_wasi_threads_destroy();
  519. #endif
  520. node = g_native_symbols_list;
  521. while (node) {
  522. node_next = node->next;
  523. wasm_runtime_free(node);
  524. node = node_next;
  525. }
  526. g_native_symbols_list = NULL;
  527. }
  528. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  529. static void
  530. invoke_no_args_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  531. {
  532. void (*native_code)(WASMExecEnv *) = func_ptr;
  533. native_code(exec_env);
  534. }
  535. static void
  536. invoke_no_args_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  537. {
  538. int32 (*native_code)(WASMExecEnv *) = func_ptr;
  539. argv_ret[0] = native_code(exec_env);
  540. }
  541. static void
  542. invoke_no_args_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  543. {
  544. int64 (*native_code)(WASMExecEnv *) = func_ptr;
  545. int64 ret = native_code(exec_env);
  546. PUT_I64_TO_ADDR(argv_ret, ret);
  547. }
  548. static void
  549. invoke_i_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  550. {
  551. void (*native_code)(WASMExecEnv *, int32) = func_ptr;
  552. native_code(exec_env, argv[0]);
  553. }
  554. static void
  555. invoke_i_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  556. {
  557. int32 (*native_code)(WASMExecEnv *, int32) = func_ptr;
  558. argv_ret[0] = native_code(exec_env, argv[0]);
  559. }
  560. static void
  561. invoke_i_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  562. {
  563. int64 (*native_code)(WASMExecEnv *, int32) = func_ptr;
  564. int64 ret = native_code(exec_env, argv[0]);
  565. PUT_I64_TO_ADDR(argv_ret, ret);
  566. }
  567. static void
  568. invoke_I_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  569. {
  570. void (*native_code)(WASMExecEnv *, int64) = func_ptr;
  571. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv));
  572. }
  573. static void
  574. invoke_I_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  575. {
  576. int32 (*native_code)(WASMExecEnv *, int64) = func_ptr;
  577. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv));
  578. }
  579. static void
  580. invoke_I_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  581. {
  582. int64 (*native_code)(WASMExecEnv *, int64) = func_ptr;
  583. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv));
  584. PUT_I64_TO_ADDR(argv_ret, ret);
  585. }
  586. static void
  587. invoke_ii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  588. {
  589. void (*native_code)(WASMExecEnv *, int32, int32) = func_ptr;
  590. native_code(exec_env, argv[0], argv[1]);
  591. }
  592. static void
  593. invoke_ii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  594. {
  595. int32 (*native_code)(WASMExecEnv *, int32, int32) = func_ptr;
  596. argv_ret[0] = native_code(exec_env, argv[0], argv[1]);
  597. }
  598. static void
  599. invoke_ii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  600. {
  601. int64 (*native_code)(WASMExecEnv *, int32, int32) = func_ptr;
  602. int64 ret = native_code(exec_env, argv[0], argv[1]);
  603. PUT_I64_TO_ADDR(argv_ret, ret);
  604. }
  605. static void
  606. invoke_iI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  607. {
  608. void (*native_code)(WASMExecEnv *, int32, int64) = func_ptr;
  609. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1));
  610. }
  611. static void
  612. invoke_iI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  613. {
  614. int32 (*native_code)(WASMExecEnv *, int32, int64) = func_ptr;
  615. argv_ret[0] =
  616. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1));
  617. }
  618. static void
  619. invoke_iI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  620. {
  621. int64 (*native_code)(WASMExecEnv *, int32, int64) = func_ptr;
  622. int64 ret =
  623. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1));
  624. PUT_I64_TO_ADDR(argv_ret, ret);
  625. }
  626. static void
  627. invoke_Ii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  628. {
  629. void (*native_code)(WASMExecEnv *, int64, int32) = func_ptr;
  630. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2]);
  631. }
  632. static void
  633. invoke_Ii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  634. {
  635. int32 (*native_code)(WASMExecEnv *, int64, int32) = func_ptr;
  636. argv_ret[0] =
  637. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2]);
  638. }
  639. static void
  640. invoke_Ii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  641. {
  642. int64 (*native_code)(WASMExecEnv *, int64, int32) = func_ptr;
  643. int64 ret =
  644. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2]);
  645. PUT_I64_TO_ADDR(argv_ret, ret);
  646. }
  647. static void
  648. invoke_II_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  649. {
  650. void (*native_code)(WASMExecEnv *, int64, int64) = func_ptr;
  651. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  652. GET_I64_FROM_ADDR((uint32 *)argv + 2));
  653. }
  654. static void
  655. invoke_II_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  656. {
  657. int32 (*native_code)(WASMExecEnv *, int64, int64) = func_ptr;
  658. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  659. GET_I64_FROM_ADDR((uint32 *)argv + 2));
  660. }
  661. static void
  662. invoke_II_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  663. {
  664. int64 (*native_code)(WASMExecEnv *, int64, int64) = func_ptr;
  665. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  666. GET_I64_FROM_ADDR((uint32 *)argv + 2));
  667. PUT_I64_TO_ADDR(argv_ret, ret);
  668. }
  669. static void
  670. invoke_iii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  671. {
  672. void (*native_code)(WASMExecEnv *, int32, int32, int32) = func_ptr;
  673. native_code(exec_env, argv[0], argv[1], argv[2]);
  674. }
  675. static void
  676. invoke_iii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  677. {
  678. int32 (*native_code)(WASMExecEnv *, int32, int32, int32) = func_ptr;
  679. argv_ret[0] = native_code(exec_env, argv[0], argv[1], argv[2]);
  680. }
  681. static void
  682. invoke_iii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  683. {
  684. int64 (*native_code)(WASMExecEnv *, int32, int32, int32) = func_ptr;
  685. int64 ret = native_code(exec_env, argv[0], argv[1], argv[2]);
  686. PUT_I64_TO_ADDR(argv_ret, ret);
  687. }
  688. static void
  689. invoke_iiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  690. {
  691. void (*native_code)(WASMExecEnv *, int32, int32, int64) = func_ptr;
  692. native_code(exec_env, argv[0], argv[1],
  693. GET_I64_FROM_ADDR((uint32 *)argv + 2));
  694. }
  695. static void
  696. invoke_iiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  697. {
  698. int32 (*native_code)(WASMExecEnv *, int32, int32, int64) = func_ptr;
  699. argv_ret[0] = native_code(exec_env, argv[0], argv[1],
  700. GET_I64_FROM_ADDR((uint32 *)argv + 2));
  701. }
  702. static void
  703. invoke_iiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  704. {
  705. int64 (*native_code)(WASMExecEnv *, int32, int32, int64) = func_ptr;
  706. int64 ret = native_code(exec_env, argv[0], argv[1],
  707. GET_I64_FROM_ADDR((uint32 *)argv + 2));
  708. PUT_I64_TO_ADDR(argv_ret, ret);
  709. }
  710. static void
  711. invoke_iIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  712. {
  713. void (*native_code)(WASMExecEnv *, int32, int64, int32) = func_ptr;
  714. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  715. argv[3]);
  716. }
  717. static void
  718. invoke_iIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  719. {
  720. int32 (*native_code)(WASMExecEnv *, int32, int64, int32) = func_ptr;
  721. argv_ret[0] = native_code(exec_env, argv[0],
  722. GET_I64_FROM_ADDR((uint32 *)argv + 1), argv[3]);
  723. }
  724. static void
  725. invoke_iIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  726. {
  727. int64 (*native_code)(WASMExecEnv *, int32, int64, int32) = func_ptr;
  728. int64 ret = native_code(exec_env, argv[0],
  729. GET_I64_FROM_ADDR((uint32 *)argv + 1), argv[3]);
  730. PUT_I64_TO_ADDR(argv_ret, ret);
  731. }
  732. static void
  733. invoke_iII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  734. {
  735. void (*native_code)(WASMExecEnv *, int32, int64, int64) = func_ptr;
  736. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  737. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  738. }
  739. static void
  740. invoke_iII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  741. {
  742. int32 (*native_code)(WASMExecEnv *, int32, int64, int64) = func_ptr;
  743. argv_ret[0] =
  744. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  745. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  746. }
  747. static void
  748. invoke_iII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  749. {
  750. int64 (*native_code)(WASMExecEnv *, int32, int64, int64) = func_ptr;
  751. int64 ret =
  752. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  753. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  754. PUT_I64_TO_ADDR(argv_ret, ret);
  755. }
  756. static void
  757. invoke_Iii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  758. {
  759. void (*native_code)(WASMExecEnv *, int64, int32, int32) = func_ptr;
  760. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2], argv[3]);
  761. }
  762. static void
  763. invoke_Iii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  764. {
  765. int32 (*native_code)(WASMExecEnv *, int64, int32, int32) = func_ptr;
  766. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  767. argv[2], argv[3]);
  768. }
  769. static void
  770. invoke_Iii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  771. {
  772. int64 (*native_code)(WASMExecEnv *, int64, int32, int32) = func_ptr;
  773. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  774. argv[2], argv[3]);
  775. PUT_I64_TO_ADDR(argv_ret, ret);
  776. }
  777. static void
  778. invoke_IiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  779. {
  780. void (*native_code)(WASMExecEnv *, int64, int32, int64) = func_ptr;
  781. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  782. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  783. }
  784. static void
  785. invoke_IiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  786. {
  787. int32 (*native_code)(WASMExecEnv *, int64, int32, int64) = func_ptr;
  788. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  789. argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3));
  790. }
  791. static void
  792. invoke_IiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  793. {
  794. int64 (*native_code)(WASMExecEnv *, int64, int32, int64) = func_ptr;
  795. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  796. argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3));
  797. PUT_I64_TO_ADDR(argv_ret, ret);
  798. }
  799. static void
  800. invoke_IIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  801. {
  802. void (*native_code)(WASMExecEnv *, int64, int64, int32) = func_ptr;
  803. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  804. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
  805. }
  806. static void
  807. invoke_IIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  808. {
  809. int32 (*native_code)(WASMExecEnv *, int64, int64, int32) = func_ptr;
  810. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  811. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
  812. }
  813. static void
  814. invoke_IIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  815. {
  816. int64 (*native_code)(WASMExecEnv *, int64, int64, int32) = func_ptr;
  817. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  818. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
  819. PUT_I64_TO_ADDR(argv_ret, ret);
  820. }
  821. static void
  822. invoke_III_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  823. {
  824. void (*native_code)(WASMExecEnv *, int64, int64, int64) = func_ptr;
  825. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  826. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  827. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  828. }
  829. static void
  830. invoke_III_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  831. {
  832. int32 (*native_code)(WASMExecEnv *, int64, int64, int64) = func_ptr;
  833. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  834. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  835. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  836. }
  837. static void
  838. invoke_III_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  839. {
  840. int64 (*native_code)(WASMExecEnv *, int64, int64, int64) = func_ptr;
  841. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  842. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  843. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  844. PUT_I64_TO_ADDR(argv_ret, ret);
  845. }
  846. static void
  847. invoke_iiii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  848. {
  849. void (*native_code)(WASMExecEnv *, int32, int32, int32, int32) = func_ptr;
  850. native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
  851. }
  852. static void
  853. invoke_iiii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  854. {
  855. int32 (*native_code)(WASMExecEnv *, int32, int32, int32, int32) = func_ptr;
  856. argv_ret[0] = native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
  857. }
  858. static void
  859. invoke_iiii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  860. {
  861. int64 (*native_code)(WASMExecEnv *, int32, int32, int32, int32) = func_ptr;
  862. int64 ret = native_code(exec_env, argv[0], argv[1], argv[2], argv[3]);
  863. PUT_I64_TO_ADDR(argv_ret, ret);
  864. }
  865. static void
  866. invoke_iiiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  867. {
  868. void (*native_code)(WASMExecEnv *, int32, int32, int32, int64) = func_ptr;
  869. native_code(exec_env, argv[0], argv[1], argv[2],
  870. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  871. }
  872. static void
  873. invoke_iiiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  874. {
  875. int32 (*native_code)(WASMExecEnv *, int32, int32, int32, int64) = func_ptr;
  876. argv_ret[0] = native_code(exec_env, argv[0], argv[1], argv[2],
  877. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  878. }
  879. static void
  880. invoke_iiiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  881. {
  882. int64 (*native_code)(WASMExecEnv *, int32, int32, int32, int64) = func_ptr;
  883. int64 ret = native_code(exec_env, argv[0], argv[1], argv[2],
  884. GET_I64_FROM_ADDR((uint32 *)argv + 3));
  885. PUT_I64_TO_ADDR(argv_ret, ret);
  886. }
  887. static void
  888. invoke_iiIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  889. {
  890. void (*native_code)(WASMExecEnv *, int32, int32, int64, int32) = func_ptr;
  891. native_code(exec_env, argv[0], argv[1],
  892. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
  893. }
  894. static void
  895. invoke_iiIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  896. {
  897. int32 (*native_code)(WASMExecEnv *, int32, int32, int64, int32) = func_ptr;
  898. argv_ret[0] = native_code(exec_env, argv[0], argv[1],
  899. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
  900. }
  901. static void
  902. invoke_iiIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  903. {
  904. int64 (*native_code)(WASMExecEnv *, int32, int32, int64, int32) = func_ptr;
  905. int64 ret = native_code(exec_env, argv[0], argv[1],
  906. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4]);
  907. PUT_I64_TO_ADDR(argv_ret, ret);
  908. }
  909. static void
  910. invoke_iiII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  911. {
  912. void (*native_code)(WASMExecEnv *, int32, int32, int64, int64) = func_ptr;
  913. native_code(exec_env, argv[0], argv[1],
  914. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  915. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  916. }
  917. static void
  918. invoke_iiII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  919. {
  920. int32 (*native_code)(WASMExecEnv *, int32, int32, int64, int64) = func_ptr;
  921. argv_ret[0] = native_code(exec_env, argv[0], argv[1],
  922. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  923. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  924. }
  925. static void
  926. invoke_iiII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  927. {
  928. int64 (*native_code)(WASMExecEnv *, int32, int32, int64, int64) = func_ptr;
  929. int64 ret = native_code(exec_env, argv[0], argv[1],
  930. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  931. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  932. PUT_I64_TO_ADDR(argv_ret, ret);
  933. }
  934. static void
  935. invoke_iIii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  936. {
  937. void (*native_code)(WASMExecEnv *, int32, int64, int32, int32) = func_ptr;
  938. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  939. argv[3], argv[4]);
  940. }
  941. static void
  942. invoke_iIii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  943. {
  944. int32 (*native_code)(WASMExecEnv *, int32, int64, int32, int32) = func_ptr;
  945. argv_ret[0] =
  946. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  947. argv[3], argv[4]);
  948. }
  949. static void
  950. invoke_iIii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  951. {
  952. int64 (*native_code)(WASMExecEnv *, int32, int64, int32, int32) = func_ptr;
  953. int64 ret =
  954. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  955. argv[3], argv[4]);
  956. PUT_I64_TO_ADDR(argv_ret, ret);
  957. }
  958. static void
  959. invoke_iIiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  960. {
  961. void (*native_code)(WASMExecEnv *, int32, int64, int32, int64) = func_ptr;
  962. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  963. argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
  964. }
  965. static void
  966. invoke_iIiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  967. {
  968. int32 (*native_code)(WASMExecEnv *, int32, int64, int32, int64) = func_ptr;
  969. argv_ret[0] =
  970. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  971. argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
  972. }
  973. static void
  974. invoke_iIiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  975. {
  976. int64 (*native_code)(WASMExecEnv *, int32, int64, int32, int64) = func_ptr;
  977. int64 ret =
  978. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  979. argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
  980. PUT_I64_TO_ADDR(argv_ret, ret);
  981. }
  982. static void
  983. invoke_iIIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  984. {
  985. void (*native_code)(WASMExecEnv *, int32, int64, int64, int32) = func_ptr;
  986. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  987. GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
  988. }
  989. static void
  990. invoke_iIIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  991. {
  992. int32 (*native_code)(WASMExecEnv *, int32, int64, int64, int32) = func_ptr;
  993. argv_ret[0] =
  994. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  995. GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
  996. }
  997. static void
  998. invoke_iIIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  999. {
  1000. int64 (*native_code)(WASMExecEnv *, int32, int64, int64, int32) = func_ptr;
  1001. int64 ret =
  1002. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  1003. GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
  1004. PUT_I64_TO_ADDR(argv_ret, ret);
  1005. }
  1006. static void
  1007. invoke_iIII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1008. {
  1009. void (*native_code)(WASMExecEnv *, int32, int64, int64, int64) = func_ptr;
  1010. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  1011. GET_I64_FROM_ADDR((uint32 *)argv + 3),
  1012. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1013. }
  1014. static void
  1015. invoke_iIII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1016. {
  1017. int32 (*native_code)(WASMExecEnv *, int32, int64, int64, int64) = func_ptr;
  1018. argv_ret[0] =
  1019. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  1020. GET_I64_FROM_ADDR((uint32 *)argv + 3),
  1021. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1022. }
  1023. static void
  1024. invoke_iIII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1025. {
  1026. int64 (*native_code)(WASMExecEnv *, int32, int64, int64, int64) = func_ptr;
  1027. int64 ret =
  1028. native_code(exec_env, argv[0], GET_I64_FROM_ADDR((uint32 *)argv + 1),
  1029. GET_I64_FROM_ADDR((uint32 *)argv + 3),
  1030. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1031. PUT_I64_TO_ADDR(argv_ret, ret);
  1032. }
  1033. static void
  1034. invoke_Iiii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1035. {
  1036. void (*native_code)(WASMExecEnv *, int64, int32, int32, int32) = func_ptr;
  1037. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2], argv[3],
  1038. argv[4]);
  1039. }
  1040. static void
  1041. invoke_Iiii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1042. {
  1043. int32 (*native_code)(WASMExecEnv *, int64, int32, int32, int32) = func_ptr;
  1044. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1045. argv[2], argv[3], argv[4]);
  1046. }
  1047. static void
  1048. invoke_Iiii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1049. {
  1050. int64 (*native_code)(WASMExecEnv *, int64, int32, int32, int32) = func_ptr;
  1051. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1052. argv[2], argv[3], argv[4]);
  1053. PUT_I64_TO_ADDR(argv_ret, ret);
  1054. }
  1055. static void
  1056. invoke_IiiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1057. {
  1058. void (*native_code)(WASMExecEnv *, int64, int32, int32, int64) = func_ptr;
  1059. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2], argv[3],
  1060. GET_I64_FROM_ADDR((uint32 *)argv + 4));
  1061. }
  1062. static void
  1063. invoke_IiiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1064. {
  1065. int32 (*native_code)(WASMExecEnv *, int64, int32, int32, int64) = func_ptr;
  1066. argv_ret[0] =
  1067. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  1068. argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
  1069. }
  1070. static void
  1071. invoke_IiiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1072. {
  1073. int64 (*native_code)(WASMExecEnv *, int64, int32, int32, int64) = func_ptr;
  1074. int64 ret =
  1075. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  1076. argv[3], GET_I64_FROM_ADDR((uint32 *)argv + 4));
  1077. PUT_I64_TO_ADDR(argv_ret, ret);
  1078. }
  1079. static void
  1080. invoke_IiIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1081. {
  1082. void (*native_code)(WASMExecEnv *, int64, int32, int64, int32) = func_ptr;
  1083. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  1084. GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
  1085. }
  1086. static void
  1087. invoke_IiIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1088. {
  1089. int32 (*native_code)(WASMExecEnv *, int64, int32, int64, int32) = func_ptr;
  1090. argv_ret[0] =
  1091. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  1092. GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
  1093. }
  1094. static void
  1095. invoke_IiIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1096. {
  1097. int64 (*native_code)(WASMExecEnv *, int64, int32, int64, int32) = func_ptr;
  1098. int64 ret =
  1099. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  1100. GET_I64_FROM_ADDR((uint32 *)argv + 3), argv[5]);
  1101. PUT_I64_TO_ADDR(argv_ret, ret);
  1102. }
  1103. static void
  1104. invoke_IiII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1105. {
  1106. void (*native_code)(WASMExecEnv *, int64, int32, int64, int64) = func_ptr;
  1107. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv), argv[2],
  1108. GET_I64_FROM_ADDR((uint32 *)argv + 3),
  1109. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1110. }
  1111. static void
  1112. invoke_IiII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1113. {
  1114. int32 (*native_code)(WASMExecEnv *, int64, int32, int64, int64) = func_ptr;
  1115. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1116. argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3),
  1117. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1118. }
  1119. static void
  1120. invoke_IiII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1121. {
  1122. int64 (*native_code)(WASMExecEnv *, int64, int32, int64, int64) = func_ptr;
  1123. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1124. argv[2], GET_I64_FROM_ADDR((uint32 *)argv + 3),
  1125. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1126. PUT_I64_TO_ADDR(argv_ret, ret);
  1127. }
  1128. static void
  1129. invoke_IIii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1130. {
  1131. void (*native_code)(WASMExecEnv *, int64, int64, int32, int32) = func_ptr;
  1132. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1133. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4], argv[5]);
  1134. }
  1135. static void
  1136. invoke_IIii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1137. {
  1138. int32 (*native_code)(WASMExecEnv *, int64, int64, int32, int32) = func_ptr;
  1139. argv_ret[0] =
  1140. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1141. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4], argv[5]);
  1142. }
  1143. static void
  1144. invoke_IIii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1145. {
  1146. int64 (*native_code)(WASMExecEnv *, int64, int64, int32, int32) = func_ptr;
  1147. int64 ret =
  1148. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1149. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4], argv[5]);
  1150. PUT_I64_TO_ADDR(argv_ret, ret);
  1151. }
  1152. static void
  1153. invoke_IIiI_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1154. {
  1155. void (*native_code)(WASMExecEnv *, int64, int64, int32, int64) = func_ptr;
  1156. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1157. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4],
  1158. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1159. }
  1160. static void
  1161. invoke_IIiI_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1162. {
  1163. int32 (*native_code)(WASMExecEnv *, int64, int64, int32, int64) = func_ptr;
  1164. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1165. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4],
  1166. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1167. }
  1168. static void
  1169. invoke_IIiI_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1170. {
  1171. int64 (*native_code)(WASMExecEnv *, int64, int64, int32, int64) = func_ptr;
  1172. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1173. GET_I64_FROM_ADDR((uint32 *)argv + 2), argv[4],
  1174. GET_I64_FROM_ADDR((uint32 *)argv + 5));
  1175. PUT_I64_TO_ADDR(argv_ret, ret);
  1176. }
  1177. static void
  1178. invoke_IIIi_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1179. {
  1180. void (*native_code)(WASMExecEnv *, int64, int64, int64, int32) = func_ptr;
  1181. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1182. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  1183. GET_I64_FROM_ADDR((uint32 *)argv + 4), argv[6]);
  1184. }
  1185. static void
  1186. invoke_IIIi_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1187. {
  1188. int32 (*native_code)(WASMExecEnv *, int64, int64, int64, int32) = func_ptr;
  1189. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1190. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  1191. GET_I64_FROM_ADDR((uint32 *)argv + 4), argv[6]);
  1192. }
  1193. static void
  1194. invoke_IIIi_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1195. {
  1196. int64 (*native_code)(WASMExecEnv *, int64, int64, int64, int32) = func_ptr;
  1197. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1198. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  1199. GET_I64_FROM_ADDR((uint32 *)argv + 4), argv[6]);
  1200. PUT_I64_TO_ADDR(argv_ret, ret);
  1201. }
  1202. static void
  1203. invoke_IIII_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1204. {
  1205. void (*native_code)(WASMExecEnv *, int64, int64, int64, int64) = func_ptr;
  1206. native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1207. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  1208. GET_I64_FROM_ADDR((uint32 *)argv + 4),
  1209. GET_I64_FROM_ADDR((uint32 *)argv + 6));
  1210. }
  1211. static void
  1212. invoke_IIII_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1213. {
  1214. int32 (*native_code)(WASMExecEnv *, int64, int64, int64, int64) = func_ptr;
  1215. argv_ret[0] = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1216. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  1217. GET_I64_FROM_ADDR((uint32 *)argv + 4),
  1218. GET_I64_FROM_ADDR((uint32 *)argv + 6));
  1219. }
  1220. static void
  1221. invoke_IIII_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1222. {
  1223. int64 (*native_code)(WASMExecEnv *, int64, int64, int64, int64) = func_ptr;
  1224. int64 ret = native_code(exec_env, GET_I64_FROM_ADDR((uint32 *)argv),
  1225. GET_I64_FROM_ADDR((uint32 *)argv + 2),
  1226. GET_I64_FROM_ADDR((uint32 *)argv + 4),
  1227. GET_I64_FROM_ADDR((uint32 *)argv + 6));
  1228. PUT_I64_TO_ADDR(argv_ret, ret);
  1229. }
  1230. static void
  1231. invoke_iiiii_v(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1232. {
  1233. void (*native_code)(WASMExecEnv *, int32, int32, int32, int32, int32) =
  1234. func_ptr;
  1235. native_code(exec_env, argv[0], argv[1], argv[2], argv[3], argv[4]);
  1236. }
  1237. static void
  1238. invoke_iiiii_i(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1239. {
  1240. int32 (*native_code)(WASMExecEnv *, int32, int32, int32, int32, int32) =
  1241. func_ptr;
  1242. argv_ret[0] =
  1243. native_code(exec_env, argv[0], argv[1], argv[2], argv[3], argv[4]);
  1244. }
  1245. static void
  1246. invoke_iiiii_I(void *func_ptr, void *exec_env, int32 *argv, int32 *argv_ret)
  1247. {
  1248. int64 (*native_code)(WASMExecEnv *, int32, int32, int32, int32, int32) =
  1249. func_ptr;
  1250. int64 ret =
  1251. native_code(exec_env, argv[0], argv[1], argv[2], argv[3], argv[4]);
  1252. PUT_I64_TO_ADDR(argv_ret, ret);
  1253. }
  1254. typedef struct QuickAOTEntry {
  1255. const char *signature;
  1256. void *func_ptr;
  1257. } QuickAOTEntry;
  1258. /* clang-format off */
  1259. static QuickAOTEntry quick_aot_entries[] = {
  1260. { "()v", invoke_no_args_v },
  1261. { "()i", invoke_no_args_i },
  1262. { "()I", invoke_no_args_I },
  1263. { "(i)v", invoke_i_v }, { "(i)i", invoke_i_i }, { "(i)I", invoke_i_I },
  1264. { "(I)v", invoke_I_v }, { "(I)i", invoke_I_i }, { "(I)I", invoke_I_I },
  1265. { "(ii)v", invoke_ii_v }, { "(ii)i", invoke_ii_i }, { "(ii)I", invoke_ii_I },
  1266. { "(iI)v", invoke_iI_v }, { "(iI)i", invoke_iI_i }, { "(iI)I", invoke_iI_I },
  1267. { "(Ii)v", invoke_Ii_v }, { "(Ii)i", invoke_Ii_i }, { "(Ii)I", invoke_Ii_I },
  1268. { "(II)v", invoke_II_v }, { "(II)i", invoke_II_i }, { "(II)I", invoke_II_I },
  1269. { "(iii)v", invoke_iii_v }, { "(iii)i", invoke_iii_i }, { "(iii)I", invoke_iii_I },
  1270. { "(iiI)v", invoke_iiI_v }, { "(iiI)i", invoke_iiI_i }, { "(iiI)I", invoke_iiI_I },
  1271. { "(iIi)v", invoke_iIi_v }, { "(iIi)i", invoke_iIi_i }, { "(iIi)I", invoke_iIi_I },
  1272. { "(iII)v", invoke_iII_v }, { "(iII)i", invoke_iII_i }, { "(iII)I", invoke_iII_I },
  1273. { "(Iii)v", invoke_Iii_v }, { "(Iii)i", invoke_Iii_i }, { "(Iii)I", invoke_Iii_I },
  1274. { "(IiI)v", invoke_IiI_v }, { "(IiI)i", invoke_IiI_i }, { "(IiI)I", invoke_IiI_I },
  1275. { "(IIi)v", invoke_IIi_v }, { "(IIi)i", invoke_IIi_i }, { "(IIi)I", invoke_IIi_I },
  1276. { "(III)v", invoke_III_v }, { "(III)i", invoke_III_i }, { "(III)I", invoke_III_I },
  1277. { "(iiii)v", invoke_iiii_v }, { "(iiii)i", invoke_iiii_i }, { "(iiii)I", invoke_iiii_I },
  1278. { "(iiiI)v", invoke_iiiI_v }, { "(iiiI)i", invoke_iiiI_i }, { "(iiiI)I", invoke_iiiI_I },
  1279. { "(iiIi)v", invoke_iiIi_v }, { "(iiIi)i", invoke_iiIi_i }, { "(iiIi)I", invoke_iiIi_I },
  1280. { "(iiII)v", invoke_iiII_v }, { "(iiII)i", invoke_iiII_i }, { "(iiII)I", invoke_iiII_I },
  1281. { "(iIii)v", invoke_iIii_v }, { "(iIii)i", invoke_iIii_i }, { "(iIii)I", invoke_iIii_I },
  1282. { "(iIiI)v", invoke_iIiI_v }, { "(iIiI)i", invoke_iIiI_i }, { "(iIiI)I", invoke_iIiI_I },
  1283. { "(iIIi)v", invoke_iIIi_v }, { "(iIIi)i", invoke_iIIi_i }, { "(iIIi)I", invoke_iIIi_I },
  1284. { "(iIII)v", invoke_iIII_v }, { "(iIII)i", invoke_iIII_i }, { "(iIII)I", invoke_iIII_I },
  1285. { "(Iiii)v", invoke_Iiii_v }, { "(Iiii)i", invoke_Iiii_i }, { "(Iiii)I", invoke_Iiii_I },
  1286. { "(IiiI)v", invoke_IiiI_v }, { "(IiiI)i", invoke_IiiI_i }, { "(IiiI)I", invoke_IiiI_I },
  1287. { "(IiIi)v", invoke_IiIi_v }, { "(IiIi)i", invoke_IiIi_i }, { "(IiIi)I", invoke_IiIi_I },
  1288. { "(IiII)v", invoke_IiII_v }, { "(IiII)i", invoke_IiII_i }, { "(IiII)I", invoke_IiII_I },
  1289. { "(IIii)v", invoke_IIii_v }, { "(IIii)i", invoke_IIii_i }, { "(IIii)I", invoke_IIii_I },
  1290. { "(IIiI)v", invoke_IIiI_v }, { "(IIiI)i", invoke_IIiI_i }, { "(IIiI)I", invoke_IIiI_I },
  1291. { "(IIIi)v", invoke_IIIi_v }, { "(IIIi)i", invoke_IIIi_i }, { "(IIIi)I", invoke_IIIi_I },
  1292. { "(IIII)v", invoke_IIII_v }, { "(IIII)i", invoke_IIII_i }, { "(IIII)I", invoke_IIII_I },
  1293. { "(iiiii)v", invoke_iiiii_v }, { "(iiiii)i", invoke_iiiii_i }, { "(iiiii)I", invoke_iiiii_I },
  1294. };
  1295. /* clang-format on */
  1296. static int
  1297. quick_aot_entry_cmp(const void *quick_aot_entry1, const void *quick_aot_entry2)
  1298. {
  1299. return strcmp(((const QuickAOTEntry *)quick_aot_entry1)->signature,
  1300. ((const QuickAOTEntry *)quick_aot_entry2)->signature);
  1301. }
  1302. static bool
  1303. quick_aot_entry_init()
  1304. {
  1305. qsort(quick_aot_entries, sizeof(quick_aot_entries) / sizeof(QuickAOTEntry),
  1306. sizeof(QuickAOTEntry), quick_aot_entry_cmp);
  1307. return true;
  1308. }
  1309. void *
  1310. wasm_native_lookup_quick_aot_entry(const WASMFuncType *func_type)
  1311. {
  1312. char signature[16] = { 0 };
  1313. uint32 param_count = func_type->param_count;
  1314. uint32 result_count = func_type->result_count, i, j = 0;
  1315. const uint8 *types = func_type->types;
  1316. QuickAOTEntry *quick_aot_entry, key = { 0 };
  1317. if (param_count > 5 || result_count > 1)
  1318. return NULL;
  1319. signature[j++] = '(';
  1320. for (i = 0; i < param_count; i++) {
  1321. if (types[i] == VALUE_TYPE_I32)
  1322. signature[j++] = 'i';
  1323. else if (types[i] == VALUE_TYPE_I64)
  1324. signature[j++] = 'I';
  1325. else
  1326. return NULL;
  1327. }
  1328. signature[j++] = ')';
  1329. if (result_count == 0) {
  1330. signature[j++] = 'v';
  1331. }
  1332. else {
  1333. if (types[i] == VALUE_TYPE_I32)
  1334. signature[j++] = 'i';
  1335. else if (types[i] == VALUE_TYPE_I64)
  1336. signature[j++] = 'I';
  1337. else
  1338. return NULL;
  1339. }
  1340. key.signature = signature;
  1341. if ((quick_aot_entry =
  1342. bsearch(&key, quick_aot_entries,
  1343. sizeof(quick_aot_entries) / sizeof(QuickAOTEntry),
  1344. sizeof(QuickAOTEntry), quick_aot_entry_cmp))) {
  1345. return quick_aot_entry->func_ptr;
  1346. }
  1347. return NULL;
  1348. }
  1349. #endif /* end of WASM_ENABLE_QUICK_AOT_ENTRY != 0 */