wasm_native.c 51 KB

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