wasm_native.c 52 KB

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