mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
ca61184ced
Fix some of the spelling issues found by CSpell.
328 lines
9.1 KiB
C
328 lines
9.1 KiB
C
/*
|
|
* 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_GC != 0
|
|
#include "mem_alloc.h"
|
|
#endif
|
|
#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_u.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,
|
|
os_get_invalid_handle())))
|
|
goto fail5;
|
|
#endif
|
|
|
|
exec_env->module_inst = module_inst;
|
|
exec_env->wasm_stack_size = stack_size;
|
|
exec_env->wasm_stack.bottom = exec_env->wasm_stack_u.bottom;
|
|
exec_env->wasm_stack.top_boundary =
|
|
exec_env->wasm_stack.bottom + stack_size;
|
|
exec_env->wasm_stack.top = exec_env->wasm_stack.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 WASM_ENABLE_GC != 0
|
|
void *gc_heap_handle = NULL;
|
|
#endif
|
|
|
|
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 = (uintptr_t)module->aux_stack_bottom;
|
|
exec_env->aux_stack_boundary =
|
|
(uintptr_t)module->aux_stack_bottom - module->aux_stack_size;
|
|
#if WASM_ENABLE_GC != 0
|
|
gc_heap_handle =
|
|
((WASMModuleInstance *)module_inst)->e->common.gc_heap_pool;
|
|
#endif
|
|
}
|
|
#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 = (uintptr_t)module->aux_stack_bottom;
|
|
exec_env->aux_stack_boundary =
|
|
(uintptr_t)module->aux_stack_bottom - module->aux_stack_size;
|
|
#if WASM_ENABLE_GC != 0
|
|
gc_heap_handle =
|
|
((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
|
|
->common.gc_heap_handle;
|
|
#endif
|
|
}
|
|
#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;
|
|
}
|
|
#if WASM_ENABLE_GC != 0
|
|
mem_allocator_enable_gc_reclaim(gc_heap_handle, cluster);
|
|
#endif
|
|
#else
|
|
#if WASM_ENABLE_GC != 0
|
|
mem_allocator_enable_gc_reclaim(gc_heap_handle, exec_env);
|
|
#endif
|
|
#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 overriden 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)
|
|
{
|
|
#if WASM_ENABLE_THREAD_MGR != 0
|
|
wasm_cluster_traverse_lock(exec_env);
|
|
#endif
|
|
exec_env->module_inst = module_inst;
|
|
#if WASM_ENABLE_THREAD_MGR != 0
|
|
wasm_cluster_traverse_unlock(exec_env);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
wasm_exec_env_restore_module_inst(
|
|
WASMExecEnv *exec_env, WASMModuleInstanceCommon *const module_inst_common)
|
|
{
|
|
WASMModuleInstanceCommon *old_module_inst_common = exec_env->module_inst;
|
|
WASMModuleInstance *old_module_inst =
|
|
(WASMModuleInstance *)old_module_inst_common;
|
|
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_common;
|
|
char cur_exception[EXCEPTION_BUF_LEN];
|
|
|
|
#if WASM_ENABLE_THREAD_MGR != 0
|
|
wasm_cluster_traverse_lock(exec_env);
|
|
#endif
|
|
exec_env->module_inst = module_inst_common;
|
|
/*
|
|
* propagate an exception if any.
|
|
*/
|
|
exception_lock(old_module_inst);
|
|
if (old_module_inst->cur_exception[0] != '\0') {
|
|
bh_memcpy_s(cur_exception, sizeof(cur_exception),
|
|
old_module_inst->cur_exception,
|
|
sizeof(old_module_inst->cur_exception));
|
|
}
|
|
else {
|
|
cur_exception[0] = '\0';
|
|
}
|
|
exception_unlock(old_module_inst);
|
|
#if WASM_ENABLE_THREAD_MGR != 0
|
|
wasm_cluster_traverse_unlock(exec_env);
|
|
#endif
|
|
if (cur_exception[0] != '\0') {
|
|
exception_lock(module_inst);
|
|
bh_memcpy_s(module_inst->cur_exception,
|
|
sizeof(module_inst->cur_exception), cur_exception,
|
|
sizeof(cur_exception));
|
|
exception_unlock(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
|
|
|
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
|
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
|