aot_stack_frame_test.cc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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 "wasm_runtime_common.h"
  8. #include "aot_runtime.h"
  9. #include "test_helper.h"
  10. #ifndef __aligned
  11. #define __aligned(n)
  12. #endif
  13. #include "wasm-apps/test_aot.h"
  14. typedef struct MyAOTFrame {
  15. uintptr_t func_index;
  16. /* Instruction pointer: offset to the bytecode array */
  17. uintptr_t ip_offset;
  18. /* Operand stack top pointer of the current frame */
  19. uint32 *sp;
  20. #if WASM_ENABLE_GC != 0
  21. /* Frame ref flags (GC only) */
  22. uint8 *frame_ref;
  23. #endif
  24. uint32 lp[1];
  25. } MyAOTFrame;
  26. class AOTStackFrameTest : public testing::Test
  27. {
  28. protected:
  29. virtual void SetUp()
  30. {
  31. memset(&init_args, 0, sizeof(RuntimeInitArgs));
  32. init_args.mem_alloc_type = Alloc_With_Pool;
  33. init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
  34. init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
  35. ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
  36. }
  37. virtual void TearDown()
  38. {
  39. DestroyFrames();
  40. wasm_runtime_destroy();
  41. }
  42. public:
  43. static void DestroyFrames()
  44. {
  45. if (my_frames) {
  46. for (uint32 i = 0; i < my_frame_num; i++) {
  47. if (my_frames[i])
  48. wasm_runtime_free(my_frames[i]);
  49. }
  50. wasm_runtime_free(my_frames);
  51. my_frames = NULL;
  52. my_frame_num = 0;
  53. }
  54. }
  55. public:
  56. RuntimeInitArgs init_args;
  57. wasm_module_t module = NULL;
  58. wasm_module_inst_t module_inst = NULL;
  59. wasm_function_inst_t func_inst = NULL;
  60. wasm_exec_env_t exec_env = NULL;
  61. static MyAOTFrame **my_frames;
  62. static uint32 my_frame_num;
  63. char error_buf[128];
  64. char global_heap_buf[512 * 1024];
  65. unsigned char test_aot_buf[16 * 1024];
  66. unsigned argv[8];
  67. };
  68. MyAOTFrame **AOTStackFrameTest::my_frames = NULL;
  69. uint32 AOTStackFrameTest::my_frame_num = 0;
  70. extern "C" {
  71. typedef void (*stack_frame_callback_t)(struct WASMExecEnv *exec_env);
  72. void
  73. aot_set_stack_frame_callback(stack_frame_callback_t callback);
  74. void
  75. aot_stack_frame_cb(struct WASMExecEnv *exec_env)
  76. {
  77. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  78. AOTModule *module = (AOTModule *)module_inst->module;
  79. AOTFrame *frame = (AOTFrame *)exec_env->cur_frame;
  80. MyAOTFrame *my_frame, **my_frames;
  81. uint32 all_cell_num, max_local_cell_num, max_stack_cell_num;
  82. uint32 frame_size_old, frame_size, i, frame_num = 0, aot_func_idx;
  83. AOTStackFrameTest::DestroyFrames();
  84. while (frame) {
  85. frame_num++;
  86. frame = frame->prev_frame;
  87. }
  88. my_frames =
  89. (MyAOTFrame **)wasm_runtime_malloc(sizeof(MyAOTFrame *) * frame_num);
  90. bh_assert(my_frames);
  91. frame = (AOTFrame *)exec_env->cur_frame;
  92. for (i = 0; i < frame_num; i++) {
  93. aot_func_idx = frame->func_index;
  94. max_local_cell_num = module->max_local_cell_nums[aot_func_idx];
  95. max_stack_cell_num = module->max_stack_cell_nums[aot_func_idx];
  96. all_cell_num = max_local_cell_num + max_stack_cell_num;
  97. frame_size_old = (uint32)offsetof(AOTFrame, lp) + all_cell_num * 4;
  98. frame_size = (uint32)offsetof(MyAOTFrame, lp) + all_cell_num * 4;
  99. my_frames[frame_num - 1 - i] = my_frame =
  100. (MyAOTFrame *)wasm_runtime_malloc(frame_size);
  101. my_frame->func_index = aot_func_idx;
  102. my_frame->ip_offset = frame->ip_offset;
  103. my_frame->sp = my_frame->lp + (frame->sp - frame->lp);
  104. #if WASM_ENABLE_GC != 0
  105. my_frame->frame_ref =
  106. (uint8 *)my_frame->lp + (frame->frame_ref - (uint8 *)frame->lp);
  107. #endif
  108. bh_memcpy_s(my_frame->lp, all_cell_num * 4, frame->lp,
  109. all_cell_num * 4);
  110. frame = frame->prev_frame;
  111. }
  112. AOTStackFrameTest::my_frames = my_frames;
  113. AOTStackFrameTest::my_frame_num = frame_num;
  114. }
  115. }
  116. TEST_F(AOTStackFrameTest, test1)
  117. {
  118. MyAOTFrame *frame, **frames;
  119. uint32 frame_num;
  120. aot_set_stack_frame_callback(aot_stack_frame_cb);
  121. bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
  122. module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
  123. sizeof(error_buf));
  124. ASSERT_TRUE(module != NULL);
  125. module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
  126. sizeof(error_buf));
  127. ASSERT_TRUE(module_inst != NULL);
  128. exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
  129. ASSERT_TRUE(exec_env != NULL);
  130. func_inst = wasm_runtime_lookup_function(module_inst, "test2");
  131. ASSERT_TRUE(func_inst != NULL);
  132. argv[0] = 1234;
  133. argv[1] = 5678;
  134. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  135. ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
  136. frames = AOTStackFrameTest::my_frames;
  137. frame_num = AOTStackFrameTest::my_frame_num;
  138. ASSERT_TRUE(frames != NULL);
  139. ASSERT_TRUE(frame_num == 1);
  140. ASSERT_TRUE(frames[0]->lp[0] == 1234);
  141. ASSERT_TRUE(frames[0]->lp[1] == 5678);
  142. ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
  143. ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
  144. ASSERT_TRUE(*(float *)(frames[0]->lp + 5) == 5566.7788f);
  145. ASSERT_TRUE(*(double *)(frames[0]->lp + 6) == 99887766.55443322);
  146. }
  147. TEST_F(AOTStackFrameTest, test2)
  148. {
  149. MyAOTFrame *frame, **frames;
  150. uint32 frame_num;
  151. aot_set_stack_frame_callback(aot_stack_frame_cb);
  152. bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
  153. module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
  154. sizeof(error_buf));
  155. ASSERT_TRUE(module != NULL);
  156. module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
  157. sizeof(error_buf));
  158. ASSERT_TRUE(module_inst != NULL);
  159. exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
  160. ASSERT_TRUE(exec_env != NULL);
  161. func_inst = wasm_runtime_lookup_function(module_inst, "test3");
  162. ASSERT_TRUE(func_inst != NULL);
  163. argv[0] = 1234;
  164. argv[1] = 5678;
  165. wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
  166. ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
  167. frames = AOTStackFrameTest::my_frames;
  168. frame_num = AOTStackFrameTest::my_frame_num;
  169. ASSERT_TRUE(frames != NULL);
  170. ASSERT_TRUE(frame_num == 2);
  171. // 5(i32) + 1(i64) local variables, occupied 7 * 4 bytes
  172. ASSERT_TRUE(frames[0]->sp - frames[0]->lp == 7);
  173. // offset of ip from module load address
  174. ASSERT_TRUE(frames[0]->ip_offset == 163);
  175. ASSERT_TRUE(frames[0]->lp[0] == 1234);
  176. ASSERT_TRUE(frames[0]->lp[1] == 5678);
  177. ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
  178. ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
  179. }