wasm_runtime_common.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "config.h"
  6. #include "bh_platform.h"
  7. #include "bh_common.h"
  8. #include "bh_assert.h"
  9. #include "bh_log.h"
  10. #include "wasm_runtime_common.h"
  11. #include "wasm_memory.h"
  12. #if WASM_ENABLE_INTERP != 0
  13. #include "../interpreter/wasm_runtime.h"
  14. #endif
  15. #if WASM_ENABLE_AOT != 0
  16. #include "../aot/aot_runtime.h"
  17. #endif
  18. static void
  19. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  20. {
  21. if (error_buf != NULL)
  22. snprintf(error_buf, error_buf_size, "%s", string);
  23. }
  24. static bool
  25. wasm_runtime_env_init()
  26. {
  27. if (bh_platform_init() != 0)
  28. return false;
  29. if (bh_log_init() != 0)
  30. return false;
  31. if (vm_thread_sys_init() != 0)
  32. return false;
  33. if (wasm_native_init() == false)
  34. return false;
  35. return true;
  36. }
  37. bool
  38. wasm_runtime_init()
  39. {
  40. if (!wasm_runtime_memory_init(Alloc_With_System_Allocator, NULL))
  41. return false;
  42. if (!wasm_runtime_env_init()) {
  43. wasm_runtime_memory_destroy();
  44. return false;
  45. }
  46. return true;
  47. }
  48. void
  49. wasm_runtime_destroy()
  50. {
  51. wasm_native_destroy();
  52. vm_thread_sys_destroy();
  53. wasm_runtime_memory_destroy();
  54. }
  55. bool
  56. wasm_runtime_full_init(RuntimeInitArgs *init_args)
  57. {
  58. if (!wasm_runtime_memory_init(init_args->mem_alloc_type,
  59. &init_args->mem_alloc_option))
  60. return false;
  61. if (!wasm_runtime_env_init()) {
  62. wasm_runtime_memory_destroy();
  63. return false;
  64. }
  65. if (init_args->n_native_symbols > 0
  66. && !wasm_runtime_register_natives(init_args->native_module_name,
  67. init_args->native_symbols,
  68. init_args->n_native_symbols)) {
  69. wasm_runtime_destroy();
  70. return false;
  71. }
  72. return true;
  73. }
  74. PackageType
  75. get_package_type(const uint8 *buf, uint32 size)
  76. {
  77. if (buf && size >= 4) {
  78. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 's' && buf[3] == 'm')
  79. return Wasm_Module_Bytecode;
  80. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 'o' && buf[3] == 't')
  81. return Wasm_Module_AoT;
  82. }
  83. return Package_Type_Unknown;
  84. }
  85. WASMModuleCommon *
  86. wasm_runtime_load(const uint8 *buf, uint32 size,
  87. char *error_buf, uint32 error_buf_size)
  88. {
  89. if (get_package_type(buf, size) == Wasm_Module_Bytecode) {
  90. #if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
  91. AOTModule *aot_module;
  92. WASMModule *module = wasm_load(buf, size, error_buf, error_buf_size);
  93. if (!module)
  94. return NULL;
  95. if (!(aot_module = aot_convert_wasm_module(module,
  96. error_buf, error_buf_size))) {
  97. wasm_unload(module);
  98. return NULL;
  99. }
  100. return (WASMModuleCommon*)aot_module;
  101. #elif WASM_ENABLE_INTERP != 0
  102. return (WASMModuleCommon*)
  103. wasm_load(buf, size, error_buf, error_buf_size);
  104. #endif
  105. }
  106. else if (get_package_type(buf, size) == Wasm_Module_AoT) {
  107. #if WASM_ENABLE_AOT != 0
  108. return (WASMModuleCommon*)
  109. aot_load_from_aot_file(buf, size, error_buf, error_buf_size);
  110. #endif /* end of WASM_ENABLE_AOT */
  111. }
  112. if (size < 4)
  113. set_error_buf(error_buf, error_buf_size,
  114. "WASM module load failed: unexpected end");
  115. else
  116. set_error_buf(error_buf, error_buf_size,
  117. "WASM module load failed: magic header not detected");
  118. return NULL;
  119. }
  120. WASMModuleCommon *
  121. wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
  122. char *error_buf, uint32_t error_buf_size)
  123. {
  124. #if WASM_ENABLE_INTERP != 0
  125. if (!is_aot)
  126. return (WASMModuleCommon*)
  127. wasm_load_from_sections(section_list,
  128. error_buf, error_buf_size);
  129. #endif
  130. #if WASM_ENABLE_AOT != 0
  131. if (is_aot)
  132. return (WASMModuleCommon*)
  133. aot_load_from_sections(section_list,
  134. error_buf, error_buf_size);
  135. #endif
  136. set_error_buf(error_buf, error_buf_size,
  137. "WASM module load failed: invalid section list type");
  138. return NULL;
  139. }
  140. void
  141. wasm_runtime_unload(WASMModuleCommon *module)
  142. {
  143. #if WASM_ENABLE_INTERP != 0
  144. if (module->module_type == Wasm_Module_Bytecode) {
  145. wasm_unload((WASMModule*)module);
  146. return;
  147. }
  148. #endif
  149. #if WASM_ENABLE_AOT != 0
  150. if (module->module_type == Wasm_Module_AoT) {
  151. aot_unload((AOTModule*)module);
  152. return;
  153. }
  154. #endif
  155. }
  156. WASMModuleInstanceCommon *
  157. wasm_runtime_instantiate(WASMModuleCommon *module,
  158. uint32 stack_size, uint32 heap_size,
  159. char *error_buf, uint32 error_buf_size)
  160. {
  161. #if WASM_ENABLE_INTERP != 0
  162. if (module->module_type == Wasm_Module_Bytecode)
  163. return (WASMModuleInstanceCommon*)
  164. wasm_instantiate((WASMModule*)module,
  165. stack_size, heap_size,
  166. error_buf, error_buf_size);
  167. #endif
  168. #if WASM_ENABLE_AOT != 0
  169. if (module->module_type == Wasm_Module_AoT)
  170. return (WASMModuleInstanceCommon*)
  171. aot_instantiate((AOTModule*)module,
  172. stack_size, heap_size,
  173. error_buf, error_buf_size);
  174. #endif
  175. set_error_buf(error_buf, error_buf_size,
  176. "Instantiate module failed, invalid module type");
  177. return NULL;
  178. }
  179. void
  180. wasm_runtime_deinstantiate(WASMModuleInstanceCommon *module_inst)
  181. {
  182. #if WASM_ENABLE_INTERP != 0
  183. if (module_inst->module_type == Wasm_Module_Bytecode) {
  184. wasm_deinstantiate((WASMModuleInstance*)module_inst);
  185. return;
  186. }
  187. #endif
  188. #if WASM_ENABLE_AOT != 0
  189. if (module_inst->module_type == Wasm_Module_AoT) {
  190. aot_deinstantiate((AOTModuleInstance*)module_inst);
  191. return;
  192. }
  193. #endif
  194. }
  195. WASMExecEnv *
  196. wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst,
  197. uint32 stack_size)
  198. {
  199. return wasm_exec_env_create(module_inst, stack_size);
  200. }
  201. void
  202. wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env)
  203. {
  204. wasm_exec_env_destroy(exec_env);
  205. }
  206. WASMModuleInstanceCommon *
  207. wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
  208. {
  209. return wasm_exec_env_get_module_inst(exec_env);
  210. }
  211. WASMFunctionInstanceCommon *
  212. wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
  213. const char *name,
  214. const char *signature)
  215. {
  216. #if WASM_ENABLE_INTERP != 0
  217. if (module_inst->module_type == Wasm_Module_Bytecode)
  218. return (WASMFunctionInstanceCommon*)
  219. wasm_lookup_function((const WASMModuleInstance*)module_inst,
  220. name, signature);
  221. #endif
  222. #if WASM_ENABLE_AOT != 0
  223. if (module_inst->module_type == Wasm_Module_AoT)
  224. return (WASMFunctionInstanceCommon*)
  225. aot_lookup_function((const AOTModuleInstance*)module_inst,
  226. name, signature);
  227. #endif
  228. return NULL;
  229. }
  230. bool
  231. wasm_runtime_call_wasm(WASMExecEnv *exec_env,
  232. WASMFunctionInstanceCommon *function,
  233. unsigned argc, uint32 argv[])
  234. {
  235. if (!exec_env
  236. || !exec_env->module_inst
  237. || exec_env->wasm_stack_size == 0
  238. || exec_env->wasm_stack.s.top_boundary !=
  239. exec_env->wasm_stack.s.bottom + exec_env->wasm_stack_size
  240. || exec_env->wasm_stack.s.top > exec_env->wasm_stack.s.top_boundary) {
  241. LOG_ERROR("Invalid exec env stack info.");
  242. return false;
  243. }
  244. exec_env->handle = vm_self_thread();
  245. #if WASM_ENABLE_INTERP != 0
  246. if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
  247. return wasm_call_function(exec_env,
  248. (WASMFunctionInstance*)function,
  249. argc, argv);
  250. #endif
  251. #if WASM_ENABLE_AOT != 0
  252. if (exec_env->module_inst->module_type == Wasm_Module_AoT)
  253. return aot_call_function(exec_env,
  254. (AOTFunctionInstance*)function,
  255. argc, argv);
  256. #endif
  257. return false;
  258. }
  259. bool
  260. wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst,
  261. WASMFunctionInstanceCommon *function,
  262. unsigned argc, uint32 argv[])
  263. {
  264. #if WASM_ENABLE_INTERP != 0
  265. if (module_inst->module_type == Wasm_Module_Bytecode)
  266. return wasm_create_exec_env_and_call_function(
  267. (WASMModuleInstance*)module_inst,
  268. (WASMFunctionInstance*)function,
  269. argc, argv);
  270. #endif
  271. #if WASM_ENABLE_AOT != 0
  272. if (module_inst->module_type == Wasm_Module_AoT)
  273. return aot_create_exec_env_and_call_function(
  274. (AOTModuleInstance*)module_inst,
  275. (AOTFunctionInstance*)function,
  276. argc, argv);
  277. #endif
  278. return false;
  279. }
  280. void
  281. wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst,
  282. const char *exception)
  283. {
  284. #if WASM_ENABLE_INTERP != 0
  285. if (module_inst->module_type == Wasm_Module_Bytecode) {
  286. wasm_set_exception((WASMModuleInstance*)module_inst, exception);
  287. return;
  288. }
  289. #endif
  290. #if WASM_ENABLE_AOT != 0
  291. if (module_inst->module_type == Wasm_Module_AoT) {
  292. aot_set_exception((AOTModuleInstance*)module_inst, exception);
  293. return;
  294. }
  295. #endif
  296. }
  297. const char*
  298. wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst)
  299. {
  300. #if WASM_ENABLE_INTERP != 0
  301. if (module_inst->module_type == Wasm_Module_Bytecode) {
  302. return wasm_get_exception((WASMModuleInstance*)module_inst);
  303. }
  304. #endif
  305. #if WASM_ENABLE_AOT != 0
  306. if (module_inst->module_type == Wasm_Module_AoT) {
  307. return aot_get_exception((AOTModuleInstance*)module_inst);
  308. }
  309. #endif
  310. return NULL;
  311. }
  312. void
  313. wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst)
  314. {
  315. wasm_runtime_set_exception(module_inst, NULL);
  316. }
  317. void
  318. wasm_runtime_set_custom_data(WASMModuleInstanceCommon *module_inst,
  319. void *custom_data)
  320. {
  321. #if WASM_ENABLE_INTERP != 0
  322. if (module_inst->module_type == Wasm_Module_Bytecode) {
  323. ((WASMModuleInstance*)module_inst)->custom_data = custom_data;
  324. return;
  325. }
  326. #endif
  327. #if WASM_ENABLE_AOT != 0
  328. if (module_inst->module_type == Wasm_Module_AoT) {
  329. ((AOTModuleInstance*)module_inst)->custom_data.ptr = custom_data;
  330. return;
  331. }
  332. #endif
  333. }
  334. void*
  335. wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst)
  336. {
  337. #if WASM_ENABLE_INTERP != 0
  338. if (module_inst->module_type == Wasm_Module_Bytecode)
  339. return ((WASMModuleInstance*)module_inst)->custom_data;
  340. #endif
  341. #if WASM_ENABLE_AOT != 0
  342. if (module_inst->module_type == Wasm_Module_AoT)
  343. return ((AOTModuleInstance*)module_inst)->custom_data.ptr;
  344. #endif
  345. return NULL;
  346. }
  347. int32
  348. wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size,
  349. void **p_native_addr)
  350. {
  351. #if WASM_ENABLE_INTERP != 0
  352. if (module_inst->module_type == Wasm_Module_Bytecode)
  353. return wasm_module_malloc((WASMModuleInstance*)module_inst, size,
  354. p_native_addr);
  355. #endif
  356. #if WASM_ENABLE_AOT != 0
  357. if (module_inst->module_type == Wasm_Module_AoT)
  358. return aot_module_malloc((AOTModuleInstance*)module_inst, size,
  359. p_native_addr);
  360. #endif
  361. return 0;
  362. }
  363. void
  364. wasm_runtime_module_free(WASMModuleInstanceCommon *module_inst, int32 ptr)
  365. {
  366. #if WASM_ENABLE_INTERP != 0
  367. if (module_inst->module_type == Wasm_Module_Bytecode) {
  368. wasm_module_free((WASMModuleInstance*)module_inst, ptr);
  369. return;
  370. }
  371. #endif
  372. #if WASM_ENABLE_AOT != 0
  373. if (module_inst->module_type == Wasm_Module_AoT) {
  374. aot_module_free((AOTModuleInstance*)module_inst, ptr);
  375. return;
  376. }
  377. #endif
  378. }
  379. int32
  380. wasm_runtime_module_dup_data(WASMModuleInstanceCommon *module_inst,
  381. const char *src, uint32 size)
  382. {
  383. #if WASM_ENABLE_INTERP != 0
  384. if (module_inst->module_type == Wasm_Module_Bytecode) {
  385. return wasm_module_dup_data((WASMModuleInstance*)module_inst, src, size);
  386. }
  387. #endif
  388. #if WASM_ENABLE_AOT != 0
  389. if (module_inst->module_type == Wasm_Module_AoT) {
  390. return aot_module_dup_data((AOTModuleInstance*)module_inst, src, size);
  391. }
  392. #endif
  393. return 0;
  394. }
  395. bool
  396. wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst,
  397. int32 app_offset, uint32 size)
  398. {
  399. #if WASM_ENABLE_INTERP != 0
  400. if (module_inst->module_type == Wasm_Module_Bytecode)
  401. return wasm_validate_app_addr((WASMModuleInstance*)module_inst,
  402. app_offset, size);
  403. #endif
  404. #if WASM_ENABLE_AOT != 0
  405. if (module_inst->module_type == Wasm_Module_AoT)
  406. return aot_validate_app_addr((AOTModuleInstance*)module_inst,
  407. app_offset, size);
  408. #endif
  409. return false;
  410. }
  411. bool
  412. wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst,
  413. int32 app_str_offset)
  414. {
  415. int32 app_end_offset;
  416. char *str, *str_end;
  417. if (!wasm_runtime_get_app_addr_range(module_inst, app_str_offset,
  418. NULL, &app_end_offset))
  419. goto fail;
  420. str = wasm_runtime_addr_app_to_native(module_inst, app_str_offset);
  421. str_end = str + (app_end_offset - app_str_offset);
  422. while (str < str_end && *str != '\0')
  423. str++;
  424. if (str == str_end)
  425. goto fail;
  426. return true;
  427. fail:
  428. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  429. return false;
  430. }
  431. bool
  432. wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst,
  433. void *native_ptr, uint32 size)
  434. {
  435. #if WASM_ENABLE_INTERP != 0
  436. if (module_inst->module_type == Wasm_Module_Bytecode)
  437. return wasm_validate_native_addr((WASMModuleInstance*)module_inst,
  438. native_ptr, size);
  439. #endif
  440. #if WASM_ENABLE_AOT != 0
  441. if (module_inst->module_type == Wasm_Module_AoT)
  442. return aot_validate_native_addr((AOTModuleInstance*)module_inst,
  443. native_ptr, size);
  444. #endif
  445. return false;
  446. }
  447. void *
  448. wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst,
  449. int32 app_offset)
  450. {
  451. #if WASM_ENABLE_INTERP != 0
  452. if (module_inst->module_type == Wasm_Module_Bytecode)
  453. return wasm_addr_app_to_native((WASMModuleInstance*)module_inst,
  454. app_offset);
  455. #endif
  456. #if WASM_ENABLE_AOT != 0
  457. if (module_inst->module_type == Wasm_Module_AoT)
  458. return aot_addr_app_to_native((AOTModuleInstance*)module_inst,
  459. app_offset);
  460. #endif
  461. return NULL;
  462. }
  463. int32
  464. wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst,
  465. void *native_ptr)
  466. {
  467. #if WASM_ENABLE_INTERP != 0
  468. if (module_inst->module_type == Wasm_Module_Bytecode)
  469. return wasm_addr_native_to_app((WASMModuleInstance*)module_inst,
  470. native_ptr);
  471. #endif
  472. #if WASM_ENABLE_AOT != 0
  473. if (module_inst->module_type == Wasm_Module_AoT)
  474. return aot_addr_native_to_app((AOTModuleInstance*)module_inst,
  475. native_ptr);
  476. #endif
  477. return 0;
  478. }
  479. bool
  480. wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst,
  481. int32 app_offset,
  482. int32 *p_app_start_offset,
  483. int32 *p_app_end_offset)
  484. {
  485. #if WASM_ENABLE_INTERP != 0
  486. if (module_inst->module_type == Wasm_Module_Bytecode)
  487. return wasm_get_app_addr_range((WASMModuleInstance*)module_inst,
  488. app_offset, p_app_start_offset,
  489. p_app_end_offset);
  490. #endif
  491. #if WASM_ENABLE_AOT != 0
  492. if (module_inst->module_type == Wasm_Module_AoT)
  493. return aot_get_app_addr_range((AOTModuleInstance*)module_inst,
  494. app_offset, p_app_start_offset,
  495. p_app_end_offset);
  496. #endif
  497. return false;
  498. }
  499. bool
  500. wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst,
  501. uint8_t *native_ptr,
  502. uint8_t **p_native_start_addr,
  503. uint8_t **p_native_end_addr)
  504. {
  505. #if WASM_ENABLE_INTERP != 0
  506. if (module_inst->module_type == Wasm_Module_Bytecode)
  507. return wasm_get_native_addr_range((WASMModuleInstance*)module_inst,
  508. native_ptr, p_native_start_addr,
  509. p_native_end_addr);
  510. #endif
  511. #if WASM_ENABLE_AOT != 0
  512. if (module_inst->module_type == Wasm_Module_AoT)
  513. return aot_get_native_addr_range((AOTModuleInstance*)module_inst,
  514. native_ptr, p_native_start_addr,
  515. p_native_end_addr);
  516. #endif
  517. return false;
  518. }
  519. uint32
  520. wasm_runtime_get_temp_ret(WASMModuleInstanceCommon *module_inst)
  521. {
  522. #if WASM_ENABLE_INTERP != 0
  523. if (module_inst->module_type == Wasm_Module_Bytecode)
  524. return ((WASMModuleInstance*)module_inst)->temp_ret;
  525. #endif
  526. #if WASM_ENABLE_AOT != 0
  527. if (module_inst->module_type == Wasm_Module_AoT)
  528. return ((AOTModuleInstance*)module_inst)->temp_ret;
  529. #endif
  530. return 0;
  531. }
  532. void
  533. wasm_runtime_set_temp_ret(WASMModuleInstanceCommon *module_inst,
  534. uint32 temp_ret)
  535. {
  536. #if WASM_ENABLE_INTERP != 0
  537. if (module_inst->module_type == Wasm_Module_Bytecode) {
  538. ((WASMModuleInstance*)module_inst)->temp_ret = temp_ret;
  539. return;
  540. }
  541. #endif
  542. #if WASM_ENABLE_AOT != 0
  543. if (module_inst->module_type == Wasm_Module_AoT) {
  544. ((AOTModuleInstance*)module_inst)->temp_ret = temp_ret;
  545. return;
  546. }
  547. #endif
  548. }
  549. uint32
  550. wasm_runtime_get_llvm_stack(WASMModuleInstanceCommon *module_inst)
  551. {
  552. #if WASM_ENABLE_INTERP != 0
  553. if (module_inst->module_type == Wasm_Module_Bytecode)
  554. return ((WASMModuleInstance*)module_inst)->llvm_stack;
  555. #endif
  556. #if WASM_ENABLE_AOT != 0
  557. if (module_inst->module_type == Wasm_Module_AoT)
  558. return ((AOTModuleInstance*)module_inst)->llvm_stack;
  559. #endif
  560. return 0;
  561. }
  562. void
  563. wasm_runtime_set_llvm_stack(WASMModuleInstanceCommon *module_inst,
  564. uint32 llvm_stack)
  565. {
  566. #if WASM_ENABLE_INTERP != 0
  567. if (module_inst->module_type == Wasm_Module_Bytecode) {
  568. ((WASMModuleInstance*)module_inst)->llvm_stack = llvm_stack;
  569. return;
  570. }
  571. #endif
  572. #if WASM_ENABLE_AOT != 0
  573. if (module_inst->module_type == Wasm_Module_AoT) {
  574. ((AOTModuleInstance*)module_inst)->llvm_stack = llvm_stack;
  575. return;
  576. }
  577. #endif
  578. }
  579. bool
  580. wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module,
  581. uint32 inc_page_count)
  582. {
  583. #if WASM_ENABLE_INTERP != 0
  584. if (module->module_type == Wasm_Module_Bytecode)
  585. return wasm_enlarge_memory((WASMModuleInstance*)module,
  586. inc_page_count);
  587. #endif
  588. #if WASM_ENABLE_AOT != 0
  589. if (module->module_type == Wasm_Module_AoT)
  590. return aot_enlarge_memory((AOTModuleInstance*)module,
  591. inc_page_count);
  592. #endif
  593. return false;
  594. }
  595. #if WASM_ENABLE_LIBC_WASI != 0
  596. void
  597. wasm_runtime_set_wasi_args(WASMModuleCommon *module,
  598. const char *dir_list[], uint32 dir_count,
  599. const char *map_dir_list[], uint32 map_dir_count,
  600. const char *env_list[], uint32 env_count,
  601. char *argv[], int argc)
  602. {
  603. WASIArguments *wasi_args = NULL;
  604. #if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
  605. if (module->module_type == Wasm_Module_Bytecode)
  606. wasi_args = &((WASMModule*)module)->wasi_args;
  607. #endif
  608. #if WASM_ENABLE_AOT != 0
  609. if (module->module_type == Wasm_Module_AoT)
  610. wasi_args = &((AOTModule*)module)->wasi_args;
  611. #endif
  612. if (wasi_args) {
  613. wasi_args->dir_list = dir_list;
  614. wasi_args->dir_count = dir_count;
  615. wasi_args->map_dir_list = map_dir_list;
  616. wasi_args->map_dir_count = map_dir_count;
  617. wasi_args->env = env_list;
  618. wasi_args->env_count = env_count;
  619. wasi_args->argv = argv;
  620. wasi_args->argc = argc;
  621. }
  622. }
  623. bool
  624. wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
  625. const char *dir_list[], uint32 dir_count,
  626. const char *map_dir_list[], uint32 map_dir_count,
  627. const char *env[], uint32 env_count,
  628. char *argv[], uint32 argc,
  629. char *error_buf, uint32 error_buf_size)
  630. {
  631. WASIContext *wasi_ctx;
  632. size_t *argv_offsets = NULL;
  633. char *argv_buf = NULL;
  634. size_t *env_offsets = NULL;
  635. char *env_buf = NULL;
  636. uint64 argv_buf_len = 0, env_buf_len = 0;
  637. uint32 argv_buf_offset = 0, env_buf_offset = 0;
  638. struct fd_table *curfds;
  639. struct fd_prestats *prestats;
  640. struct argv_environ_values *argv_environ;
  641. int32 offset_argv_offsets = 0, offset_env_offsets = 0;
  642. int32 offset_argv_buf = 0, offset_env_buf = 0;
  643. int32 offset_curfds = 0;
  644. int32 offset_prestats = 0;
  645. int32 offset_argv_environ = 0;
  646. __wasi_fd_t wasm_fd = 3;
  647. int32 raw_fd;
  648. char *path, resolved_path[PATH_MAX];
  649. uint64 total_size;
  650. uint32 i;
  651. if (!(wasi_ctx = wasm_runtime_malloc(sizeof(WASIContext)))) {
  652. set_error_buf(error_buf, error_buf_size,
  653. "Init wasi environment failed: allocate memory failed.");
  654. return false;
  655. }
  656. memset(wasi_ctx, 0, sizeof(WASIContext));
  657. wasm_runtime_set_wasi_ctx(module_inst, wasi_ctx);
  658. #if WASM_ENABLE_INTERP != 0
  659. if (module_inst->module_type == Wasm_Module_Bytecode
  660. && !((WASMModuleInstance*)module_inst)->default_memory)
  661. return true;
  662. #endif
  663. #if WASM_ENABLE_AOT != 0
  664. if (module_inst->module_type == Wasm_Module_AoT
  665. && !((AOTModuleInstance*)module_inst)->memory_data.ptr)
  666. return true;
  667. #endif
  668. /* process argv[0], trip the path and suffix, only keep the program name */
  669. for (i = 0; i < argc; i++)
  670. argv_buf_len += strlen(argv[i]) + 1;
  671. total_size = sizeof(size_t) * (uint64)argc;
  672. if (total_size >= UINT32_MAX
  673. || !(offset_argv_offsets = wasm_runtime_module_malloc
  674. (module_inst, (uint32)total_size,
  675. (void**)&argv_offsets))
  676. || argv_buf_len >= UINT32_MAX
  677. || !(offset_argv_buf = wasm_runtime_module_malloc
  678. (module_inst, (uint32)argv_buf_len,
  679. (void**)&argv_buf))) {
  680. set_error_buf(error_buf, error_buf_size,
  681. "Init wasi environment failed: allocate memory failed.");
  682. goto fail;
  683. }
  684. for (i = 0; i < argc; i++) {
  685. argv_offsets[i] = argv_buf_offset;
  686. bh_strcpy_s(argv_buf + argv_buf_offset,
  687. (uint32)argv_buf_len - argv_buf_offset, argv[i]);
  688. argv_buf_offset += (uint32)(strlen(argv[i]) + 1);
  689. }
  690. for (i = 0; i < env_count; i++)
  691. env_buf_len += strlen(env[i]) + 1;
  692. total_size = sizeof(size_t) * (uint64)argc;
  693. if (total_size >= UINT32_MAX
  694. || !(offset_env_offsets = wasm_runtime_module_malloc
  695. (module_inst, (uint32)total_size,
  696. (void**)&env_offsets))
  697. || env_buf_len >= UINT32_MAX
  698. || !(offset_env_buf = wasm_runtime_module_malloc
  699. (module_inst, (uint32)env_buf_len,
  700. (void**)&env_buf))) {
  701. set_error_buf(error_buf, error_buf_size,
  702. "Init wasi environment failed: allocate memory failed.");
  703. goto fail;
  704. }
  705. for (i = 0; i < env_count; i++) {
  706. env_offsets[i] = env_buf_offset;
  707. bh_strcpy_s(env_buf + env_buf_offset,
  708. (uint32)env_buf_len - env_buf_offset, env[i]);
  709. env_buf_offset += (uint32)(strlen(env[i]) + 1);
  710. }
  711. if (!(offset_curfds = wasm_runtime_module_malloc
  712. (module_inst, sizeof(struct fd_table), (void**)&curfds))
  713. || !(offset_prestats = wasm_runtime_module_malloc
  714. (module_inst, sizeof(struct fd_prestats), (void**)&prestats))
  715. || !(offset_argv_environ = wasm_runtime_module_malloc
  716. (module_inst, sizeof(struct argv_environ_values),
  717. (void**)&argv_environ))) {
  718. set_error_buf(error_buf, error_buf_size,
  719. "Init wasi environment failed: allocate memory failed.");
  720. goto fail;
  721. }
  722. wasi_ctx->curfds = curfds;
  723. wasi_ctx->prestats = prestats;
  724. wasi_ctx->argv_environ = argv_environ;
  725. fd_table_init(curfds);
  726. fd_prestats_init(prestats);
  727. if (!argv_environ_init(argv_environ,
  728. argv_offsets, argc,
  729. argv_buf, argv_buf_len,
  730. env_offsets, env_count,
  731. env_buf, env_buf_len)) {
  732. set_error_buf(error_buf, error_buf_size,
  733. "Init wasi environment failed: "
  734. "init argument environment failed.");
  735. goto fail;
  736. }
  737. /* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
  738. if (!fd_table_insert_existing(curfds, 0, 0)
  739. || !fd_table_insert_existing(curfds, 1, 1)
  740. || !fd_table_insert_existing(curfds, 2, 2)) {
  741. set_error_buf(error_buf, error_buf_size,
  742. "Init wasi environment failed: init fd table failed.");
  743. goto fail;
  744. }
  745. wasm_fd = 3;
  746. for (i = 0; i < dir_count; i++, wasm_fd++) {
  747. path = realpath(dir_list[i], resolved_path);
  748. if (!path) {
  749. if (error_buf)
  750. snprintf(error_buf, error_buf_size,
  751. "error while pre-opening directory %s: %d\n",
  752. dir_list[i], errno);
  753. goto fail;
  754. }
  755. raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
  756. if (raw_fd == -1) {
  757. if (error_buf)
  758. snprintf(error_buf, error_buf_size,
  759. "error while pre-opening directory %s: %d\n",
  760. dir_list[i], errno);
  761. goto fail;
  762. }
  763. fd_table_insert_existing(curfds, wasm_fd, raw_fd);
  764. fd_prestats_insert(prestats, dir_list[i], wasm_fd);
  765. }
  766. return true;
  767. fail:
  768. if (offset_curfds != 0)
  769. wasm_runtime_module_free(module_inst, offset_curfds);
  770. if (offset_prestats != 0)
  771. wasm_runtime_module_free(module_inst, offset_prestats);
  772. if (offset_argv_environ != 0)
  773. wasm_runtime_module_free(module_inst, offset_argv_environ);
  774. if (offset_argv_buf)
  775. wasm_runtime_module_free(module_inst, offset_argv_buf);
  776. if (offset_argv_offsets)
  777. wasm_runtime_module_free(module_inst, offset_argv_offsets);
  778. if (offset_env_buf)
  779. wasm_runtime_module_free(module_inst, offset_env_buf);
  780. if (offset_env_offsets)
  781. wasm_runtime_module_free(module_inst, offset_env_offsets);
  782. return false;
  783. }
  784. bool
  785. wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst)
  786. {
  787. #if WASM_ENABLE_INTERP != 0
  788. if (module_inst->module_type == Wasm_Module_Bytecode
  789. && ((WASMModuleInstance*)module_inst)->module->is_wasi_module)
  790. return true;
  791. #endif
  792. #if WASM_ENABLE_AOT != 0
  793. if (module_inst->module_type == Wasm_Module_AoT
  794. && ((AOTModule*)((AOTModuleInstance*)module_inst)->aot_module.ptr)
  795. ->is_wasi_module)
  796. return true;
  797. #endif
  798. return false;
  799. }
  800. WASMFunctionInstanceCommon *
  801. wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst)
  802. {
  803. uint32 i;
  804. #if WASM_ENABLE_INTERP != 0
  805. if (module_inst->module_type == Wasm_Module_Bytecode) {
  806. WASMModuleInstance *wasm_inst = (WASMModuleInstance*)module_inst;
  807. WASMFunctionInstance *func;
  808. for (i = 0; i < wasm_inst->export_func_count; i++) {
  809. if (!strcmp(wasm_inst->export_functions[i].name, "_start")) {
  810. func = wasm_inst->export_functions[i].function;
  811. if (func->u.func->func_type->param_count != 0
  812. || func->u.func->func_type->result_count != 0) {
  813. LOG_ERROR("Lookup wasi _start function failed: "
  814. "invalid function type.\n");
  815. return NULL;
  816. }
  817. return (WASMFunctionInstanceCommon*)func;
  818. }
  819. }
  820. return NULL;
  821. }
  822. #endif
  823. #if WASM_ENABLE_AOT != 0
  824. if (module_inst->module_type == Wasm_Module_AoT) {
  825. AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
  826. AOTModule *module = (AOTModule*)aot_inst->aot_module.ptr;
  827. for (i = 0; i < module->export_func_count; i++) {
  828. if (!strcmp(module->export_funcs[i].func_name, "_start")) {
  829. AOTFuncType *func_type = module->export_funcs[i].func_type;
  830. if (func_type->param_count != 0
  831. || func_type->result_count != 0) {
  832. LOG_ERROR("Lookup wasi _start function failed: "
  833. "invalid function type.\n");
  834. return NULL;
  835. }
  836. return (WASMFunctionInstanceCommon*)&module->export_funcs[i];
  837. }
  838. }
  839. return NULL;
  840. }
  841. #endif /* end of WASM_ENABLE_AOT */
  842. return NULL;
  843. }
  844. void
  845. wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
  846. {
  847. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  848. if (wasi_ctx) {
  849. if (wasi_ctx->argv_environ)
  850. argv_environ_destroy(wasi_ctx->argv_environ);
  851. if (wasi_ctx->curfds)
  852. fd_table_destroy(wasi_ctx->curfds);
  853. if (wasi_ctx->prestats)
  854. fd_prestats_destroy(wasi_ctx->prestats);
  855. wasm_runtime_free(wasi_ctx);
  856. }
  857. }
  858. WASIContext *
  859. wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst)
  860. {
  861. #if WASM_ENABLE_INTERP != 0
  862. if (module_inst->module_type == Wasm_Module_Bytecode)
  863. return ((WASMModuleInstance*)module_inst)->wasi_ctx;
  864. #endif
  865. #if WASM_ENABLE_AOT != 0
  866. if (module_inst->module_type == Wasm_Module_AoT)
  867. return ((AOTModuleInstance*)module_inst)->wasi_ctx.ptr;
  868. #endif
  869. return NULL;
  870. }
  871. void
  872. wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst,
  873. WASIContext *wasi_ctx)
  874. {
  875. #if WASM_ENABLE_INTERP != 0
  876. if (module_inst->module_type == Wasm_Module_Bytecode)
  877. ((WASMModuleInstance*)module_inst)->wasi_ctx = wasi_ctx;
  878. #endif
  879. #if WASM_ENABLE_AOT != 0
  880. if (module_inst->module_type == Wasm_Module_AoT)
  881. ((AOTModuleInstance*)module_inst)->wasi_ctx.ptr = wasi_ctx;
  882. #endif
  883. }
  884. #endif /* end of WASM_ENABLE_LIBC_WASI */
  885. /**
  886. * Implementation of wasm_application_execute_main()
  887. */
  888. static WASMFunctionInstanceCommon *
  889. resolve_main_function(const WASMModuleInstanceCommon *module_inst)
  890. {
  891. uint32 i;
  892. #if WASM_ENABLE_INTERP != 0
  893. if (module_inst->module_type == Wasm_Module_Bytecode) {
  894. WASMModuleInstance *wasm_inst = (WASMModuleInstance*)module_inst;
  895. for (i = 0; i < wasm_inst->export_func_count; i++) {
  896. if (!strcmp(wasm_inst->export_functions[i].name, "_main")
  897. || !strcmp(wasm_inst->export_functions[i].name, "main"))
  898. return (WASMFunctionInstanceCommon*)
  899. wasm_inst->export_functions[i].function;
  900. }
  901. LOG_ERROR("WASM execute application failed: main function not found.\n");
  902. return NULL;
  903. }
  904. #endif
  905. #if WASM_ENABLE_AOT != 0
  906. if (module_inst->module_type == Wasm_Module_AoT) {
  907. AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
  908. AOTModule *module = (AOTModule*)aot_inst->aot_module.ptr;
  909. for (i = 0; i < module->export_func_count; i++) {
  910. if (!strcmp(module->export_funcs[i].func_name, "_main")
  911. || !strcmp(module->export_funcs[i].func_name, "main"))
  912. return (WASMFunctionInstanceCommon*)&module->export_funcs[i];
  913. }
  914. LOG_ERROR("WASM execute application failed: main function not found.\n");
  915. return NULL;
  916. }
  917. #endif
  918. return NULL;
  919. }
  920. static bool
  921. check_main_func_type(const WASMType *type)
  922. {
  923. if (!(type->param_count == 0 || type->param_count == 2)
  924. ||type->result_count > 1) {
  925. LOG_ERROR("WASM execute application failed: invalid main function type.\n");
  926. return false;
  927. }
  928. if (type->param_count == 2
  929. && !(type->types[0] == VALUE_TYPE_I32
  930. && type->types[1] == VALUE_TYPE_I32)) {
  931. LOG_ERROR("WASM execute application failed: invalid main function type.\n");
  932. return false;
  933. }
  934. if (type->result_count
  935. && type->types[type->param_count] != VALUE_TYPE_I32) {
  936. LOG_ERROR("WASM execute application failed: invalid main function type.\n");
  937. return false;
  938. }
  939. return true;
  940. }
  941. bool
  942. wasm_application_execute_main(WASMModuleInstanceCommon *module_inst,
  943. int argc, char *argv[])
  944. {
  945. WASMFunctionInstanceCommon *func;
  946. WASMType *func_type = NULL;
  947. uint32 argc1 = 0, argv1[2] = { 0 };
  948. uint32 total_argv_size = 0;
  949. uint64 total_size;
  950. int32 argv_buf_offset, i;
  951. char *argv_buf, *p, *p_end;
  952. int32 *argv_offsets;
  953. #if WASM_ENABLE_LIBC_WASI != 0
  954. if (wasm_runtime_is_wasi_mode(module_inst)) {
  955. /* In wasi mode, we should call function named "_start"
  956. which initializes the wasi envrionment and then calls
  957. the actual main function. Directly call main function
  958. may cause exception thrown. */
  959. if ((func = wasm_runtime_lookup_wasi_start_function(module_inst)))
  960. return wasm_runtime_create_exec_env_and_call_wasm(
  961. module_inst, func, 0, NULL);
  962. /* if no start function is found, we execute
  963. the main function as normal */
  964. }
  965. #endif /* end of WASM_ENABLE_LIBC_WASI */
  966. func = resolve_main_function(module_inst);
  967. if (!func) {
  968. wasm_runtime_set_exception(module_inst,
  969. "lookup main function failed.");
  970. return false;
  971. }
  972. #if WASM_ENABLE_INTERP != 0
  973. if (module_inst->module_type == Wasm_Module_Bytecode) {
  974. if (((WASMFunctionInstance*)func)->is_import_func) {
  975. wasm_runtime_set_exception(module_inst,
  976. "lookup main function failed.");
  977. return false;
  978. }
  979. func_type = ((WASMFunctionInstance*)func)->u.func->func_type;
  980. }
  981. #endif
  982. #if WASM_ENABLE_AOT != 0
  983. if (module_inst->module_type == Wasm_Module_AoT)
  984. func_type = ((AOTFunctionInstance*)func)->func_type;
  985. #endif
  986. if (!check_main_func_type(func_type)) {
  987. wasm_runtime_set_exception(module_inst,
  988. "invalid function type of main function.");
  989. return false;
  990. }
  991. if (func_type->param_count) {
  992. for (i = 0; i < argc; i++)
  993. total_argv_size += (uint32)(strlen(argv[i]) + 1);
  994. total_argv_size = align_uint(total_argv_size, 4);
  995. total_size = (uint64)total_argv_size + sizeof(int32) * (uint64)argc;
  996. if (total_size >= UINT32_MAX
  997. || !(argv_buf_offset =
  998. wasm_runtime_module_malloc(module_inst, (uint32)total_size,
  999. (void**)&argv_buf))) {
  1000. wasm_runtime_set_exception(module_inst,
  1001. "allocate memory failed.");
  1002. return false;
  1003. }
  1004. p = argv_buf;
  1005. argv_offsets = (int32*)(p + total_argv_size);
  1006. p_end = p + total_size;
  1007. for (i = 0; i < argc; i++) {
  1008. bh_memcpy_s(p, (uint32)(p_end - p), argv[i], (uint32)(strlen(argv[i]) + 1));
  1009. argv_offsets[i] = argv_buf_offset + (int32)(p - argv_buf);
  1010. p += strlen(argv[i]) + 1;
  1011. }
  1012. argc1 = 2;
  1013. argv1[0] = (uint32)argc;
  1014. argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
  1015. }
  1016. return wasm_runtime_create_exec_env_and_call_wasm(module_inst, func,
  1017. argc1, argv1);
  1018. }
  1019. /**
  1020. * Implementation of wasm_application_execute_func()
  1021. */
  1022. static WASMFunctionInstanceCommon*
  1023. resolve_function(const WASMModuleInstanceCommon *module_inst,
  1024. const char *name)
  1025. {
  1026. uint32 i;
  1027. #if WASM_ENABLE_INTERP != 0
  1028. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1029. WASMModuleInstance *wasm_inst = (WASMModuleInstance*)module_inst;
  1030. for (i = 0; i < wasm_inst->export_func_count; i++) {
  1031. if (!strcmp(wasm_inst->export_functions[i].name, name))
  1032. return wasm_inst->export_functions[i].function;
  1033. }
  1034. return NULL;
  1035. }
  1036. #endif
  1037. #if WASM_ENABLE_AOT != 0
  1038. if (module_inst->module_type == Wasm_Module_AoT) {
  1039. AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
  1040. AOTModule *module = (AOTModule*)aot_inst->aot_module.ptr;
  1041. for (i = 0; i < module->export_func_count; i++) {
  1042. if (!strcmp(module->export_funcs[i].func_name, name))
  1043. return (WASMFunctionInstance*)&module->export_funcs[i];
  1044. }
  1045. return NULL;
  1046. }
  1047. #endif
  1048. return NULL;
  1049. }
  1050. union ieee754_float {
  1051. float f;
  1052. /* This is the IEEE 754 single-precision format. */
  1053. union {
  1054. struct {
  1055. unsigned int negative:1;
  1056. unsigned int exponent:8;
  1057. unsigned int mantissa:23;
  1058. } ieee_big_endian;
  1059. struct {
  1060. unsigned int mantissa:23;
  1061. unsigned int exponent:8;
  1062. unsigned int negative:1;
  1063. } ieee_little_endian;
  1064. } ieee;
  1065. };
  1066. union ieee754_double {
  1067. double d;
  1068. /* This is the IEEE 754 double-precision format. */
  1069. union {
  1070. struct {
  1071. unsigned int negative:1;
  1072. unsigned int exponent:11;
  1073. /* Together these comprise the mantissa. */
  1074. unsigned int mantissa0:20;
  1075. unsigned int mantissa1:32;
  1076. } ieee_big_endian;
  1077. struct {
  1078. /* Together these comprise the mantissa. */
  1079. unsigned int mantissa1:32;
  1080. unsigned int mantissa0:20;
  1081. unsigned int exponent:11;
  1082. unsigned int negative:1;
  1083. } ieee_little_endian;
  1084. } ieee;
  1085. };
  1086. static union {
  1087. int a;
  1088. char b;
  1089. } __ue = { .a = 1 };
  1090. #define is_little_endian() (__ue.b == 1)
  1091. bool
  1092. wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
  1093. const char *name, int argc, char *argv[])
  1094. {
  1095. WASMFunctionInstanceCommon *func;
  1096. WASMType *type = NULL;
  1097. uint32 argc1, *argv1 = NULL;
  1098. int32 i, p;
  1099. uint64 total_size;
  1100. const char *exception;
  1101. char buf[128];
  1102. bh_assert(argc >= 0);
  1103. func = resolve_function(module_inst, name);
  1104. if (!func) {
  1105. snprintf(buf, sizeof(buf), "lookup function %s failed.", name);
  1106. wasm_runtime_set_exception(module_inst, buf);
  1107. goto fail;
  1108. }
  1109. #if WASM_ENABLE_INTERP != 0
  1110. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1111. WASMFunctionInstance *wasm_func = (WASMFunctionInstance*)func;
  1112. if (wasm_func->is_import_func) {
  1113. snprintf(buf, sizeof(buf), "lookup function %s failed.", name);
  1114. wasm_runtime_set_exception(module_inst, buf);
  1115. goto fail;
  1116. }
  1117. type = wasm_func->u.func->func_type;
  1118. argc1 = wasm_func->param_cell_num;
  1119. }
  1120. #endif
  1121. #if WASM_ENABLE_AOT != 0
  1122. if (module_inst->module_type == Wasm_Module_AoT) {
  1123. type = ((AOTFunctionInstance*)func)->func_type;
  1124. argc1 = wasm_type_param_cell_num(type);
  1125. }
  1126. #endif
  1127. if (type->param_count != (uint32)argc) {
  1128. wasm_runtime_set_exception(module_inst,
  1129. "invalid input argument count.");
  1130. goto fail;
  1131. }
  1132. total_size = sizeof(uint32) * (uint64)(argc1 > 2 ? argc1 : 2);
  1133. if (total_size >= UINT32_MAX
  1134. || (!(argv1 = wasm_runtime_malloc((uint32)total_size)))) {
  1135. wasm_runtime_set_exception(module_inst, "allocate memory failed.");
  1136. goto fail;
  1137. }
  1138. /* Clear errno before parsing arguments */
  1139. errno = 0;
  1140. /* Parse arguments */
  1141. for (i = 0, p = 0; i < argc; i++) {
  1142. char *endptr = NULL;
  1143. bh_assert(argv[i] != NULL);
  1144. if (argv[i][0] == '\0') {
  1145. snprintf(buf, sizeof(buf), "invalid input argument %d.", i);
  1146. wasm_runtime_set_exception(module_inst, buf);
  1147. goto fail;
  1148. }
  1149. switch (type->types[i]) {
  1150. case VALUE_TYPE_I32:
  1151. argv1[p++] = (uint32)strtoul(argv[i], &endptr, 0);
  1152. break;
  1153. case VALUE_TYPE_I64:
  1154. {
  1155. union { uint64 val; uint32 parts[2]; } u;
  1156. u.val = strtoull(argv[i], &endptr, 0);
  1157. argv1[p++] = u.parts[0];
  1158. argv1[p++] = u.parts[1];
  1159. break;
  1160. }
  1161. case VALUE_TYPE_F32:
  1162. {
  1163. float32 f32 = strtof(argv[i], &endptr);
  1164. if (isnan(f32)) {
  1165. if (argv[i][0] == '-') {
  1166. union ieee754_float u;
  1167. u.f = f32;
  1168. if (is_little_endian())
  1169. u.ieee.ieee_little_endian.negative = 1;
  1170. else
  1171. u.ieee.ieee_big_endian.negative = 1;
  1172. memcpy(&f32, &u.f, sizeof(float));
  1173. }
  1174. if (endptr[0] == ':') {
  1175. uint32 sig;
  1176. union ieee754_float u;
  1177. sig = (uint32)strtoul(endptr + 1, &endptr, 0);
  1178. u.f = f32;
  1179. if (is_little_endian())
  1180. u.ieee.ieee_little_endian.mantissa = sig;
  1181. else
  1182. u.ieee.ieee_big_endian.mantissa = sig;
  1183. memcpy(&f32, &u.f, sizeof(float));
  1184. }
  1185. }
  1186. memcpy(&argv1[p++], &f32, sizeof(float));
  1187. break;
  1188. }
  1189. case VALUE_TYPE_F64:
  1190. {
  1191. union { float64 val; uint32 parts[2]; } u;
  1192. u.val = strtod(argv[i], &endptr);
  1193. if (isnan(u.val)) {
  1194. if (argv[i][0] == '-') {
  1195. union ieee754_double ud;
  1196. ud.d = u.val;
  1197. if (is_little_endian())
  1198. ud.ieee.ieee_little_endian.negative = 1;
  1199. else
  1200. ud.ieee.ieee_big_endian.negative = 1;
  1201. memcpy(&u.val, &ud.d, sizeof(double));
  1202. }
  1203. if (endptr[0] == ':') {
  1204. uint64 sig;
  1205. union ieee754_double ud;
  1206. sig = strtoull(endptr + 1, &endptr, 0);
  1207. ud.d = u.val;
  1208. if (is_little_endian()) {
  1209. ud.ieee.ieee_little_endian.mantissa0 = sig >> 32;
  1210. ud.ieee.ieee_little_endian.mantissa1 = (uint32)sig;
  1211. }
  1212. else {
  1213. ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
  1214. ud.ieee.ieee_big_endian.mantissa1 = (uint32)sig;
  1215. }
  1216. memcpy(&u.val, &ud.d, sizeof(double));
  1217. }
  1218. }
  1219. argv1[p++] = u.parts[0];
  1220. argv1[p++] = u.parts[1];
  1221. break;
  1222. }
  1223. }
  1224. if (endptr && *endptr != '\0' && *endptr != '_') {
  1225. snprintf(buf, sizeof(buf), "invalid input argument %d: %s.",
  1226. i, argv[i]);
  1227. wasm_runtime_set_exception(module_inst, buf);
  1228. goto fail;
  1229. }
  1230. if (errno != 0) {
  1231. snprintf(buf, sizeof(buf),
  1232. "prepare function argument error, errno: %d.", errno);
  1233. wasm_runtime_set_exception(module_inst, buf);
  1234. goto fail;
  1235. }
  1236. }
  1237. bh_assert(p == (int32)argc1);
  1238. wasm_runtime_set_exception(module_inst, NULL);
  1239. if (!wasm_runtime_create_exec_env_and_call_wasm(module_inst, func,
  1240. argc1, argv1)) {
  1241. goto fail;
  1242. }
  1243. /* print return value */
  1244. switch (type->types[type->param_count]) {
  1245. case VALUE_TYPE_I32:
  1246. bh_printf("0x%x:i32", argv1[0]);
  1247. break;
  1248. case VALUE_TYPE_I64:
  1249. {
  1250. char buf[16];
  1251. union { uint64 val; uint32 parts[2]; } u;
  1252. u.parts[0] = argv1[0];
  1253. u.parts[1] = argv1[1];
  1254. if (sizeof(long) == 4)
  1255. snprintf(buf, sizeof(buf), "%s", "0x%llx:i64");
  1256. else
  1257. snprintf(buf, sizeof(buf), "%s", "0x%lx:i64");
  1258. bh_printf(buf, u.val);
  1259. break;
  1260. }
  1261. case VALUE_TYPE_F32:
  1262. bh_printf("%.7g:f32", *(float32*)argv1);
  1263. break;
  1264. case VALUE_TYPE_F64:
  1265. {
  1266. union { float64 val; uint32 parts[2]; } u;
  1267. u.parts[0] = argv1[0];
  1268. u.parts[1] = argv1[1];
  1269. bh_printf("%.7g:f64", u.val);
  1270. break;
  1271. }
  1272. }
  1273. bh_printf("\n");
  1274. wasm_runtime_free(argv1);
  1275. return true;
  1276. fail:
  1277. if (argv1)
  1278. wasm_runtime_free(argv1);
  1279. exception = wasm_runtime_get_exception(module_inst);
  1280. bh_assert(exception);
  1281. bh_printf("%s\n", exception);
  1282. return false;
  1283. }
  1284. bool
  1285. wasm_runtime_register_natives(const char *module_name,
  1286. NativeSymbol *native_symbols,
  1287. uint32 n_native_symbols)
  1288. {
  1289. return wasm_native_register_natives(module_name,
  1290. native_symbols, n_native_symbols);
  1291. }
  1292. /**
  1293. * Implementation of wasm_runtime_invoke_native()
  1294. */
  1295. static inline void
  1296. word_copy(uint32 *dest, uint32 *src, unsigned num)
  1297. {
  1298. for (; num > 0; num--)
  1299. *dest++ = *src++;
  1300. }
  1301. #define PUT_I64_TO_ADDR(addr, value) do { \
  1302. union { int64 val; uint32 parts[2]; } u; \
  1303. u.val = (value); \
  1304. (addr)[0] = u.parts[0]; \
  1305. (addr)[1] = u.parts[1]; \
  1306. } while (0)
  1307. #define PUT_F64_TO_ADDR(addr, value) do { \
  1308. union { float64 val; uint32 parts[2]; } u; \
  1309. u.val = (value); \
  1310. (addr)[0] = u.parts[0]; \
  1311. (addr)[1] = u.parts[1]; \
  1312. } while (0)
  1313. /* The invoke native implementation on ARM platform with VFP co-processor */
  1314. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP)
  1315. typedef void (*GenericFunctionPointer)();
  1316. int64 invokeNative(GenericFunctionPointer f, uint32 *args, uint32 n_stacks);
  1317. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint32*, uint32);
  1318. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint32*, uint32);
  1319. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint32*,uint32);
  1320. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint32*, uint32);
  1321. typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint32*, uint32);
  1322. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  1323. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  1324. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  1325. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  1326. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  1327. #define MAX_REG_INTS 4
  1328. #define MAX_REG_FLOATS 16
  1329. bool
  1330. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  1331. const WASMType *func_type, const char *signature,
  1332. uint32 *argv, uint32 argc, uint32 *argv_ret)
  1333. {
  1334. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  1335. /* argv buf layout: int args(fix cnt) + float args(fix cnt) + stack args */
  1336. uint32 argv_buf[32], *argv1 = argv_buf, *fps, *ints, *stacks, size;
  1337. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_fps = 0, n_stacks = 0;
  1338. uint32 arg_i32, ptr_len;
  1339. bool ret = false;
  1340. n_ints++; /* exec env */
  1341. /* Traverse firstly to calculate stack args count */
  1342. for (i = 0; i < func_type->param_count; i++) {
  1343. switch (func_type->types[i]) {
  1344. case VALUE_TYPE_I32:
  1345. if (n_ints < MAX_REG_INTS)
  1346. n_ints++;
  1347. else
  1348. n_stacks++;
  1349. break;
  1350. case VALUE_TYPE_I64:
  1351. if (n_ints < MAX_REG_INTS - 1) {
  1352. /* 64-bit data must be 8 bytes aligned in arm */
  1353. if (n_ints & 1)
  1354. n_ints++;
  1355. n_ints += 2;
  1356. }
  1357. else {
  1358. /* 64-bit data must be 8 bytes aligned in arm */
  1359. if (n_stacks & 1)
  1360. n_stacks++;
  1361. n_stacks += 2;
  1362. }
  1363. break;
  1364. case VALUE_TYPE_F32:
  1365. if (n_fps < MAX_REG_FLOATS)
  1366. n_fps++;
  1367. else
  1368. n_stacks++;
  1369. break;
  1370. case VALUE_TYPE_F64:
  1371. if (n_fps < MAX_REG_FLOATS - 1) {
  1372. /* 64-bit data must be 8 bytes aligned in arm */
  1373. if (n_fps & 1)
  1374. n_fps++;
  1375. n_fps += 2;
  1376. }
  1377. else {
  1378. /* 64-bit data must be 8 bytes aligned in arm */
  1379. if (n_stacks & 1)
  1380. n_stacks++;
  1381. n_stacks += 2;
  1382. }
  1383. break;
  1384. default:
  1385. bh_assert(0);
  1386. break;
  1387. }
  1388. }
  1389. argc1 = MAX_REG_INTS + MAX_REG_FLOATS + n_stacks;
  1390. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  1391. size = sizeof(uint32) * (uint32)argc1;
  1392. if (size >= UINT32_MAX
  1393. || !(argv1 = wasm_runtime_malloc((uint32)size))) {
  1394. wasm_runtime_set_exception(exec_env->module_inst,
  1395. "allocate memory failed.");
  1396. return false;
  1397. }
  1398. }
  1399. ints = argv1;
  1400. fps = ints + MAX_REG_INTS;
  1401. stacks = fps + MAX_REG_FLOATS;
  1402. n_ints = 0;
  1403. n_fps = 0;
  1404. n_stacks = 0;
  1405. ints[n_ints++] = (uint32)(uintptr_t)exec_env;
  1406. /* Traverse secondly to fill in each argument */
  1407. for (i = 0; i < func_type->param_count; i++) {
  1408. switch (func_type->types[i]) {
  1409. case VALUE_TYPE_I32:
  1410. {
  1411. arg_i32 = *argv_src++;
  1412. if (signature) {
  1413. if (signature[i + 1] == '*') {
  1414. /* param is a pointer */
  1415. if (signature[i + 2] == '~')
  1416. /* pointer with length followed */
  1417. ptr_len = *argv_src;
  1418. else
  1419. /* pointer without length followed */
  1420. ptr_len = 1;
  1421. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  1422. goto fail;
  1423. arg_i32 = (uintptr_t)
  1424. wasm_runtime_addr_app_to_native(module, arg_i32);
  1425. }
  1426. else if (signature[i + 1] == '$') {
  1427. /* param is a string */
  1428. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  1429. goto fail;
  1430. arg_i32 = (uintptr_t)
  1431. wasm_runtime_addr_app_to_native(module, arg_i32);
  1432. }
  1433. }
  1434. if (n_ints < MAX_REG_INTS)
  1435. ints[n_ints++] = arg_i32;
  1436. else
  1437. stacks[n_stacks++] = arg_i32;
  1438. break;
  1439. }
  1440. case VALUE_TYPE_I64:
  1441. if (n_ints < MAX_REG_INTS - 1) {
  1442. /* 64-bit data must be 8 bytes aligned in arm */
  1443. if (n_ints & 1)
  1444. n_ints++;
  1445. *(uint64*)&ints[n_ints] = *(uint64*)argv_src;
  1446. n_ints += 2;
  1447. }
  1448. else {
  1449. /* 64-bit data must be 8 bytes aligned in arm */
  1450. if (n_stacks & 1)
  1451. n_stacks++;
  1452. *(uint64*)&stacks[n_stacks] = *(uint64*)argv_src;
  1453. n_stacks += 2;
  1454. }
  1455. argv_src += 2;
  1456. break;
  1457. case VALUE_TYPE_F32:
  1458. if (n_fps < MAX_REG_FLOATS)
  1459. *(float32*)&fps[n_fps++] = *(float32*)argv_src++;
  1460. else
  1461. *(float32*)&stacks[n_stacks++] = *(float32*)argv_src++;
  1462. break;
  1463. case VALUE_TYPE_F64:
  1464. if (n_fps < MAX_REG_FLOATS - 1) {
  1465. /* 64-bit data must be 8 bytes aligned in arm */
  1466. if (n_fps & 1)
  1467. n_fps++;
  1468. *(float64*)&fps[n_fps] = *(float64*)argv_src;
  1469. n_fps += 2;
  1470. }
  1471. else {
  1472. /* 64-bit data must be 8 bytes aligned in arm */
  1473. if (n_stacks & 1)
  1474. n_stacks++;
  1475. *(float64*)&stacks[n_stacks] = *(float64*)argv_src;
  1476. n_stacks += 2;
  1477. }
  1478. argv_src += 2;
  1479. break;
  1480. default:
  1481. bh_assert(0);
  1482. break;
  1483. }
  1484. }
  1485. if (func_type->result_count == 0) {
  1486. invokeNative_Void(func_ptr, argv1, n_stacks);
  1487. }
  1488. else {
  1489. switch (func_type->types[func_type->param_count]) {
  1490. case VALUE_TYPE_I32:
  1491. argv_ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
  1492. break;
  1493. case VALUE_TYPE_I64:
  1494. PUT_I64_TO_ADDR(argv_ret, invokeNative_Int64(func_ptr, argv1, n_stacks));
  1495. break;
  1496. case VALUE_TYPE_F32:
  1497. *(float32*)argv_ret = invokeNative_Float32(func_ptr, argv1, n_stacks);
  1498. break;
  1499. case VALUE_TYPE_F64:
  1500. PUT_F64_TO_ADDR(argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
  1501. break;
  1502. default:
  1503. bh_assert(0);
  1504. break;
  1505. }
  1506. }
  1507. ret = true;
  1508. fail:
  1509. if (argv1 != argv_buf)
  1510. wasm_runtime_free(argv1);
  1511. return ret;
  1512. }
  1513. #endif /* end of defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP) */
  1514. #if defined(BUILD_TARGET_X86_32) \
  1515. || defined(BUILD_TARGET_ARM) \
  1516. || defined(BUILD_TARGET_THUMB) \
  1517. || defined(BUILD_TARGET_MIPS) \
  1518. || defined(BUILD_TARGET_XTENSA)
  1519. typedef void (*GenericFunctionPointer)();
  1520. int64 invokeNative(GenericFunctionPointer f, uint32 *args, uint32 sz);
  1521. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  1522. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  1523. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  1524. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  1525. typedef void (*VoidFuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  1526. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  1527. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  1528. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  1529. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  1530. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  1531. bool
  1532. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  1533. const WASMType *func_type, const char *signature,
  1534. uint32 *argv, uint32 argc, uint32 *argv_ret)
  1535. {
  1536. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  1537. uint32 argv_buf[32], *argv1 = argv_buf, argc1, i, j = 0;
  1538. uint32 arg_i32, ptr_len;
  1539. uint64 size;
  1540. bool ret = false;
  1541. #if defined(BUILD_TARGET_X86_32)
  1542. argc1 = argc + 2;
  1543. #else
  1544. /* arm/thumb/mips/xtensa, 64-bit data must be 8 bytes aligned,
  1545. so we need to allocate more memory. */
  1546. argc1 = func_type->param_count * 2 + 2;
  1547. #endif
  1548. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  1549. size = sizeof(uint32) * (uint64)argc1;
  1550. if (size >= UINT_MAX
  1551. || !(argv1 = wasm_runtime_malloc((uint32)size))) {
  1552. wasm_runtime_set_exception(exec_env->module_inst,
  1553. "allocate memory failed.");
  1554. return false;
  1555. }
  1556. }
  1557. for (i = 0; i < sizeof(WASMExecEnv*) / sizeof(uint32); i++)
  1558. argv1[j++] = ((uint32*)&exec_env)[i];
  1559. for (i = 0; i < func_type->param_count; i++) {
  1560. switch (func_type->types[i]) {
  1561. case VALUE_TYPE_I32:
  1562. {
  1563. arg_i32 = *argv++;
  1564. if (signature) {
  1565. if (signature[i + 1] == '*') {
  1566. /* param is a pointer */
  1567. if (signature[i + 2] == '~')
  1568. /* pointer with length followed */
  1569. ptr_len = *argv;
  1570. else
  1571. /* pointer without length followed */
  1572. ptr_len = 1;
  1573. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  1574. goto fail;
  1575. arg_i32 = (uintptr_t)
  1576. wasm_runtime_addr_app_to_native(module, arg_i32);
  1577. }
  1578. else if (signature[i + 1] == '$') {
  1579. /* param is a string */
  1580. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  1581. goto fail;
  1582. arg_i32 = (uintptr_t)
  1583. wasm_runtime_addr_app_to_native(module, arg_i32);
  1584. }
  1585. }
  1586. argv1[j++] = arg_i32;
  1587. break;
  1588. }
  1589. case VALUE_TYPE_I64:
  1590. case VALUE_TYPE_F64:
  1591. #if !defined(BUILD_TARGET_X86_32)
  1592. /* 64-bit data must be 8 bytes aligned in arm, thumb, mips
  1593. and xtensa */
  1594. if (j & 1)
  1595. j++;
  1596. #endif
  1597. argv1[j++] = *argv++;
  1598. argv1[j++] = *argv++;
  1599. break;
  1600. case VALUE_TYPE_F32:
  1601. argv1[j++] = *argv++;
  1602. break;
  1603. default:
  1604. bh_assert(0);
  1605. break;
  1606. }
  1607. }
  1608. argc1 = j;
  1609. if (func_type->result_count == 0) {
  1610. invokeNative_Void(func_ptr, argv1, argc1);
  1611. }
  1612. else {
  1613. switch (func_type->types[func_type->param_count]) {
  1614. case VALUE_TYPE_I32:
  1615. argv_ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
  1616. break;
  1617. case VALUE_TYPE_I64:
  1618. PUT_I64_TO_ADDR(argv_ret, invokeNative_Int64(func_ptr, argv1, argc1));
  1619. break;
  1620. case VALUE_TYPE_F32:
  1621. *(float32*)argv_ret = invokeNative_Float32(func_ptr, argv1, argc1);
  1622. break;
  1623. case VALUE_TYPE_F64:
  1624. PUT_F64_TO_ADDR(argv_ret, invokeNative_Float64(func_ptr, argv1, argc1));
  1625. break;
  1626. default:
  1627. bh_assert(0);
  1628. break;
  1629. }
  1630. }
  1631. ret = true;
  1632. fail:
  1633. if (argv1 != argv_buf)
  1634. wasm_runtime_free(argv1);
  1635. return ret;
  1636. }
  1637. #endif /* end of defined(BUILD_TARGET_X86_32) \
  1638. || defined(BUILD_TARGET_ARM) \
  1639. || defined(BUILD_TARGET_THUMB) \
  1640. || defined(BUILD_TARGET_MIPS) \
  1641. || defined(BUILD_TARGET_XTENSA) */
  1642. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
  1643. typedef void (*GenericFunctionPointer)();
  1644. int64 invokeNative(GenericFunctionPointer f, uint64 *args, uint64 n_stacks);
  1645. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  1646. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  1647. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64*,uint64);
  1648. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  1649. typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64*, uint64);
  1650. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  1651. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  1652. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  1653. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  1654. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  1655. #if defined(_WIN32) || defined(_WIN32_)
  1656. #define MAX_REG_FLOATS 4
  1657. #define MAX_REG_INTS 4
  1658. #else
  1659. #define MAX_REG_FLOATS 8
  1660. #define MAX_REG_INTS 6
  1661. #endif
  1662. bool
  1663. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  1664. const WASMType *func_type, const char *signature,
  1665. uint32 *argv, uint32 argc, uint32 *argv_ret)
  1666. {
  1667. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  1668. uint64 argv_buf[32], *argv1 = argv_buf, *fps, *ints, *stacks, size, arg_i64;
  1669. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
  1670. uint32 arg_i32, ptr_len;
  1671. bool ret = false;
  1672. #if defined(_WIN32) || defined(_WIN32_)
  1673. /* important difference in calling conventions */
  1674. #define n_fps n_ints
  1675. #else
  1676. int n_fps = 0;
  1677. #endif
  1678. argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2;
  1679. if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
  1680. size = sizeof(uint64) * (uint64)argc1;
  1681. if (size >= UINT32_MAX
  1682. || !(argv1 = wasm_runtime_malloc((uint32)size))) {
  1683. wasm_runtime_set_exception(exec_env->module_inst,
  1684. "allocate memory failed.");
  1685. return false;
  1686. }
  1687. }
  1688. fps = argv1;
  1689. ints = fps + MAX_REG_FLOATS;
  1690. stacks = ints + MAX_REG_INTS;
  1691. ints[n_ints++] = (uint64)(uintptr_t)exec_env;
  1692. for (i = 0; i < func_type->param_count; i++) {
  1693. switch (func_type->types[i]) {
  1694. case VALUE_TYPE_I32:
  1695. {
  1696. arg_i32 = *argv_src++;
  1697. arg_i64 = arg_i32;
  1698. if (signature) {
  1699. if (signature[i + 1] == '*') {
  1700. /* param is a pointer */
  1701. if (signature[i + 2] == '~')
  1702. /* pointer with length followed */
  1703. ptr_len = *argv_src;
  1704. else
  1705. /* pointer without length followed */
  1706. ptr_len = 1;
  1707. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  1708. goto fail;
  1709. arg_i64 = (uintptr_t)
  1710. wasm_runtime_addr_app_to_native(module, arg_i32);
  1711. }
  1712. else if (signature[i + 1] == '$') {
  1713. /* param is a string */
  1714. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  1715. goto fail;
  1716. arg_i64 = (uintptr_t)
  1717. wasm_runtime_addr_app_to_native(module, arg_i32);
  1718. }
  1719. }
  1720. if (n_ints < MAX_REG_INTS)
  1721. ints[n_ints++] = arg_i64;
  1722. else
  1723. stacks[n_stacks++] = arg_i64;
  1724. break;
  1725. }
  1726. case VALUE_TYPE_I64:
  1727. if (n_ints < MAX_REG_INTS)
  1728. ints[n_ints++] = *(uint64*)argv_src;
  1729. else
  1730. stacks[n_stacks++] = *(uint64*)argv_src;
  1731. argv_src += 2;
  1732. break;
  1733. case VALUE_TYPE_F32:
  1734. if (n_fps < MAX_REG_FLOATS)
  1735. *(float32*)&fps[n_fps++] = *(float32*)argv_src++;
  1736. else
  1737. *(float32*)&stacks[n_stacks++] = *(float32*)argv_src++;
  1738. break;
  1739. case VALUE_TYPE_F64:
  1740. if (n_fps < MAX_REG_FLOATS)
  1741. *(float64*)&fps[n_fps++] = *(float64*)argv_src;
  1742. else
  1743. *(float64*)&stacks[n_stacks++] = *(float64*)argv_src;
  1744. argv_src += 2;
  1745. break;
  1746. default:
  1747. bh_assert(0);
  1748. break;
  1749. }
  1750. }
  1751. if (func_type->result_count == 0) {
  1752. invokeNative_Void(func_ptr, argv1, n_stacks);
  1753. }
  1754. else {
  1755. switch (func_type->types[func_type->param_count]) {
  1756. case VALUE_TYPE_I32:
  1757. argv_ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
  1758. break;
  1759. case VALUE_TYPE_I64:
  1760. PUT_I64_TO_ADDR(argv_ret, invokeNative_Int64(func_ptr, argv1, n_stacks));
  1761. break;
  1762. case VALUE_TYPE_F32:
  1763. *(float32*)argv_ret = invokeNative_Float32(func_ptr, argv1, n_stacks);
  1764. break;
  1765. case VALUE_TYPE_F64:
  1766. PUT_F64_TO_ADDR(argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
  1767. break;
  1768. default:
  1769. bh_assert(0);
  1770. break;
  1771. }
  1772. }
  1773. ret = true;
  1774. fail:
  1775. if (argv1 != argv_buf)
  1776. wasm_runtime_free(argv1);
  1777. return ret;
  1778. }
  1779. #endif /* end of defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) */