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:
@ -93,6 +93,10 @@ extern "C" {
|
||||
#define MAX_PAGE_COUNT_FLAG 0x01
|
||||
#define SHARED_MEMORY_FLAG 0x02
|
||||
#define MEMORY64_FLAG 0x04
|
||||
#define MAX_TABLE_SIZE_FLAG 0x01
|
||||
/* the shared flag for table is not actual used now */
|
||||
#define SHARED_TABLE_FLAG 0x02
|
||||
#define TABLE64_FLAG 0x04
|
||||
|
||||
/**
|
||||
* In the multi-memory proposal, the memarg in loads and stores are
|
||||
@ -494,6 +498,7 @@ typedef struct WASMTableType {
|
||||
* 0: no max size and not shared
|
||||
* 1: has max size
|
||||
* 2: shared
|
||||
* 4: table64
|
||||
*/
|
||||
uint8 flags;
|
||||
bool possible_grow;
|
||||
@ -520,6 +525,7 @@ typedef uint64 mem_offset_t;
|
||||
typedef uint32 mem_offset_t;
|
||||
#define PR_MEM_OFFSET PRIu32
|
||||
#endif
|
||||
typedef mem_offset_t tbl_elem_idx_t;
|
||||
|
||||
typedef struct WASMMemory {
|
||||
uint32 flags;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -51,6 +51,18 @@ has_module_memory64(WASMModule *module)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_table_64bit(WASMModule *module, uint32 table_idx)
|
||||
{
|
||||
if (table_idx < module->import_table_count)
|
||||
return !!(module->import_tables[table_idx].u.table.table_type.flags
|
||||
& TABLE64_FLAG);
|
||||
else
|
||||
return !!(module->tables[table_idx].table_type.flags & TABLE64_FLAG);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
@ -2201,10 +2213,14 @@ fail:
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size)
|
||||
adjust_table_max_size(bool is_table64, uint32 init_size, uint32 max_size_flag,
|
||||
uint32 *max_size)
|
||||
{
|
||||
uint32 default_max_size;
|
||||
|
||||
/* TODO: current still use UINT32_MAX as upper limit for table size to keep
|
||||
* ABI unchanged */
|
||||
(void)is_table64;
|
||||
if (UINT32_MAX / 2 > init_size)
|
||||
default_max_size = init_size * 2;
|
||||
else
|
||||
@ -2499,9 +2515,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
const char *table_name, WASMTableImport *table,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
uint32 declare_elem_type = 0, declare_max_size_flag = 0,
|
||||
declare_init_size = 0, declare_max_size = 0;
|
||||
const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
|
||||
uint32 declare_elem_type = 0, table_flag = 0, declare_init_size = 0,
|
||||
declare_max_size = 0;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *sub_module = NULL;
|
||||
WASMTable *linked_table = NULL;
|
||||
@ -2510,6 +2526,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMRefType ref_type;
|
||||
bool need_ref_type_map;
|
||||
#endif
|
||||
bool is_table64 = false;
|
||||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
@ -2548,23 +2565,29 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
#endif
|
||||
#endif /* end of WASM_ENABLE_GC == 0 */
|
||||
|
||||
read_leb_uint32(p, p_end, declare_max_size_flag);
|
||||
if (declare_max_size_flag > 1) {
|
||||
set_error_buf(error_buf, error_buf_size, "integer too large");
|
||||
p_org = p;
|
||||
read_leb_uint32(p, p_end, table_flag);
|
||||
is_table64 = table_flag & TABLE64_FLAG;
|
||||
if (p - p_org > 1) {
|
||||
LOG_VERBOSE("integer representation too long(import table)");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wasm_table_check_flags(table_flag, error_buf, error_buf_size, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_leb_uint32(p, p_end, declare_init_size);
|
||||
|
||||
if (declare_max_size_flag) {
|
||||
if (table_flag & MAX_TABLE_SIZE_FLAG) {
|
||||
read_leb_uint32(p, p_end, declare_max_size);
|
||||
if (!check_table_max_size(declare_init_size, declare_max_size,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
}
|
||||
|
||||
adjust_table_max_size(declare_init_size, declare_max_size_flag,
|
||||
&declare_max_size);
|
||||
adjust_table_max_size(is_table64, declare_init_size,
|
||||
table_flag & MAX_TABLE_SIZE_FLAG, &declare_max_size);
|
||||
|
||||
*p_buf = p;
|
||||
|
||||
@ -2582,7 +2605,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
declare_elem_type = linked_table->table_type.elem_type;
|
||||
declare_init_size = linked_table->table_type.init_size;
|
||||
declare_max_size = linked_table->table_type.max_size;
|
||||
declare_max_size_flag = linked_table->table_type.flags;
|
||||
table_flag = linked_table->table_type.flags;
|
||||
table->import_table_linked = linked_table;
|
||||
table->import_module = sub_module;
|
||||
}
|
||||
@ -2591,12 +2614,17 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE != 0 */
|
||||
|
||||
/* (table (export "table") 10 20 funcref) */
|
||||
/* (table (export "table64") 10 20 funcref) */
|
||||
/* we need this section working in wamrc */
|
||||
if (!strcmp("spectest", sub_module_name)) {
|
||||
const uint32 spectest_table_init_size = 10;
|
||||
const uint32 spectest_table_max_size = 20;
|
||||
|
||||
if (strcmp("table", table_name)) {
|
||||
if (strcmp("table", table_name)
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
&& strcmp("table64", table_name)
|
||||
#endif
|
||||
) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"incompatible import type or unknown import");
|
||||
return false;
|
||||
@ -2616,7 +2644,7 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
/* now we believe all declaration are ok */
|
||||
table->table_type.elem_type = declare_elem_type;
|
||||
table->table_type.init_size = declare_init_size;
|
||||
table->table_type.flags = declare_max_size_flag;
|
||||
table->table_type.flags = table_flag;
|
||||
table->table_type.max_size = declare_max_size;
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
@ -2709,7 +2737,7 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
read_leb_uint32(p, p_end, mem_flag);
|
||||
is_memory64 = mem_flag & MEMORY64_FLAG;
|
||||
if (p - p_org > 1) {
|
||||
LOG_VERBOSE("integer representation too long");
|
||||
LOG_VERBOSE("integer representation too long(import memory)");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags");
|
||||
return false;
|
||||
}
|
||||
@ -3024,6 +3052,7 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||
WASMRefType ref_type;
|
||||
bool need_ref_type_map;
|
||||
#endif
|
||||
bool is_table64 = false;
|
||||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
@ -3061,34 +3090,20 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
||||
p_org = p;
|
||||
read_leb_uint32(p, p_end, table->table_type.flags);
|
||||
#if WASM_ENABLE_SHARED_MEMORY == 0
|
||||
if (p - p_org > 1) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"integer representation too long");
|
||||
return false;
|
||||
}
|
||||
if (table->table_type.flags > 1) {
|
||||
set_error_buf(error_buf, error_buf_size, "integer too large");
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
is_table64 = table->table_type.flags & TABLE64_FLAG;
|
||||
if (p - p_org > 1) {
|
||||
LOG_VERBOSE("integer representation too long(table)");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags");
|
||||
return false;
|
||||
}
|
||||
if (table->table_type.flags == 2) {
|
||||
set_error_buf(error_buf, error_buf_size, "tables cannot be shared");
|
||||
|
||||
if (!wasm_table_check_flags(table->table_type.flags, error_buf,
|
||||
error_buf_size, false)) {
|
||||
return false;
|
||||
}
|
||||
if (table->table_type.flags > 1) {
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
read_leb_uint32(p, p_end, table->table_type.init_size);
|
||||
|
||||
if (table->table_type.flags) {
|
||||
if (table->table_type.flags & MAX_TABLE_SIZE_FLAG) {
|
||||
read_leb_uint32(p, p_end, table->table_type.max_size);
|
||||
if (!check_table_max_size(table->table_type.init_size,
|
||||
table->table_type.max_size, error_buf,
|
||||
@ -3096,7 +3111,8 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMModule *module,
|
||||
return false;
|
||||
}
|
||||
|
||||
adjust_table_max_size(table->table_type.init_size, table->table_type.flags,
|
||||
adjust_table_max_size(is_table64, table->table_type.init_size,
|
||||
table->table_type.flags & MAX_TABLE_SIZE_FLAG,
|
||||
&table->table_type.max_size);
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
@ -3128,7 +3144,7 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
||||
read_leb_uint32(p, p_end, memory->flags);
|
||||
is_memory64 = memory->flags & MEMORY64_FLAG;
|
||||
if (p - p_org > 1) {
|
||||
LOG_VERBOSE("integer representation too long");
|
||||
LOG_VERBOSE("integer representation too long(memory)");
|
||||
set_error_buf(error_buf, error_buf_size, "invalid limits flags");
|
||||
return false;
|
||||
}
|
||||
@ -4402,6 +4418,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint8 table_elem_idx_type;
|
||||
uint32 table_segment_count, i;
|
||||
uint64 total_size;
|
||||
WASMTableSeg *table_segment;
|
||||
@ -4424,6 +4441,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
"invalid elements segment kind");
|
||||
return false;
|
||||
}
|
||||
table_elem_idx_type = VALUE_TYPE_I32;
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
|
||||
read_leb_uint32(p, p_end, table_segment->mode);
|
||||
@ -4459,9 +4477,17 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
if (!check_table_index(module, table_segment->table_index,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
if (!load_init_expr(
|
||||
module, &p, p_end, &table_segment->base_offset,
|
||||
VALUE_TYPE_I32, NULL, error_buf, error_buf_size))
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type =
|
||||
is_table_64bit(module, table_segment->table_index)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (!load_init_expr(module, &p, p_end,
|
||||
&table_segment->base_offset,
|
||||
table_elem_idx_type, NULL, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
|
||||
if (table_segment->mode == 0) {
|
||||
@ -4509,9 +4535,16 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
&table_segment->table_index,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
if (!load_init_expr(
|
||||
module, &p, p_end, &table_segment->base_offset,
|
||||
VALUE_TYPE_I32, NULL, error_buf, error_buf_size))
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type =
|
||||
is_table_64bit(module, table_segment->table_index)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (!load_init_expr(module, &p, p_end,
|
||||
&table_segment->base_offset,
|
||||
table_elem_idx_type, NULL, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
if (!load_elem_type(module, &p, p_end,
|
||||
&table_segment->elem_type,
|
||||
@ -4563,7 +4596,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
"unknown element segment kind");
|
||||
return false;
|
||||
}
|
||||
#else /* else of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
|
||||
#else /* else of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
|
||||
/*
|
||||
* like: 00 41 05 0b 04 00 01 00 01
|
||||
* for: (elem 0 (offset (i32.const 5)) $f1 $f2 $f1 $f2)
|
||||
@ -4572,8 +4605,14 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
&table_segment->table_index, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type =
|
||||
is_table_64bit(module, table_segment->table_index)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (!load_init_expr(module, &p, p_end, &table_segment->base_offset,
|
||||
VALUE_TYPE_I32, NULL, error_buf,
|
||||
table_elem_idx_type, NULL, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
if (!load_func_index_vec(&p, p_end, module, table_segment,
|
||||
@ -4588,6 +4627,16 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
return false;
|
||||
#endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (table_elem_idx_type == VALUE_TYPE_I64
|
||||
&& table_segment->base_offset.u.u64 > UINT32_MAX) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"In table64, table base offset can't be "
|
||||
"larger than UINT32_MAX");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
if (table_segment->elem_type == VALUE_TYPE_EXTERNREF)
|
||||
module->is_ref_types_used = true;
|
||||
@ -6110,6 +6159,12 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (!check_memory64_flags_consistency(module, error_buf, error_buf_size,
|
||||
false))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
calculate_global_data_offset(module);
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
@ -9608,6 +9663,7 @@ fail:
|
||||
#define POP_REF(Type) TEMPLATE_POP_REF(Type)
|
||||
#define PUSH_MEM_OFFSET() TEMPLATE_PUSH_REF(mem_offset_type)
|
||||
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
||||
#define PUSH_TBL_ELEM_IDX() TEMPLATE_PUSH_REF(table_elem_idx_type)
|
||||
|
||||
#define POP_I32() TEMPLATE_POP(I32)
|
||||
#define POP_F32() TEMPLATE_POP(F32)
|
||||
@ -9618,6 +9674,7 @@ fail:
|
||||
#define POP_EXTERNREF() TEMPLATE_POP(EXTERNREF)
|
||||
#define POP_STRINGREF() TEMPLATE_POP(STRINGREF)
|
||||
#define POP_MEM_OFFSET() TEMPLATE_POP_REF(mem_offset_type)
|
||||
#define POP_TBL_ELEM_IDX() TEMPLATE_POP_REF(table_elem_idx_type)
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
|
||||
@ -10803,7 +10860,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
{
|
||||
uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org;
|
||||
uint32 param_count, local_count, global_count;
|
||||
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type;
|
||||
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type,
|
||||
table_elem_idx_type;
|
||||
BlockType func_block_type;
|
||||
uint16 *local_offsets, local_offset;
|
||||
uint32 type_idx, func_idx, local_idx, global_idx, table_idx;
|
||||
@ -10838,6 +10896,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
|
||||
#else
|
||||
mem_offset_type = VALUE_TYPE_I32;
|
||||
table_elem_idx_type = VALUE_TYPE_I32;
|
||||
#endif
|
||||
uint32 memidx;
|
||||
|
||||
@ -11997,8 +12056,13 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
/* skip elem idx */
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
|
||||
if (type_idx >= module->type_count) {
|
||||
set_error_buf(error_buf, error_buf_size, "unknown type");
|
||||
@ -12375,8 +12439,8 @@ re_scan:
|
||||
break;
|
||||
}
|
||||
|
||||
/* table.get x. tables[x]. [i32] -> [t] */
|
||||
/* table.set x. tables[x]. [i32 t] -> [] */
|
||||
/* table.get x. tables[x]. [it] -> [t] */
|
||||
/* table.set x. tables[x]. [it t] -> [] */
|
||||
case WASM_OP_TABLE_GET:
|
||||
case WASM_OP_TABLE_SET:
|
||||
{
|
||||
@ -12407,8 +12471,13 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (opcode == WASM_OP_TABLE_GET) {
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PUSH_OFFSET_TYPE(decl_ref_type);
|
||||
#endif
|
||||
@ -12419,7 +12488,7 @@ re_scan:
|
||||
POP_OFFSET_TYPE(decl_ref_type);
|
||||
#endif
|
||||
POP_TYPE(decl_ref_type);
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
@ -14702,7 +14771,12 @@ re_scan:
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
POP_TBL_ELEM_IDX();
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
module->is_ref_types_used = true;
|
||||
@ -14727,7 +14801,8 @@ re_scan:
|
||||
}
|
||||
case WASM_OP_TABLE_COPY:
|
||||
{
|
||||
uint8 src_type, dst_type;
|
||||
uint8 src_type, dst_type, src_tbl_idx_type,
|
||||
dst_tbl_idx_type, min_tbl_idx_type;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
WASMRefType *src_ref_type = NULL, *dst_ref_type = NULL;
|
||||
#endif
|
||||
@ -14773,9 +14848,31 @@ re_scan:
|
||||
emit_uint32(loader_ctx, dst_tbl_idx);
|
||||
emit_uint32(loader_ctx, src_tbl_idx);
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
src_tbl_idx_type = is_table_64bit(module, src_tbl_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
dst_tbl_idx_type = is_table_64bit(module, dst_tbl_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
min_tbl_idx_type =
|
||||
(src_tbl_idx_type == VALUE_TYPE_I32
|
||||
|| dst_tbl_idx_type == VALUE_TYPE_I32)
|
||||
? VALUE_TYPE_I32
|
||||
: VALUE_TYPE_I64;
|
||||
#else
|
||||
src_tbl_idx_type = VALUE_TYPE_I32;
|
||||
dst_tbl_idx_type = VALUE_TYPE_I32;
|
||||
min_tbl_idx_type = VALUE_TYPE_I32;
|
||||
#endif
|
||||
|
||||
table_elem_idx_type = min_tbl_idx_type;
|
||||
POP_TBL_ELEM_IDX();
|
||||
table_elem_idx_type = src_tbl_idx_type;
|
||||
POP_TBL_ELEM_IDX();
|
||||
table_elem_idx_type = dst_tbl_idx_type;
|
||||
POP_TBL_ELEM_IDX();
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
module->is_ref_types_used = true;
|
||||
@ -14795,7 +14892,12 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
PUSH_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
PUSH_TBL_ELEM_IDX();
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
module->is_ref_types_used = true;
|
||||
@ -14844,15 +14946,20 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
POP_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
POP_OFFSET_TYPE(decl_type);
|
||||
#endif
|
||||
POP_TYPE(decl_type);
|
||||
if (opcode1 == WASM_OP_TABLE_GROW)
|
||||
PUSH_I32();
|
||||
PUSH_TBL_ELEM_IDX();
|
||||
else
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
|
||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||
module->is_ref_types_used = true;
|
||||
|
||||
@ -33,12 +33,25 @@ has_module_memory64(WASMModule *module)
|
||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
if (module->import_memory_count > 0)
|
||||
return !!(module->import_memories[0].u.mem_type.flags & MEMORY64_FLAG);
|
||||
return !!(module->import_memories[0].u.memory.mem_type.flags
|
||||
& MEMORY64_FLAG);
|
||||
else if (module->memory_count > 0)
|
||||
return !!(module->memories[0].flags & MEMORY64_FLAG);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_table_64bit(WASMModule *module, uint32 table_idx)
|
||||
{
|
||||
if (table_idx < module->import_table_count)
|
||||
return !!(module->import_tables[table_idx].u.table.table_type.flags
|
||||
& TABLE64_FLAG);
|
||||
else
|
||||
return !!(module->tables[table_idx].table_type.flags & TABLE64_FLAG);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
@ -577,11 +590,15 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
}
|
||||
|
||||
static void
|
||||
adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size)
|
||||
adjust_table_max_size(bool is_table64, uint32 init_size, uint32 max_size_flag,
|
||||
uint32 *max_size)
|
||||
{
|
||||
uint32 default_max_size = init_size * 2 > WASM_TABLE_MAX_SIZE
|
||||
? init_size * 2
|
||||
: WASM_TABLE_MAX_SIZE;
|
||||
/* TODO: current still use UINT32_MAX as upper limit for table size to keep
|
||||
* ABI unchanged */
|
||||
(void)is_table64;
|
||||
|
||||
if (max_size_flag) {
|
||||
/* module defines the table limitation */
|
||||
@ -642,8 +659,8 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
uint32 declare_elem_type = 0, declare_max_size_flag = 0,
|
||||
declare_init_size = 0, declare_max_size = 0;
|
||||
uint32 declare_elem_type = 0, table_flag = 0, declare_init_size = 0,
|
||||
declare_max_size = 0;
|
||||
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
/* 0x70 or 0x6F */
|
||||
@ -654,24 +671,29 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
#endif
|
||||
);
|
||||
|
||||
read_leb_uint32(p, p_end, declare_max_size_flag);
|
||||
read_leb_uint32(p, p_end, table_flag);
|
||||
|
||||
if (!wasm_table_check_flags(table_flag, error_buf, error_buf_size, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_leb_uint32(p, p_end, declare_init_size);
|
||||
if (declare_max_size_flag & 1) {
|
||||
if (table_flag & MAX_TABLE_SIZE_FLAG) {
|
||||
read_leb_uint32(p, p_end, declare_max_size);
|
||||
bh_assert(table->table_type.init_size <= table->table_type.max_size);
|
||||
}
|
||||
|
||||
adjust_table_max_size(declare_init_size, declare_max_size_flag,
|
||||
&declare_max_size);
|
||||
adjust_table_max_size(table_flag & TABLE64_FLAG, declare_init_size,
|
||||
table_flag & MAX_TABLE_SIZE_FLAG, &declare_max_size);
|
||||
*p_buf = p;
|
||||
|
||||
bh_assert(
|
||||
!((declare_max_size_flag & 1) && declare_init_size > declare_max_size));
|
||||
bh_assert(!((table_flag & MAX_TABLE_SIZE_FLAG)
|
||||
&& declare_init_size > declare_max_size));
|
||||
|
||||
/* now we believe all declaration are ok */
|
||||
table->table_type.elem_type = declare_elem_type;
|
||||
table->table_type.init_size = declare_init_size;
|
||||
table->table_type.flags = declare_max_size_flag;
|
||||
table->table_type.flags = table_flag;
|
||||
table->table_type.max_size = declare_max_size;
|
||||
return true;
|
||||
}
|
||||
@ -789,16 +811,22 @@ load_table(const uint8 **p_buf, const uint8 *buf_end, WASMTable *table,
|
||||
p_org = p;
|
||||
read_leb_uint32(p, p_end, table->table_type.flags);
|
||||
bh_assert(p - p_org <= 1);
|
||||
bh_assert(table->table_type.flags <= 1);
|
||||
(void)p_org;
|
||||
|
||||
if (!wasm_table_check_flags(table->table_type.flags, error_buf,
|
||||
error_buf_size, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_leb_uint32(p, p_end, table->table_type.init_size);
|
||||
if (table->table_type.flags == 1) {
|
||||
if (table->table_type.flags == MAX_TABLE_SIZE_FLAG) {
|
||||
read_leb_uint32(p, p_end, table->table_type.max_size);
|
||||
bh_assert(table->table_type.init_size <= table->table_type.max_size);
|
||||
}
|
||||
|
||||
adjust_table_max_size(table->table_type.init_size, table->table_type.flags,
|
||||
adjust_table_max_size(table->table_type.flags & TABLE64_FLAG,
|
||||
table->table_type.init_size,
|
||||
table->table_type.flags & MAX_TABLE_SIZE_FLAG,
|
||||
&table->table_type.max_size);
|
||||
|
||||
*p_buf = p;
|
||||
@ -1575,6 +1603,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint8 table_elem_idx_type;
|
||||
uint32 table_segment_count, i, table_index, function_count;
|
||||
uint64 total_size;
|
||||
WASMTableSeg *table_segment;
|
||||
@ -1592,6 +1621,7 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
table_segment = module->table_segments;
|
||||
for (i = 0; i < table_segment_count; i++, table_segment++) {
|
||||
bh_assert(p < p_end);
|
||||
table_elem_idx_type = VALUE_TYPE_I32;
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
read_leb_uint32(p, p_end, table_segment->mode);
|
||||
@ -1608,9 +1638,15 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type =
|
||||
is_table_64bit(module, table_segment->table_index)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (!load_init_expr(
|
||||
module, &p, p_end, &table_segment->base_offset,
|
||||
VALUE_TYPE_I32, error_buf, error_buf_size))
|
||||
table_elem_idx_type, error_buf, error_buf_size))
|
||||
return false;
|
||||
|
||||
if (table_segment->mode == 0) {
|
||||
@ -1646,9 +1682,15 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
&table_segment->table_index,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type =
|
||||
is_table_64bit(module, table_segment->table_index)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (!load_init_expr(
|
||||
module, &p, p_end, &table_segment->base_offset,
|
||||
VALUE_TYPE_I32, error_buf, error_buf_size))
|
||||
table_elem_idx_type, error_buf, error_buf_size))
|
||||
return false;
|
||||
if (!load_elem_type(&p, p_end, &table_segment->elem_type,
|
||||
table_segment->mode == 2 ? true : false,
|
||||
@ -1691,13 +1733,29 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
&table_segment->table_index, error_buf,
|
||||
error_buf_size))
|
||||
return false;
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type =
|
||||
is_table_64bit(module, table_segment->table_index)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (!load_init_expr(module, &p, p_end, &table_segment->base_offset,
|
||||
VALUE_TYPE_I32, error_buf, error_buf_size))
|
||||
table_elem_idx_type, error_buf, error_buf_size))
|
||||
return false;
|
||||
if (!load_func_index_vec(&p, p_end, module, table_segment,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
#endif /* WASM_ENABLE_REF_TYPES != 0 */
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (table_elem_idx_type == VALUE_TYPE_I64
|
||||
&& table_segment->base_offset.u.u64 > UINT32_MAX) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"In table64, table base offset can't be "
|
||||
"larger than UINT32_MAX");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1781,8 +1839,8 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
/* This memory_flag is from memory instead of data segment */
|
||||
uint8 memory_flag;
|
||||
if (module->import_memory_count > 0) {
|
||||
memory_flag =
|
||||
module->import_memories[mem_index].u.mem_type.flags;
|
||||
memory_flag = module->import_memories[mem_index]
|
||||
.u.memory.mem_type.flags;
|
||||
}
|
||||
else {
|
||||
memory_flag =
|
||||
@ -2948,6 +3006,12 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (!check_memory64_flags_consistency(module, error_buf, error_buf_size,
|
||||
false))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
calculate_global_data_offset(module);
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
@ -5214,6 +5278,13 @@ fail:
|
||||
} while (0)
|
||||
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
||||
|
||||
#define PUSH_TBL_ELEM_IDX() \
|
||||
do { \
|
||||
if (!(wasm_loader_push_frame_ref(loader_ctx, table_elem_idx_type, \
|
||||
error_buf, error_buf_size))) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_MEM_OFFSET() \
|
||||
do { \
|
||||
if (!wasm_loader_pop_frame_ref_offset(loader_ctx, mem_offset_type, \
|
||||
@ -5221,6 +5292,13 @@ fail:
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_TBL_ELEM_IDX() \
|
||||
do { \
|
||||
if (!(wasm_loader_pop_frame_ref(loader_ctx, table_elem_idx_type, \
|
||||
error_buf, error_buf_size))) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_AND_PUSH(type_pop, type_push) \
|
||||
do { \
|
||||
if (!(wasm_loader_push_pop_frame_ref_offset( \
|
||||
@ -5284,6 +5362,13 @@ fail:
|
||||
|
||||
#define PUSH_PAGE_COUNT() PUSH_MEM_OFFSET()
|
||||
|
||||
#define PUSH_TBL_ELEM_IDX() \
|
||||
do { \
|
||||
if (!(wasm_loader_push_frame_ref(loader_ctx, table_elem_idx_type, \
|
||||
error_buf, error_buf_size))) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_I32() \
|
||||
do { \
|
||||
if (!(wasm_loader_pop_frame_ref(loader_ctx, VALUE_TYPE_I32, error_buf, \
|
||||
@ -5326,6 +5411,13 @@ fail:
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_TBL_ELEM_IDX() \
|
||||
do { \
|
||||
if (!(wasm_loader_pop_frame_ref(loader_ctx, table_elem_idx_type, \
|
||||
error_buf, error_buf_size))) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
#define POP_AND_PUSH(type_pop, type_push) \
|
||||
do { \
|
||||
if (!(wasm_loader_push_pop_frame_ref(loader_ctx, 1, type_push, \
|
||||
@ -5945,7 +6037,8 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
{
|
||||
uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org;
|
||||
uint32 param_count, local_count, global_count;
|
||||
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type;
|
||||
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type,
|
||||
table_elem_idx_type;
|
||||
BlockType func_block_type;
|
||||
uint16 *local_offsets, local_offset;
|
||||
uint32 count, local_idx, global_idx, u32, align, i, memidx;
|
||||
@ -5976,6 +6069,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
mem_offset_type = is_memory64 ? VALUE_TYPE_I64 : VALUE_TYPE_I32;
|
||||
#else
|
||||
mem_offset_type = VALUE_TYPE_I32;
|
||||
table_elem_idx_type = VALUE_TYPE_I32;
|
||||
#endif
|
||||
|
||||
global_count = module->import_global_count + module->global_count;
|
||||
@ -6588,8 +6682,13 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
/* skip elem idx */
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
|
||||
bh_assert(type_idx < module->type_count);
|
||||
|
||||
@ -6865,8 +6964,8 @@ re_scan:
|
||||
break;
|
||||
}
|
||||
|
||||
/* table.get x. tables[x]. [i32] -> [t] */
|
||||
/* table.set x. tables[x]. [i32 t] -> [] */
|
||||
/* table.get x. tables[x]. [it] -> [t] */
|
||||
/* table.set x. tables[x]. [it t] -> [] */
|
||||
case WASM_OP_TABLE_GET:
|
||||
case WASM_OP_TABLE_SET:
|
||||
{
|
||||
@ -6882,8 +6981,13 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
if (opcode == WASM_OP_TABLE_GET) {
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
PUSH_OFFSET_TYPE(decl_ref_type);
|
||||
#endif
|
||||
@ -6894,7 +6998,7 @@ re_scan:
|
||||
POP_OFFSET_TYPE(decl_ref_type);
|
||||
#endif
|
||||
POP_TYPE(decl_ref_type);
|
||||
POP_I32();
|
||||
POP_TBL_ELEM_IDX();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -7819,7 +7923,12 @@ re_scan:
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
POP_TBL_ELEM_IDX();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_ELEM_DROP:
|
||||
@ -7838,7 +7947,8 @@ re_scan:
|
||||
case WASM_OP_TABLE_COPY:
|
||||
{
|
||||
uint8 src_ref_type, dst_ref_type;
|
||||
uint32 src_tbl_idx, dst_tbl_idx;
|
||||
uint32 src_tbl_idx, dst_tbl_idx, src_tbl_idx_type,
|
||||
dst_tbl_idx_type, min_tbl_idx_type;
|
||||
|
||||
read_leb_uint32(p, p_end, src_tbl_idx);
|
||||
if (!get_table_elem_type(module, src_tbl_idx,
|
||||
@ -7862,9 +7972,31 @@ re_scan:
|
||||
emit_uint32(loader_ctx, src_tbl_idx);
|
||||
emit_uint32(loader_ctx, dst_tbl_idx);
|
||||
#endif
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
POP_I32();
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
src_tbl_idx_type = is_table_64bit(module, src_tbl_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
dst_tbl_idx_type = is_table_64bit(module, dst_tbl_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
min_tbl_idx_type =
|
||||
(src_tbl_idx_type == VALUE_TYPE_I32
|
||||
|| dst_tbl_idx_type == VALUE_TYPE_I32)
|
||||
? VALUE_TYPE_I32
|
||||
: VALUE_TYPE_I64;
|
||||
#else
|
||||
src_tbl_idx_type = VALUE_TYPE_I32;
|
||||
dst_tbl_idx_type = VALUE_TYPE_I32;
|
||||
min_tbl_idx_type = VALUE_TYPE_I32;
|
||||
#endif
|
||||
|
||||
table_elem_idx_type = min_tbl_idx_type;
|
||||
POP_TBL_ELEM_IDX();
|
||||
table_elem_idx_type = src_tbl_idx_type;
|
||||
POP_TBL_ELEM_IDX();
|
||||
table_elem_idx_type = dst_tbl_idx_type;
|
||||
POP_TBL_ELEM_IDX();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_TABLE_SIZE:
|
||||
@ -7882,7 +8014,12 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
PUSH_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
PUSH_TBL_ELEM_IDX();
|
||||
break;
|
||||
}
|
||||
case WASM_OP_TABLE_GROW:
|
||||
@ -7914,15 +8051,20 @@ re_scan:
|
||||
emit_uint32(loader_ctx, table_idx);
|
||||
#endif
|
||||
|
||||
POP_I32();
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
table_elem_idx_type = is_table_64bit(module, table_idx)
|
||||
? VALUE_TYPE_I64
|
||||
: VALUE_TYPE_I32;
|
||||
#endif
|
||||
POP_TBL_ELEM_IDX();
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
POP_OFFSET_TYPE(decl_ref_type);
|
||||
#endif
|
||||
POP_TYPE(decl_ref_type);
|
||||
if (opcode1 == WASM_OP_TABLE_GROW)
|
||||
PUSH_I32();
|
||||
PUSH_TBL_ELEM_IDX();
|
||||
else
|
||||
POP_I32();
|
||||
PUSH_TBL_ELEM_IDX();
|
||||
break;
|
||||
}
|
||||
#endif /* WASM_ENABLE_REF_TYPES */
|
||||
|
||||
@ -678,6 +678,8 @@ tables_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||
uninitialized elements */
|
||||
#endif
|
||||
|
||||
table->is_table64 = import->u.table.table_type.flags & TABLE64_FLAG;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
*table_linked = table_inst_linked;
|
||||
if (table_inst_linked != NULL) {
|
||||
@ -736,6 +738,7 @@ tables_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||
/* For GC, all elements have already been set to NULL_REF (0) as
|
||||
uninitialized elements */
|
||||
#endif
|
||||
table->is_table64 = module->tables[i].table_type.flags & TABLE64_FLAG;
|
||||
table->elem_type = module->tables[i].table_type.elem_type;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
table->elem_ref_type.elem_ref_type =
|
||||
|
||||
@ -157,7 +157,8 @@ struct WASMMemoryInstance {
|
||||
struct WASMTableInstance {
|
||||
/* The element type */
|
||||
uint8 elem_type;
|
||||
uint8 __padding__[7];
|
||||
uint8 is_table64;
|
||||
uint8 __padding__[6];
|
||||
union {
|
||||
#if WASM_ENABLE_GC != 0
|
||||
WASMRefType *elem_ref_type;
|
||||
|
||||
Reference in New Issue
Block a user