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:
Wenyong Huang
2022-10-18 10:59:28 +08:00
committed by GitHub
parent dc4dcc3d6f
commit a182926a73
49 changed files with 3790 additions and 3274 deletions

View File

@ -2,16 +2,20 @@
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "wasm_c_api_internal.h"
#include "bh_assert.h"
#include "wasm_memory.h"
#include "wasm_runtime_common.h"
#if WASM_ENABLE_INTERP != 0
#include "wasm_runtime.h"
#endif
#if WASM_ENABLE_AOT != 0
#include "aot_runtime.h"
#endif
#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT == 0
#include "aot.h"
#include "aot_llvm.h"
#endif /*WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT == 0*/
#endif /*WASM_ENABLE_AOT != 0*/
#define ASSERT_NOT_IMPLEMENTED() bh_assert(!"not implemented")
#define UNREACHABLE() bh_assert(!"unreachable")
@ -302,9 +306,11 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
goto failed;
}
#if BH_DEBUG != 0
#ifndef NDEBUG
/*DEBUG*/
bh_log_set_verbose_level(5);
#else
/*VERBOSE*/
bh_log_set_verbose_level(3);
#endif
@ -1655,7 +1661,7 @@ wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt,
#if WASM_ENABLE_AOT != 0
if (inst_comm_rt->module_type == Wasm_Module_AoT) {
trap->frames = ((AOTModuleInstance *)inst_comm_rt)->frames.ptr;
trap->frames = ((AOTModuleInstance *)inst_comm_rt)->frames;
}
#endif
#endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */
@ -2379,6 +2385,61 @@ failed_exporttype_new:
wasm_exporttype_vec_delete(out);
}
#if WASM_ENABLE_JIT == 0 || WASM_ENABLE_LAZY_JIT != 0
void
wasm_module_serialize(wasm_module_t *module, own wasm_byte_vec_t *out)
{
(void)module;
(void)out;
LOG_ERROR("only supported serialization in JIT with eager compilation");
}
own wasm_module_t *
wasm_module_deserialize(wasm_store_t *module, const wasm_byte_vec_t *binary)
{
(void)module;
(void)binary;
LOG_ERROR("only supported deserialization in JIT with eager compilation");
return NULL;
}
#else
extern uint8 *
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
uint32 *p_aot_file_size);
void
wasm_module_serialize(wasm_module_t *module, own wasm_byte_vec_t *out)
{
wasm_module_ex_t *module_ex;
AOTCompContext *comp_ctx;
AOTCompData *comp_data;
uint8 *aot_file_buf = NULL;
uint32 aot_file_size = 0;
if (!module || !out)
return;
module_ex = module_to_module_ext(module);
comp_ctx = ((WASMModule *)(module_ex->module_comm_rt))->comp_ctx;
comp_data = ((WASMModule *)(module_ex->module_comm_rt))->comp_data;
bh_assert(comp_ctx != NULL && comp_data != NULL);
aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data, &aot_file_size);
if (!aot_file_buf)
return;
wasm_byte_vec_new(out, aot_file_size, (wasm_byte_t *)aot_file_buf);
wasm_runtime_free(aot_file_buf);
return;
}
own wasm_module_t *
wasm_module_deserialize(wasm_store_t *store, const wasm_byte_vec_t *binary)
{
return wasm_module_new(store, binary);
}
#endif
static wasm_func_t *
wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
wasm_func_callback_t func_callback)
@ -2482,9 +2543,9 @@ wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt,
#if WASM_ENABLE_INTERP != 0
if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
bh_assert(func_idx_rt
< ((WASMModuleInstance *)inst_comm_rt)->function_count);
< ((WASMModuleInstance *)inst_comm_rt)->e->function_count);
WASMFunctionInstance *func_interp =
((WASMModuleInstance *)inst_comm_rt)->functions + func_idx_rt;
((WASMModuleInstance *)inst_comm_rt)->e->functions + func_idx_rt;
type_rt = func_interp->is_import_func
? func_interp->u.func_import->func_type
: func_interp->u.func->func_type;
@ -2496,7 +2557,7 @@ wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt,
/* use same index to trace the function type in AOTFuncType **func_types
*/
AOTModule *module_aot =
((AOTModuleInstance *)inst_comm_rt)->aot_module.ptr;
(AOTModule *)((AOTModuleInstance *)inst_comm_rt)->module;
if (func_idx_rt < module_aot->import_func_count) {
type_rt = (module_aot->import_funcs + func_idx_rt)->func_type;
}
@ -2605,6 +2666,7 @@ params_to_argv(const wasm_val_vec_t *params,
}
if (!params || !params->num_elems || !params->size || !params->data) {
LOG_ERROR("the parameter params is invalid");
return false;
}
@ -2662,6 +2724,7 @@ argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs,
}
if (!results || !results->size || !results->data) {
LOG_ERROR("the parameter results is invalid");
return false;
}
@ -2748,7 +2811,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
#if WASM_ENABLE_INTERP != 0
if (func->inst_comm_rt->module_type == Wasm_Module_Bytecode) {
func_comm_rt = ((WASMModuleInstance *)func->inst_comm_rt)->functions
func_comm_rt = ((WASMModuleInstance *)func->inst_comm_rt)->e->functions
+ func->func_idx_rt;
}
#endif
@ -2758,7 +2821,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
if (!(func_comm_rt = func->func_comm_rt)) {
AOTModuleInstance *inst_aot =
(AOTModuleInstance *)func->inst_comm_rt;
AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr;
AOTModule *module_aot = (AOTModule *)inst_aot->module;
uint32 export_i = 0, export_func_j = 0;
for (; export_i < module_aot->export_count; ++export_i) {
@ -2766,7 +2829,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
if (export->kind == EXPORT_KIND_FUNC) {
if (export->index == func->func_idx_rt) {
func_comm_rt =
(AOTFunctionInstance *)inst_aot->export_funcs.ptr
(AOTFunctionInstance *)inst_aot->export_functions
+ export_func_j;
((wasm_func_t *)func)->func_comm_rt = func_comm_rt;
break;
@ -2788,6 +2851,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
param_count = wasm_func_param_arity(func);
result_count = wasm_func_result_arity(func);
alloc_count = (param_count > result_count) ? param_count : result_count;
if (alloc_count > (size_t)sizeof(argv_buf) / sizeof(uint64)) {
if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) {
@ -2968,7 +3032,7 @@ interp_global_set(const WASMModuleInstance *inst_interp, uint16 global_idx_rt,
const wasm_val_t *v)
{
const WASMGlobalInstance *global_interp =
inst_interp->globals + global_idx_rt;
inst_interp->e->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0
uint8 *data = global_interp->import_global_inst
@ -2987,7 +3051,7 @@ static bool
interp_global_get(const WASMModuleInstance *inst_interp, uint16 global_idx_rt,
wasm_val_t *out)
{
WASMGlobalInstance *global_interp = inst_interp->globals + global_idx_rt;
WASMGlobalInstance *global_interp = inst_interp->e->globals + global_idx_rt;
uint8 val_type_rt = global_interp->type;
#if WASM_ENABLE_MULTI_MODULE != 0
uint8 *data = global_interp->import_global_inst
@ -3007,7 +3071,7 @@ static bool
aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
const wasm_val_t *v)
{
AOTModule *module_aot = inst_aot->aot_module.ptr;
AOTModule *module_aot = (AOTModule *)inst_aot->module;
uint8 val_type_rt = 0;
uint32 data_offset = 0;
void *data = NULL;
@ -3025,7 +3089,7 @@ aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
.type;
}
data = (void *)((uint8 *)inst_aot->global_data.ptr + data_offset);
data = (void *)(inst_aot->global_data + data_offset);
return wasm_val_to_rt_val((WASMModuleInstanceCommon *)inst_aot, val_type_rt,
v, data);
}
@ -3034,7 +3098,7 @@ static bool
aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
wasm_val_t *out)
{
AOTModule *module_aot = inst_aot->aot_module.ptr;
AOTModule *module_aot = (AOTModule *)inst_aot->module;
uint8 val_type_rt = 0;
uint32 data_offset = 0;
uint8 *data = NULL;
@ -3052,7 +3116,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt,
.type;
}
data = (uint8 *)inst_aot->global_data.ptr + data_offset;
data = inst_aot->global_data + data_offset;
return rt_val_to_wasm_val(data, val_type_rt, out);
}
#endif
@ -3149,7 +3213,7 @@ wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt,
#if WASM_ENABLE_INTERP != 0
if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
WASMGlobalInstance *global_interp =
((WASMModuleInstance *)inst_comm_rt)->globals + global_idx_rt;
((WASMModuleInstance *)inst_comm_rt)->e->globals + global_idx_rt;
val_type_rt = global_interp->type;
is_mutable = global_interp->is_mutable;
init = true;
@ -3159,7 +3223,7 @@ wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt,
#if WASM_ENABLE_AOT != 0
if (inst_comm_rt->module_type == Wasm_Module_AoT) {
AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt;
AOTModule *module_aot = inst_aot->aot_module.ptr;
AOTModule *module_aot = (AOTModule *)inst_aot->module;
init = true;
@ -3257,7 +3321,6 @@ wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt,
wasm_table_t *table = NULL;
uint8 val_type_rt = 0;
uint32 init_size = 0, max_size = 0;
bool init_flag = false;
bh_assert(singleton_engine);
@ -3272,46 +3335,12 @@ wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt,
table->store = store;
table->kind = WASM_EXTERN_TABLE;
#if WASM_ENABLE_INTERP != 0
if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
WASMTableInstance *table_interp =
((WASMModuleInstance *)inst_comm_rt)->tables[table_idx_rt];
val_type_rt = table_interp->elem_type;
init_size = table_interp->cur_size;
max_size = table_interp->max_size;
init_flag = true;
}
#endif
#if WASM_ENABLE_AOT != 0
if (inst_comm_rt->module_type == Wasm_Module_AoT) {
AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt;
AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr;
if (table_idx_rt < module_aot->import_table_count) {
AOTImportTable *table_aot =
module_aot->import_tables + table_idx_rt;
val_type_rt = table_aot->elem_type;
init_size = table_aot->table_init_size;
max_size = table_aot->table_max_size;
}
else {
AOTTable *table_aot =
module_aot->tables
+ (table_idx_rt - module_aot->import_table_count);
val_type_rt = table_aot->elem_type;
init_size = table_aot->table_init_size;
max_size = table_aot->table_max_size;
}
init_flag = true;
}
#endif
/*
* a wrong combination of module filetype and compilation flags
* leads to below branch
*/
if (!init_flag) {
if (!wasm_runtime_get_table_inst_elem_type(
inst_comm_rt, table_idx_rt, &val_type_rt, &init_size, &max_size)) {
/*
* a wrong combination of module filetype and compilation flags
* leads to below branch
*/
goto failed;
}
@ -3400,19 +3429,18 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index)
if (index >= table_interp->cur_size) {
return NULL;
}
ref_idx = ((uint32 *)table_interp->base_addr)[index];
ref_idx = table_interp->elems[index];
}
#endif
#if WASM_ENABLE_AOT != 0
if (table->inst_comm_rt->module_type == Wasm_Module_AoT) {
AOTModuleInstance *inst_aot = (AOTModuleInstance *)table->inst_comm_rt;
AOTTableInstance *table_aot =
(AOTTableInstance *)inst_aot->tables.ptr + table->table_idx_rt;
AOTTableInstance *table_aot = inst_aot->tables[table->table_idx_rt];
if (index >= table_aot->cur_size) {
return NULL;
}
ref_idx = table_aot->data[index];
ref_idx = table_aot->elems[index];
}
#endif
@ -3472,24 +3500,23 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index,
return false;
}
p_ref_idx = ((uint32 *)table_interp->base_addr) + index;
p_ref_idx = table_interp->elems + index;
function_count =
((WASMModuleInstance *)table->inst_comm_rt)->function_count;
((WASMModuleInstance *)table->inst_comm_rt)->e->function_count;
}
#endif
#if WASM_ENABLE_AOT != 0
if (table->inst_comm_rt->module_type == Wasm_Module_AoT) {
AOTModuleInstance *inst_aot = (AOTModuleInstance *)table->inst_comm_rt;
AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr;
AOTTableInstance *table_aot =
(AOTTableInstance *)inst_aot->tables.ptr + table->table_idx_rt;
AOTModule *module_aot = (AOTModule *)inst_aot->module;
AOTTableInstance *table_aot = inst_aot->tables[table->table_idx_rt];
if (index >= table_aot->cur_size) {
return false;
}
p_ref_idx = table_aot->data + index;
p_ref_idx = table_aot->elems + index;
function_count = module_aot->func_count;
}
#endif
@ -3545,7 +3572,7 @@ wasm_table_size(const wasm_table_t *table)
#if WASM_ENABLE_AOT != 0
if (table->inst_comm_rt->module_type == Wasm_Module_AoT) {
AOTModuleInstance *inst_aot = (AOTModuleInstance *)table->inst_comm_rt;
AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr;
AOTModule *module_aot = (AOTModule *)inst_aot->module;
if (table->table_idx_rt < module_aot->import_table_count) {
AOTImportTable *table_aot =
@ -3660,7 +3687,7 @@ wasm_memory_new_internal(wasm_store_t *store, uint16 memory_idx_rt,
#if WASM_ENABLE_AOT != 0
if (inst_comm_rt->module_type == Wasm_Module_AoT) {
AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt;
AOTModule *module_aot = (AOTModule *)(inst_aot->aot_module.ptr);
AOTModule *module_aot = (AOTModule *)inst_aot->module;
if (memory_idx_rt < module_aot->import_memory_count) {
min_pages = module_aot->import_memories->mem_init_page_count;
@ -3744,8 +3771,8 @@ wasm_memory_data(wasm_memory_t *memory)
AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm;
AOTMemoryInstance *memory_inst =
((AOTMemoryInstance **)
module_inst->memories.ptr)[memory->memory_idx_rt];
return (byte_t *)memory_inst->memory_data.ptr;
module_inst->memories)[memory->memory_idx_rt];
return (byte_t *)memory_inst->memory_data;
}
#endif
@ -3781,7 +3808,7 @@ wasm_memory_data_size(const wasm_memory_t *memory)
AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm;
AOTMemoryInstance *memory_inst =
((AOTMemoryInstance **)
module_inst->memories.ptr)[memory->memory_idx_rt];
module_inst->memories)[memory->memory_idx_rt];
return memory_inst->cur_page_count * memory_inst->num_bytes_per_page;
}
#endif
@ -3818,7 +3845,7 @@ wasm_memory_size(const wasm_memory_t *memory)
AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm;
AOTMemoryInstance *memory_inst =
((AOTMemoryInstance **)
module_inst->memories.ptr)[memory->memory_idx_rt];
module_inst->memories)[memory->memory_idx_rt];
return memory_inst->cur_page_count;
}
#endif
@ -4197,7 +4224,7 @@ aot_process_export(wasm_store_t *store, const AOTModuleInstance *inst_aot,
bh_assert(store && inst_aot && externals);
module_aot = (AOTModule *)inst_aot->aot_module.ptr;
module_aot = (AOTModule *)inst_aot->module;
bh_assert(module_aot);
for (i = 0; i < module_aot->export_count; ++i) {
@ -4420,8 +4447,9 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
uint32 export_cnt =
((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_tab_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_mem_count;
+ ((AOTModuleInstance *)instance->inst_comm_rt)->export_table_count
+ ((AOTModuleInstance *)instance->inst_comm_rt)
->export_memory_count;
INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized,
export_cnt);

View File

@ -65,7 +65,7 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *i = (AOTModuleInstance *)module_inst;
AOTModule *m = (AOTModule *)i->aot_module.ptr;
AOTModule *m = (AOTModule *)i->module;
exec_env->native_symbol = m->native_symbol_list;
}
#endif
@ -135,7 +135,7 @@ wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
/* Set the aux_stack_boundary and aux_stack_bottom */
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModule *module =
(AOTModule *)(((AOTModuleInstance *)module_inst)->aot_module.ptr);
(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;

View File

@ -4,6 +4,7 @@
*/
#include "wasm_runtime_common.h"
#include "../interpreter/wasm_runtime.h"
#include "bh_platform.h"
#include "mem_alloc.h"
@ -138,6 +139,9 @@ wasm_runtime_free_internal(void *ptr)
{
if (!ptr) {
LOG_WARNING("warning: wasm_runtime_free with NULL pointer\n");
#if BH_ENABLE_GC_VERIFY != 0
exit(-1);
#endif
return;
}
@ -160,6 +164,9 @@ wasm_runtime_malloc(unsigned int size)
LOG_WARNING("warning: wasm_runtime_malloc with size zero\n");
/* At lease alloc 1 byte to avoid malloc failed */
size = 1;
#if BH_ENABLE_GC_VERIFY != 0
exit(-1);
#endif
}
return wasm_runtime_malloc_internal(size);
@ -185,3 +192,446 @@ wasm_runtime_get_mem_alloc_info(mem_alloc_info_t *mem_alloc_info)
}
return false;
}
bool
wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
uint32 app_offset, uint32 size)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
goto fail;
}
/* integer overflow check */
if (app_offset > UINT32_MAX - size) {
goto fail;
}
if (app_offset + size <= memory_inst->memory_data_size) {
return true;
}
fail:
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
}
bool
wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
uint32 app_str_offset)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
uint32 app_end_offset;
char *str, *str_end;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL,
&app_end_offset))
goto fail;
str = wasm_runtime_addr_app_to_native(module_inst_comm, 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_set_exception(module_inst, "out of bounds memory access");
return false;
}
bool
wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
void *native_ptr, uint32 size)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
goto fail;
}
/* integer overflow check */
if ((uintptr_t)addr > UINTPTR_MAX - size) {
goto fail;
}
if (memory_inst->memory_data <= addr
&& addr + size <= memory_inst->memory_data_end) {
return true;
}
fail:
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
}
void *
wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
uint32 app_offset)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
return NULL;
}
addr = memory_inst->memory_data + app_offset;
if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
return addr;
return NULL;
}
uint32
wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
void *native_ptr)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
return 0;
}
if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
return (uint32)(addr - memory_inst->memory_data);
return 0;
}
bool
wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
uint32 app_offset, uint32 *p_app_start_offset,
uint32 *p_app_end_offset)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint32 memory_data_size;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
return false;
}
memory_data_size = memory_inst->memory_data_size;
if (app_offset < memory_data_size) {
if (p_app_start_offset)
*p_app_start_offset = 0;
if (p_app_end_offset)
*p_app_end_offset = memory_data_size;
return true;
}
return false;
}
bool
wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm,
uint8 *native_ptr,
uint8 **p_native_start_addr,
uint8 **p_native_end_addr)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
memory_inst = wasm_get_default_memory(module_inst);
if (!memory_inst) {
return false;
}
if (memory_inst->memory_data <= addr
&& addr < memory_inst->memory_data_end) {
if (p_native_start_addr)
*p_native_start_addr = memory_inst->memory_data;
if (p_native_end_addr)
*p_native_end_addr = memory_inst->memory_data_end;
return true;
}
return false;
}
bool
wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
uint32 app_buf_addr, uint32 app_buf_size,
void **p_native_addr)
{
WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
uint8 *native_addr;
if (!memory_inst) {
goto fail;
}
native_addr = memory_inst->memory_data + app_buf_addr;
/* No need to check the app_offset and buf_size if memory access
boundary check with hardware trap is enabled */
#ifndef OS_ENABLE_HW_BOUND_CHECK
if (app_buf_addr >= memory_inst->memory_data_size) {
goto fail;
}
if (!is_str) {
if (app_buf_size > memory_inst->memory_data_size - app_buf_addr) {
goto fail;
}
}
else {
const char *str, *str_end;
/* The whole string must be in the linear memory */
str = (const char *)native_addr;
str_end = (const char *)memory_inst->memory_data_end;
while (str < str_end && *str != '\0')
str++;
if (str == str_end)
goto fail;
}
#endif
*p_native_addr = (void *)native_addr;
return true;
fail:
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
}
WASMMemoryInstance *
wasm_get_default_memory(WASMModuleInstance *module_inst)
{
if (module_inst->memories)
return module_inst->memories[0];
else
return NULL;
}
#ifndef OS_ENABLE_HW_BOUND_CHECK
bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{
WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint8 *memory_data_old, *memory_data_new, *heap_data_old;
uint32 num_bytes_per_page, heap_size, total_size_old;
uint32 cur_page_count, max_page_count, total_page_count;
uint64 total_size_new;
bool ret = true;
if (!memory)
return false;
heap_data_old = memory->heap_data;
heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
memory_data_old = memory->memory_data;
total_size_old = memory->memory_data_size;
num_bytes_per_page = memory->num_bytes_per_page;
cur_page_count = memory->cur_page_count;
max_page_count = memory->max_page_count;
total_page_count = inc_page_count + cur_page_count;
total_size_new = num_bytes_per_page * (uint64)total_page_count;
if (inc_page_count <= 0)
/* No need to enlarge memory */
return true;
if (total_page_count < cur_page_count /* integer overflow */
|| total_page_count > max_page_count) {
return false;
}
bh_assert(total_size_new <= 4 * (uint64)BH_GB);
if (total_size_new > UINT32_MAX) {
/* Resize to 1 page with size 4G-1 */
num_bytes_per_page = UINT32_MAX;
total_page_count = max_page_count = 1;
total_size_new = UINT32_MAX;
}
#if WASM_ENABLE_SHARED_MEMORY != 0
if (memory->is_shared) {
memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_page_count;
memory->max_page_count = max_page_count;
/* No need to update memory->memory_data_size as it is
initialized with the maximum memory data size for
shared memory */
return true;
}
#endif
if (heap_size > 0) {
if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
wasm_runtime_show_app_heap_corrupted_prompt();
return false;
}
}
if (!(memory_data_new =
wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
return false;
}
if (memory_data_old) {
bh_memcpy_s(memory_data_new, (uint32)total_size_new,
memory_data_old, total_size_old);
wasm_runtime_free(memory_data_old);
}
}
memset(memory_data_new + total_size_old, 0,
(uint32)total_size_new - total_size_old);
if (heap_size > 0) {
if (mem_allocator_migrate(memory->heap_handle,
(char *)heap_data_old
+ (memory_data_new - memory_data_old),
heap_size)
!= 0) {
/* Don't return here as memory->memory_data is obsolete and
must be updated to be correctly used later. */
ret = false;
}
}
memory->heap_data = memory_data_new + (heap_data_old - memory_data_old);
memory->heap_data_end = memory->heap_data + heap_size;
memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_page_count;
memory->max_page_count = max_page_count;
memory->memory_data_size = (uint32)total_size_new;
memory->memory_data = memory_data_new;
memory->memory_data_end = memory_data_new + (uint32)total_size_new;
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
#if UINTPTR_MAX == UINT64_MAX
memory->mem_bound_check_1byte.u64 = total_size_new - 1;
memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
#else
memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1;
memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2;
memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4;
memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8;
memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16;
#endif
#endif
return ret;
}
#else
bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{
WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint32 num_bytes_per_page, total_size_old;
uint32 cur_page_count, max_page_count, total_page_count;
uint64 total_size_new;
if (!memory)
return false;
num_bytes_per_page = memory->num_bytes_per_page;
cur_page_count = memory->cur_page_count;
max_page_count = memory->max_page_count;
total_size_old = num_bytes_per_page * cur_page_count;
total_page_count = inc_page_count + cur_page_count;
total_size_new = num_bytes_per_page * (uint64)total_page_count;
if (inc_page_count <= 0)
/* No need to enlarge memory */
return true;
if (total_page_count < cur_page_count /* integer overflow */
|| total_page_count > max_page_count) {
return false;
}
bh_assert(total_size_new <= 4 * (uint64)BH_GB);
if (total_size_new > UINT32_MAX) {
/* Resize to 1 page with size 4G-1 */
num_bytes_per_page = UINT32_MAX;
total_page_count = max_page_count = 1;
total_size_new = UINT32_MAX;
}
#ifdef BH_PLATFORM_WINDOWS
if (!os_mem_commit(memory->memory_data_end,
(uint32)total_size_new - total_size_old,
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
return false;
}
#endif
if (os_mprotect(memory->memory_data_end,
(uint32)total_size_new - total_size_old,
MMAP_PROT_READ | MMAP_PROT_WRITE)
!= 0) {
#ifdef BH_PLATFORM_WINDOWS
os_mem_decommit(memory->memory_data_end,
(uint32)total_size_new - total_size_old);
#endif
return false;
}
/* The increased pages are filled with zero by the OS when os_mmap,
no need to memset it again here */
memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_page_count;
memory->max_page_count = max_page_count;
memory->memory_data_size = (uint32)total_size_new;
memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
memory->mem_bound_check_1byte.u64 = total_size_new - 1;
memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
#endif
return true;
}
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */

View File

@ -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 {

View File

@ -852,17 +852,6 @@ wasm_runtime_dump_line_buf_impl(const char *line_buf, bool dump_or_print,
WASMModuleCommon *
wasm_exec_env_get_module(WASMExecEnv *exec_env);
/**
* Enlarge wasm memory data space.
*
* @param module the wasm module instance
* @param inc_page_count denote the page number to increase
* @return return true if enlarge successfully, false otherwise
*/
bool
wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module,
uint32 inc_page_count);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_register_natives(const char *module_name,
@ -900,6 +889,16 @@ wasm_runtime_dump_module_inst_mem_consumption(
void
wasm_runtime_dump_exec_env_mem_consumption(const WASMExecEnv *exec_env);
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);
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);
bool
wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm,
const WASMExport *export_, WASMType **out);

View File

@ -314,44 +314,26 @@ uint32
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
uint64 expect, int64 timeout, bool wait64)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
AtomicWaitInfo *wait_info;
AtomicWaitNode *wait_node;
bool check_ret, is_timeout;
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode) {
WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
/* Currently we have only one memory instance */
if (!module_inst->memories[0]->is_shared) {
wasm_runtime_set_exception(module, "expected shared memory");
return -1;
}
if ((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + (wait64 ? 8 : 4)
> module_inst->memories[0]->memory_data_end) {
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
}
bh_assert(module->module_type == Wasm_Module_Bytecode
|| module->module_type == Wasm_Module_AoT);
/* Currently we have only one memory instance */
if (!module_inst->memories[0]->is_shared) {
wasm_runtime_set_exception(module, "expected shared memory");
return -1;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module;
AOTMemoryInstance *aot_memory =
((AOTMemoryInstance **)aot_inst->memories.ptr)[0];
/* Currently we have only one memory instance */
if (!aot_memory->is_shared) {
wasm_runtime_set_exception(module, "expected shared memory");
return -1;
}
if ((uint8 *)address < (uint8 *)aot_memory->memory_data.ptr
|| (uint8 *)address + (wait64 ? 8 : 4)
> (uint8 *)aot_memory->memory_data_end.ptr) {
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
}
if ((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + (wait64 ? 8 : 4)
> module_inst->memories[0]->memory_data_end) {
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
}
#endif
/* acquire the wait info, create new one if not exists */
wait_info = acquire_wait_info(address, true);
@ -433,33 +415,18 @@ uint32
wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
uint32 count)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
uint32 notify_result;
AtomicWaitInfo *wait_info;
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode) {
WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
if ((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + 4
> module_inst->memories[0]->memory_data_end) {
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
}
bh_assert(module->module_type == Wasm_Module_Bytecode
|| module->module_type == Wasm_Module_AoT);
if ((uint8 *)address < module_inst->memories[0]->memory_data
|| (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end) {
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
}
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_inst = (AOTModuleInstance *)module;
AOTMemoryInstance *aot_memory =
((AOTMemoryInstance **)aot_inst->memories.ptr)[0];
if ((uint8 *)address < (uint8 *)aot_memory->memory_data.ptr
|| (uint8 *)address + 4
> (uint8 *)aot_memory->memory_data_end.ptr) {
wasm_runtime_set_exception(module, "out of bounds memory access");
return -1;
}
}
#endif
wait_info = acquire_wait_info(address, false);