wasm_exec_env.c 6.0 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 "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. exec_env->module_inst = module_inst;
  49. exec_env->wasm_stack_size = stack_size;
  50. exec_env->wasm_stack.s.top_boundary =
  51. exec_env->wasm_stack.s.bottom + stack_size;
  52. exec_env->wasm_stack.s.top = exec_env->wasm_stack.s.bottom;
  53. #if WASM_ENABLE_AOT != 0
  54. if (module_inst->module_type == Wasm_Module_AoT) {
  55. AOTModuleInstance *i = (AOTModuleInstance *)module_inst;
  56. AOTModule *m = (AOTModule *)i->aot_module.ptr;
  57. exec_env->native_symbol = m->native_symbol_list;
  58. }
  59. #endif
  60. #if WASM_ENABLE_MEMORY_TRACING != 0
  61. wasm_runtime_dump_exec_env_mem_consumption(exec_env);
  62. #endif
  63. return exec_env;
  64. #if WASM_ENABLE_THREAD_MGR != 0
  65. #if WASM_ENABLE_DEBUG_INTERP != 0
  66. fail4:
  67. os_cond_destroy(&exec_env->wait_cond);
  68. #endif
  69. fail3:
  70. os_mutex_destroy(&exec_env->wait_lock);
  71. fail2:
  72. #endif
  73. #if WASM_ENABLE_AOT != 0
  74. wasm_runtime_free(exec_env->argv_buf);
  75. fail1:
  76. #endif
  77. wasm_runtime_free(exec_env);
  78. return NULL;
  79. }
  80. void
  81. wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
  82. {
  83. #if WASM_ENABLE_THREAD_MGR != 0
  84. os_mutex_destroy(&exec_env->wait_lock);
  85. os_cond_destroy(&exec_env->wait_cond);
  86. #if WASM_ENABLE_DEBUG_INTERP != 0
  87. wasm_cluster_destroy_exenv_status(exec_env->current_status);
  88. #endif
  89. #endif
  90. #if WASM_ENABLE_AOT != 0
  91. wasm_runtime_free(exec_env->argv_buf);
  92. #endif
  93. wasm_runtime_free(exec_env);
  94. }
  95. WASMExecEnv *
  96. wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
  97. uint32 stack_size)
  98. {
  99. #if WASM_ENABLE_THREAD_MGR != 0
  100. WASMCluster *cluster;
  101. #endif
  102. WASMExecEnv *exec_env =
  103. wasm_exec_env_create_internal(module_inst, stack_size);
  104. if (!exec_env)
  105. return NULL;
  106. #if WASM_ENABLE_INTERP != 0
  107. /* Set the aux_stack_boundary and aux_stack_bottom */
  108. if (module_inst->module_type == Wasm_Module_Bytecode) {
  109. WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
  110. exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
  111. exec_env->aux_stack_boundary.boundary =
  112. module->aux_stack_bottom - module->aux_stack_size;
  113. }
  114. #endif
  115. #if WASM_ENABLE_AOT != 0
  116. /* Set the aux_stack_boundary and aux_stack_bottom */
  117. if (module_inst->module_type == Wasm_Module_AoT) {
  118. AOTModule *module =
  119. (AOTModule *)(((AOTModuleInstance *)module_inst)->aot_module.ptr);
  120. exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
  121. exec_env->aux_stack_boundary.boundary =
  122. module->aux_stack_bottom - module->aux_stack_size;
  123. }
  124. #endif
  125. #if WASM_ENABLE_THREAD_MGR != 0
  126. /* Create a new cluster for this exec_env */
  127. if (!(cluster = wasm_cluster_create(exec_env))) {
  128. wasm_exec_env_destroy_internal(exec_env);
  129. return NULL;
  130. }
  131. #endif /* end of WASM_ENABLE_THREAD_MGR */
  132. return exec_env;
  133. }
  134. void
  135. wasm_exec_env_destroy(WASMExecEnv *exec_env)
  136. {
  137. #if WASM_ENABLE_THREAD_MGR != 0
  138. /* Terminate all sub-threads */
  139. WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
  140. if (cluster) {
  141. wasm_cluster_terminate_all_except_self(cluster, exec_env);
  142. #if WASM_ENABLE_DEBUG_INTERP != 0
  143. /* Must fire exit event after other threads exits, otherwise
  144. the stopped thread will be overrided by other threads */
  145. wasm_cluster_thread_exited(exec_env);
  146. #endif
  147. wasm_cluster_del_exec_env(cluster, exec_env);
  148. }
  149. #endif /* end of WASM_ENABLE_THREAD_MGR */
  150. wasm_exec_env_destroy_internal(exec_env);
  151. }
  152. WASMModuleInstanceCommon *
  153. wasm_exec_env_get_module_inst(WASMExecEnv *exec_env)
  154. {
  155. return exec_env->module_inst;
  156. }
  157. void
  158. wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
  159. WASMModuleInstanceCommon *const module_inst)
  160. {
  161. exec_env->module_inst = module_inst;
  162. }
  163. void
  164. wasm_exec_env_set_thread_info(WASMExecEnv *exec_env)
  165. {
  166. exec_env->handle = os_self_thread();
  167. exec_env->native_stack_boundary = os_thread_get_stack_boundary()
  168. + RESERVED_BYTES_TO_NATIVE_STACK_BOUNDARY;
  169. }
  170. #if WASM_ENABLE_THREAD_MGR != 0
  171. void *
  172. wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env)
  173. {
  174. return exec_env->thread_arg;
  175. }
  176. void
  177. wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
  178. {
  179. exec_env->thread_arg = thread_arg;
  180. }
  181. #endif
  182. #ifdef OS_ENABLE_HW_BOUND_CHECK
  183. void
  184. wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
  185. {
  186. jmpbuf->prev = exec_env->jmpbuf_stack_top;
  187. exec_env->jmpbuf_stack_top = jmpbuf;
  188. }
  189. WASMJmpBuf *
  190. wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env)
  191. {
  192. WASMJmpBuf *stack_top = exec_env->jmpbuf_stack_top;
  193. if (stack_top) {
  194. exec_env->jmpbuf_stack_top = stack_top->prev;
  195. return stack_top;
  196. }
  197. return NULL;
  198. }
  199. #endif