memory64: Implement threads opcodes and update some APIs (#3260)

- Support threads opcodes in classic-interpreter
- Support memory64 memory in related runtime API
- Modify main function type check when it's memory64 wasm file
- Modify `wasm_runtime_invoke_native` and `wasm_runtime_invoke_native_raw` to
  handle registered native function pointer argument when memory64 is enabled
This commit is contained in:
TianlongLiang 2024-03-28 16:00:56 +08:00 committed by GitHub
parent 2c06e22d4a
commit d7886953bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 246 additions and 238 deletions

View File

@ -914,9 +914,10 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
bh_assert(max_memory_data_size <= MAX_LINEAR_MEMORY_SIZE); bh_assert(max_memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
(void)max_memory_data_size; (void)max_memory_data_size;
if (wasm_allocate_linear_memory(&p, is_shared_memory, num_bytes_per_page, /* TODO: memory64 uses is_memory64 flag */
init_page_count, max_page_count, if (wasm_allocate_linear_memory(&p, is_shared_memory, false,
&memory_data_size) num_bytes_per_page, init_page_count,
max_page_count, &memory_data_size)
!= BHT_OK) { != BHT_OK) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"allocate linear memory failed"); "allocate linear memory failed");

View File

@ -61,7 +61,7 @@ static union {
* Implementation of wasm_application_execute_main() * Implementation of wasm_application_execute_main()
*/ */
static bool static bool
check_main_func_type(const WASMFuncType *type) check_main_func_type(const WASMFuncType *type, bool is_memory64)
{ {
if (!(type->param_count == 0 || type->param_count == 2) if (!(type->param_count == 0 || type->param_count == 2)
|| type->result_count > 1) { || type->result_count > 1) {
@ -72,7 +72,8 @@ check_main_func_type(const WASMFuncType *type)
if (type->param_count == 2 if (type->param_count == 2
&& !(type->types[0] == VALUE_TYPE_I32 && !(type->types[0] == VALUE_TYPE_I32
&& type->types[1] == VALUE_TYPE_I32)) { && type->types[1]
== (is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32))) {
LOG_ERROR( LOG_ERROR(
"WASM execute application failed: invalid main function type.\n"); "WASM execute application failed: invalid main function type.\n");
return false; return false;
@ -94,14 +95,18 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
WASMFunctionInstanceCommon *func; WASMFunctionInstanceCommon *func;
WASMFuncType *func_type = NULL; WASMFuncType *func_type = NULL;
WASMExecEnv *exec_env = NULL; WASMExecEnv *exec_env = NULL;
uint32 argc1 = 0, argv1[2] = { 0 }; uint32 argc1 = 0, argv1[3] = { 0 };
uint32 total_argv_size = 0; uint32 total_argv_size = 0;
uint64 total_size; uint64 total_size;
uint64 argv_buf_offset = 0; uint64 argv_buf_offset = 0;
int32 i; int32 i;
char *argv_buf, *p, *p_end; char *argv_buf, *p, *p_end;
uint32 *argv_offsets, module_type; uint32 *argv_offsets, module_type;
bool ret, is_import_func = true; bool ret, is_import_func = true, is_memory64 = false;
#if WASM_ENABLE_MEMORY64 != 0
WASMModuleInstance *wasm_module_inst = (WASMModuleInstance *)module_inst;
is_memory64 = wasm_module_inst->memories[0]->is_memory64;
#endif
exec_env = wasm_runtime_get_exec_env_singleton(module_inst); exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
if (!exec_env) { if (!exec_env) {
@ -187,7 +192,7 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
return false; return false;
} }
if (!check_main_func_type(func_type)) { if (!check_main_func_type(func_type, is_memory64)) {
wasm_runtime_set_exception(module_inst, wasm_runtime_set_exception(module_inst,
"invalid function type of main function"); "invalid function type of main function");
return false; return false;
@ -218,11 +223,21 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
p += strlen(argv[i]) + 1; p += strlen(argv[i]) + 1;
} }
argc1 = 2;
argv1[0] = (uint32)argc; argv1[0] = (uint32)argc;
/* TODO: memory64 uint64 when the memory idx is i64 */ #if WASM_ENABLE_MEMORY64 != 0
argv1[1] = if (is_memory64) {
(uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets); argc1 = 3;
uint64 app_addr =
wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
PUT_I64_TO_ADDR(&argv[1], app_addr);
}
else
#endif
{
argc1 = 2;
argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst,
argv_offsets);
}
} }
ret = wasm_runtime_call_wasm(exec_env, func, argc1, argv1); ret = wasm_runtime_call_wasm(exec_env, func, argc1, argv1);

View File

@ -286,6 +286,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
{ {
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst; WASMMemoryInstance *memory_inst;
uint64 max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
@ -299,9 +300,13 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail; goto fail;
} }
#if WASM_ENABLE_MEMORY64 != 0
if (memory_inst->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check */ /* boundary overflow check */
if (size > MAX_LINEAR_MEMORY_SIZE if (size > max_linear_memory_size
|| app_offset > MAX_LINEAR_MEMORY_SIZE - size) { || app_offset > max_linear_memory_size - size) {
goto fail; goto fail;
} }
@ -324,7 +329,7 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
uint64 app_str_offset) uint64 app_str_offset)
{ {
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
uint64 app_end_offset; uint64 app_end_offset, max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
char *str, *str_end; char *str, *str_end;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
@ -338,10 +343,14 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
&app_end_offset)) &app_end_offset))
goto fail; goto fail;
#if WASM_ENABLE_MEMORY64 != 0
if (module_inst->memories[0]->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check, max start offset can only be size - 1, while end /* boundary overflow check, max start offset can only be size - 1, while end
* offset can be size */ * offset can be size */
if (app_str_offset >= MAX_LINEAR_MEMORY_SIZE if (app_str_offset >= max_linear_memory_size
|| app_end_offset > MAX_LINEAR_MEMORY_SIZE) || app_end_offset > max_linear_memory_size)
goto fail; goto fail;
str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset); str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset);
@ -364,6 +373,7 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm; WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst; WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr; uint8 *addr = (uint8 *)native_ptr;
uint64 max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT); || module_inst_comm->module_type == Wasm_Module_AoT);
@ -377,8 +387,12 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail; goto fail;
} }
#if WASM_ENABLE_MEMORY64 != 0
if (memory_inst->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check */ /* boundary overflow check */
if (size > MAX_LINEAR_MEMORY_SIZE || (uintptr_t)addr > UINTPTR_MAX - size) { if (size > max_linear_memory_size || (uintptr_t)addr > UINTPTR_MAX - size) {
goto fail; goto fail;
} }
@ -896,8 +910,9 @@ wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst)
int int
wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory, wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
uint64 num_bytes_per_page, uint64 init_page_count, bool is_memory64, uint64 num_bytes_per_page,
uint64 max_page_count, uint64 *memory_data_size) uint64 init_page_count, uint64 max_page_count,
uint64 *memory_data_size)
{ {
uint64 map_size, page_size; uint64 map_size, page_size;
@ -926,7 +941,16 @@ wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
page_size = os_getpagesize(); page_size = os_getpagesize();
*memory_data_size = init_page_count * num_bytes_per_page; *memory_data_size = init_page_count * num_bytes_per_page;
bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
#if WASM_ENABLE_MEMORY64 != 0
if (is_memory64) {
bh_assert(*memory_data_size <= MAX_LINEAR_MEM64_MEMORY_SIZE);
}
else
#endif
{
bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
}
align_as_and_cast(*memory_data_size, page_size); align_as_and_cast(*memory_data_size, page_size);
if (map_size > 0) { if (map_size > 0) {

View File

@ -64,8 +64,9 @@ wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst);
int int
wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory, wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
uint64 num_bytes_per_page, uint64 init_page_count, bool is_memory64, uint64 num_bytes_per_page,
uint64 max_page_count, uint64 *memory_data_size); uint64 init_page_count, uint64 max_page_count,
uint64 *memory_data_size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -3668,7 +3668,7 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env); WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *); typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *);
NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr; NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr;
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size; uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size, arg_i64;
uint32 *argv_src = argv, i, argc1, ptr_len; uint32 *argv_src = argv, i, argc1, ptr_len;
uint32 arg_i32; uint32 arg_i32;
bool ret = false; bool ret = false;
@ -3692,9 +3692,11 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
case VALUE_TYPE_FUNCREF: case VALUE_TYPE_FUNCREF:
#endif #endif
{ {
/* TODO: memory64 the data type of ptr_len and argc depends on
* mem idx type */
*(uint32 *)argv_dst = arg_i32 = *argv_src++; *(uint32 *)argv_dst = arg_i32 = *argv_src++;
/* TODO: memory64 if future there is a way for supporting
* wasm64 and wasm32 in libc at the same time, remove the
* macro control */
#if WASM_ENABLE_MEMORY64 == 0
if (signature) { if (signature) {
if (signature[i + 1] == '*') { if (signature[i + 1] == '*') {
/* param is a pointer */ /* param is a pointer */
@ -3724,9 +3726,49 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
module, (uint64)arg_i32); module, (uint64)arg_i32);
} }
} }
#endif
break; break;
} }
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
#if WASM_ENABLE_MEMORY64 != 0
{
PUT_I64_TO_ADDR((uint32 *)argv_dst,
GET_I64_FROM_ADDR(argv_src));
argv_src += 2;
arg_i64 = *argv_dst;
if (signature) {
/* TODO: memory64 pointer with length need a new symbol
* to represent type i64, with '~' still represent i32
* length */
if (signature[i + 1] == '*') {
/* param is a pointer */
if (signature[i + 2] == '~')
/* pointer with length followed */
ptr_len = *argv_src;
else
/* pointer without length followed */
ptr_len = 1;
if (!wasm_runtime_validate_app_addr(module, arg_i64,
(uint64)ptr_len))
goto fail;
*argv_dst = (uint64)wasm_runtime_addr_app_to_native(
module, arg_i64);
}
else if (signature[i + 1] == '$') {
/* param is a string */
if (!wasm_runtime_validate_app_str_addr(module,
arg_i64))
goto fail;
*argv_dst = (uint64)wasm_runtime_addr_app_to_native(
module, arg_i64);
}
}
break;
}
#endif
case VALUE_TYPE_F64: case VALUE_TYPE_F64:
bh_memcpy_s(argv_dst, sizeof(uint64), argv_src, bh_memcpy_s(argv_dst, sizeof(uint64), argv_src,
sizeof(uint32) * 2); sizeof(uint32) * 2);
@ -3855,6 +3897,9 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
fail: fail:
if (argv1 != argv_buf) if (argv1 != argv_buf)
wasm_runtime_free(argv1); wasm_runtime_free(argv1);
#if WASM_ENABLE_MEMORY64 == 0
(void)arg_i64;
#endif
return ret; return ret;
} }
@ -4117,8 +4162,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
{ {
arg_i32 = *argv_src++; arg_i32 = *argv_src++;
/* TODO: memory64 the data type of ptr_len and argc depends on
* mem idx type */
if (signature) { if (signature) {
if (signature[i + 1] == '*') { if (signature[i + 1] == '*') {
/* param is a pointer */ /* param is a pointer */
@ -4494,8 +4537,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
{ {
arg_i32 = *argv++; arg_i32 = *argv++;
/* TODO: memory64 the data type of ptr_len and argc depends on
* mem idx type */
if (signature) { if (signature) {
if (signature[i + 1] == '*') { if (signature[i + 1] == '*') {
/* param is a pointer */ /* param is a pointer */
@ -4811,8 +4852,10 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
{ {
arg_i32 = *argv_src++; arg_i32 = *argv_src++;
arg_i64 = arg_i32; arg_i64 = arg_i32;
/* TODO: memory64 the data type of ptr_len and argc depends on /* TODO: memory64 if future there is a way for supporting
* mem idx type */ * wasm64 and wasm32 in libc at the same time, remove the
* macro control */
#if WASM_ENABLE_MEMORY64 == 0
if (signature) { if (signature) {
if (signature[i + 1] == '*') { if (signature[i + 1] == '*') {
/* param is a pointer */ /* param is a pointer */
@ -4840,6 +4883,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
module, (uint64)arg_i32); module, (uint64)arg_i32);
} }
} }
#endif
if (n_ints < MAX_REG_INTS) if (n_ints < MAX_REG_INTS)
ints[n_ints++] = arg_i64; ints[n_ints++] = arg_i64;
else else
@ -4847,6 +4891,47 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
break; break;
} }
case VALUE_TYPE_I64: case VALUE_TYPE_I64:
#if WASM_ENABLE_MEMORY64 != 0
{
arg_i64 = GET_I64_FROM_ADDR(argv_src);
argv_src += 2;
if (signature) {
/* TODO: memory64 pointer with length need a new symbol
* to represent type i64, with '~' still represent i32
* length */
if (signature[i + 1] == '*') {
/* param is a pointer */
if (signature[i + 2] == '~')
/* pointer with length followed */
ptr_len = *argv_src;
else
/* pointer without length followed */
ptr_len = 1;
if (!wasm_runtime_validate_app_addr(module, arg_i64,
(uint64)ptr_len))
goto fail;
arg_i64 = (uint64)wasm_runtime_addr_app_to_native(
module, arg_i64);
}
else if (signature[i + 1] == '$') {
/* param is a string */
if (!wasm_runtime_validate_app_str_addr(module,
arg_i64))
goto fail;
arg_i64 = (uint64)wasm_runtime_addr_app_to_native(
module, arg_i64);
}
}
if (n_ints < MAX_REG_INTS)
ints[n_ints++] = arg_i64;
else
stacks[n_stacks++] = arg_i64;
break;
}
#endif
#if WASM_ENABLE_GC != 0 #if WASM_ENABLE_GC != 0
case REF_TYPE_FUNCREF: case REF_TYPE_FUNCREF:
case REF_TYPE_EXTERNREF: case REF_TYPE_EXTERNREF:

View File

@ -951,7 +951,7 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
uint32 readv, sval; \ uint32 readv, sval; \
\ \
sval = POP_I32(); \ sval = POP_I32(); \
addr = POP_I32(); \ addr = POP_MEM_OFFSET(); \
\ \
if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##8_U) { \ if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##8_U) { \
CHECK_MEMORY_OVERFLOW(1); \ CHECK_MEMORY_OVERFLOW(1); \
@ -991,7 +991,7 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
uint64 readv, sval; \ uint64 readv, sval; \
\ \
sval = (uint64)POP_I64(); \ sval = (uint64)POP_I64(); \
addr = POP_I32(); \ addr = POP_MEM_OFFSET(); \
\ \
if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##8_U) { \ if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##8_U) { \
CHECK_MEMORY_OVERFLOW(1); \ CHECK_MEMORY_OVERFLOW(1); \
@ -1510,7 +1510,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#endif #endif
#endif #endif
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
/* TODO: multi-memories for now assuming the memory idx type is consistent
* across multi-memories */
bool is_memory64 = false; bool is_memory64 = false;
if (memory)
is_memory64 = memory->is_memory64;
#endif #endif
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
@ -4170,7 +4174,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
global = globals + global_idx; global = globals + global_idx;
global_addr = get_global_addr(global_data, global); global_addr = get_global_addr(global_data, global);
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
if (module->memories[0]->is_memory64) { if (is_memory64) {
aux_stack_top = *(uint64 *)(frame_sp - 2); aux_stack_top = *(uint64 *)(frame_sp - 2);
} }
else else
@ -4188,7 +4192,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception; goto got_exception;
} }
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
if (module->memories[0]->is_memory64) { if (is_memory64) {
*(uint64 *)global_addr = aux_stack_top; *(uint64 *)global_addr = aux_stack_top;
frame_sp -= 2; frame_sp -= 2;
} }
@ -4228,9 +4232,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
@ -4247,9 +4248,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(8); CHECK_MEMORY_OVERFLOW(8);
@ -4265,9 +4263,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -4283,9 +4278,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -4301,9 +4293,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
@ -4319,9 +4308,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
@ -4337,9 +4323,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -4355,9 +4338,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -4373,9 +4353,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
@ -4391,9 +4368,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
@ -4410,9 +4384,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
opcode = *(frame_ip - 1); opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
@ -4428,9 +4399,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
@ -4448,9 +4416,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
frame_sp--; frame_sp--;
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4476,9 +4441,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
frame_sp -= 2; frame_sp -= 2;
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4509,9 +4471,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
opcode = *(frame_ip - 1); opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
sval = (uint32)POP_I32(); sval = (uint32)POP_I32();
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4539,9 +4498,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
opcode = *(frame_ip - 1); opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_uint32(frame_ip, frame_ip_end, flags);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
sval = (uint64)POP_I64(); sval = (uint64)POP_I64();
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4568,9 +4524,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
uint32 reserved; uint32 reserved;
read_leb_uint32(frame_ip, frame_ip_end, reserved); read_leb_uint32(frame_ip, frame_ip_end, reserved);
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
PUSH_PAGE_COUNT(memory->cur_page_count); PUSH_PAGE_COUNT(memory->cur_page_count);
(void)reserved; (void)reserved;
HANDLE_OP_END(); HANDLE_OP_END();
@ -4581,9 +4534,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 reserved, delta, uint32 reserved, delta,
prev_page_count = memory->cur_page_count; prev_page_count = memory->cur_page_count;
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
read_leb_uint32(frame_ip, frame_ip_end, reserved); read_leb_uint32(frame_ip, frame_ip_end, reserved);
delta = (uint32)POP_PAGE_COUNT(); delta = (uint32)POP_PAGE_COUNT();
@ -5601,9 +5551,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
read_leb_uint32(frame_ip, frame_ip_end, segment); read_leb_uint32(frame_ip, frame_ip_end, segment);
/* skip memory index */ /* skip memory index */
frame_ip++; frame_ip++;
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
bytes = (uint64)(uint32)POP_I32(); bytes = (uint64)(uint32)POP_I32();
offset = (uint64)(uint32)POP_I32(); offset = (uint64)(uint32)POP_I32();
@ -5654,9 +5601,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 *mdst, *msrc; uint8 *mdst, *msrc;
frame_ip += 2; frame_ip += 2;
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
len = POP_MEM_OFFSET(); len = POP_MEM_OFFSET();
src = POP_MEM_OFFSET(); src = POP_MEM_OFFSET();
dst = POP_MEM_OFFSET(); dst = POP_MEM_OFFSET();
@ -5689,9 +5633,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 fill_val, *mdst; uint8 fill_val, *mdst;
frame_ip++; frame_ip++;
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0]->is_memory64;
#endif
len = POP_MEM_OFFSET(); len = POP_MEM_OFFSET();
fill_val = POP_I32(); fill_val = POP_I32();
dst = POP_MEM_OFFSET(); dst = POP_MEM_OFFSET();
@ -5924,7 +5865,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
HANDLE_OP(WASM_OP_ATOMIC_PREFIX) HANDLE_OP(WASM_OP_ATOMIC_PREFIX)
{ {
uint32 offset = 0, align = 0, addr; mem_offset_t offset = 0, addr;
uint32 align = 0;
uint32 opcode1; uint32 opcode1;
read_leb_uint32(frame_ip, frame_ip_end, opcode1); read_leb_uint32(frame_ip, frame_ip_end, opcode1);
@ -5934,7 +5876,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode != WASM_OP_ATOMIC_FENCE) { if (opcode != WASM_OP_ATOMIC_FENCE) {
read_leb_uint32(frame_ip, frame_ip_end, align); read_leb_uint32(frame_ip, frame_ip_end, align);
read_leb_uint32(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
} }
switch (opcode) { switch (opcode) {
@ -5943,7 +5885,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 notify_count, ret; uint32 notify_count, ret;
notify_count = POP_I32(); notify_count = POP_I32();
addr = POP_I32(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
@ -5963,7 +5905,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
timeout = POP_I64(); timeout = POP_I64();
expect = POP_I32(); expect = POP_I32();
addr = POP_I32(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
@ -5987,7 +5929,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
timeout = POP_I64(); timeout = POP_I64();
expect = POP_I64(); expect = POP_I64();
addr = POP_I32(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(8); CHECK_MEMORY_OVERFLOW(8);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
@ -6018,7 +5960,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
uint32 readv; uint32 readv;
addr = POP_I32(); addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) { if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -6053,7 +5995,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
uint64 readv; uint64 readv;
addr = POP_I32(); addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) { if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -6095,7 +6037,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 sval; uint32 sval;
sval = (uint32)POP_I32(); sval = (uint32)POP_I32();
addr = POP_I32(); addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I32_STORE8) { if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -6129,7 +6071,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint64 sval; uint64 sval;
sval = (uint64)POP_I64(); sval = (uint64)POP_I64();
addr = POP_I32(); addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I64_STORE8) { if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -6156,7 +6098,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_MEMORY_OVERFLOW(8); CHECK_MEMORY_OVERFLOW(8);
CHECK_ATOMIC_MEMORY_ACCESS(); CHECK_ATOMIC_MEMORY_ACCESS();
shared_memory_lock(memory); shared_memory_lock(memory);
PUT_I64_TO_ADDR((uint32 *)maddr, sval); STORE_I64(maddr, sval);
shared_memory_unlock(memory); shared_memory_unlock(memory);
} }
break; break;
@ -6170,7 +6112,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
sval = POP_I32(); sval = POP_I32();
expect = POP_I32(); expect = POP_I32();
addr = POP_I32(); addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U) { if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U) {
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
@ -6216,7 +6158,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
sval = (uint64)POP_I64(); sval = (uint64)POP_I64();
expect = (uint64)POP_I64(); expect = (uint64)POP_I64();
addr = POP_I32(); addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U) { if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U) {
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);

View File

@ -7672,8 +7672,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
opcode = (uint8)opcode1; opcode = (uint8)opcode1;
if (opcode != WASM_OP_ATOMIC_FENCE) { if (opcode != WASM_OP_ATOMIC_FENCE) {
skip_leb_uint32(p, p_end); /* align */ skip_leb_uint32(p, p_end); /* align */
skip_leb_uint32(p, p_end); /* offset */ skip_leb_mem_offset(p, p_end); /* offset */
} }
else { else {
/* atomic.fence doesn't have memarg */ /* atomic.fence doesn't have memarg */
@ -10785,6 +10785,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
#endif #endif
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
bool is_memory64 = false; bool is_memory64 = false;
/* TODO: multi-memories for now assuming the memory idx type is consistent
* across multi-memories */
if (module->import_memory_count > 0)
is_memory64 = module->import_memories[0].u.memory.flags & MEMORY64_FLAG;
else if (module->memory_count > 0)
is_memory64 = module->memories[0].flags & MEMORY64_FLAG;
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif #endif
global_count = module->import_global_count + module->global_count; global_count = module->import_global_count + module->global_count;
@ -12977,13 +12987,7 @@ re_scan:
} }
#endif #endif
CHECK_MEMORY(); CHECK_MEMORY();
read_leb_uint32(p, p_end, align); /* align */ read_leb_uint32(p, p_end, align); /* align */
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0].flags & MEMORY64_FLAG;
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
read_leb_mem_offset(p, p_end, mem_offset); /* offset */ read_leb_mem_offset(p, p_end, mem_offset); /* offset */
if (!check_memory_access_align(opcode, align, error_buf, if (!check_memory_access_align(opcode, align, error_buf,
error_buf_size)) { error_buf_size)) {
@ -13055,14 +13059,6 @@ re_scan:
"zero byte expected"); "zero byte expected");
goto fail; goto fail;
} }
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type = module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
PUSH_PAGE_COUNT(); PUSH_PAGE_COUNT();
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -13079,13 +13075,6 @@ re_scan:
"zero byte expected"); "zero byte expected");
goto fail; goto fail;
} }
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type = module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_AND_PUSH(mem_offset_type, mem_offset_type); POP_AND_PUSH(mem_offset_type, mem_offset_type);
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -14447,14 +14436,6 @@ re_scan:
POP_I32(); POP_I32();
POP_I32(); POP_I32();
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type =
module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_MEM_OFFSET(); POP_MEM_OFFSET();
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
func->has_memory_operations = true; func->has_memory_operations = true;
@ -14498,14 +14479,6 @@ re_scan:
&& module->memory_count == 0) && module->memory_count == 0)
goto fail_unknown_memory; goto fail_unknown_memory;
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type =
module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
@ -14526,14 +14499,6 @@ re_scan:
&& module->memory_count == 0) { && module->memory_count == 0) {
goto fail_unknown_memory; goto fail_unknown_memory;
} }
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type =
module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_I32(); POP_I32();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
@ -15450,7 +15415,6 @@ re_scan:
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
case WASM_OP_ATOMIC_PREFIX: case WASM_OP_ATOMIC_PREFIX:
{ {
/* TODO: memory64 offset type changes */
uint32 opcode1; uint32 opcode1;
read_leb_uint32(p, p_end, opcode1); read_leb_uint32(p, p_end, opcode1);
@ -15460,8 +15424,8 @@ re_scan:
#endif #endif
if (opcode1 != WASM_OP_ATOMIC_FENCE) { if (opcode1 != WASM_OP_ATOMIC_FENCE) {
CHECK_MEMORY(); CHECK_MEMORY();
read_leb_uint32(p, p_end, align); /* align */ read_leb_uint32(p, p_end, align); /* align */
read_leb_uint32(p, p_end, mem_offset); /* offset */ read_leb_mem_offset(p, p_end, mem_offset); /* offset */
if (!check_memory_align_equal(opcode1, align, error_buf, if (!check_memory_align_equal(opcode1, align, error_buf,
error_buf_size)) { error_buf_size)) {
goto fail; goto fail;
@ -15475,18 +15439,20 @@ re_scan:
#endif #endif
switch (opcode1) { switch (opcode1) {
case WASM_OP_ATOMIC_NOTIFY: case WASM_OP_ATOMIC_NOTIFY:
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); POP_I32();
POP_MEM_OFFSET();
PUSH_I32();
break; break;
case WASM_OP_ATOMIC_WAIT32: case WASM_OP_ATOMIC_WAIT32:
POP_I64(); POP_I64();
POP_I32(); POP_I32();
POP_I32(); POP_MEM_OFFSET();
PUSH_I32(); PUSH_I32();
break; break;
case WASM_OP_ATOMIC_WAIT64: case WASM_OP_ATOMIC_WAIT64:
POP_I64(); POP_I64();
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
PUSH_I32(); PUSH_I32();
break; break;
case WASM_OP_ATOMIC_FENCE: case WASM_OP_ATOMIC_FENCE:
@ -15500,26 +15466,26 @@ re_scan:
case WASM_OP_ATOMIC_I32_LOAD: case WASM_OP_ATOMIC_I32_LOAD:
case WASM_OP_ATOMIC_I32_LOAD8_U: case WASM_OP_ATOMIC_I32_LOAD8_U:
case WASM_OP_ATOMIC_I32_LOAD16_U: case WASM_OP_ATOMIC_I32_LOAD16_U:
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I32);
break; break;
case WASM_OP_ATOMIC_I32_STORE: case WASM_OP_ATOMIC_I32_STORE:
case WASM_OP_ATOMIC_I32_STORE8: case WASM_OP_ATOMIC_I32_STORE8:
case WASM_OP_ATOMIC_I32_STORE16: case WASM_OP_ATOMIC_I32_STORE16:
POP_I32(); POP_I32();
POP_I32(); POP_MEM_OFFSET();
break; break;
case WASM_OP_ATOMIC_I64_LOAD: case WASM_OP_ATOMIC_I64_LOAD:
case WASM_OP_ATOMIC_I64_LOAD8_U: case WASM_OP_ATOMIC_I64_LOAD8_U:
case WASM_OP_ATOMIC_I64_LOAD16_U: case WASM_OP_ATOMIC_I64_LOAD16_U:
case WASM_OP_ATOMIC_I64_LOAD32_U: case WASM_OP_ATOMIC_I64_LOAD32_U:
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64); POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I64);
break; break;
case WASM_OP_ATOMIC_I64_STORE: case WASM_OP_ATOMIC_I64_STORE:
case WASM_OP_ATOMIC_I64_STORE8: case WASM_OP_ATOMIC_I64_STORE8:
case WASM_OP_ATOMIC_I64_STORE16: case WASM_OP_ATOMIC_I64_STORE16:
case WASM_OP_ATOMIC_I64_STORE32: case WASM_OP_ATOMIC_I64_STORE32:
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
break; break;
case WASM_OP_ATOMIC_RMW_I32_ADD: case WASM_OP_ATOMIC_RMW_I32_ADD:
case WASM_OP_ATOMIC_RMW_I32_ADD8_U: case WASM_OP_ATOMIC_RMW_I32_ADD8_U:
@ -15539,7 +15505,9 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I32_XCHG: case WASM_OP_ATOMIC_RMW_I32_XCHG:
case WASM_OP_ATOMIC_RMW_I32_XCHG8_U: case WASM_OP_ATOMIC_RMW_I32_XCHG8_U:
case WASM_OP_ATOMIC_RMW_I32_XCHG16_U: case WASM_OP_ATOMIC_RMW_I32_XCHG16_U:
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); POP_I32();
POP_MEM_OFFSET();
PUSH_I32();
break; break;
case WASM_OP_ATOMIC_RMW_I64_ADD: case WASM_OP_ATOMIC_RMW_I64_ADD:
case WASM_OP_ATOMIC_RMW_I64_ADD8_U: case WASM_OP_ATOMIC_RMW_I64_ADD8_U:
@ -15566,7 +15534,7 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I64_XCHG16_U: case WASM_OP_ATOMIC_RMW_I64_XCHG16_U:
case WASM_OP_ATOMIC_RMW_I64_XCHG32_U: case WASM_OP_ATOMIC_RMW_I64_XCHG32_U:
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
PUSH_I64(); PUSH_I64();
break; break;
case WASM_OP_ATOMIC_RMW_I32_CMPXCHG: case WASM_OP_ATOMIC_RMW_I32_CMPXCHG:
@ -15574,7 +15542,7 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U: case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U:
POP_I32(); POP_I32();
POP_I32(); POP_I32();
POP_I32(); POP_MEM_OFFSET();
PUSH_I32(); PUSH_I32();
break; break;
case WASM_OP_ATOMIC_RMW_I64_CMPXCHG: case WASM_OP_ATOMIC_RMW_I64_CMPXCHG:
@ -15583,7 +15551,7 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U: case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U:
POP_I64(); POP_I64();
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
PUSH_I64(); PUSH_I64();
break; break;
default: default:

View File

@ -3895,8 +3895,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
opcode = (uint8)opcode1; opcode = (uint8)opcode1;
if (opcode != WASM_OP_ATOMIC_FENCE) { if (opcode != WASM_OP_ATOMIC_FENCE) {
skip_leb_uint32(p, p_end); /* align */ skip_leb_uint32(p, p_end); /* align */
skip_leb_uint32(p, p_end); /* offset */ skip_leb_mem_offset(p, p_end); /* offset */
} }
else { else {
/* atomic.fence doesn't have memarg */ /* atomic.fence doesn't have memarg */
@ -5960,6 +5960,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
#endif #endif
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
bool is_memory64 = false; bool is_memory64 = false;
/* TODO: multi-memories for now assuming the memory idx type is consistent
* across multi-memories */
if (module->import_memory_count > 0)
is_memory64 = module->import_memories[0].u.memory.flags & MEMORY64_FLAG;
else if (module->memory_count > 0)
is_memory64 = module->memories[0].flags & MEMORY64_FLAG;
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif #endif
global_count = module->import_global_count + module->global_count; global_count = module->import_global_count + module->global_count;
@ -7269,13 +7279,7 @@ re_scan:
} }
#endif #endif
CHECK_MEMORY(); CHECK_MEMORY();
read_leb_uint32(p, p_end, align); /* align */ read_leb_uint32(p, p_end, align); /* align */
#if WASM_ENABLE_MEMORY64 != 0
is_memory64 = module->memories[0].flags & MEMORY64_FLAG;
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
read_leb_mem_offset(p, p_end, mem_offset); /* offset */ read_leb_mem_offset(p, p_end, mem_offset); /* offset */
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_uint32(loader_ctx, mem_offset); emit_uint32(loader_ctx, mem_offset);
@ -7340,13 +7344,6 @@ re_scan:
/* reserved byte 0x00 */ /* reserved byte 0x00 */
bh_assert(*p == 0x00); bh_assert(*p == 0x00);
p++; p++;
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type = module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
PUSH_PAGE_COUNT(); PUSH_PAGE_COUNT();
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -7360,13 +7357,6 @@ re_scan:
/* reserved byte 0x00 */ /* reserved byte 0x00 */
bh_assert(*p == 0x00); bh_assert(*p == 0x00);
p++; p++;
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type = module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_AND_PUSH(mem_offset_type, mem_offset_type); POP_AND_PUSH(mem_offset_type, mem_offset_type);
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -7718,14 +7708,6 @@ re_scan:
POP_I32(); POP_I32();
POP_I32(); POP_I32();
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type =
module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_MEM_OFFSET(); POP_MEM_OFFSET();
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
func->has_memory_operations = true; func->has_memory_operations = true;
@ -7755,14 +7737,6 @@ re_scan:
+ module->memory_count + module->memory_count
> 0); > 0);
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type =
module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
@ -7780,14 +7754,6 @@ re_scan:
+ module->memory_count + module->memory_count
> 0); > 0);
#if WASM_ENABLE_MEMORY64 != 0
mem_offset_type =
module->memories[0].flags & MEMORY64_FLAG
? VALUE_TYPE_I64
: VALUE_TYPE_I32;
#else
mem_offset_type = VALUE_TYPE_I32;
#endif
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_I32(); POP_I32();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
@ -7945,7 +7911,6 @@ re_scan:
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
case WASM_OP_ATOMIC_PREFIX: case WASM_OP_ATOMIC_PREFIX:
{ {
/* TODO: memory64 offset type changes */
uint32 opcode1; uint32 opcode1;
read_leb_uint32(p, p_end, opcode1); read_leb_uint32(p, p_end, opcode1);
@ -7955,8 +7920,8 @@ re_scan:
#endif #endif
if (opcode1 != WASM_OP_ATOMIC_FENCE) { if (opcode1 != WASM_OP_ATOMIC_FENCE) {
CHECK_MEMORY(); CHECK_MEMORY();
read_leb_uint32(p, p_end, align); /* align */ read_leb_uint32(p, p_end, align); /* align */
read_leb_uint32(p, p_end, mem_offset); /* offset */ read_leb_mem_offset(p, p_end, mem_offset); /* offset */
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_uint32(loader_ctx, mem_offset); emit_uint32(loader_ctx, mem_offset);
#endif #endif
@ -7966,18 +7931,20 @@ re_scan:
#endif #endif
switch (opcode1) { switch (opcode1) {
case WASM_OP_ATOMIC_NOTIFY: case WASM_OP_ATOMIC_NOTIFY:
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); POP_I32();
POP_MEM_OFFSET();
PUSH_I32();
break; break;
case WASM_OP_ATOMIC_WAIT32: case WASM_OP_ATOMIC_WAIT32:
POP_I64(); POP_I64();
POP_I32(); POP_I32();
POP_I32(); POP_MEM_OFFSET();
PUSH_I32(); PUSH_I32();
break; break;
case WASM_OP_ATOMIC_WAIT64: case WASM_OP_ATOMIC_WAIT64:
POP_I64(); POP_I64();
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
PUSH_I32(); PUSH_I32();
break; break;
case WASM_OP_ATOMIC_FENCE: case WASM_OP_ATOMIC_FENCE:
@ -7988,26 +7955,26 @@ re_scan:
case WASM_OP_ATOMIC_I32_LOAD: case WASM_OP_ATOMIC_I32_LOAD:
case WASM_OP_ATOMIC_I32_LOAD8_U: case WASM_OP_ATOMIC_I32_LOAD8_U:
case WASM_OP_ATOMIC_I32_LOAD16_U: case WASM_OP_ATOMIC_I32_LOAD16_U:
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I32);
break; break;
case WASM_OP_ATOMIC_I32_STORE: case WASM_OP_ATOMIC_I32_STORE:
case WASM_OP_ATOMIC_I32_STORE8: case WASM_OP_ATOMIC_I32_STORE8:
case WASM_OP_ATOMIC_I32_STORE16: case WASM_OP_ATOMIC_I32_STORE16:
POP_I32(); POP_I32();
POP_I32(); POP_MEM_OFFSET();
break; break;
case WASM_OP_ATOMIC_I64_LOAD: case WASM_OP_ATOMIC_I64_LOAD:
case WASM_OP_ATOMIC_I64_LOAD8_U: case WASM_OP_ATOMIC_I64_LOAD8_U:
case WASM_OP_ATOMIC_I64_LOAD16_U: case WASM_OP_ATOMIC_I64_LOAD16_U:
case WASM_OP_ATOMIC_I64_LOAD32_U: case WASM_OP_ATOMIC_I64_LOAD32_U:
POP_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I64); POP_AND_PUSH(mem_offset_type, VALUE_TYPE_I64);
break; break;
case WASM_OP_ATOMIC_I64_STORE: case WASM_OP_ATOMIC_I64_STORE:
case WASM_OP_ATOMIC_I64_STORE8: case WASM_OP_ATOMIC_I64_STORE8:
case WASM_OP_ATOMIC_I64_STORE16: case WASM_OP_ATOMIC_I64_STORE16:
case WASM_OP_ATOMIC_I64_STORE32: case WASM_OP_ATOMIC_I64_STORE32:
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
break; break;
case WASM_OP_ATOMIC_RMW_I32_ADD: case WASM_OP_ATOMIC_RMW_I32_ADD:
case WASM_OP_ATOMIC_RMW_I32_ADD8_U: case WASM_OP_ATOMIC_RMW_I32_ADD8_U:
@ -8027,7 +7994,9 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I32_XCHG: case WASM_OP_ATOMIC_RMW_I32_XCHG:
case WASM_OP_ATOMIC_RMW_I32_XCHG8_U: case WASM_OP_ATOMIC_RMW_I32_XCHG8_U:
case WASM_OP_ATOMIC_RMW_I32_XCHG16_U: case WASM_OP_ATOMIC_RMW_I32_XCHG16_U:
POP2_AND_PUSH(VALUE_TYPE_I32, VALUE_TYPE_I32); POP_I32();
POP_MEM_OFFSET();
PUSH_I32();
break; break;
case WASM_OP_ATOMIC_RMW_I64_ADD: case WASM_OP_ATOMIC_RMW_I64_ADD:
case WASM_OP_ATOMIC_RMW_I64_ADD8_U: case WASM_OP_ATOMIC_RMW_I64_ADD8_U:
@ -8054,7 +8023,7 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I64_XCHG16_U: case WASM_OP_ATOMIC_RMW_I64_XCHG16_U:
case WASM_OP_ATOMIC_RMW_I64_XCHG32_U: case WASM_OP_ATOMIC_RMW_I64_XCHG32_U:
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
PUSH_I64(); PUSH_I64();
break; break;
case WASM_OP_ATOMIC_RMW_I32_CMPXCHG: case WASM_OP_ATOMIC_RMW_I32_CMPXCHG:
@ -8062,7 +8031,7 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U: case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U:
POP_I32(); POP_I32();
POP_I32(); POP_I32();
POP_I32(); POP_MEM_OFFSET();
PUSH_I32(); PUSH_I32();
break; break;
case WASM_OP_ATOMIC_RMW_I64_CMPXCHG: case WASM_OP_ATOMIC_RMW_I64_CMPXCHG:
@ -8071,7 +8040,7 @@ re_scan:
case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U: case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U:
POP_I64(); POP_I64();
POP_I64(); POP_I64();
POP_I32(); POP_MEM_OFFSET();
PUSH_I64(); PUSH_I64();
break; break;
default: default:

View File

@ -310,8 +310,9 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
bh_assert(memory != NULL); bh_assert(memory != NULL);
if (wasm_allocate_linear_memory(&memory->memory_data, is_shared_memory, if (wasm_allocate_linear_memory(&memory->memory_data, is_shared_memory,
num_bytes_per_page, init_page_count, memory->is_memory64, num_bytes_per_page,
max_page_count, &memory_data_size) init_page_count, max_page_count,
&memory_data_size)
!= BHT_OK) { != BHT_OK) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"allocate linear memory failed"); "allocate linear memory failed");

View File

@ -17,7 +17,7 @@ void
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception); wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
uint32 uint32
wasm_runtime_module_realloc(wasm_module_inst_t module, uint32 ptr, uint32 size, wasm_runtime_module_realloc(wasm_module_inst_t module, uint64 ptr, uint64 size,
void **p_native_addr); void **p_native_addr);
/* clang-format off */ /* clang-format off */

View File

@ -65,9 +65,11 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
/* integer overflow */ /* integer overflow */
return NULL; return NULL;
#if WASM_ENABLE_MEMORY64 == 0
if (request_size > 16 * (uint64)UINT32_MAX) if (request_size > 16 * (uint64)UINT32_MAX)
/* at most 16 G is allowed */ /* at most 64 G is allowed */
return NULL; return NULL;
#endif
if (prot & MMAP_PROT_READ) if (prot & MMAP_PROT_READ)
map_prot |= PROT_READ; map_prot |= PROT_READ;