Support table64 extension in classic-interp and AOT running modes (#3811)
Add table64 extension(in Memory64 proposal) support in classic-interp and AOT running modes, currently still use uint32 to represent table's initial and maximum size to keep AOT ABI unchanged.
This commit is contained in:
@ -511,9 +511,9 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define PUSH_MEM_OFFSET(value) \
|
||||
#define COND_PUSH_TEMPLATE(cond, value) \
|
||||
do { \
|
||||
if (is_memory64) { \
|
||||
if (cond) { \
|
||||
PUT_I64_TO_ADDR(frame_sp, value); \
|
||||
frame_sp += 2; \
|
||||
} \
|
||||
@ -521,8 +521,11 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
||||
*(int32 *)frame_sp++ = (int32)(value); \
|
||||
} \
|
||||
} while (0)
|
||||
#define PUSH_MEM_OFFSET(value) COND_PUSH_TEMPLATE(is_memory64, value)
|
||||
#define PUSH_TBL_ELEM_IDX(value) COND_PUSH_TEMPLATE(is_table64, value)
|
||||
#else
|
||||
#define PUSH_MEM_OFFSET(value) PUSH_I32(value)
|
||||
#define PUSH_TBL_ELEM_IDX(value) PUSH_I32(value)
|
||||
#endif
|
||||
|
||||
#define PUSH_PAGE_COUNT(value) PUSH_MEM_OFFSET(value)
|
||||
@ -558,8 +561,10 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define POP_MEM_OFFSET() (is_memory64 ? POP_I64() : POP_I32())
|
||||
#define POP_TBL_ELEM_IDX() (is_table64 ? POP_I64() : POP_I32())
|
||||
#else
|
||||
#define POP_MEM_OFFSET() POP_I32()
|
||||
#define POP_TBL_ELEM_IDX() POP_I32()
|
||||
#endif
|
||||
|
||||
#define POP_PAGE_COUNT() POP_MEM_OFFSET()
|
||||
@ -1562,7 +1567,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
uint8 opcode;
|
||||
uint32 i, depth, cond, count, fidx, tidx, lidx, frame_size = 0;
|
||||
uint32 all_cell_num = 0;
|
||||
int32 val;
|
||||
tbl_elem_idx_t val;
|
||||
uint8 *else_addr, *end_addr, *maddr = NULL;
|
||||
uint32 local_idx, local_offset, global_idx;
|
||||
uint8 local_type, *global_addr;
|
||||
@ -1602,6 +1607,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
bool is_memory64 = false;
|
||||
bool is_table64 = false;
|
||||
if (memory)
|
||||
is_memory64 = memory->is_memory64;
|
||||
#endif
|
||||
@ -2315,7 +2321,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
|
||||
/**
|
||||
* type check. compiler will make sure all like
|
||||
* (call_indirect (type $x) (i32.const 1))
|
||||
* (call_indirect (type $x) (it.const 1))
|
||||
* the function type has to be defined in the module also
|
||||
* no matter it is used or not
|
||||
*/
|
||||
@ -2334,9 +2340,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
/* clang-format on */
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
val = POP_I32();
|
||||
if ((uint32)val >= tbl_inst->cur_size) {
|
||||
val = POP_TBL_ELEM_IDX();
|
||||
if (val >= tbl_inst->cur_size) {
|
||||
wasm_set_exception(module, "undefined element");
|
||||
goto got_exception;
|
||||
}
|
||||
@ -2482,15 +2491,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
|
||||
HANDLE_OP(WASM_OP_TABLE_GET)
|
||||
{
|
||||
uint32 tbl_idx, elem_idx;
|
||||
uint32 tbl_idx;
|
||||
tbl_elem_idx_t elem_idx;
|
||||
WASMTableInstance *tbl_inst;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
|
||||
bh_assert(tbl_idx < module->table_count);
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
elem_idx = POP_I32();
|
||||
elem_idx = POP_TBL_ELEM_IDX();
|
||||
if (elem_idx >= tbl_inst->cur_size) {
|
||||
wasm_set_exception(module, "out of bounds table access");
|
||||
goto got_exception;
|
||||
@ -2507,20 +2520,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
HANDLE_OP(WASM_OP_TABLE_SET)
|
||||
{
|
||||
WASMTableInstance *tbl_inst;
|
||||
uint32 tbl_idx, elem_idx;
|
||||
uint32 tbl_idx;
|
||||
tbl_elem_idx_t elem_idx;
|
||||
table_elem_type_t elem_val;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
|
||||
bh_assert(tbl_idx < module->table_count);
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
elem_val = POP_I32();
|
||||
#else
|
||||
elem_val = POP_REF();
|
||||
#endif
|
||||
elem_idx = POP_I32();
|
||||
elem_idx = POP_TBL_ELEM_IDX();
|
||||
if (elem_idx >= tbl_inst->cur_size) {
|
||||
wasm_set_exception(module, "out of bounds table access");
|
||||
goto got_exception;
|
||||
@ -4616,13 +4633,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
|
||||
HANDLE_OP(WASM_OP_MEMORY_GROW)
|
||||
{
|
||||
uint32 mem_idx, delta, prev_page_count;
|
||||
uint32 mem_idx, prev_page_count;
|
||||
mem_offset_t delta;
|
||||
|
||||
read_leb_memidx(frame_ip, frame_ip_end, mem_idx);
|
||||
prev_page_count = memory->cur_page_count;
|
||||
delta = (uint32)POP_PAGE_COUNT();
|
||||
delta = POP_PAGE_COUNT();
|
||||
|
||||
if (!wasm_enlarge_memory_with_idx(module, delta, mem_idx)) {
|
||||
if (
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
delta > UINT32_MAX ||
|
||||
#endif
|
||||
!wasm_enlarge_memory_with_idx(module, (uint32)delta,
|
||||
mem_idx)) {
|
||||
/* failed to memory.grow, return -1 */
|
||||
PUSH_PAGE_COUNT(-1);
|
||||
}
|
||||
@ -5778,8 +5801,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
|
||||
case WASM_OP_TABLE_INIT:
|
||||
{
|
||||
uint32 tbl_idx, elem_idx;
|
||||
uint32 n, s, d;
|
||||
uint32 tbl_idx;
|
||||
tbl_elem_idx_t elem_idx, d;
|
||||
uint32 n, s;
|
||||
WASMTableInstance *tbl_inst;
|
||||
table_elem_type_t *table_elems;
|
||||
InitializerExpression *tbl_seg_init_values = NULL,
|
||||
@ -5793,10 +5817,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
bh_assert(tbl_idx < module->module->table_count);
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
n = (uint32)POP_I32();
|
||||
s = (uint32)POP_I32();
|
||||
d = (uint32)POP_I32();
|
||||
d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
|
||||
|
||||
if (!bh_bitmap_get_bit(module->e->common.elem_dropped,
|
||||
elem_idx)) {
|
||||
@ -5809,8 +5836,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
.value_count;
|
||||
}
|
||||
|
||||
if (offset_len_out_of_bounds(s, n, tbl_seg_len)
|
||||
|| offset_len_out_of_bounds(d, n,
|
||||
/* TODO: memory64 current implementation of table64
|
||||
* still assumes the max table size UINT32_MAX
|
||||
*/
|
||||
if (
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
d > UINT32_MAX ||
|
||||
#endif
|
||||
offset_len_out_of_bounds(s, n, tbl_seg_len)
|
||||
|| offset_len_out_of_bounds((uint32)d, n,
|
||||
tbl_inst->cur_size)) {
|
||||
wasm_set_exception(module,
|
||||
"out of bounds table access");
|
||||
@ -5864,7 +5898,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
case WASM_OP_TABLE_COPY:
|
||||
{
|
||||
uint32 src_tbl_idx, dst_tbl_idx;
|
||||
uint32 n, s, d;
|
||||
tbl_elem_idx_t n, s, d;
|
||||
WASMTableInstance *src_tbl_inst, *dst_tbl_inst;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx);
|
||||
@ -5877,14 +5911,29 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
|
||||
src_tbl_inst = wasm_get_table_inst(module, src_tbl_idx);
|
||||
|
||||
n = (uint32)POP_I32();
|
||||
s = (uint32)POP_I32();
|
||||
d = (uint32)POP_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = src_tbl_inst->is_table64
|
||||
&& dst_tbl_inst->is_table64;
|
||||
#endif
|
||||
n = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = src_tbl_inst->is_table64;
|
||||
#endif
|
||||
s = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = dst_tbl_inst->is_table64;
|
||||
#endif
|
||||
d = (tbl_elem_idx_t)POP_TBL_ELEM_IDX();
|
||||
|
||||
if (offset_len_out_of_bounds(d, n,
|
||||
if (
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
n > UINT32_MAX || s > UINT32_MAX || d > UINT32_MAX
|
||||
||
|
||||
#endif
|
||||
offset_len_out_of_bounds((uint32)d, (uint32)n,
|
||||
dst_tbl_inst->cur_size)
|
||||
|| offset_len_out_of_bounds(
|
||||
s, n, src_tbl_inst->cur_size)) {
|
||||
(uint32)s, (uint32)n, src_tbl_inst->cur_size)) {
|
||||
wasm_set_exception(module,
|
||||
"out of bounds table access");
|
||||
goto got_exception;
|
||||
@ -5907,28 +5956,37 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
case WASM_OP_TABLE_GROW:
|
||||
{
|
||||
WASMTableInstance *tbl_inst;
|
||||
uint32 tbl_idx, n, orig_tbl_sz;
|
||||
uint32 tbl_idx, orig_tbl_sz;
|
||||
tbl_elem_idx_t n;
|
||||
table_elem_type_t init_val;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
|
||||
bh_assert(tbl_idx < module->table_count);
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
orig_tbl_sz = tbl_inst->cur_size;
|
||||
|
||||
n = POP_I32();
|
||||
n = POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_GC == 0
|
||||
init_val = POP_I32();
|
||||
#else
|
||||
init_val = POP_REF();
|
||||
#endif
|
||||
|
||||
if (!wasm_enlarge_table(module, tbl_idx, n, init_val)) {
|
||||
PUSH_I32(-1);
|
||||
if (
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
n > UINT32_MAX ||
|
||||
#endif
|
||||
!wasm_enlarge_table(module, tbl_idx, (uint32)n,
|
||||
init_val)) {
|
||||
PUSH_TBL_ELEM_IDX(-1);
|
||||
}
|
||||
else {
|
||||
PUSH_I32(orig_tbl_sz);
|
||||
PUSH_TBL_ELEM_IDX(orig_tbl_sz);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -5941,13 +5999,17 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
bh_assert(tbl_idx < module->table_count);
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
PUSH_I32(tbl_inst->cur_size);
|
||||
PUSH_TBL_ELEM_IDX(tbl_inst->cur_size);
|
||||
break;
|
||||
}
|
||||
case WASM_OP_TABLE_FILL:
|
||||
{
|
||||
uint32 tbl_idx, n;
|
||||
uint32 tbl_idx;
|
||||
tbl_elem_idx_t n, elem_idx;
|
||||
WASMTableInstance *tbl_inst;
|
||||
table_elem_type_t fill_val;
|
||||
|
||||
@ -5955,24 +6017,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
bh_assert(tbl_idx < module->table_count);
|
||||
|
||||
tbl_inst = wasm_get_table_inst(module, tbl_idx);
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
is_table64 = tbl_inst->is_table64;
|
||||
#endif
|
||||
|
||||
n = POP_I32();
|
||||
n = POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_GC == 0
|
||||
fill_val = POP_I32();
|
||||
#else
|
||||
fill_val = POP_REF();
|
||||
#endif
|
||||
i = POP_I32();
|
||||
elem_idx = POP_TBL_ELEM_IDX();
|
||||
|
||||
if (offset_len_out_of_bounds(i, n,
|
||||
if (
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
n > UINT32_MAX || elem_idx > UINT32_MAX ||
|
||||
#endif
|
||||
offset_len_out_of_bounds((uint32)elem_idx,
|
||||
(uint32)n,
|
||||
tbl_inst->cur_size)) {
|
||||
wasm_set_exception(module,
|
||||
"out of bounds table access");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
for (; n != 0; i++, n--) {
|
||||
tbl_inst->elems[i] = fill_val;
|
||||
for (; n != 0; elem_idx++, n--) {
|
||||
tbl_inst->elems[elem_idx] = fill_val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user