wasm_exec_env.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _WASM_EXEC_ENV_H
  6. #define _WASM_EXEC_ENV_H
  7. #include "bh_assert.h"
  8. #if WASM_ENABLE_INTERP != 0
  9. #include "../interpreter/wasm.h"
  10. #endif
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. struct WASMModuleInstanceCommon;
  15. struct WASMInterpFrame;
  16. #if WASM_ENABLE_THREAD_MGR != 0
  17. typedef struct WASMCluster WASMCluster;
  18. #endif
  19. #ifdef OS_ENABLE_HW_BOUND_CHECK
  20. typedef struct WASMJmpBuf {
  21. struct WASMJmpBuf *prev;
  22. korp_jmpbuf jmpbuf;
  23. } WASMJmpBuf;
  24. #endif
  25. /* Execution environment */
  26. typedef struct WASMExecEnv {
  27. /* Next thread's exec env of a WASM module instance. */
  28. struct WASMExecEnv *next;
  29. /* Previous thread's exec env of a WASM module instance. */
  30. struct WASMExecEnv *prev;
  31. /* Note: field module_inst, argv_buf, native_stack_boundary,
  32. suspend_flags, aux_stack_boundary, aux_stack_bottom, and
  33. native_symbol are used by AOTed code, don't change the
  34. places of them */
  35. /* The WASM module instance of current thread */
  36. struct WASMModuleInstanceCommon *module_inst;
  37. #if WASM_ENABLE_AOT != 0
  38. uint32 *argv_buf;
  39. #endif
  40. /* The boundary of native stack. When runtime detects that native
  41. frame may overrun this boundary, it throws stack overflow
  42. exception. */
  43. uint8 *native_stack_boundary;
  44. /* Used to terminate or suspend current thread
  45. bit 0: need to terminate
  46. bit 1: need to suspend
  47. bit 2: need to go into breakpoint
  48. bit 3: return from pthread_exit */
  49. union {
  50. uint32 flags;
  51. uintptr_t __padding__;
  52. } suspend_flags;
  53. /* Auxiliary stack boundary */
  54. union {
  55. uint32 boundary;
  56. uintptr_t __padding__;
  57. } aux_stack_boundary;
  58. /* Auxiliary stack bottom */
  59. union {
  60. uint32 bottom;
  61. uintptr_t __padding__;
  62. } aux_stack_bottom;
  63. #if WASM_ENABLE_AOT != 0
  64. /* Native symbol list, reserved */
  65. void **native_symbol;
  66. #endif
  67. #if WASM_ENABLE_THREAD_MGR != 0
  68. /* thread return value */
  69. void *thread_ret_value;
  70. /* Must be provided by thread library */
  71. void* (*thread_start_routine)(void *);
  72. void *thread_arg;
  73. /* pointer to the cluster */
  74. WASMCluster *cluster;
  75. /* used to support debugger */
  76. korp_mutex wait_lock;
  77. korp_cond wait_cond;
  78. #endif
  79. /* attachment for native function */
  80. void *attachment;
  81. void *user_data;
  82. /* Current interpreter frame of current thread */
  83. struct WASMInterpFrame *cur_frame;
  84. /* The native thread handle of current thread */
  85. korp_tid handle;
  86. #if WASM_ENABLE_INTERP != 0 && WASM_ENABLE_FAST_INTERP == 0
  87. BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
  88. #endif
  89. #ifdef OS_ENABLE_HW_BOUND_CHECK
  90. WASMJmpBuf *jmpbuf_stack_top;
  91. #endif
  92. #if WASM_ENABLE_REF_TYPES != 0
  93. uint16 nested_calling_depth;
  94. #endif
  95. #if WASM_ENABLE_MEMORY_PROFILING != 0
  96. uint32 max_wasm_stack_used;
  97. #endif
  98. /* The WASM stack size */
  99. uint32 wasm_stack_size;
  100. /* The WASM stack of current thread */
  101. union {
  102. uint64 __make_it_8_byte_aligned_;
  103. struct {
  104. /* The top boundary of the stack. */
  105. uint8 *top_boundary;
  106. /* Top cell index which is free. */
  107. uint8 *top;
  108. /* The WASM stack. */
  109. uint8 bottom[1];
  110. } s;
  111. } wasm_stack;
  112. } WASMExecEnv;
  113. WASMExecEnv *
  114. wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
  115. uint32 stack_size);
  116. void
  117. wasm_exec_env_destroy_internal(WASMExecEnv *exec_env);
  118. WASMExecEnv *
  119. wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
  120. uint32 stack_size);
  121. void
  122. wasm_exec_env_destroy(WASMExecEnv *exec_env);
  123. /**
  124. * Allocate a WASM frame from the WASM stack.
  125. *
  126. * @param exec_env the current execution environment
  127. * @param size size of the WASM frame, it must be a multiple of 4
  128. *
  129. * @return the WASM frame if there is enough space in the stack area
  130. * with a protection area, NULL otherwise
  131. */
  132. static inline void *
  133. wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size)
  134. {
  135. uint8 *addr = exec_env->wasm_stack.s.top;
  136. bh_assert(!(size & 3));
  137. /* The outs area size cannot be larger than the frame size, so
  138. multiplying by 2 is enough. */
  139. if (addr + size * 2 > exec_env->wasm_stack.s.top_boundary) {
  140. /* WASM stack overflow. */
  141. return NULL;
  142. }
  143. exec_env->wasm_stack.s.top += size;
  144. #if WASM_ENABLE_MEMORY_PROFILING != 0
  145. {
  146. uint32 wasm_stack_used = exec_env->wasm_stack.s.top
  147. - exec_env->wasm_stack.s.bottom;
  148. if (wasm_stack_used > exec_env->max_wasm_stack_used)
  149. exec_env->max_wasm_stack_used = wasm_stack_used;
  150. }
  151. #endif
  152. return addr;
  153. }
  154. static inline void
  155. wasm_exec_env_free_wasm_frame(WASMExecEnv *exec_env, void *prev_top)
  156. {
  157. bh_assert((uint8 *)prev_top >= exec_env->wasm_stack.s.bottom);
  158. exec_env->wasm_stack.s.top = (uint8 *)prev_top;
  159. }
  160. /**
  161. * Get the current WASM stack top pointer.
  162. *
  163. * @param exec_env the current execution environment
  164. *
  165. * @return the current WASM stack top pointer
  166. */
  167. static inline void*
  168. wasm_exec_env_wasm_stack_top(WASMExecEnv *exec_env)
  169. {
  170. return exec_env->wasm_stack.s.top;
  171. }
  172. /**
  173. * Set the current frame pointer.
  174. *
  175. * @param exec_env the current execution environment
  176. * @param frame the WASM frame to be set for the current exec env
  177. */
  178. static inline void
  179. wasm_exec_env_set_cur_frame(WASMExecEnv *exec_env,
  180. struct WASMInterpFrame *frame)
  181. {
  182. exec_env->cur_frame = frame;
  183. }
  184. /**
  185. * Get the current frame pointer.
  186. *
  187. * @param exec_env the current execution environment
  188. *
  189. * @return the current frame pointer
  190. */
  191. static inline struct WASMInterpFrame*
  192. wasm_exec_env_get_cur_frame(WASMExecEnv *exec_env)
  193. {
  194. return exec_env->cur_frame;
  195. }
  196. struct WASMModuleInstanceCommon *
  197. wasm_exec_env_get_module_inst(WASMExecEnv *exec_env);
  198. void
  199. wasm_exec_env_set_thread_info(WASMExecEnv *exec_env);
  200. #if WASM_ENABLE_THREAD_MGR != 0
  201. void *
  202. wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env);
  203. void
  204. wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg);
  205. #endif
  206. #ifdef OS_ENABLE_HW_BOUND_CHECK
  207. void
  208. wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf);
  209. WASMJmpBuf *
  210. wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env);
  211. #endif
  212. #ifdef __cplusplus
  213. }
  214. #endif
  215. #endif /* end of _WASM_EXEC_ENV_H */