Implement memory64 for classic interpreter (#3266)

Adding a new cmake flag (cache variable) `WAMR_BUILD_MEMORY64` to enable
the memory64 feature, it can only be enabled on the 64-bit platform/target and
can only use software boundary check. And when it is enabled, it can support both
i32 and i64 linear memory types. The main modifications are:

- wasm loader & mini-loader: loading and bytecode validating process 
- wasm runtime: memory instantiating process
- classic-interpreter: wasm code executing process
- Support memory64 memory in related runtime APIs
- 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
- memory64 classic-interpreter spec test in `test_wamr.sh` and in CI

Currently, it supports memory64 memory wasm file that uses core spec
(including bulk memory proposal) opcodes and threads opcodes.

ps.
https://github.com/bytecodealliance/wasm-micro-runtime/issues/3091
https://github.com/bytecodealliance/wasm-micro-runtime/pull/3240
https://github.com/bytecodealliance/wasm-micro-runtime/pull/3260
This commit is contained in:
Wenyong Huang
2024-04-02 15:22:07 +08:00
committed by GitHub
parent 6b0b5de1c5
commit a23fa9f86c
22 changed files with 1084 additions and 342 deletions

View File

@ -46,8 +46,10 @@ typedef float64 CellType_F64;
#define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory)
#endif
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#if WASM_ENABLE_MEMORY64 == 0
#if (!defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0)
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
@ -69,7 +71,8 @@ typedef float64 CellType_F64;
else \
goto out_of_bounds; \
} while (0)
#else
#else /* else of !defined(OS_ENABLE_HW_BOUND_CHECK) || \
WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
@ -80,8 +83,37 @@ typedef float64 CellType_F64;
do { \
maddr = memory->memory_data + (uint32)(start); \
} while (0)
#endif /* !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
#endif /* end of !defined(OS_ENABLE_HW_BOUND_CHECK) || \
WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 */
#else /* else of WASM_ENABLE_MEMORY64 == 0 */
#define CHECK_MEMORY_OVERFLOW(bytes) \
do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \
/* If memory64 is enabled, offset1, offset1 + bytes can overflow */ \
if (disable_bounds_checks \
|| (offset1 >= offset && offset1 + bytes >= offset1 \
&& offset1 + bytes <= get_linear_mem_size())) \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
} while (0)
#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
do { \
uint64 offset1 = (uint64)(start); \
/* If memory64 is enabled, offset1 + bytes can overflow */ \
if (disable_bounds_checks \
|| (offset1 + bytes >= offset1 \
&& offset1 + bytes <= get_linear_mem_size())) \
/* App heap space is not valid space for \
bulk memory operation */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
} while (0)
#endif /* end of WASM_ENABLE_MEMORY64 == 0 */
#define CHECK_ATOMIC_MEMORY_ACCESS() \
do { \
@ -472,6 +504,23 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
#define SET_LABEL_TYPE(_label_type) (void)0
#endif
#if WASM_ENABLE_MEMORY64 != 0
#define PUSH_MEM_OFFSET(value) \
do { \
if (is_memory64) { \
PUT_I64_TO_ADDR(frame_sp, value); \
frame_sp += 2; \
} \
else { \
*(int32 *)frame_sp++ = (int32)(value); \
} \
} while (0)
#else
#define PUSH_MEM_OFFSET(value) PUSH_I32(value)
#endif
#define PUSH_PAGE_COUNT(value) PUSH_MEM_OFFSET(value)
#define PUSH_CSP(_label_type, param_cell_num, cell_num, _target_addr) \
do { \
bh_assert(frame_csp < frame->csp_boundary); \
@ -501,6 +550,14 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
GET_REF_FROM_ADDR(frame_sp))
#endif
#if WASM_ENABLE_MEMORY64 != 0
#define POP_MEM_OFFSET() (is_memory64 ? POP_I64() : POP_I32())
#else
#define POP_MEM_OFFSET() POP_I32()
#endif
#define POP_PAGE_COUNT() POP_MEM_OFFSET()
#define POP_CSP_CHECK_OVERFLOW(n) \
do { \
bh_assert(frame_csp - n >= frame->csp_bottom); \
@ -567,51 +624,73 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
frame_csp = frame->csp; \
} while (0)
#define read_leb_int64(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = (int64)_val; \
if (_val & 0x40) \
/* sign extend */ \
res |= 0xFFFFFFFFFFFFFF80LL; \
p++; \
break; \
} \
uint32 _off = 0; \
res = (int64)read_leb(p, &_off, 64, true); \
p += _off; \
#define read_leb_int64(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = (int64)_val; \
if (_val & 0x40) \
/* sign extend */ \
res |= 0xFFFFFFFFFFFFFF80LL; \
p++; \
} \
else { \
uint32 _off = 0; \
res = (int64)read_leb(p, &_off, 64, true); \
p += _off; \
} \
} while (0)
#define read_leb_uint32(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = _val; \
p++; \
break; \
} \
uint32 _off = 0; \
res = (uint32)read_leb(p, &_off, 32, false); \
p += _off; \
#define read_leb_uint32(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = _val; \
p++; \
} \
else { \
uint32 _off = 0; \
res = (uint32)read_leb(p, &_off, 32, false); \
p += _off; \
} \
} while (0)
#define read_leb_int32(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = (int32)_val; \
if (_val & 0x40) \
/* sign extend */ \
res |= 0xFFFFFF80; \
p++; \
break; \
} \
uint32 _off = 0; \
res = (int32)read_leb(p, &_off, 32, true); \
p += _off; \
#define read_leb_int32(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = (int32)_val; \
if (_val & 0x40) \
/* sign extend */ \
res |= 0xFFFFFF80; \
p++; \
} \
else { \
uint32 _off = 0; \
res = (int32)read_leb(p, &_off, 32, true); \
p += _off; \
} \
} while (0)
#if WASM_ENABLE_MEMORY64 != 0
#define read_leb_mem_offset(p, p_end, res) \
do { \
uint8 _val = *p; \
if (!(_val & 0x80)) { \
res = (mem_offset_t)_val; \
p++; \
} \
else { \
uint32 _off = 0; \
res = (mem_offset_t)read_leb(p, &_off, is_memory64 ? 64 : 32, \
false); \
p += _off; \
} \
} while (0)
#else
#define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
#endif
#if WASM_ENABLE_LABELS_AS_VALUES == 0
#define RECOVER_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func)
#else
@ -872,7 +951,7 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
uint32 readv, sval; \
\
sval = POP_I32(); \
addr = POP_I32(); \
addr = POP_MEM_OFFSET(); \
\
if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##8_U) { \
CHECK_MEMORY_OVERFLOW(1); \
@ -912,7 +991,7 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
uint64 readv, sval; \
\
sval = (uint64)POP_I64(); \
addr = POP_I32(); \
addr = POP_MEM_OFFSET(); \
\
if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##8_U) { \
CHECK_MEMORY_OVERFLOW(1); \
@ -1430,6 +1509,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMStringviewIterObjectRef stringview_iter_obj;
#endif
#endif
#if WASM_ENABLE_MEMORY64 != 0
/* TODO: multi-memories for now assuming the memory idx type is consistent
* across multi-memories */
bool is_memory64 = false;
if (memory)
is_memory64 = memory->is_memory64;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL;
@ -4087,8 +4173,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
bh_assert(global_idx < module->e->global_count);
global = globals + global_idx;
global_addr = get_global_addr(global_data, global);
/* TODO: Memory64 the data type depends on mem idx type */
aux_stack_top = (uint64)(*(uint32 *)(frame_sp - 1));
#if WASM_ENABLE_MEMORY64 != 0
if (is_memory64) {
aux_stack_top = *(uint64 *)(frame_sp - 2);
}
else
#endif
{
aux_stack_top = (uint64)(*(uint32 *)(frame_sp - 1));
}
if (aux_stack_top <= (uint64)exec_env->aux_stack_boundary) {
wasm_set_exception(module, "wasm auxiliary stack overflow");
goto got_exception;
@ -4098,8 +4191,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
"wasm auxiliary stack underflow");
goto got_exception;
}
*(int32 *)global_addr = aux_stack_top;
frame_sp--;
#if WASM_ENABLE_MEMORY64 != 0
if (is_memory64) {
*(uint64 *)global_addr = aux_stack_top;
frame_sp -= 2;
}
else
#endif
{
*(uint32 *)global_addr = aux_stack_top;
frame_sp--;
}
#if WASM_ENABLE_MEMORY_PROFILING != 0
if (module->module->aux_stack_top_global_index != (uint32)-1) {
uint32 aux_stack_used =
@ -4126,11 +4228,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_LOAD)
HANDLE_OP(WASM_OP_F32_LOAD)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4);
PUSH_I32(LOAD_I32(maddr));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4141,11 +4244,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD)
HANDLE_OP(WASM_OP_F64_LOAD)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(8);
PUSH_I64(LOAD_I64(maddr));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4155,11 +4259,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_LOAD8_S)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1);
PUSH_I32(sign_ext_8_32(*(int8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4169,11 +4274,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_LOAD8_U)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1);
PUSH_I32((uint32)(*(uint8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4183,11 +4289,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_LOAD16_S)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2);
PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4197,11 +4304,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_LOAD16_U)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2);
PUSH_I32((uint32)(LOAD_U16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4211,11 +4319,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD8_S)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1);
PUSH_I64(sign_ext_8_64(*(int8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4225,11 +4334,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD8_U)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1);
PUSH_I64((uint64)(*(uint8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4239,11 +4349,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD16_S)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2);
PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4253,11 +4364,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD16_U)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2);
PUSH_I64((uint64)(LOAD_U16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4267,12 +4379,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD32_S)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4);
PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4282,11 +4395,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_LOAD32_U)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
addr = POP_I32();
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4);
PUSH_I64((uint64)(LOAD_U32(maddr)));
CHECK_READ_WATCHPOINT(addr, offset);
@ -4298,14 +4412,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_STORE)
HANDLE_OP(WASM_OP_F32_STORE)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
frame_sp--;
addr = POP_I32();
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4);
STORE_U32(maddr, frame_sp[1]);
#if WASM_ENABLE_MEMORY64 != 0
if (is_memory64) {
STORE_U32(maddr, frame_sp[2]);
}
else
#endif
{
STORE_U32(maddr, frame_sp[1]);
}
CHECK_WRITE_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END();
@ -4314,15 +4437,26 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_STORE)
HANDLE_OP(WASM_OP_F64_STORE)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
frame_sp -= 2;
addr = POP_I32();
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(8);
PUT_I64_TO_ADDR((uint32 *)maddr,
GET_I64_FROM_ADDR(frame_sp + 1));
#if WASM_ENABLE_MEMORY64 != 0
if (is_memory64) {
PUT_I64_TO_ADDR((mem_offset_t *)maddr,
GET_I64_FROM_ADDR(frame_sp + 2));
}
else
#endif
{
PUT_I64_TO_ADDR((uint32 *)maddr,
GET_I64_FROM_ADDR(frame_sp + 1));
}
CHECK_WRITE_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END();
@ -4331,14 +4465,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I32_STORE8)
HANDLE_OP(WASM_OP_I32_STORE16)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
uint32 sval;
opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
sval = (uint32)POP_I32();
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_I32_STORE8) {
CHECK_MEMORY_OVERFLOW(1);
@ -4357,14 +4492,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_I64_STORE16)
HANDLE_OP(WASM_OP_I64_STORE32)
{
uint32 offset, flags, addr;
uint32 flags;
mem_offset_t offset, addr;
uint64 sval;
opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, offset);
read_leb_mem_offset(frame_ip, frame_ip_end, offset);
sval = (uint64)POP_I64();
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_I64_STORE8) {
CHECK_MEMORY_OVERFLOW(1);
@ -4388,7 +4524,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
uint32 reserved;
read_leb_uint32(frame_ip, frame_ip_end, reserved);
PUSH_I32(memory->cur_page_count);
PUSH_PAGE_COUNT(memory->cur_page_count);
(void)reserved;
HANDLE_OP_END();
}
@ -4399,15 +4535,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
prev_page_count = memory->cur_page_count;
read_leb_uint32(frame_ip, frame_ip_end, reserved);
delta = (uint32)POP_I32();
delta = (uint32)POP_PAGE_COUNT();
if (!wasm_enlarge_memory(module, delta)) {
/* failed to memory.grow, return -1 */
PUSH_I32(-1);
PUSH_PAGE_COUNT(-1);
}
else {
/* success, return previous page count */
PUSH_I32(prev_page_count);
PUSH_PAGE_COUNT(prev_page_count);
/* update memory size, no need to update memory ptr as
it isn't changed in wasm_enlarge_memory */
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
@ -5407,7 +5543,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_BULK_MEMORY != 0
case WASM_OP_MEMORY_INIT:
{
uint32 addr, segment;
uint32 segment;
mem_offset_t addr;
uint64 bytes, offset, seg_len;
uint8 *data;
@ -5417,7 +5554,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
bytes = (uint64)(uint32)POP_I32();
offset = (uint64)(uint32)POP_I32();
addr = (uint32)POP_I32();
addr = (mem_offset_t)POP_MEM_OFFSET();
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = get_linear_mem_size();
@ -5460,14 +5597,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
case WASM_OP_MEMORY_COPY:
{
uint32 dst, src, len;
mem_offset_t dst, src, len;
uint8 *mdst, *msrc;
frame_ip += 2;
len = POP_I32();
src = POP_I32();
dst = POP_I32();
len = POP_MEM_OFFSET();
src = POP_MEM_OFFSET();
dst = POP_MEM_OFFSET();
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = get_linear_mem_size();
@ -5493,13 +5629,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
case WASM_OP_MEMORY_FILL:
{
uint32 dst, len;
mem_offset_t dst, len;
uint8 fill_val, *mdst;
frame_ip++;
len = POP_I32();
len = POP_MEM_OFFSET();
fill_val = POP_I32();
dst = POP_I32();
dst = POP_MEM_OFFSET();
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = get_linear_mem_size();
@ -5729,7 +5865,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_SHARED_MEMORY != 0
HANDLE_OP(WASM_OP_ATOMIC_PREFIX)
{
uint32 offset = 0, align = 0, addr;
mem_offset_t offset = 0, addr;
uint32 align = 0;
uint32 opcode1;
read_leb_uint32(frame_ip, frame_ip_end, opcode1);
@ -5739,7 +5876,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (opcode != WASM_OP_ATOMIC_FENCE) {
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) {
@ -5748,7 +5885,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 notify_count, ret;
notify_count = POP_I32();
addr = POP_I32();
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4);
CHECK_ATOMIC_MEMORY_ACCESS();
@ -5768,7 +5905,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
timeout = POP_I64();
expect = POP_I32();
addr = POP_I32();
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4);
CHECK_ATOMIC_MEMORY_ACCESS();
@ -5792,7 +5929,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
timeout = POP_I64();
expect = POP_I64();
addr = POP_I32();
addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(8);
CHECK_ATOMIC_MEMORY_ACCESS();
@ -5823,7 +5960,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
uint32 readv;
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
CHECK_MEMORY_OVERFLOW(1);
@ -5858,7 +5995,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{
uint64 readv;
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
CHECK_MEMORY_OVERFLOW(1);
@ -5900,7 +6037,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 sval;
sval = (uint32)POP_I32();
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
CHECK_MEMORY_OVERFLOW(1);
@ -5934,7 +6071,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint64 sval;
sval = (uint64)POP_I64();
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
CHECK_MEMORY_OVERFLOW(1);
@ -5961,7 +6098,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
CHECK_MEMORY_OVERFLOW(8);
CHECK_ATOMIC_MEMORY_ACCESS();
shared_memory_lock(memory);
PUT_I64_TO_ADDR((uint32 *)maddr, sval);
STORE_I64(maddr, sval);
shared_memory_unlock(memory);
}
break;
@ -5975,7 +6112,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
sval = POP_I32();
expect = POP_I32();
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U) {
CHECK_MEMORY_OVERFLOW(1);
@ -6021,7 +6158,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
sval = (uint64)POP_I64();
expect = (uint64)POP_I64();
addr = POP_I32();
addr = POP_MEM_OFFSET();
if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U) {
CHECK_MEMORY_OVERFLOW(1);