wasm_exec_env.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. #if WASM_ENABLE_DEBUG_INTERP != 0
  132. wasm_debug_instance_create(cluster);
  133. #endif
  134. #endif /* end of WASM_ENABLE_THREAD_MGR */
  135. return exec_env;
  136. }
  137. void
  138. wasm_exec_env_destroy(WASMExecEnv *exec_env)
  139. {
  140. #if WASM_ENABLE_THREAD_MGR != 0
  141. /* Terminate all sub-threads */
  142. WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
  143. if (cluster) {
  144. #if WASM_ENABLE_DEBUG_INTERP != 0
  145. wasm_cluster_thread_exited(exec_env);
  146. wasm_debug_instance_destroy(cluster);
  147. #endif
  148. wasm_cluster_terminate_all_except_self(cluster, exec_env);
  149. wasm_cluster_del_exec_env(cluster, exec_env);
  150. }
  151. #endif /* end of WASM_ENABLE_THREAD_MGR */
  152. wasm_exec_env_destroy_internal(exec_env);
  153. }
  154. WASMModuleInstanceCommon *
  155. wasm_exec_env_get_module_inst(WASMExecEnv *exec_env)
  156. {
  157. return exec_env->module_inst;
  158. }
  159. void
  160. wasm_exec_env_set_thread_info(WASMExecEnv *exec_env)
  161. {
  162. exec_env->handle = os_self_thread();
  163. exec_env->native_stack_boundary = os_thread_get_stack_boundary()
  164. + RESERVED_BYTES_TO_NATIVE_STACK_BOUNDARY;
  165. }
  166. #if WASM_ENABLE_THREAD_MGR != 0
  167. void *
  168. wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env)
  169. {
  170. return exec_env->thread_arg;
  171. }
  172. void
  173. wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
  174. {
  175. exec_env->thread_arg = thread_arg;
  176. }
  177. #endif
  178. #ifdef OS_ENABLE_HW_BOUND_CHECK
  179. void
  180. wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
  181. {
  182. jmpbuf->prev = exec_env->jmpbuf_stack_top;
  183. exec_env->jmpbuf_stack_top = jmpbuf;
  184. }
  185. WASMJmpBuf *
  186. wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env)
  187. {
  188. WASMJmpBuf *stack_top = exec_env->jmpbuf_stack_top;
  189. if (stack_top) {
  190. exec_env->jmpbuf_stack_top = stack_top->prev;
  191. return stack_top;
  192. }
  193. return NULL;
  194. }
  195. #endif