wasm_runtime_common.c 72 KB

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