wasm_exec_env.h 6.5 KB

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