wasm_vm.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "gtest/gtest.h"
  6. #include "bh_platform.h"
  7. #include "bh_read_file.h"
  8. #include "wasm_export.h"
  9. #if WASM_ENABLE_MULTI_MODULE != 0
  10. #include "wasm.h"
  11. #include "wasm_runtime.h"
  12. #endif
  13. #include "wasm-apps/app1_wasm.h"
  14. #include "wasm-apps/app2_wasm.h"
  15. #include "wasm-apps/app3_wasm.h"
  16. #define EightK (8 * 1024)
  17. // To use a test fixture, derive a class from testing::Test.
  18. class WasmVMTest : public testing::Test
  19. {
  20. protected:
  21. // You should make the members protected s.t. they can be
  22. // accessed from sub-classes.
  23. // virtual void SetUp() will be called before each test is run. You
  24. // should define it if you need to initialize the varaibles.
  25. // Otherwise, this can be skipped.
  26. void SetUp()
  27. {
  28. memset(&init_args, 0, sizeof(RuntimeInitArgs));
  29. init_args.mem_alloc_type = Alloc_With_Pool;
  30. init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
  31. init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
  32. ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
  33. // bh_log_set_verbose_level(5);
  34. clean = true;
  35. }
  36. // virtual void TearDown() will be called after each test is run.
  37. // You should define it if there is cleanup work to do. Otherwise,
  38. // you don't have to provide it.
  39. //
  40. void TearDown()
  41. {
  42. if (clean) {
  43. wasm_runtime_destroy();
  44. }
  45. }
  46. public:
  47. wasm_module_t module = NULL;
  48. wasm_module_inst_t module_inst = NULL;
  49. wasm_function_inst_t func_inst = NULL;
  50. wasm_exec_env_t exec_env = NULL;
  51. char error_buf[128];
  52. char global_heap_buf[512 * 1024];
  53. RuntimeInitArgs init_args;
  54. bool clean = true;
  55. };
  56. TEST_F(WasmVMTest, Test_app1)
  57. {
  58. unsigned argv[10];
  59. ASSERT_TRUE(app1_wasm != NULL);
  60. /* Load module */
  61. module = wasm_runtime_load(app1_wasm, sizeof(app1_wasm), error_buf,
  62. sizeof(error_buf));
  63. if (module == nullptr) {
  64. printf("error: %s\n", error_buf);
  65. }
  66. ASSERT_TRUE(module != NULL);
  67. /* Initiate module */
  68. module_inst = wasm_runtime_instantiate(module, 8 * 1024, 8 * 1024,
  69. error_buf, sizeof(error_buf));
  70. ASSERT_TRUE(module_inst != NULL);
  71. exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
  72. ASSERT_TRUE(exec_env != NULL);
  73. /* _on_init() function doesn't exist */
  74. func_inst = wasm_runtime_lookup_function(module_inst, "_on_init");
  75. ASSERT_TRUE(func_inst == NULL);
  76. /* on_init() function exists */
  77. func_inst = wasm_runtime_lookup_function(module_inst, "on_init");
  78. ASSERT_TRUE(func_inst != NULL);
  79. ASSERT_TRUE(wasm_runtime_call_wasm(exec_env, func_inst, 0, NULL) == true);
  80. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  81. /* call my_malloc */
  82. func_inst = wasm_runtime_lookup_function(module_inst, "my_malloc");
  83. ASSERT_TRUE(func_inst != NULL);
  84. /* malloc with very large size */
  85. argv[0] = 10 * 1024;
  86. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  87. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  88. wasm_runtime_clear_exception(module_inst);
  89. ASSERT_EQ(argv[0], 0);
  90. /* malloc 1K, should success */
  91. argv[0] = 1024;
  92. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  93. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  94. /* convert to native address */
  95. ASSERT_TRUE(wasm_runtime_validate_app_addr(module_inst, argv[0], 1));
  96. char *buf = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  97. ASSERT_TRUE(buf != NULL);
  98. ASSERT_EQ(wasm_runtime_addr_native_to_app(module_inst, buf), argv[0]);
  99. int32 buf_offset = argv[0];
  100. /* call memcpy */
  101. char *buf1 = buf + 100;
  102. memcpy(buf1, "123456", 7);
  103. func_inst = wasm_runtime_lookup_function(module_inst, "my_memcpy");
  104. ASSERT_TRUE(func_inst != NULL);
  105. argv[0] = buf_offset;
  106. argv[1] = buf_offset + 100;
  107. argv[2] = 7;
  108. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  109. ASSERT_TRUE(strcmp(buf, buf1) == 0);
  110. /* call strdup */
  111. func_inst = wasm_runtime_lookup_function(module_inst, "my_strdup");
  112. ASSERT_TRUE(func_inst != NULL);
  113. argv[0] = buf_offset;
  114. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  115. int32 buf_offset1 = argv[0];
  116. ASSERT_NE(buf_offset, buf_offset1);
  117. buf1 = (char *)wasm_runtime_addr_app_to_native(module_inst, buf_offset1);
  118. ASSERT_TRUE(strcmp(buf, buf1) == 0);
  119. wasm_runtime_deinstantiate(module_inst);
  120. wasm_runtime_unload(module);
  121. wasm_runtime_destroy_exec_env(exec_env);
  122. }
  123. TEST_F(WasmVMTest, Test_app2)
  124. {
  125. unsigned argv[10];
  126. /* Load module */
  127. module = wasm_runtime_load(app2_wasm, sizeof(app2_wasm), error_buf,
  128. sizeof(error_buf));
  129. ASSERT_TRUE(module != NULL);
  130. /* Initiate module */
  131. module_inst = wasm_runtime_instantiate(module, 8 * 1024, 8 * 1024,
  132. error_buf, sizeof(error_buf));
  133. ASSERT_TRUE(module_inst != NULL);
  134. exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
  135. ASSERT_TRUE(exec_env != NULL);
  136. /* _on_init() function doesn't exist */
  137. func_inst = wasm_runtime_lookup_function(module_inst, "_on_init");
  138. ASSERT_TRUE(func_inst == NULL);
  139. /* on_init() function exists */
  140. func_inst = wasm_runtime_lookup_function(module_inst, "on_init");
  141. ASSERT_TRUE(func_inst != NULL);
  142. ASSERT_TRUE(wasm_runtime_call_wasm(exec_env, func_inst, 0, NULL) == true);
  143. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  144. /* call my_malloc */
  145. func_inst = wasm_runtime_lookup_function(module_inst, "my_malloc");
  146. ASSERT_TRUE(func_inst != NULL);
  147. /* malloc 1K, should success */
  148. argv[0] = 1024;
  149. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  150. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  151. /* convert to native address */
  152. ASSERT_TRUE(wasm_runtime_validate_app_addr(module_inst, argv[0], 1));
  153. char *buf = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  154. ASSERT_TRUE(buf != NULL);
  155. ASSERT_EQ(wasm_runtime_addr_native_to_app(module_inst, buf), argv[0]);
  156. int32 buf_offset = argv[0];
  157. /* call memcpy */
  158. char *buf1 = buf + 100;
  159. memcpy(buf1, "123456", 7);
  160. func_inst = wasm_runtime_lookup_function(module_inst, "my_memcpy");
  161. ASSERT_TRUE(func_inst != NULL);
  162. argv[0] = buf_offset;
  163. argv[1] = buf_offset + 100;
  164. argv[2] = 7;
  165. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  166. ASSERT_TRUE(strcmp(buf, buf1) == 0);
  167. /* call memcmp */
  168. func_inst = wasm_runtime_lookup_function(module_inst, "my_memcmp");
  169. ASSERT_TRUE(func_inst != NULL);
  170. argv[0] = buf_offset;
  171. argv[1] = buf_offset + 100;
  172. argv[2] = 7;
  173. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  174. ASSERT_TRUE(argv[0] == 0);
  175. /* call printf */
  176. char *format = buf + 200;
  177. memcpy(format, "string0 is %s", 13);
  178. func_inst = wasm_runtime_lookup_function(module_inst, "my_printf");
  179. ASSERT_TRUE(func_inst != NULL);
  180. argv[0] = wasm_runtime_addr_native_to_app(module_inst, format);
  181. argv[1] = buf_offset;
  182. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  183. ASSERT_TRUE(argv[0] == 17);
  184. /* call sprintf */
  185. memcpy(format, "string1 is %s", 13);
  186. func_inst = wasm_runtime_lookup_function(module_inst, "my_sprintf");
  187. ASSERT_TRUE(func_inst != NULL);
  188. argv[0] = buf_offset + 300;
  189. int32 argv0_tmp = argv[0];
  190. argv[1] = wasm_runtime_addr_native_to_app(module_inst, format);
  191. argv[2] = buf_offset;
  192. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  193. ASSERT_TRUE(
  194. memcmp((char *)wasm_runtime_addr_app_to_native(module_inst, argv0_tmp),
  195. "string1 is 123456", 17)
  196. == 0);
  197. ASSERT_TRUE(argv[0] == 17);
  198. /* call snprintf */
  199. memcpy(format, "string2 is %s", 13);
  200. func_inst = wasm_runtime_lookup_function(module_inst, "my_snprintf");
  201. ASSERT_TRUE(func_inst != NULL);
  202. argv[0] = buf_offset + 400;
  203. argv0_tmp = argv[0];
  204. argv[1] = 3;
  205. argv[2] = wasm_runtime_addr_native_to_app(module_inst, format);
  206. argv[3] = buf_offset;
  207. wasm_runtime_call_wasm(exec_env, func_inst, 4, argv);
  208. ASSERT_TRUE(
  209. memcmp((char *)wasm_runtime_addr_app_to_native(module_inst, argv0_tmp),
  210. "st\0", 3)
  211. == 0);
  212. ASSERT_TRUE(argv[0] == 17);
  213. /* call puts */
  214. func_inst = wasm_runtime_lookup_function(module_inst, "my_puts");
  215. ASSERT_TRUE(func_inst != NULL);
  216. argv[0] = buf_offset;
  217. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  218. ASSERT_TRUE(argv[0] != EOF);
  219. /* call putchar */
  220. func_inst = wasm_runtime_lookup_function(module_inst, "my_putchar");
  221. ASSERT_TRUE(func_inst != NULL);
  222. argv[0] = buf_offset;
  223. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  224. ASSERT_TRUE(argv[0] != EOF);
  225. /* call memmove without memory coverage*/
  226. func_inst = wasm_runtime_lookup_function(module_inst, "my_memmove");
  227. ASSERT_TRUE(func_inst != NULL);
  228. argv[0] = buf_offset + 10;
  229. argv[1] = buf_offset + 100;
  230. argv[2] = 6;
  231. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  232. buf1 = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  233. ASSERT_TRUE(strcmp(buf + 100, buf1) == 0);
  234. ASSERT_TRUE(memcmp(buf1, "123456", 6) == 0);
  235. /* call memmove with memory coverage*/
  236. func_inst = wasm_runtime_lookup_function(module_inst, "my_memmove");
  237. ASSERT_TRUE(func_inst != NULL);
  238. argv[0] = buf_offset + 95;
  239. argv[1] = buf_offset + 100;
  240. argv[2] = 6;
  241. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  242. buf1 = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  243. ASSERT_TRUE(strcmp(buf + 100, buf1) != 0);
  244. ASSERT_TRUE(memcmp(buf1, "123456", 6) == 0);
  245. ASSERT_TRUE(memcmp(buf + 100, "623456", 6) == 0);
  246. /* call memset*/
  247. func_inst = wasm_runtime_lookup_function(module_inst, "my_memset");
  248. ASSERT_TRUE(func_inst != NULL);
  249. argv[0] = buf_offset + 100;
  250. argv[1] = 48;
  251. argv[2] = 4;
  252. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  253. ASSERT_TRUE(memcmp(buf + 100, "000056", 6) == 0);
  254. /* call strchr*/
  255. func_inst = wasm_runtime_lookup_function(module_inst, "my_strchr");
  256. ASSERT_TRUE(func_inst != NULL);
  257. argv[0] = buf_offset;
  258. argv[1] = 49; // asc2 for char "1"
  259. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  260. buf1 = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  261. ASSERT_TRUE(buf1 - buf == 0);
  262. /* call strcmp */
  263. func_inst = wasm_runtime_lookup_function(module_inst, "my_strcmp");
  264. ASSERT_TRUE(func_inst != NULL);
  265. argv[0] = buf_offset;
  266. argv[1] = buf_offset;
  267. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  268. ASSERT_TRUE(argv[0] == 0);
  269. argv[0] = buf_offset;
  270. argv[1] = buf_offset + 1;
  271. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  272. ASSERT_TRUE(argv[0] != 0);
  273. /* call strcpy */
  274. func_inst = wasm_runtime_lookup_function(module_inst, "my_strcpy");
  275. ASSERT_TRUE(func_inst != NULL);
  276. argv[0] = buf_offset + 110;
  277. argv[1] = buf_offset;
  278. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  279. ASSERT_TRUE(memcmp(buf + 110, "123456", 6) == 0);
  280. /* call strlen */
  281. buf1 = buf + 110;
  282. memcpy(buf1, "123456\0", 7);
  283. func_inst = wasm_runtime_lookup_function(module_inst, "my_strlen");
  284. ASSERT_TRUE(func_inst != NULL);
  285. argv[0] = buf_offset + 110;
  286. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  287. ASSERT_TRUE(argv[0] == 6);
  288. /* call strncmp */
  289. buf1 = buf + 110;
  290. memcpy(buf1, "123457", 6);
  291. func_inst = wasm_runtime_lookup_function(module_inst, "my_strncmp");
  292. ASSERT_TRUE(func_inst != NULL);
  293. argv[0] = buf_offset;
  294. argv[1] = buf_offset + 110;
  295. argv[2] = 5;
  296. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  297. ASSERT_TRUE(argv[0] == 0);
  298. argv[0] = buf_offset;
  299. argv[1] = buf_offset + 110;
  300. argv[2] = 6;
  301. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  302. ASSERT_TRUE(argv[0] != 0);
  303. /* call strncpy */
  304. func_inst = wasm_runtime_lookup_function(module_inst, "my_strncpy");
  305. ASSERT_TRUE(func_inst != NULL);
  306. argv[0] = buf_offset + 130;
  307. argv[1] = buf_offset;
  308. argv[2] = 5;
  309. wasm_runtime_call_wasm(exec_env, func_inst, 3, argv);
  310. buf1 = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  311. ASSERT_TRUE(memcmp(buf, buf1, 5) == 0);
  312. ASSERT_TRUE(memcmp(buf, buf1, 6) != 0);
  313. /* call _my_calloc */
  314. func_inst = wasm_runtime_lookup_function(module_inst, "my_calloc");
  315. ASSERT_TRUE(func_inst != NULL);
  316. /* calloc, should success */
  317. argv[0] = 10;
  318. argv[1] = 4;
  319. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  320. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  321. /* convert to native address */
  322. ASSERT_TRUE(wasm_runtime_validate_app_addr(module_inst, argv[0], 40));
  323. char *buf2 = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  324. ASSERT_TRUE(buf2 != NULL);
  325. ASSERT_EQ(wasm_runtime_addr_native_to_app(module_inst, buf2), argv[0]);
  326. int32 buf_offset1 = argv[0];
  327. /* call _my_free */
  328. memcpy(buf2, "123456", 6);
  329. func_inst = wasm_runtime_lookup_function(module_inst, "my_free");
  330. ASSERT_TRUE(func_inst != NULL);
  331. argv[0] = buf_offset1;
  332. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  333. ASSERT_TRUE(memcmp(buf2, "123456", 6) != 0);
  334. wasm_runtime_deinstantiate(module_inst);
  335. wasm_runtime_unload(module);
  336. wasm_runtime_destroy_exec_env(exec_env);
  337. }
  338. TEST_F(WasmVMTest, Test_app3)
  339. {
  340. unsigned argv[10];
  341. /* Load module */
  342. module = wasm_runtime_load(app3_wasm, sizeof(app3_wasm), error_buf,
  343. sizeof(error_buf));
  344. ASSERT_TRUE(module != NULL);
  345. /* Initiate module */
  346. module_inst = wasm_runtime_instantiate(module, 8 * 1024, 8 * 1024,
  347. error_buf, sizeof(error_buf));
  348. ASSERT_TRUE(module_inst != NULL);
  349. exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
  350. ASSERT_TRUE(exec_env != NULL);
  351. /* _on_init() function doesn't exist */
  352. func_inst = wasm_runtime_lookup_function(module_inst, "_on_init");
  353. ASSERT_TRUE(func_inst == NULL);
  354. /* on_init() function exists */
  355. func_inst = wasm_runtime_lookup_function(module_inst, "on_init");
  356. ASSERT_TRUE(func_inst != NULL);
  357. ASSERT_TRUE(wasm_runtime_call_wasm(exec_env, func_inst, 0, NULL) == true);
  358. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  359. /* call my_malloc */
  360. func_inst = wasm_runtime_lookup_function(module_inst, "my_malloc");
  361. ASSERT_TRUE(func_inst != NULL);
  362. /* malloc with very large size */
  363. argv[0] = 10 * 1024;
  364. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  365. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  366. wasm_runtime_clear_exception(module_inst);
  367. ASSERT_EQ(argv[0], 0);
  368. /* malloc 1K, should success */
  369. argv[0] = 1024;
  370. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  371. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  372. /* convert to native address */
  373. ASSERT_TRUE(wasm_runtime_validate_app_addr(module_inst, argv[0], 1));
  374. char *buf = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  375. ASSERT_TRUE(buf != NULL);
  376. ASSERT_EQ(wasm_runtime_addr_native_to_app(module_inst, buf), argv[0]);
  377. int32 buf_offset = argv[0];
  378. /* call my_malloc */
  379. func_inst = wasm_runtime_lookup_function(module_inst, "my_malloc");
  380. ASSERT_TRUE(func_inst != NULL);
  381. /* malloc, should success */
  382. argv[0] = 10;
  383. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  384. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  385. /* convert to native address */
  386. ASSERT_TRUE(wasm_runtime_validate_app_addr(module_inst, argv[0], 1));
  387. char *buf1 = (char *)wasm_runtime_addr_app_to_native(module_inst, argv[0]);
  388. ASSERT_TRUE(buf1 != NULL);
  389. ASSERT_EQ(wasm_runtime_addr_native_to_app(module_inst, buf1), argv[0]);
  390. int32 buf_offset1 = argv[0];
  391. wasm_runtime_deinstantiate(module_inst);
  392. wasm_runtime_unload(module);
  393. wasm_runtime_destroy_exec_env(exec_env);
  394. }
  395. #if WASM_ENABLE_MULTI_MODULE != 0
  396. static const char *module_search_path = ".";
  397. static bool call_destroyer = false;
  398. static bool
  399. module_reader_callback(package_type_t module_type, const char *module_name,
  400. uint8 **p_buffer, uint32 *p_size)
  401. {
  402. const char *format = "%s/%s.wasm";
  403. int sz = strlen(module_search_path) + strlen("/") + strlen(module_name)
  404. + strlen(".wasm") + 1;
  405. char *wasm_file_name = (char *)BH_MALLOC(sz);
  406. if (!wasm_file_name) {
  407. return false;
  408. }
  409. snprintf(wasm_file_name, sz, format, module_search_path, module_name);
  410. printf("going to open %s\n", wasm_file_name);
  411. call_destroyer = false;
  412. *p_buffer = (uint8_t *)bh_read_file_to_buffer(wasm_file_name, p_size);
  413. BH_FREE(wasm_file_name);
  414. return *p_buffer != NULL;
  415. }
  416. static void
  417. module_destroyer_callback(uint8 *buffer, uint32 size)
  418. {
  419. wasm_runtime_free(buffer);
  420. call_destroyer = true;
  421. }
  422. TEST_F(WasmVMTest, Test_app4_single)
  423. {
  424. uint8 *buffer = NULL;
  425. uint32 buffer_size = 0;
  426. bool ret = false;
  427. unsigned argv[10];
  428. wasm_runtime_set_module_reader(&module_reader_callback,
  429. &module_destroyer_callback);
  430. /* m1 only */
  431. ret = module_reader_callback(Wasm_Module_Bytecode, "m1", &buffer,
  432. &buffer_size);
  433. ASSERT_TRUE(ret);
  434. ASSERT_TRUE(buffer_size > 0);
  435. ASSERT_TRUE(buffer != NULL);
  436. module =
  437. wasm_runtime_load(buffer, buffer_size, error_buf, sizeof(error_buf));
  438. ASSERT_TRUE(module != NULL);
  439. ASSERT_FALSE(wasm_runtime_find_module_registered("m1"));
  440. wasm_runtime_register_module("m1", module, error_buf, sizeof(error_buf));
  441. ASSERT_TRUE(wasm_runtime_find_module_registered("m1"));
  442. module_inst = wasm_runtime_instantiate(module, EightK, EightK, error_buf,
  443. sizeof(error_buf));
  444. ASSERT_TRUE(module_inst != NULL);
  445. exec_env = wasm_runtime_create_exec_env(module_inst, EightK);
  446. ASSERT_TRUE(exec_env != NULL);
  447. func_inst = wasm_runtime_lookup_function(module_inst, "f1");
  448. ASSERT_TRUE(func_inst != NULL);
  449. ASSERT_FALSE(((WASMFunctionInstance *)func_inst)->is_import_func);
  450. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->param_cell_num == 0);
  451. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->ret_cell_num == 1);
  452. wasm_runtime_call_wasm(exec_env, func_inst, 0, argv);
  453. printf("exception is %s", wasm_runtime_get_exception(module_inst));
  454. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  455. ASSERT_TRUE(argv[0] == 1);
  456. wasm_runtime_destroy_exec_env(exec_env);
  457. wasm_runtime_deinstantiate(module_inst);
  458. wasm_runtime_unload(module);
  459. // call destroyer and without exception
  460. ASSERT_FALSE(call_destroyer);
  461. module_destroyer_callback(buffer, buffer_size);
  462. clean = false;
  463. wasm_runtime_destroy();
  464. }
  465. TEST_F(WasmVMTest, Test_app4_plus_one)
  466. {
  467. uint8 *buffer = NULL;
  468. uint32 buffer_size = 0;
  469. bool ret = false;
  470. uint32_t argv[10] = { 0 };
  471. wasm_runtime_set_module_reader(&module_reader_callback,
  472. &module_destroyer_callback);
  473. /* m2 -> m1 */
  474. ret = module_reader_callback(Wasm_Module_Bytecode, "m2", &buffer,
  475. &buffer_size);
  476. ASSERT_TRUE(ret);
  477. ASSERT_TRUE(buffer_size > 0);
  478. ASSERT_TRUE(buffer != NULL);
  479. module =
  480. wasm_runtime_load(buffer, buffer_size, error_buf, sizeof(error_buf));
  481. ASSERT_TRUE(module != NULL);
  482. module_inst = wasm_runtime_instantiate(module, EightK, EightK, error_buf,
  483. sizeof(error_buf));
  484. ASSERT_TRUE(module_inst != NULL);
  485. exec_env = wasm_runtime_create_exec_env(module_inst, EightK);
  486. ASSERT_TRUE(exec_env != NULL);
  487. printf("------------------- m1-f1 ---------------------\n");
  488. func_inst = wasm_runtime_lookup_function(module_inst, "m1-f1");
  489. ASSERT_TRUE(func_inst != NULL);
  490. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->is_import_func);
  491. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->param_cell_num == 0);
  492. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->ret_cell_num == 1);
  493. wasm_runtime_call_wasm(exec_env, func_inst, 0, argv);
  494. printf("exception is %s\n", wasm_runtime_get_exception(module_inst));
  495. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  496. ASSERT_TRUE(argv[0] == 1);
  497. printf("------------------- f2 ---------------------\n");
  498. func_inst = wasm_runtime_lookup_function(module_inst, "f2");
  499. ASSERT_TRUE(func_inst != NULL);
  500. ASSERT_FALSE(((WASMFunctionInstance *)func_inst)->is_import_func);
  501. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->param_cell_num == 1);
  502. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->ret_cell_num == 1);
  503. argv[0] = 2;
  504. wasm_runtime_call_wasm(exec_env, func_inst, 1, argv);
  505. printf("exception is %s\n", wasm_runtime_get_exception(module_inst));
  506. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  507. ASSERT_TRUE(argv[0] == 3);
  508. printf("------------------- f3 ---------------------\n");
  509. func_inst = wasm_runtime_lookup_function(module_inst, "f3");
  510. ASSERT_TRUE(func_inst != NULL);
  511. ASSERT_FALSE(((WASMFunctionInstance *)func_inst)->is_import_func);
  512. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->param_cell_num == 2);
  513. ASSERT_TRUE(((WASMFunctionInstance *)func_inst)->ret_cell_num == 1);
  514. argv[0] = 4;
  515. argv[1] = 9;
  516. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  517. printf("exception is %s\n", wasm_runtime_get_exception(module_inst));
  518. ASSERT_TRUE(wasm_runtime_get_exception(module_inst) == NULL);
  519. ASSERT_TRUE(argv[0] == 9);
  520. wasm_runtime_destroy_exec_env(exec_env);
  521. wasm_runtime_deinstantiate(module_inst);
  522. wasm_runtime_unload(module);
  523. ASSERT_FALSE(call_destroyer);
  524. }
  525. TEST_F(WasmVMTest, Test_app4_family)
  526. {
  527. uint8 *buffer = NULL;
  528. uint32 buffer_size = 0;
  529. bool ret = false;
  530. wasm_runtime_set_module_reader(&module_reader_callback,
  531. &module_destroyer_callback);
  532. /* m3 -> m2[->m1], m1 */
  533. ret = module_reader_callback(Wasm_Module_Bytecode, "m3", &buffer,
  534. &buffer_size);
  535. ASSERT_TRUE(ret);
  536. ASSERT_TRUE(buffer_size > 0);
  537. ASSERT_TRUE(buffer != NULL);
  538. module =
  539. wasm_runtime_load(buffer, buffer_size, error_buf, sizeof(error_buf));
  540. ASSERT_TRUE(module != NULL);
  541. wasm_runtime_unload(module);
  542. ASSERT_FALSE(call_destroyer);
  543. }
  544. static const WASMModule *
  545. search_sub_module(const WASMModule *parent_module, const char *sub_module_name)
  546. {
  547. WASMRegisteredModule *node = (WASMRegisteredModule *)bh_list_first_elem(
  548. parent_module->import_module_list);
  549. while (node && strcmp(node->module_name, sub_module_name)) {
  550. node = (WASMRegisteredModule *)bh_list_elem_next(node);
  551. }
  552. return node ? (WASMModule *)node->module : NULL;
  553. }
  554. TEST_F(WasmVMTest, Test_app4_reuse)
  555. {
  556. uint8 *buffer = NULL;
  557. uint32 buffer_size = 0;
  558. bool ret = false;
  559. wasm_runtime_set_module_reader(&module_reader_callback,
  560. &module_destroyer_callback);
  561. /* m3 -> m2[->m1], m1 */
  562. ret = module_reader_callback(Wasm_Module_Bytecode, "m3", &buffer,
  563. &buffer_size);
  564. ASSERT_TRUE(buffer != NULL);
  565. WASMModule *m3 = (WASMModule *)wasm_runtime_load(
  566. buffer, buffer_size, error_buf, sizeof(error_buf));
  567. ASSERT_TRUE(m3 != NULL);
  568. const WASMModule *m2 = search_sub_module(m3, "m2");
  569. const WASMModule *m1_in_m2 = search_sub_module(m2, "m1");
  570. const WASMModule *m1_in_m3 = search_sub_module(m3, "m1");
  571. ASSERT_EQ(m1_in_m2, m1_in_m3);
  572. }
  573. #endif /* WASM_ENABLE_MULTI_MODULE */