| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /*
- * Copyright (C) 2019 Intel Corporation. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #include "wasm_exec_env.h"
- #include "wasm_runtime_common.h"
- #if WASM_ENABLE_INTERP != 0
- #include "../interpreter/wasm_runtime.h"
- #endif
- #if WASM_ENABLE_AOT != 0
- #include "../aot/aot_runtime.h"
- #endif
- #if WASM_ENABLE_AOT != 0
- #include "aot_runtime.h"
- #endif
- #if WASM_ENABLE_THREAD_MGR != 0
- #include "../libraries/thread-mgr/thread_manager.h"
- #if WASM_ENABLE_DEBUG_INTERP != 0
- #include "../libraries/debug-engine/debug_engine.h"
- #endif
- #endif
- WASMExecEnv *
- wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
- uint32 stack_size)
- {
- uint64 total_size =
- offsetof(WASMExecEnv, wasm_stack.s.bottom) + (uint64)stack_size;
- WASMExecEnv *exec_env;
- if (total_size >= UINT32_MAX
- || !(exec_env = wasm_runtime_malloc((uint32)total_size)))
- return NULL;
- memset(exec_env, 0, (uint32)total_size);
- #if WASM_ENABLE_AOT != 0
- if (!(exec_env->argv_buf = wasm_runtime_malloc(sizeof(uint32) * 64))) {
- goto fail1;
- }
- #endif
- #if WASM_ENABLE_THREAD_MGR != 0
- if (os_mutex_init(&exec_env->wait_lock) != 0)
- goto fail2;
- if (os_cond_init(&exec_env->wait_cond) != 0)
- goto fail3;
- #if WASM_ENABLE_DEBUG_INTERP != 0
- if (!(exec_env->current_status = wasm_cluster_create_exenv_status()))
- goto fail4;
- #endif
- #endif
- #ifdef OS_ENABLE_HW_BOUND_CHECK
- if (!(exec_env->exce_check_guard_page =
- os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE)))
- goto fail5;
- #endif
- exec_env->module_inst = module_inst;
- exec_env->wasm_stack_size = stack_size;
- exec_env->wasm_stack.s.top_boundary =
- exec_env->wasm_stack.s.bottom + stack_size;
- exec_env->wasm_stack.s.top = exec_env->wasm_stack.s.bottom;
- #if WASM_ENABLE_AOT != 0
- if (module_inst->module_type == Wasm_Module_AoT) {
- AOTModuleInstance *i = (AOTModuleInstance *)module_inst;
- AOTModule *m = (AOTModule *)i->module;
- exec_env->native_symbol = m->native_symbol_list;
- }
- #endif
- #if WASM_ENABLE_MEMORY_TRACING != 0
- wasm_runtime_dump_exec_env_mem_consumption(exec_env);
- #endif
- return exec_env;
- #ifdef OS_ENABLE_HW_BOUND_CHECK
- fail5:
- #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
- wasm_cluster_destroy_exenv_status(exec_env->current_status);
- #endif
- #endif
- #if WASM_ENABLE_THREAD_MGR != 0
- #if WASM_ENABLE_DEBUG_INTERP != 0
- fail4:
- os_cond_destroy(&exec_env->wait_cond);
- #endif
- fail3:
- os_mutex_destroy(&exec_env->wait_lock);
- fail2:
- #endif
- #if WASM_ENABLE_AOT != 0
- wasm_runtime_free(exec_env->argv_buf);
- fail1:
- #endif
- wasm_runtime_free(exec_env);
- return NULL;
- }
- void
- wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
- {
- #ifdef OS_ENABLE_HW_BOUND_CHECK
- os_munmap(exec_env->exce_check_guard_page, os_getpagesize());
- #endif
- #if WASM_ENABLE_THREAD_MGR != 0
- os_mutex_destroy(&exec_env->wait_lock);
- os_cond_destroy(&exec_env->wait_cond);
- #if WASM_ENABLE_DEBUG_INTERP != 0
- wasm_cluster_destroy_exenv_status(exec_env->current_status);
- #endif
- #endif
- #if WASM_ENABLE_AOT != 0
- wasm_runtime_free(exec_env->argv_buf);
- #endif
- wasm_runtime_free(exec_env);
- }
- WASMExecEnv *
- wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
- uint32 stack_size)
- {
- #if WASM_ENABLE_THREAD_MGR != 0
- WASMCluster *cluster;
- #endif
- WASMExecEnv *exec_env =
- wasm_exec_env_create_internal(module_inst, stack_size);
- if (!exec_env)
- return NULL;
- #if WASM_ENABLE_INTERP != 0
- /* Set the aux_stack_boundary and aux_stack_bottom */
- if (module_inst->module_type == Wasm_Module_Bytecode) {
- WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
- exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
- exec_env->aux_stack_boundary.boundary =
- module->aux_stack_bottom - module->aux_stack_size;
- }
- #endif
- #if WASM_ENABLE_AOT != 0
- /* Set the aux_stack_boundary and aux_stack_bottom */
- if (module_inst->module_type == Wasm_Module_AoT) {
- AOTModule *module =
- (AOTModule *)((AOTModuleInstance *)module_inst)->module;
- exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
- exec_env->aux_stack_boundary.boundary =
- module->aux_stack_bottom - module->aux_stack_size;
- }
- #endif
- #if WASM_ENABLE_THREAD_MGR != 0
- /* Create a new cluster for this exec_env */
- if (!(cluster = wasm_cluster_create(exec_env))) {
- wasm_exec_env_destroy_internal(exec_env);
- return NULL;
- }
- #endif /* end of WASM_ENABLE_THREAD_MGR */
- return exec_env;
- }
- void
- wasm_exec_env_destroy(WASMExecEnv *exec_env)
- {
- #if WASM_ENABLE_THREAD_MGR != 0
- /* Wait for all sub-threads */
- WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
- if (cluster) {
- wasm_cluster_wait_for_all_except_self(cluster, exec_env);
- #if WASM_ENABLE_DEBUG_INTERP != 0
- /* Must fire exit event after other threads exits, otherwise
- the stopped thread will be overrided by other threads */
- wasm_cluster_thread_exited(exec_env);
- #endif
- /* We have waited for other threads, this is the only alive thread, so
- * we don't acquire cluster->lock because the cluster will be destroyed
- * inside this function */
- wasm_cluster_del_exec_env(cluster, exec_env);
- }
- #endif /* end of WASM_ENABLE_THREAD_MGR */
- wasm_exec_env_destroy_internal(exec_env);
- }
- WASMModuleInstanceCommon *
- wasm_exec_env_get_module_inst(WASMExecEnv *exec_env)
- {
- return exec_env->module_inst;
- }
- void
- wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
- WASMModuleInstanceCommon *const module_inst)
- {
- exec_env->module_inst = module_inst;
- }
- void
- wasm_exec_env_set_thread_info(WASMExecEnv *exec_env)
- {
- uint8 *stack_boundary = os_thread_get_stack_boundary();
- #if WASM_ENABLE_THREAD_MGR != 0
- os_mutex_lock(&exec_env->wait_lock);
- #endif
- exec_env->handle = os_self_thread();
- exec_env->native_stack_boundary =
- stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL;
- exec_env->native_stack_top_min = (void *)UINTPTR_MAX;
- #if WASM_ENABLE_THREAD_MGR != 0
- os_mutex_unlock(&exec_env->wait_lock);
- #endif
- }
- #if WASM_ENABLE_THREAD_MGR != 0
- void *
- wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env)
- {
- return exec_env->thread_arg;
- }
- void
- wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
- {
- exec_env->thread_arg = thread_arg;
- }
- #endif
- #if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
- void
- wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
- {
- jmpbuf->prev = exec_env->jmpbuf_stack_top;
- exec_env->jmpbuf_stack_top = jmpbuf;
- }
- WASMJmpBuf *
- wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env)
- {
- WASMJmpBuf *stack_top = exec_env->jmpbuf_stack_top;
- if (stack_top) {
- exec_env->jmpbuf_stack_top = stack_top->prev;
- return stack_top;
- }
- return NULL;
- }
- #endif
|