wasm_exec_env.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_exec_env.h"
  6. #include "wasm_runtime_common.h"
  7. #if WASM_ENABLE_INTERP != 0
  8. #include "../interpreter/wasm_runtime.h"
  9. #endif
  10. #if WASM_ENABLE_AOT != 0
  11. #include "../aot/aot_runtime.h"
  12. #endif
  13. #if WASM_ENABLE_AOT != 0
  14. #include "aot_runtime.h"
  15. #endif
  16. #if WASM_ENABLE_THREAD_MGR != 0
  17. #include "../libraries/thread-mgr/thread_manager.h"
  18. #if WASM_ENABLE_DEBUG_INTERP != 0
  19. #include "../libraries/debug-engine/debug_engine.h"
  20. #endif
  21. #endif
  22. WASMExecEnv *
  23. wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
  24. uint32 stack_size)
  25. {
  26. uint64 total_size =
  27. offsetof(WASMExecEnv, wasm_stack.s.bottom) + (uint64)stack_size;
  28. WASMExecEnv *exec_env;
  29. if (total_size >= UINT32_MAX
  30. || !(exec_env = wasm_runtime_malloc((uint32)total_size)))
  31. return NULL;
  32. memset(exec_env, 0, (uint32)total_size);
  33. #if WASM_ENABLE_AOT != 0
  34. if (!(exec_env->argv_buf = wasm_runtime_malloc(sizeof(uint32) * 64))) {
  35. goto fail1;
  36. }
  37. #endif
  38. #if WASM_ENABLE_THREAD_MGR != 0
  39. if (os_mutex_init(&exec_env->wait_lock) != 0)
  40. goto fail2;
  41. if (os_cond_init(&exec_env->wait_cond) != 0)
  42. goto fail3;
  43. #if WASM_ENABLE_DEBUG_INTERP != 0
  44. if (!(exec_env->current_status = wasm_cluster_create_exenv_status()))
  45. goto fail4;
  46. #endif
  47. #endif
  48. #ifdef OS_ENABLE_HW_BOUND_CHECK
  49. if (!(exec_env->exce_check_guard_page =
  50. os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE,
  51. os_get_invalid_handle())))
  52. goto fail5;
  53. #endif
  54. exec_env->module_inst = module_inst;
  55. exec_env->wasm_stack_size = stack_size;
  56. exec_env->wasm_stack.s.top_boundary =
  57. exec_env->wasm_stack.s.bottom + stack_size;
  58. exec_env->wasm_stack.s.top = exec_env->wasm_stack.s.bottom;
  59. #if WASM_ENABLE_AOT != 0
  60. if (module_inst->module_type == Wasm_Module_AoT) {
  61. AOTModuleInstance *i = (AOTModuleInstance *)module_inst;
  62. AOTModule *m = (AOTModule *)i->module;
  63. exec_env->native_symbol = m->native_symbol_list;
  64. }
  65. #endif
  66. #if WASM_ENABLE_MEMORY_TRACING != 0
  67. wasm_runtime_dump_exec_env_mem_consumption(exec_env);
  68. #endif
  69. return exec_env;
  70. #ifdef OS_ENABLE_HW_BOUND_CHECK
  71. fail5:
  72. #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
  73. wasm_cluster_destroy_exenv_status(exec_env->current_status);
  74. #endif
  75. #endif
  76. #if WASM_ENABLE_THREAD_MGR != 0
  77. #if WASM_ENABLE_DEBUG_INTERP != 0
  78. fail4:
  79. os_cond_destroy(&exec_env->wait_cond);
  80. #endif
  81. fail3:
  82. os_mutex_destroy(&exec_env->wait_lock);
  83. fail2:
  84. #endif
  85. #if WASM_ENABLE_AOT != 0
  86. wasm_runtime_free(exec_env->argv_buf);
  87. fail1:
  88. #endif
  89. wasm_runtime_free(exec_env);
  90. return NULL;
  91. }
  92. void
  93. wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
  94. {
  95. #ifdef OS_ENABLE_HW_BOUND_CHECK
  96. os_munmap(exec_env->exce_check_guard_page, os_getpagesize());
  97. #endif
  98. #if WASM_ENABLE_THREAD_MGR != 0
  99. os_mutex_destroy(&exec_env->wait_lock);
  100. os_cond_destroy(&exec_env->wait_cond);
  101. #if WASM_ENABLE_DEBUG_INTERP != 0
  102. wasm_cluster_destroy_exenv_status(exec_env->current_status);
  103. #endif
  104. #endif
  105. #if WASM_ENABLE_AOT != 0
  106. wasm_runtime_free(exec_env->argv_buf);
  107. #endif
  108. wasm_runtime_free(exec_env);
  109. }
  110. WASMExecEnv *
  111. wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
  112. uint32 stack_size)
  113. {
  114. #if WASM_ENABLE_THREAD_MGR != 0
  115. WASMCluster *cluster;
  116. #endif
  117. WASMExecEnv *exec_env =
  118. wasm_exec_env_create_internal(module_inst, stack_size);
  119. if (!exec_env)
  120. return NULL;
  121. #if WASM_ENABLE_INTERP != 0
  122. /* Set the aux_stack_boundary and aux_stack_bottom */
  123. if (module_inst->module_type == Wasm_Module_Bytecode) {
  124. WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
  125. exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
  126. exec_env->aux_stack_boundary.boundary =
  127. module->aux_stack_bottom - module->aux_stack_size;
  128. }
  129. #endif
  130. #if WASM_ENABLE_AOT != 0
  131. /* Set the aux_stack_boundary and aux_stack_bottom */
  132. if (module_inst->module_type == Wasm_Module_AoT) {
  133. AOTModule *module =
  134. (AOTModule *)((AOTModuleInstance *)module_inst)->module;
  135. exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
  136. exec_env->aux_stack_boundary.boundary =
  137. module->aux_stack_bottom - module->aux_stack_size;
  138. }
  139. #endif
  140. #if WASM_ENABLE_THREAD_MGR != 0
  141. /* Create a new cluster for this exec_env */
  142. if (!(cluster = wasm_cluster_create(exec_env))) {
  143. wasm_exec_env_destroy_internal(exec_env);
  144. return NULL;
  145. }
  146. #endif /* end of WASM_ENABLE_THREAD_MGR */
  147. return exec_env;
  148. }
  149. void
  150. wasm_exec_env_destroy(WASMExecEnv *exec_env)
  151. {
  152. #if WASM_ENABLE_THREAD_MGR != 0
  153. /* Wait for all sub-threads */
  154. WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
  155. if (cluster) {
  156. wasm_cluster_wait_for_all_except_self(cluster, exec_env);
  157. #if WASM_ENABLE_DEBUG_INTERP != 0
  158. /* Must fire exit event after other threads exits, otherwise
  159. the stopped thread will be overrided by other threads */
  160. wasm_cluster_thread_exited(exec_env);
  161. #endif
  162. /* We have waited for other threads, this is the only alive thread, so
  163. * we don't acquire cluster->lock because the cluster will be destroyed
  164. * inside this function */
  165. wasm_cluster_del_exec_env(cluster, exec_env);
  166. }
  167. #endif /* end of WASM_ENABLE_THREAD_MGR */
  168. wasm_exec_env_destroy_internal(exec_env);
  169. }
  170. WASMModuleInstanceCommon *
  171. wasm_exec_env_get_module_inst(WASMExecEnv *exec_env)
  172. {
  173. return exec_env->module_inst;
  174. }
  175. void
  176. wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
  177. WASMModuleInstanceCommon *const module_inst)
  178. {
  179. #if WASM_ENABLE_THREAD_MGR != 0
  180. wasm_cluster_traverse_lock(exec_env);
  181. #endif
  182. exec_env->module_inst = module_inst;
  183. #if WASM_ENABLE_THREAD_MGR != 0
  184. wasm_cluster_traverse_unlock(exec_env);
  185. #endif
  186. }
  187. void
  188. wasm_exec_env_restore_module_inst(
  189. WASMExecEnv *exec_env, WASMModuleInstanceCommon *const module_inst_common)
  190. {
  191. WASMModuleInstanceCommon *old_module_inst_common = exec_env->module_inst;
  192. WASMModuleInstance *old_module_inst =
  193. (WASMModuleInstance *)old_module_inst_common;
  194. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_common;
  195. char cur_exception[EXCEPTION_BUF_LEN];
  196. #if WASM_ENABLE_THREAD_MGR != 0
  197. wasm_cluster_traverse_lock(exec_env);
  198. #endif
  199. exec_env->module_inst = module_inst_common;
  200. /*
  201. * propagate an exception if any.
  202. */
  203. exception_lock(old_module_inst);
  204. if (old_module_inst->cur_exception[0] != '\0') {
  205. bh_memcpy_s(cur_exception, sizeof(cur_exception),
  206. old_module_inst->cur_exception,
  207. sizeof(old_module_inst->cur_exception));
  208. }
  209. else {
  210. cur_exception[0] = '\0';
  211. }
  212. exception_unlock(old_module_inst);
  213. #if WASM_ENABLE_THREAD_MGR != 0
  214. wasm_cluster_traverse_unlock(exec_env);
  215. #endif
  216. if (cur_exception[0] != '\0') {
  217. exception_lock(module_inst);
  218. bh_memcpy_s(module_inst->cur_exception,
  219. sizeof(module_inst->cur_exception), cur_exception,
  220. sizeof(cur_exception));
  221. exception_unlock(module_inst);
  222. }
  223. }
  224. void
  225. wasm_exec_env_set_thread_info(WASMExecEnv *exec_env)
  226. {
  227. uint8 *stack_boundary = os_thread_get_stack_boundary();
  228. #if WASM_ENABLE_THREAD_MGR != 0
  229. os_mutex_lock(&exec_env->wait_lock);
  230. #endif
  231. exec_env->handle = os_self_thread();
  232. exec_env->native_stack_boundary =
  233. stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL;
  234. exec_env->native_stack_top_min = (void *)UINTPTR_MAX;
  235. #if WASM_ENABLE_THREAD_MGR != 0
  236. os_mutex_unlock(&exec_env->wait_lock);
  237. #endif
  238. }
  239. #if WASM_ENABLE_THREAD_MGR != 0
  240. void *
  241. wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env)
  242. {
  243. return exec_env->thread_arg;
  244. }
  245. void
  246. wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
  247. {
  248. exec_env->thread_arg = thread_arg;
  249. }
  250. #endif
  251. #ifdef OS_ENABLE_HW_BOUND_CHECK
  252. void
  253. wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
  254. {
  255. jmpbuf->prev = exec_env->jmpbuf_stack_top;
  256. exec_env->jmpbuf_stack_top = jmpbuf;
  257. }
  258. WASMJmpBuf *
  259. wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env)
  260. {
  261. WASMJmpBuf *stack_top = exec_env->jmpbuf_stack_top;
  262. if (stack_top) {
  263. exec_env->jmpbuf_stack_top = stack_top->prev;
  264. return stack_top;
  265. }
  266. return NULL;
  267. }
  268. #endif