wasm_native.c 49 KB

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