wasm_native.c 52 KB

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