main.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "bh_platform.h"
  8. #include "bh_read_file.h"
  9. #include "wasm_export.h"
  10. #if WASM_ENABLE_LIBC_WASI != 0
  11. #include "../common/libc_wasi.c"
  12. #endif
  13. #include "../common/wasm_proposal.c"
  14. static int app_argc;
  15. static char **app_argv;
  16. /* clang-format off */
  17. static int
  18. print_help(void)
  19. {
  20. printf("Usage: iwasm [-options] wasm_file [args...]\n");
  21. printf("options:\n");
  22. printf(" -f|--function name Specify a function name of the module to run rather\n"
  23. " than main\n");
  24. #if WASM_ENABLE_LOG != 0
  25. printf(" -v=n Set log verbose level (0 to 5, default is 2) larger\n"
  26. " level with more log\n");
  27. #endif
  28. #if WASM_ENABLE_INTERP != 0
  29. printf(" --interp Run the wasm app with interpreter mode\n");
  30. #endif
  31. #if WASM_ENABLE_FAST_JIT != 0
  32. printf(" --fast-jit Run the wasm app with fast jit mode\n");
  33. #endif
  34. #if WASM_ENABLE_JIT != 0
  35. printf(" --llvm-jit Run the wasm app with llvm jit mode\n");
  36. #endif
  37. #if WASM_ENABLE_JIT != 0 && WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_LAZY_JIT != 0
  38. printf(" --multi-tier-jit Run the wasm app with multi-tier jit mode\n");
  39. #endif
  40. printf(" --stack-size=n Set maximum stack size in bytes, default is 64 KB\n");
  41. #if WASM_ENABLE_LIBC_WASI !=0
  42. printf(" --heap-size=n Set maximum heap size in bytes, default is 0 KB when libc wasi is enabled\n");
  43. #else
  44. printf(" --heap-size=n Set maximum heap size in bytes, default is 16 KB when libc wasi is diabled\n");
  45. #endif
  46. #if WASM_ENABLE_SHARED_HEAP != 0
  47. printf(" --shared-heap-size=n Create shared heap of n bytes and attach to the wasm app.\n");
  48. printf(" The size n will be adjusted to a minumum number aligned to page size\n");
  49. #endif
  50. #if WASM_ENABLE_FAST_JIT != 0
  51. printf(" --jit-codecache-size=n Set fast jit maximum code cache size in bytes,\n");
  52. printf(" default is %u KB\n", FAST_JIT_DEFAULT_CODE_CACHE_SIZE / 1024);
  53. #endif
  54. #if WASM_ENABLE_GC != 0
  55. printf(" --gc-heap-size=n Set maximum gc heap size in bytes,\n");
  56. printf(" default is %u KB\n", GC_HEAP_SIZE_DEFAULT / 1024);
  57. #endif
  58. #if WASM_ENABLE_JIT != 0
  59. printf(" --llvm-jit-size-level=n Set LLVM JIT size level, default is 3\n");
  60. printf(" --llvm-jit-opt-level=n Set LLVM JIT optimization level, default is 3\n");
  61. #endif /* WASM_ENABLE_JIT != 0 */
  62. printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
  63. " that runs commands in the form of `FUNC ARG...`\n");
  64. #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
  65. printf(" --disable-bounds-checks Disable bounds checks for memory accesses\n");
  66. #endif
  67. #if WASM_ENABLE_LIBC_WASI != 0
  68. libc_wasi_print_help();
  69. #endif
  70. #if WASM_ENABLE_MULTI_MODULE != 0
  71. printf(" --module-path=<path> Indicate a module search path. default is current\n"
  72. " directory('./')\n");
  73. #endif
  74. #if WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
  75. printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n");
  76. #endif
  77. #if WASM_ENABLE_DEBUG_INTERP != 0
  78. printf(" -g=ip:port Set the debug sever address, default is debug disabled\n");
  79. printf(" if port is 0, then a random port will be used\n");
  80. #endif
  81. printf(" --version Show version information\n");
  82. return 1;
  83. }
  84. /* clang-format on */
  85. static const void *
  86. app_instance_main(wasm_module_inst_t module_inst)
  87. {
  88. const char *exception;
  89. wasm_application_execute_main(module_inst, app_argc, app_argv);
  90. exception = wasm_runtime_get_exception(module_inst);
  91. return exception;
  92. }
  93. static const void *
  94. app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
  95. {
  96. wasm_application_execute_func(module_inst, func_name, app_argc - 1,
  97. app_argv + 1);
  98. /* The result of wasm function or exception info was output inside
  99. wasm_application_execute_func(), here we don't output them again. */
  100. return wasm_runtime_get_exception(module_inst);
  101. }
  102. /**
  103. * Split a space separated strings into an array of strings
  104. * Returns NULL on failure
  105. * Memory must be freed by caller
  106. * Based on: http://stackoverflow.com/a/11198630/471795
  107. */
  108. static char **
  109. split_string(char *str, int *count)
  110. {
  111. char **res = NULL, **res1;
  112. char *p, *next_token;
  113. int idx = 0;
  114. /* split string and append tokens to 'res' */
  115. do {
  116. p = strtok_s(str, " ", &next_token);
  117. str = NULL;
  118. res1 = res;
  119. res = (char **)realloc(res1, sizeof(char *) * (uint32)(idx + 1));
  120. if (res == NULL) {
  121. free(res1);
  122. return NULL;
  123. }
  124. res[idx++] = p;
  125. } while (p);
  126. /**
  127. * Due to the function name,
  128. * res[0] might contain a '\' to indicate a space
  129. * func\name -> func name
  130. */
  131. p = strchr(res[0], '\\');
  132. while (p) {
  133. *p = ' ';
  134. p = strchr(p, '\\');
  135. }
  136. if (count) {
  137. *count = idx - 1;
  138. }
  139. return res;
  140. }
  141. static void *
  142. app_instance_repl(wasm_module_inst_t module_inst)
  143. {
  144. char buffer[4096];
  145. char *cmd;
  146. size_t n;
  147. while ((printf("webassembly> "), fflush(stdout),
  148. cmd = fgets(buffer, sizeof(buffer), stdin))
  149. != NULL) {
  150. bh_assert(cmd);
  151. n = strlen(cmd);
  152. if (cmd[n - 1] == '\n') {
  153. if (n == 1)
  154. continue;
  155. else
  156. cmd[n - 1] = '\0';
  157. }
  158. if (!strcmp(cmd, "__exit__")) {
  159. printf("exit repl mode\n");
  160. break;
  161. }
  162. app_argv = split_string(cmd, &app_argc);
  163. if (app_argv == NULL) {
  164. LOG_ERROR("Wasm prepare param failed: split string failed.\n");
  165. break;
  166. }
  167. if (app_argc != 0) {
  168. const char *exception;
  169. wasm_application_execute_func(module_inst, app_argv[0],
  170. app_argc - 1, app_argv + 1);
  171. if ((exception = wasm_runtime_get_exception(module_inst)))
  172. printf("%s\n", exception);
  173. }
  174. free(app_argv);
  175. }
  176. return NULL;
  177. }
  178. #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
  179. static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
  180. #else
  181. static void *
  182. malloc_func(
  183. #if WASM_MEM_ALLOC_WITH_USAGE != 0
  184. mem_alloc_usage_t usage,
  185. #endif
  186. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  187. void *user_data,
  188. #endif
  189. unsigned int size)
  190. {
  191. return malloc(size);
  192. }
  193. static void *
  194. realloc_func(
  195. #if WASM_MEM_ALLOC_WITH_USAGE != 0
  196. mem_alloc_usage_t usage, bool full_size_mmaped,
  197. #endif
  198. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  199. void *user_data,
  200. #endif
  201. void *ptr, unsigned int size)
  202. {
  203. return realloc(ptr, size);
  204. }
  205. static void
  206. free_func(
  207. #if WASM_MEM_ALLOC_WITH_USAGE != 0
  208. mem_alloc_usage_t usage,
  209. #endif
  210. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  211. void *user_data,
  212. #endif
  213. void *ptr)
  214. {
  215. free(ptr);
  216. }
  217. #endif /* end of WASM_ENABLE_GLOBAL_HEAP_POOL */
  218. #if WASM_ENABLE_MULTI_MODULE != 0
  219. static char *
  220. handle_module_path(const char *module_path)
  221. {
  222. /* next character after '=' */
  223. return (strchr(module_path, '=')) + 1;
  224. }
  225. static char *module_search_path = ".";
  226. static bool
  227. module_reader_callback(package_type_t module_type, const char *module_name,
  228. uint8 **p_buffer, uint32 *p_size)
  229. {
  230. char *file_format = NULL;
  231. #if WASM_ENABLE_INTERP != 0
  232. if (module_type == Wasm_Module_Bytecode)
  233. file_format = ".wasm";
  234. #endif
  235. #if WASM_ENABLE_AOT != 0
  236. if (module_type == Wasm_Module_AoT)
  237. file_format = ".aot";
  238. #endif
  239. bh_assert(file_format);
  240. const char *format = "%s/%s%s";
  241. int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
  242. + strlen(file_format) + 1;
  243. char *wasm_file_name = wasm_runtime_malloc(sz);
  244. if (!wasm_file_name) {
  245. return false;
  246. }
  247. snprintf(wasm_file_name, sz, format, module_search_path, module_name,
  248. file_format);
  249. *p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_name, p_size);
  250. wasm_runtime_free(wasm_file_name);
  251. return *p_buffer != NULL;
  252. }
  253. static void
  254. module_destroyer_callback(uint8 *buffer, uint32 size)
  255. {
  256. if (!buffer) {
  257. return;
  258. }
  259. wasm_runtime_free(buffer);
  260. buffer = NULL;
  261. }
  262. #endif /* WASM_ENABLE_MULTI_MODULE */
  263. int
  264. main(int argc, char *argv[])
  265. {
  266. int32 ret = -1;
  267. char *wasm_file = NULL;
  268. const char *func_name = NULL;
  269. uint8 *wasm_file_buf = NULL;
  270. uint32 wasm_file_size;
  271. uint32 stack_size = 64 * 1024;
  272. #if WASM_ENABLE_LIBC_WASI != 0
  273. uint32 heap_size = 0;
  274. #else
  275. uint32 heap_size = 16 * 1024;
  276. #endif
  277. #if WASM_ENABLE_SHARED_HEAP != 0
  278. SharedHeapInitArgs shared_heap_init_args;
  279. uint32 shared_heap_size = 0;
  280. void *shared_heap = NULL;
  281. #endif
  282. #if WASM_ENABLE_FAST_JIT != 0
  283. uint32 jit_code_cache_size = FAST_JIT_DEFAULT_CODE_CACHE_SIZE;
  284. #endif
  285. #if WASM_ENABLE_GC != 0
  286. uint32 gc_heap_size = GC_HEAP_SIZE_DEFAULT;
  287. #endif
  288. #if WASM_ENABLE_JIT != 0
  289. uint32 llvm_jit_size_level = 3;
  290. uint32 llvm_jit_opt_level = 3;
  291. #endif
  292. wasm_module_t wasm_module = NULL;
  293. wasm_module_inst_t wasm_module_inst = NULL;
  294. RunningMode running_mode = 0;
  295. RuntimeInitArgs init_args;
  296. struct InstantiationArgs2 *inst_args;
  297. char error_buf[128] = { 0 };
  298. #if WASM_ENABLE_LOG != 0
  299. int log_verbose_level = 2;
  300. #endif
  301. bool is_repl_mode = false;
  302. bool is_xip_file = false;
  303. #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
  304. bool disable_bounds_checks = false;
  305. #endif
  306. #if WASM_ENABLE_LIBC_WASI != 0
  307. libc_wasi_parse_context_t wasi_parse_ctx;
  308. #endif
  309. #if WASM_ENABLE_DEBUG_INTERP != 0
  310. char *ip_addr = NULL;
  311. int instance_port = 0;
  312. #endif
  313. #if WASM_ENABLE_LIBC_WASI != 0
  314. memset(&wasi_parse_ctx, 0, sizeof(wasi_parse_ctx));
  315. #endif
  316. /* Process options. */
  317. for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
  318. if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
  319. argc--, argv++;
  320. if (argc < 2) {
  321. return print_help();
  322. }
  323. func_name = argv[0];
  324. }
  325. #if WASM_ENABLE_INTERP != 0
  326. else if (!strcmp(argv[0], "--interp")) {
  327. running_mode = Mode_Interp;
  328. }
  329. #endif
  330. #if WASM_ENABLE_FAST_JIT != 0
  331. else if (!strcmp(argv[0], "--fast-jit")) {
  332. running_mode = Mode_Fast_JIT;
  333. }
  334. #endif
  335. #if WASM_ENABLE_JIT != 0
  336. else if (!strcmp(argv[0], "--llvm-jit")) {
  337. running_mode = Mode_LLVM_JIT;
  338. }
  339. #endif
  340. #if WASM_ENABLE_JIT != 0 && WASM_ENABLE_FAST_JIT != 0
  341. else if (!strcmp(argv[0], "--multi-tier-jit")) {
  342. running_mode = Mode_Multi_Tier_JIT;
  343. }
  344. #endif
  345. #if WASM_ENABLE_LOG != 0
  346. else if (!strncmp(argv[0], "-v=", 3)) {
  347. log_verbose_level = atoi(argv[0] + 3);
  348. if (log_verbose_level < 0 || log_verbose_level > 5)
  349. return print_help();
  350. }
  351. #endif
  352. else if (!strcmp(argv[0], "--repl")) {
  353. is_repl_mode = true;
  354. }
  355. #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
  356. else if (!strcmp(argv[0], "--disable-bounds-checks")) {
  357. disable_bounds_checks = true;
  358. }
  359. #endif
  360. else if (!strncmp(argv[0], "--stack-size=", 13)) {
  361. if (argv[0][13] == '\0')
  362. return print_help();
  363. stack_size = atoi(argv[0] + 13);
  364. }
  365. else if (!strncmp(argv[0], "--heap-size=", 12)) {
  366. if (argv[0][12] == '\0')
  367. return print_help();
  368. heap_size = atoi(argv[0] + 12);
  369. }
  370. #if WASM_ENABLE_SHARED_HEAP != 0
  371. else if (!strncmp(argv[0], "--shared-heap-size=", 19)) {
  372. if (argv[0][19] == '\0')
  373. return print_help();
  374. shared_heap_size = atoi(argv[0] + 19);
  375. }
  376. #endif
  377. #if WASM_ENABLE_FAST_JIT != 0
  378. else if (!strncmp(argv[0], "--jit-codecache-size=", 21)) {
  379. if (argv[0][21] == '\0')
  380. return print_help();
  381. jit_code_cache_size = atoi(argv[0] + 21);
  382. }
  383. #endif
  384. #if WASM_ENABLE_GC != 0
  385. else if (!strncmp(argv[0], "--gc-heap-size=", 15)) {
  386. if (argv[0][15] == '\0')
  387. return print_help();
  388. gc_heap_size = atoi(argv[0] + 15);
  389. }
  390. #endif
  391. #if WASM_ENABLE_JIT != 0
  392. else if (!strncmp(argv[0], "--llvm-jit-size-level=", 22)) {
  393. if (argv[0][22] == '\0')
  394. return print_help();
  395. llvm_jit_size_level = atoi(argv[0] + 22);
  396. if (llvm_jit_size_level < 1) {
  397. printf("LLVM JIT size level shouldn't be smaller than 1, "
  398. "setting it to 1\n");
  399. llvm_jit_size_level = 1;
  400. }
  401. else if (llvm_jit_size_level > 3) {
  402. printf("LLVM JIT size level shouldn't be greater than 3, "
  403. "setting it to 3\n");
  404. llvm_jit_size_level = 3;
  405. }
  406. }
  407. else if (!strncmp(argv[0], "--llvm-jit-opt-level=", 21)) {
  408. if (argv[0][21] == '\0')
  409. return print_help();
  410. llvm_jit_opt_level = atoi(argv[0] + 21);
  411. if (llvm_jit_opt_level < 1) {
  412. printf("LLVM JIT opt level shouldn't be smaller than 1, "
  413. "setting it to 1\n");
  414. llvm_jit_opt_level = 1;
  415. }
  416. else if (llvm_jit_opt_level > 3) {
  417. printf("LLVM JIT opt level shouldn't be greater than 3, "
  418. "setting it to 3\n");
  419. llvm_jit_opt_level = 3;
  420. }
  421. }
  422. #endif
  423. #if WASM_ENABLE_MULTI_MODULE != 0
  424. else if (!strncmp(argv[0],
  425. "--module-path=", strlen("--module-path="))) {
  426. module_search_path = handle_module_path(argv[0]);
  427. if (!strlen(module_search_path)) {
  428. return print_help();
  429. }
  430. }
  431. #endif
  432. #if WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
  433. else if (!strncmp(argv[0], "--max-threads=", 14)) {
  434. if (argv[0][14] == '\0')
  435. return print_help();
  436. wasm_runtime_set_max_thread_num(atoi(argv[0] + 14));
  437. }
  438. #endif
  439. #if WASM_ENABLE_DEBUG_INTERP != 0
  440. else if (!strncmp(argv[0], "-g=", 3)) {
  441. char *port_str = strchr(argv[0] + 3, ':');
  442. char *port_end;
  443. if (port_str == NULL)
  444. return print_help();
  445. *port_str = '\0';
  446. instance_port = strtoul(port_str + 1, &port_end, 10);
  447. if (port_str[1] == '\0' || *port_end != '\0')
  448. return print_help();
  449. ip_addr = argv[0] + 3;
  450. }
  451. #endif
  452. else if (!strcmp(argv[0], "--version")) {
  453. uint32 major, minor, patch;
  454. wasm_runtime_get_version(&major, &minor, &patch);
  455. printf("iwasm %" PRIu32 ".%" PRIu32 ".%" PRIu32 "\n", major, minor,
  456. patch);
  457. printf("\n");
  458. wasm_proposal_print_status();
  459. return 0;
  460. }
  461. else {
  462. #if WASM_ENABLE_LIBC_WASI != 0
  463. libc_wasi_parse_result_t result =
  464. libc_wasi_parse(argv[0], &wasi_parse_ctx);
  465. switch (result) {
  466. case LIBC_WASI_PARSE_RESULT_OK:
  467. continue;
  468. case LIBC_WASI_PARSE_RESULT_NEED_HELP:
  469. return print_help();
  470. case LIBC_WASI_PARSE_RESULT_BAD_PARAM:
  471. return 1;
  472. }
  473. #else
  474. return print_help();
  475. #endif
  476. }
  477. }
  478. if (argc == 0)
  479. return print_help();
  480. wasm_file = argv[0];
  481. app_argc = argc;
  482. app_argv = argv;
  483. memset(&init_args, 0, sizeof(RuntimeInitArgs));
  484. init_args.running_mode = running_mode;
  485. #if WASM_ENABLE_GLOBAL_HEAP_POOL != 0
  486. init_args.mem_alloc_type = Alloc_With_Pool;
  487. init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
  488. init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
  489. #else
  490. init_args.mem_alloc_type = Alloc_With_Allocator;
  491. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  492. /* Set user data for the allocator is needed */
  493. /* init_args.mem_alloc_option.allocator.user_data = user_data; */
  494. #endif
  495. init_args.mem_alloc_option.allocator.malloc_func = malloc_func;
  496. init_args.mem_alloc_option.allocator.realloc_func = realloc_func;
  497. init_args.mem_alloc_option.allocator.free_func = free_func;
  498. #endif
  499. #if WASM_ENABLE_FAST_JIT != 0
  500. init_args.fast_jit_code_cache_size = jit_code_cache_size;
  501. #endif
  502. #if WASM_ENABLE_GC != 0
  503. init_args.gc_heap_size = gc_heap_size;
  504. #endif
  505. #if WASM_ENABLE_JIT != 0
  506. init_args.llvm_jit_size_level = llvm_jit_size_level;
  507. init_args.llvm_jit_opt_level = llvm_jit_opt_level;
  508. #endif
  509. #if WASM_ENABLE_DEBUG_INTERP != 0
  510. init_args.instance_port = instance_port;
  511. if (ip_addr)
  512. /* ensure that init_args.ip_addr is null terminated */
  513. strncpy_s(init_args.ip_addr, sizeof(init_args.ip_addr) - 1, ip_addr,
  514. strlen(ip_addr));
  515. #endif
  516. /* initialize runtime environment */
  517. if (!wasm_runtime_full_init(&init_args)) {
  518. printf("Init runtime environment failed.\n");
  519. return -1;
  520. }
  521. #if WASM_ENABLE_LOG != 0
  522. bh_log_set_verbose_level(log_verbose_level);
  523. #endif
  524. /* load WASM byte buffer from WASM bin file */
  525. if (!(wasm_file_buf =
  526. (uint8 *)bh_read_file_to_buffer(wasm_file, &wasm_file_size)))
  527. goto fail1;
  528. #if WASM_ENABLE_AOT != 0
  529. if (wasm_runtime_is_xip_file(wasm_file_buf, wasm_file_size)) {
  530. uint8 *wasm_file_mapped;
  531. int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
  532. int map_flags = MMAP_MAP_32BIT;
  533. if (!(wasm_file_mapped = os_mmap(NULL, (uint32)wasm_file_size, map_prot,
  534. map_flags, os_get_invalid_handle()))) {
  535. printf("mmap memory failed\n");
  536. wasm_runtime_free(wasm_file_buf);
  537. goto fail1;
  538. }
  539. bh_memcpy_s(wasm_file_mapped, wasm_file_size, wasm_file_buf,
  540. wasm_file_size);
  541. wasm_runtime_free(wasm_file_buf);
  542. wasm_file_buf = wasm_file_mapped;
  543. is_xip_file = true;
  544. }
  545. #endif
  546. #if WASM_ENABLE_MULTI_MODULE != 0
  547. wasm_runtime_set_module_reader(module_reader_callback,
  548. module_destroyer_callback);
  549. #endif
  550. /* load WASM module */
  551. if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
  552. error_buf, sizeof(error_buf)))) {
  553. printf("%s\n", error_buf);
  554. goto fail2;
  555. }
  556. if (!wasm_runtime_instantiation_args_create(&inst_args)) {
  557. printf("failed to create instantiate args\n");
  558. goto fail3;
  559. }
  560. wasm_runtime_instantiation_args_set_default_stack_size(inst_args,
  561. stack_size);
  562. wasm_runtime_instantiation_args_set_host_managed_heap_size(inst_args,
  563. heap_size);
  564. #if WASM_ENABLE_LIBC_WASI != 0
  565. libc_wasi_set_init_args(inst_args, argc, argv, &wasi_parse_ctx);
  566. #endif
  567. /* instantiate the module */
  568. wasm_module_inst = wasm_runtime_instantiate_ex2(
  569. wasm_module, inst_args, error_buf, sizeof(error_buf));
  570. wasm_runtime_instantiation_args_destroy(inst_args);
  571. if (!wasm_module_inst) {
  572. printf("%s\n", error_buf);
  573. goto fail3;
  574. }
  575. #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
  576. if (disable_bounds_checks) {
  577. wasm_runtime_set_bounds_checks(wasm_module_inst, false);
  578. }
  579. #endif
  580. #if WASM_ENABLE_DEBUG_INTERP != 0
  581. if (ip_addr != NULL) {
  582. wasm_exec_env_t exec_env =
  583. wasm_runtime_get_exec_env_singleton(wasm_module_inst);
  584. uint32_t debug_port;
  585. if (exec_env == NULL) {
  586. printf("%s\n", wasm_runtime_get_exception(wasm_module_inst));
  587. goto fail4;
  588. }
  589. debug_port = wasm_runtime_start_debug_instance(exec_env);
  590. if (debug_port == 0) {
  591. printf("Failed to start debug instance\n");
  592. goto fail4;
  593. }
  594. }
  595. #endif
  596. #if WASM_ENABLE_SHARED_HEAP != 0
  597. if (shared_heap_size > 0) {
  598. memset(&shared_heap_init_args, 0, sizeof(shared_heap_init_args));
  599. shared_heap_init_args.size = shared_heap_size;
  600. shared_heap = wasm_runtime_create_shared_heap(&shared_heap_init_args);
  601. if (!shared_heap) {
  602. printf("Create preallocated shared heap failed\n");
  603. goto fail6;
  604. }
  605. /* attach module instance to the shared heap */
  606. if (!wasm_runtime_attach_shared_heap(wasm_module_inst, shared_heap)) {
  607. printf("Attach shared heap failed.\n");
  608. goto fail6;
  609. }
  610. }
  611. #endif
  612. ret = 0;
  613. const char *exception = NULL;
  614. if (is_repl_mode) {
  615. app_instance_repl(wasm_module_inst);
  616. }
  617. else if (func_name) {
  618. exception = app_instance_func(wasm_module_inst, func_name);
  619. if (exception) {
  620. /* got an exception */
  621. ret = 1;
  622. }
  623. }
  624. else {
  625. exception = app_instance_main(wasm_module_inst);
  626. if (exception) {
  627. /* got an exception */
  628. ret = 1;
  629. }
  630. }
  631. #if WASM_ENABLE_LIBC_WASI != 0
  632. if (ret == 0) {
  633. /* propagate wasi exit code. */
  634. ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst);
  635. }
  636. #endif
  637. if (exception)
  638. printf("%s\n", exception);
  639. #if WASM_ENABLE_SHARED_HEAP != 0
  640. fail6:
  641. #endif
  642. /* fail5: label is used by posix/main.c */
  643. #if WASM_ENABLE_DEBUG_INTERP != 0
  644. fail4:
  645. #endif
  646. /* destroy the module instance */
  647. wasm_runtime_deinstantiate(wasm_module_inst);
  648. fail3:
  649. /* unload the module */
  650. wasm_runtime_unload(wasm_module);
  651. fail2:
  652. /* free the file buffer */
  653. if (!is_xip_file)
  654. wasm_runtime_free(wasm_file_buf);
  655. else
  656. os_munmap(wasm_file_buf, wasm_file_size);
  657. fail1:
  658. /* destroy runtime environment */
  659. wasm_runtime_destroy();
  660. return ret;
  661. }