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:
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user