Refactor interpreter/AOT module instance layout (#1559)
Refactor the layout of interpreter and AOT module instance: - Unify the interp/AOT module instance, use the same WASMModuleInstance/ WASMMemoryInstance/WASMTableInstance data structures for both interpreter and AOT - Make the offset of most fields the same in module instance for both interpreter and AOT, append memory instance structure, global data and table instances to the end of module instance for interpreter mode (like AOT mode) - For extra fields in WASM module instance, use WASMModuleInstanceExtra to create a field `e` for interpreter - Change the LLVM JIT module instance creating process, LLVM JIT uses the WASM module and module instance same as interpreter/Fast-JIT mode. So that Fast JIT and LLVM JIT can access the same data structures, and make it possible to implement the Multi-tier JIT (tier-up from Fast JIT to LLVM JIT) in the future - Unify some APIs: merge some APIs for module instance and memory instance's related operations (only implement one copy) Note that the AOT ABI is same, the AOT file format, AOT relocation types, how AOT code accesses the AOT module instance and so on are kept unchanged. Refer to: https://github.com/bytecodealliance/wasm-micro-runtime/issues/1384
This commit is contained in:
@ -135,43 +135,117 @@ static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;
|
||||
static void
|
||||
runtime_signal_handler(void *sig_addr)
|
||||
{
|
||||
WASMModuleInstanceCommon *module_inst;
|
||||
WASMSignalInfo sig_info;
|
||||
WASMModuleInstance *module_inst;
|
||||
WASMMemoryInstance *memory_inst;
|
||||
WASMJmpBuf *jmpbuf_node;
|
||||
uint8 *mapped_mem_start_addr = NULL;
|
||||
uint8 *mapped_mem_end_addr = NULL;
|
||||
uint8 *stack_min_addr;
|
||||
uint32 page_size;
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
|
||||
sig_info.exec_env_tls = exec_env_tls;
|
||||
sig_info.sig_addr = sig_addr;
|
||||
if (exec_env_tls) {
|
||||
module_inst = exec_env_tls->module_inst;
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
wasm_signal_handler(&sig_info);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
aot_signal_handler(&sig_info);
|
||||
#endif
|
||||
/* Check whether current thread is running wasm function */
|
||||
if (exec_env_tls && exec_env_tls->handle == os_self_thread()
|
||||
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
|
||||
/* Get mapped mem info of current instance */
|
||||
module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
|
||||
/* Get the default memory instance */
|
||||
memory_inst = wasm_get_default_memory(module_inst);
|
||||
if (memory_inst) {
|
||||
mapped_mem_start_addr = memory_inst->memory_data;
|
||||
mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
|
||||
}
|
||||
|
||||
/* Get stack info of current thread */
|
||||
page_size = os_getpagesize();
|
||||
stack_min_addr = os_thread_get_stack_boundary();
|
||||
|
||||
if (memory_inst
|
||||
&& (mapped_mem_start_addr <= (uint8 *)sig_addr
|
||||
&& (uint8 *)sig_addr < mapped_mem_end_addr)) {
|
||||
/* The address which causes segmentation fault is inside
|
||||
the memory instance's guard regions */
|
||||
wasm_set_exception(module_inst, "out of bounds memory access");
|
||||
os_longjmp(jmpbuf_node->jmpbuf, 1);
|
||||
}
|
||||
else if (stack_min_addr - page_size <= (uint8 *)sig_addr
|
||||
&& (uint8 *)sig_addr
|
||||
< stack_min_addr + page_size * guard_page_count) {
|
||||
/* The address which causes segmentation fault is inside
|
||||
native thread's guard page */
|
||||
wasm_set_exception(module_inst, "native stack overflow");
|
||||
os_longjmp(jmpbuf_node->jmpbuf, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static LONG
|
||||
runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
|
||||
{
|
||||
WASMModuleInstanceCommon *module_inst;
|
||||
WASMSignalInfo sig_info;
|
||||
PEXCEPTION_RECORD ExceptionRecord = exce_info->ExceptionRecord;
|
||||
uint8 *sig_addr = (uint8 *)ExceptionRecord->ExceptionInformation[1];
|
||||
WASMModuleInstance *module_inst;
|
||||
WASMMemoryInstance *memory_inst;
|
||||
WASMJmpBuf *jmpbuf_node;
|
||||
uint8 *mapped_mem_start_addr = NULL;
|
||||
uint8 *mapped_mem_end_addr = NULL;
|
||||
uint32 page_size = os_getpagesize();
|
||||
|
||||
sig_info.exec_env_tls = exec_env_tls;
|
||||
sig_info.exce_info = exce_info;
|
||||
if (exec_env_tls) {
|
||||
module_inst = exec_env_tls->module_inst;
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_exception_handler(&sig_info);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_exception_handler(&sig_info);
|
||||
#endif
|
||||
if (exec_env_tls && exec_env_tls->handle == os_self_thread()
|
||||
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
|
||||
module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
|
||||
if (ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||
/* Get the default memory instance */
|
||||
memory_inst = wasm_get_default_memory(module_inst);
|
||||
if (memory_inst) {
|
||||
mapped_mem_start_addr = memory_inst->memory_data;
|
||||
mapped_mem_end_addr =
|
||||
memory_inst->memory_data + 8 * (uint64)BH_GB;
|
||||
if (mapped_mem_start_addr <= (uint8 *)sig_addr
|
||||
&& (uint8 *)sig_addr < mapped_mem_end_addr) {
|
||||
/* The address which causes segmentation fault is inside
|
||||
the memory instance's guard regions.
|
||||
Set exception and let the wasm func continue to run, when
|
||||
the wasm func returns, the caller will check whether the
|
||||
exception is thrown and return to runtime. */
|
||||
wasm_set_exception(module_inst,
|
||||
"out of bounds memory access");
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
/* Continue to search next exception handler for
|
||||
interpreter mode as it can be caught by
|
||||
`__try { .. } __except { .. }` sentences in
|
||||
wasm_runtime.c */
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else {
|
||||
/* Skip current instruction and continue to run for
|
||||
AOT mode. TODO: implement unwind support for AOT
|
||||
code in Windows platform */
|
||||
exce_info->ContextRecord->Rip++;
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
|
||||
/* Set stack overflow exception and let the wasm func continue
|
||||
to run, when the wasm func returns, the caller will check
|
||||
whether the exception is thrown and return to runtime, and
|
||||
the damaged stack will be recovered by _resetstkoflw(). */
|
||||
wasm_set_exception(module_inst, "native stack overflow");
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else {
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os_printf("Unhandled exception thrown: exception code: 0x%lx, "
|
||||
"exception address: %p, exception information: %p\n",
|
||||
ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionAddress,
|
||||
sig_addr);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif /* end of BH_PLATFORM_WINDOWS */
|
||||
@ -912,22 +986,7 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
WASMModuleCommon *module_common = NULL;
|
||||
|
||||
if (get_package_type(buf, size) == Wasm_Module_Bytecode) {
|
||||
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
||||
AOTModule *aot_module;
|
||||
WASMModule *module = wasm_load(buf, size, error_buf, error_buf_size);
|
||||
if (!module)
|
||||
return NULL;
|
||||
|
||||
if (!(aot_module =
|
||||
aot_convert_wasm_module(module, error_buf, error_buf_size))) {
|
||||
wasm_unload(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
module_common = (WASMModuleCommon *)aot_module;
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
#elif WASM_ENABLE_INTERP != 0
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
module_common =
|
||||
(WASMModuleCommon *)wasm_load(buf, size, error_buf, error_buf_size);
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
@ -1235,19 +1294,18 @@ wasm_runtime_dump_mem_consumption(WASMExecEnv *exec_env)
|
||||
&module_inst_mem_consps);
|
||||
wasm_get_module_mem_consumption(wasm_module, &module_mem_consps);
|
||||
if (wasm_module_inst->module->aux_stack_top_global_index != (uint32)-1)
|
||||
max_aux_stack_used = wasm_module_inst->max_aux_stack_used;
|
||||
max_aux_stack_used = wasm_module_inst->e->max_aux_stack_used;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst_common->module_type == Wasm_Module_AoT) {
|
||||
AOTModuleInstance *aot_module_inst =
|
||||
(AOTModuleInstance *)module_inst_common;
|
||||
AOTModule *aot_module = (AOTModule *)aot_module_inst->aot_module.ptr;
|
||||
AOTModule *aot_module = (AOTModule *)aot_module_inst->module;
|
||||
module_common = (WASMModuleCommon *)aot_module;
|
||||
if (aot_module_inst->memories.ptr) {
|
||||
AOTMemoryInstance **memories =
|
||||
(AOTMemoryInstance **)aot_module_inst->memories.ptr;
|
||||
heap_handle = memories[0]->heap_handle.ptr;
|
||||
if (aot_module_inst->memories) {
|
||||
AOTMemoryInstance **memories = aot_module_inst->memories;
|
||||
heap_handle = memories[0]->heap_handle;
|
||||
}
|
||||
aot_get_module_inst_mem_consumption(aot_module_inst,
|
||||
&module_inst_mem_consps);
|
||||
@ -1982,99 +2040,130 @@ fail1:
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_create_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
|
||||
wasm_runtime_create_exec_env_singleton(
|
||||
WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_create_exec_env_singleton(
|
||||
(WASMModuleInstance *)module_inst);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_create_exec_env_singleton((AOTModuleInstance *)module_inst);
|
||||
#endif
|
||||
return false;
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
|
||||
if (module_inst->exec_env_singleton) {
|
||||
return true;
|
||||
}
|
||||
|
||||
exec_env = wasm_exec_env_create(module_inst_comm,
|
||||
module_inst->default_wasm_stack_size);
|
||||
if (exec_env)
|
||||
module_inst->exec_env_singleton = exec_env;
|
||||
|
||||
return exec_env ? true : false;
|
||||
}
|
||||
|
||||
WASMExecEnv *
|
||||
wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
|
||||
wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
if (!((WASMModuleInstance *)module_inst)->exec_env_singleton) {
|
||||
wasm_create_exec_env_singleton((WASMModuleInstance *)module_inst);
|
||||
}
|
||||
return ((WASMModuleInstance *)module_inst)->exec_env_singleton;
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
|
||||
if (!module_inst->exec_env_singleton) {
|
||||
wasm_runtime_create_exec_env_singleton(module_inst_comm);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
if (!((AOTModuleInstance *)module_inst)->exec_env_singleton.ptr) {
|
||||
aot_create_exec_env_singleton((AOTModuleInstance *)module_inst);
|
||||
}
|
||||
return (WASMExecEnv *)((AOTModuleInstance *)module_inst)
|
||||
->exec_env_singleton.ptr;
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
return module_inst->exec_env_singleton;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst,
|
||||
const char *exception)
|
||||
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
wasm_set_exception((WASMModuleInstance *)module_inst, exception);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
aot_set_exception((AOTModuleInstance *)module_inst, exception);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (exception)
|
||||
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
|
||||
"Exception: %s", exception);
|
||||
else
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
static const char *exception_msgs[] = {
|
||||
"unreachable", /* EXCE_UNREACHABLE */
|
||||
"allocate memory failed", /* EXCE_OUT_OF_MEMORY */
|
||||
"out of bounds memory access", /* EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS */
|
||||
"integer overflow", /* EXCE_INTEGER_OVERFLOW */
|
||||
"integer divide by zero", /* EXCE_INTEGER_DIVIDE_BY_ZERO */
|
||||
"invalid conversion to integer", /* EXCE_INVALID_CONVERSION_TO_INTEGER */
|
||||
"indirect call type mismatch", /* EXCE_INVALID_FUNCTION_TYPE_INDEX */
|
||||
"invalid function index", /* EXCE_INVALID_FUNCTION_INDEX */
|
||||
"undefined element", /* EXCE_UNDEFINED_ELEMENT */
|
||||
"uninitialized element", /* EXCE_UNINITIALIZED_ELEMENT */
|
||||
"failed to call unlinked import function", /* EXCE_CALL_UNLINKED_IMPORT_FUNC */
|
||||
"native stack overflow", /* EXCE_NATIVE_STACK_OVERFLOW */
|
||||
"unaligned atomic", /* EXCE_UNALIGNED_ATOMIC */
|
||||
"wasm auxiliary stack overflow", /* EXCE_AUX_STACK_OVERFLOW */
|
||||
"wasm auxiliary stack underflow", /* EXCE_AUX_STACK_UNDERFLOW */
|
||||
"out of bounds table access", /* EXCE_OUT_OF_BOUNDS_TABLE_ACCESS */
|
||||
"wasm operand stack overflow", /* EXCE_OPERAND_STACK_OVERFLOW */
|
||||
"", /* EXCE_ALREADY_THROWN */
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
void
|
||||
wasm_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id)
|
||||
{
|
||||
if (id < EXCE_NUM)
|
||||
wasm_set_exception(module_inst, exception_msgs[id]);
|
||||
else
|
||||
wasm_set_exception(module_inst, "unknown exception");
|
||||
}
|
||||
|
||||
const char *
|
||||
wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst)
|
||||
wasm_get_exception(WASMModuleInstance *module_inst)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
return wasm_get_exception((WASMModuleInstance *)module_inst);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
return aot_get_exception((AOTModuleInstance *)module_inst);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
if (module_inst->cur_exception[0] == '\0')
|
||||
return NULL;
|
||||
else
|
||||
return module_inst->cur_exception;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst)
|
||||
wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst_comm,
|
||||
const char *exception)
|
||||
{
|
||||
wasm_runtime_set_exception(module_inst, NULL);
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
wasm_set_exception(module_inst, exception);
|
||||
}
|
||||
|
||||
const char *
|
||||
wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
return wasm_get_exception(module_inst);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
|
||||
void *custom_data)
|
||||
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
((WASMModuleInstance *)module_inst)->custom_data = custom_data;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
((AOTModuleInstance *)module_inst)->custom_data.ptr = custom_data;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
wasm_runtime_set_exception(module_inst_comm, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
module_inst->custom_data = custom_data;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2089,17 +2178,13 @@ wasm_runtime_set_custom_data(WASMModuleInstanceCommon *module_inst,
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst)
|
||||
wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return ((WASMModuleInstance *)module_inst)->custom_data;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return ((AOTModuleInstance *)module_inst)->custom_data.ptr;
|
||||
#endif
|
||||
return NULL;
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
return module_inst->custom_data;
|
||||
}
|
||||
|
||||
uint32
|
||||
@ -2171,155 +2256,6 @@ wasm_runtime_module_dup_data(WASMModuleInstanceCommon *module_inst,
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst,
|
||||
uint32 app_offset, uint32 size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_validate_app_addr((WASMModuleInstance *)module_inst,
|
||||
app_offset, size);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_validate_app_addr((AOTModuleInstance *)module_inst,
|
||||
app_offset, size);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst,
|
||||
uint32 app_str_offset)
|
||||
{
|
||||
uint32 app_end_offset;
|
||||
char *str, *str_end;
|
||||
|
||||
if (!wasm_runtime_get_app_addr_range(module_inst, app_str_offset, NULL,
|
||||
&app_end_offset))
|
||||
goto fail;
|
||||
|
||||
str = wasm_runtime_addr_app_to_native(module_inst, app_str_offset);
|
||||
str_end = str + (app_end_offset - app_str_offset);
|
||||
while (str < str_end && *str != '\0')
|
||||
str++;
|
||||
if (str == str_end)
|
||||
goto fail;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst,
|
||||
void *native_ptr, uint32 size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_validate_native_addr((WASMModuleInstance *)module_inst,
|
||||
native_ptr, size);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_validate_native_addr((AOTModuleInstance *)module_inst,
|
||||
native_ptr, size);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst,
|
||||
uint32 app_offset)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_addr_app_to_native((WASMModuleInstance *)module_inst,
|
||||
app_offset);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_addr_app_to_native((AOTModuleInstance *)module_inst,
|
||||
app_offset);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst,
|
||||
void *native_ptr)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_addr_native_to_app((WASMModuleInstance *)module_inst,
|
||||
native_ptr);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_addr_native_to_app((AOTModuleInstance *)module_inst,
|
||||
native_ptr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst,
|
||||
uint32 app_offset, uint32 *p_app_start_offset,
|
||||
uint32 *p_app_end_offset)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_get_app_addr_range((WASMModuleInstance *)module_inst,
|
||||
app_offset, p_app_start_offset,
|
||||
p_app_end_offset);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_get_app_addr_range((AOTModuleInstance *)module_inst,
|
||||
app_offset, p_app_start_offset,
|
||||
p_app_end_offset);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst,
|
||||
uint8 *native_ptr,
|
||||
uint8 **p_native_start_addr,
|
||||
uint8 **p_native_end_addr)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_get_native_addr_range((WASMModuleInstance *)module_inst,
|
||||
native_ptr, p_native_start_addr,
|
||||
p_native_end_addr);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_get_native_addr_range((AOTModuleInstance *)module_inst,
|
||||
native_ptr, p_native_start_addr,
|
||||
p_native_end_addr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module,
|
||||
uint32 inc_page_count)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_enlarge_memory((WASMModuleInstance *)module,
|
||||
inc_page_count);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
return aot_enlarge_memory((AOTModuleInstance *)module, inc_page_count);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
|
||||
static WASIArguments *
|
||||
@ -2477,19 +2413,6 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
|
||||
|
||||
wasm_runtime_set_wasi_ctx(module_inst, wasi_ctx);
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode
|
||||
&& !((WASMModuleInstance *)module_inst)->default_memory)
|
||||
return true;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT
|
||||
&& !((AOTModuleInstance *)module_inst)
|
||||
->global_table_data.memory_instances[0]
|
||||
.memory_data.ptr)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
/* process argv[0], trip the path and suffix, only keep the program name */
|
||||
if (!copy_string_array((const char **)argv, argc, &argv_buf, &argv_list,
|
||||
&argv_buf_size)) {
|
||||
@ -2796,7 +2719,7 @@ wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst)
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT
|
||||
&& ((AOTModule *)((AOTModuleInstance *)module_inst)->aot_module.ptr)
|
||||
&& ((AOTModule *)((AOTModuleInstance *)module_inst)->module)
|
||||
->import_wasi_api)
|
||||
return true;
|
||||
#endif
|
||||
@ -2832,7 +2755,7 @@ wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst)
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
|
||||
AOTFunctionInstance *export_funcs =
|
||||
(AOTFunctionInstance *)aot_inst->export_funcs.ptr;
|
||||
(AOTFunctionInstance *)aot_inst->export_functions;
|
||||
for (i = 0; i < aot_inst->export_func_count; i++) {
|
||||
if (!strcmp(export_funcs[i].func_name, "_start")) {
|
||||
AOTFuncType *func_type = export_funcs[i].u.func.func_type;
|
||||
@ -2905,49 +2828,37 @@ wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
|
||||
#endif
|
||||
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst)
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return ((WASMModuleInstance *)module_inst)->wasi_ctx;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return ((AOTModuleInstance *)module_inst)->wasi_ctx.ptr;
|
||||
#endif
|
||||
return NULL;
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
return module_inst->wasi_ctx;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst,
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASIContext *wasi_ctx)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
((WASMModuleInstance *)module_inst)->wasi_ctx = wasi_ctx;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
((AOTModuleInstance *)module_inst)->wasi_ctx.ptr = wasi_ctx;
|
||||
#endif
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
module_inst->wasi_ctx = wasi_ctx;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_exec_env_get_module(WASMExecEnv *exec_env)
|
||||
{
|
||||
WASMModuleInstanceCommon *module_inst =
|
||||
WASMModuleInstanceCommon *module_inst_comm =
|
||||
wasm_runtime_get_module_inst(exec_env);
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return (WASMModuleCommon *)((WASMModuleInstance *)module_inst)->module;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return (WASMModuleCommon *)((AOTModuleInstance *)module_inst)
|
||||
->aot_module.ptr;
|
||||
#endif
|
||||
return NULL;
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
return (WASMModuleCommon *)module_inst->module;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
|
||||
@ -4510,8 +4421,8 @@ interp_mark_all_externrefs(WASMModuleInstance *module_inst)
|
||||
WASMGlobalInstance *global;
|
||||
WASMTableInstance *table;
|
||||
|
||||
global = module_inst->globals;
|
||||
for (i = 0; i < module_inst->global_count; i++, global++) {
|
||||
global = module_inst->e->globals;
|
||||
for (i = 0; i < module_inst->e->global_count; i++, global++) {
|
||||
if (global->type == VALUE_TYPE_EXTERNREF) {
|
||||
externref_idx = *(uint32 *)(global_data + global->data_offset);
|
||||
mark_externref(externref_idx);
|
||||
@ -4519,14 +4430,23 @@ interp_mark_all_externrefs(WASMModuleInstance *module_inst)
|
||||
}
|
||||
|
||||
for (i = 0; i < module_inst->table_count; i++) {
|
||||
uint8 elem_type = 0;
|
||||
uint32 init_size, max_size;
|
||||
|
||||
table = wasm_get_table_inst(module_inst, i);
|
||||
if (table->elem_type == VALUE_TYPE_EXTERNREF) {
|
||||
table_data = (uint32 *)table->base_addr;
|
||||
(void)wasm_runtime_get_table_inst_elem_type(
|
||||
(WASMModuleInstanceCommon *)module_inst, i, &elem_type, &init_size,
|
||||
&max_size);
|
||||
|
||||
if (elem_type == VALUE_TYPE_EXTERNREF) {
|
||||
table_data = table->elems;
|
||||
for (j = 0; j < table->cur_size; j++) {
|
||||
externref_idx = table_data[j];
|
||||
mark_externref(externref_idx);
|
||||
}
|
||||
}
|
||||
(void)init_size;
|
||||
(void)max_size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -4536,25 +4456,23 @@ static void
|
||||
aot_mark_all_externrefs(AOTModuleInstance *module_inst)
|
||||
{
|
||||
uint32 i = 0, j = 0;
|
||||
const AOTModule *module = (AOTModule *)(module_inst->aot_module.ptr);
|
||||
const AOTModule *module = (AOTModule *)module_inst->module;
|
||||
const AOTTable *table = module->tables;
|
||||
const AOTGlobal *global = module->globals;
|
||||
const AOTTableInstance *table_inst =
|
||||
(AOTTableInstance *)module_inst->tables.ptr;
|
||||
const AOTTableInstance *table_inst;
|
||||
|
||||
for (i = 0; i < module->global_count; i++, global++) {
|
||||
if (global->type == VALUE_TYPE_EXTERNREF) {
|
||||
mark_externref(*(uint32 *)((uint8 *)module_inst->global_data.ptr
|
||||
+ global->data_offset));
|
||||
mark_externref(
|
||||
*(uint32 *)(module_inst->global_data + global->data_offset));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < module->table_count;
|
||||
i++, table_inst = aot_next_tbl_inst(table_inst)) {
|
||||
|
||||
for (i = 0; i < module->table_count; i++) {
|
||||
table_inst = module_inst->tables[i];
|
||||
if ((table + i)->elem_type == VALUE_TYPE_EXTERNREF) {
|
||||
while (j < table_inst->cur_size) {
|
||||
mark_externref(table_inst->data[j++]);
|
||||
mark_externref(table_inst->elems[j++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4707,6 +4625,82 @@ wasm_runtime_dump_call_stack_to_buf(wasm_exec_env_t exec_env, char *buf,
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
|
||||
|
||||
bool
|
||||
wasm_runtime_get_table_elem_type(const WASMModuleCommon *module_comm,
|
||||
uint32 table_idx, uint8 *out_elem_type,
|
||||
uint32 *out_min_size, uint32 *out_max_size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_comm->module_type == Wasm_Module_Bytecode) {
|
||||
WASMModule *module = (WASMModule *)module_comm;
|
||||
|
||||
if (table_idx < module->import_table_count) {
|
||||
WASMTableImport *import_table =
|
||||
&((module->import_tables + table_idx)->u.table);
|
||||
*out_elem_type = import_table->elem_type;
|
||||
*out_min_size = import_table->init_size;
|
||||
*out_max_size = import_table->max_size;
|
||||
}
|
||||
else {
|
||||
WASMTable *table =
|
||||
module->tables + (table_idx - module->import_table_count);
|
||||
*out_elem_type = table->elem_type;
|
||||
*out_min_size = table->init_size;
|
||||
*out_max_size = table->max_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_comm->module_type == Wasm_Module_AoT) {
|
||||
AOTModule *module = (AOTModule *)module_comm;
|
||||
|
||||
if (table_idx < module->import_table_count) {
|
||||
AOTImportTable *import_table = module->import_tables + table_idx;
|
||||
*out_elem_type = VALUE_TYPE_FUNCREF;
|
||||
*out_min_size = import_table->table_init_size;
|
||||
*out_max_size = import_table->table_max_size;
|
||||
}
|
||||
else {
|
||||
AOTTable *table =
|
||||
module->tables + (table_idx - module->import_table_count);
|
||||
*out_elem_type = table->elem_type;
|
||||
*out_min_size = table->table_init_size;
|
||||
*out_max_size = table->table_max_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_get_table_inst_elem_type(
|
||||
const WASMModuleInstanceCommon *module_inst_comm, uint32 table_idx,
|
||||
uint8 *out_elem_type, uint32 *out_min_size, uint32 *out_max_size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance *)module_inst_comm;
|
||||
return wasm_runtime_get_table_elem_type(
|
||||
(WASMModuleCommon *)module_inst->module, table_idx, out_elem_type,
|
||||
out_min_size, out_max_size);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst_comm->module_type == Wasm_Module_AoT) {
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm;
|
||||
return wasm_runtime_get_table_elem_type(
|
||||
(WASMModuleCommon *)module_inst->module, table_idx, out_elem_type,
|
||||
out_min_size, out_max_size);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm,
|
||||
const WASMExport *export, WASMType **out)
|
||||
@ -4847,50 +4841,8 @@ wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm,
|
||||
uint8 *out_elem_type, uint32 *out_min_size,
|
||||
uint32 *out_max_size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_comm->module_type == Wasm_Module_Bytecode) {
|
||||
WASMModule *module = (WASMModule *)module_comm;
|
||||
|
||||
if (export->index < module->import_table_count) {
|
||||
WASMTableImport *import_table =
|
||||
&((module->import_tables + export->index)->u.table);
|
||||
*out_elem_type = import_table->elem_type;
|
||||
*out_min_size = import_table->init_size;
|
||||
*out_max_size = import_table->max_size;
|
||||
}
|
||||
else {
|
||||
WASMTable *table =
|
||||
module->tables + (export->index - module->import_table_count);
|
||||
*out_elem_type = table->elem_type;
|
||||
*out_min_size = table->init_size;
|
||||
*out_max_size = table->max_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_comm->module_type == Wasm_Module_AoT) {
|
||||
AOTModule *module = (AOTModule *)module_comm;
|
||||
|
||||
if (export->index < module->import_table_count) {
|
||||
AOTImportTable *import_table =
|
||||
module->import_tables + export->index;
|
||||
*out_elem_type = VALUE_TYPE_FUNCREF;
|
||||
*out_min_size = import_table->table_init_size;
|
||||
*out_max_size = import_table->table_max_size;
|
||||
}
|
||||
else {
|
||||
AOTTable *table =
|
||||
module->tables + (export->index - module->import_table_count);
|
||||
*out_elem_type = table->elem_type;
|
||||
*out_min_size = table->table_init_size;
|
||||
*out_max_size = table->table_max_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
return wasm_runtime_get_table_elem_type(
|
||||
module_comm, export->index, out_elem_type, out_min_size, out_max_size);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@ -5036,10 +4988,13 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
||||
if (trap) {
|
||||
if (trap->message->data) {
|
||||
/* since trap->message->data does not end with '\0' */
|
||||
char trap_message[128] = { 0 };
|
||||
bh_memcpy_s(trap_message, 127, trap->message->data,
|
||||
(trap->message->size < 127 ? (uint32)trap->message->size
|
||||
: 127));
|
||||
char trap_message[108] = { 0 };
|
||||
uint32 max_size_to_copy = (uint32)sizeof(trap_message) - 1;
|
||||
uint32 size_to_copy = (trap->message->size < max_size_to_copy)
|
||||
? (uint32)trap->message->size
|
||||
: max_size_to_copy;
|
||||
bh_memcpy_s(trap_message, (uint32)sizeof(trap_message),
|
||||
trap->message->data, size_to_copy);
|
||||
wasm_runtime_set_exception(module_inst, trap_message);
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user