Import reference-types feature (#612)

Implement spec reference-types proposal for interpreter, AOT and JIT, update documents and add sample. And upgrade AOT_CURRENT_VERSION to 3 as AOT file format and AOT module instance layout are changed.

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang
2021-04-15 11:29:20 +08:00
committed by GitHub
parent 7706e4b151
commit 03d45f1d62
48 changed files with 5557 additions and 856 deletions

View File

@ -20,22 +20,29 @@ extern "C" {
#define VALUE_TYPE_F32 0x7D
#define VALUE_TYPE_F64 0x7C
#define VALUE_TYPE_V128 0x7B
#define VALUE_TYPE_FUNCREF 0x70
#define VALUE_TYPE_EXTERNREF 0x6F
#define VALUE_TYPE_VOID 0x40
/* Used by AOT */
#define VALUE_TYPE_I1 0x41
/* Used by loader to represent any type of i32/i64/f32/f64 */
#define VALUE_TYPE_ANY 0x42
/* Table Element Type */
#define TABLE_ELEM_TYPE_ANY_FUNC 0x70
#define DEFAULT_NUM_BYTES_PER_PAGE 65536
#define NULL_REF (0xFFFFFFFF)
#define TABLE_MAX_SIZE (1024)
#define INIT_EXPR_TYPE_I32_CONST 0x41
#define INIT_EXPR_TYPE_I64_CONST 0x42
#define INIT_EXPR_TYPE_F32_CONST 0x43
#define INIT_EXPR_TYPE_F64_CONST 0x44
#define INIT_EXPR_TYPE_V128_CONST 0xFD
/* = WASM_OP_REF_FUNC */
#define INIT_EXPR_TYPE_FUNCREF_CONST 0xD2
/* = WASM_OP_REF_NULL */
#define INIT_EXPR_TYPE_REFNULL_CONST 0xD0
#define INIT_EXPR_TYPE_GET_GLOBAL 0x23
#define INIT_EXPR_TYPE_ERROR 0xff
@ -105,6 +112,7 @@ typedef union WASMValue {
typedef struct InitializerExpression {
/* type of INIT_EXPR_TYPE_XXX */
/* it actually is instr, in some places, requires constant only */
uint8 init_expr_type;
WASMValue u;
} InitializerExpression;
@ -124,6 +132,7 @@ typedef struct WASMTable {
uint32 init_size;
/* specified if (flags & 1), else it is 0x10000 */
uint32 max_size;
bool possible_grow;
} WASMTable;
typedef struct WASMMemory {
@ -141,6 +150,7 @@ typedef struct WASMTableImport {
uint32 init_size;
/* specified if (flags & 1), else it is 0x10000 */
uint32 max_size;
bool possible_grow;
#if WASM_ENABLE_MULTI_MODULE != 0
WASMModule *import_module;
WASMTable *import_table_linked;
@ -257,6 +267,12 @@ typedef struct WASMExport {
} WASMExport;
typedef struct WASMTableSeg {
/* 0 to 7 */
uint32 mode;
/* funcref or externref, elemkind will be considered as funcref */
uint32 elem_type;
bool is_dropped;
/* optional, only for active */
uint32 table_index;
InitializerExpression base_offset;
uint32 function_count;
@ -456,6 +472,10 @@ wasm_value_type_size(uint8 value_type)
switch (value_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
#if WASM_ENABLE_REF_TYPES != 0
case VALUE_TYPE_FUNCREF:
case VALUE_TYPE_EXTERNREF:
#endif
return sizeof(int32);
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
@ -475,11 +495,14 @@ wasm_value_type_cell_num(uint8 value_type)
{
if (value_type == VALUE_TYPE_VOID)
return 0;
else if (value_type == VALUE_TYPE_I32
|| value_type == VALUE_TYPE_F32)
else if (value_type == VALUE_TYPE_I32 || value_type == VALUE_TYPE_F32
#if WASM_ENABLE_REF_TYPES != 0
|| value_type == VALUE_TYPE_FUNCREF
|| value_type == VALUE_TYPE_EXTERNREF
#endif
)
return 1;
else if (value_type == VALUE_TYPE_I64
|| value_type == VALUE_TYPE_F64)
else if (value_type == VALUE_TYPE_I64 || value_type == VALUE_TYPE_F64)
return 2;
#if WASM_ENABLE_SIMD != 0
else if (value_type == VALUE_TYPE_V128)

View File

@ -871,7 +871,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint8 *global_data = module->global_data;
uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
WASMTableInstance *table = module->default_table;
WASMType **wasm_types = module->module->types;
WASMGlobalInstance *globals = module->globals, *global;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
@ -1099,7 +1098,8 @@ label_pop_csp_n:
#endif
{
WASMType *cur_type, *cur_func_type;
WASMTableInstance *cur_table_inst;
WASMTableInstance *tbl_inst;
uint32 tbl_idx;
#if WASM_ENABLE_TAIL_CALL != 0
opcode = *(frame_ip - 1);
#endif
@ -1114,41 +1114,35 @@ label_pop_csp_n:
* no matter it is used or not
*/
read_leb_uint32(frame_ip, frame_ip_end, tidx);
if (tidx >= module->module->type_count) {
wasm_set_exception(module, "unknown type");
goto got_exception;
}
bh_assert(tidx < module->module->type_count);
cur_type = wasm_types[tidx];
/* to skip 0x00 here */
frame_ip++;
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);
val = POP_I32();
/* careful, it might be a table in another module */
cur_table_inst = table;
#if WASM_ENABLE_MULTI_MODULE != 0
if (table->table_inst_linked) {
cur_table_inst = table->table_inst_linked;
}
#endif
if (val < 0 || val >= (int32)cur_table_inst->cur_size) {
if (val < 0 || val >= (int32)tbl_inst->cur_size) {
wasm_set_exception(module, "undefined element");
goto got_exception;
}
fidx = ((uint32*)cur_table_inst->base_addr)[val];
fidx = ((uint32*)tbl_inst->base_addr)[val];
if (fidx == (uint32)-1) {
wasm_set_exception(module, "uninitialized element");
goto got_exception;
}
#if WASM_ENABLE_MULTI_MODULE != 0
if (fidx >= module->function_count) {
/*
* we might be using a table injected by host or
* another module. In that case, we don't validate
* the elem value while loading
*/
if (fidx >= module->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
#endif
/* always call module own functions */
cur_func = module->functions + fidx;
@ -1201,6 +1195,99 @@ label_pop_csp_n:
HANDLE_OP_END ();
}
#if WASM_ENABLE_REF_TYPES != 0
HANDLE_OP (WASM_OP_SELECT_T):
{
uint32 vec_len;
uint8 type;
read_leb_uint32(frame_ip, frame_ip_end, vec_len);
type = *frame_ip++;
cond = (uint32)POP_I32();
if (type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64) {
frame_sp -= 2;
if (!cond) {
*(frame_sp - 2) = *frame_sp;
*(frame_sp - 1) = *(frame_sp + 1);
}
}
else {
frame_sp--;
if (!cond)
*(frame_sp - 1) = *frame_sp;
}
(void)vec_len;
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_TABLE_GET):
{
uint32 tbl_idx, 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);
elem_idx = POP_I32();
if (elem_idx >= tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
PUSH_I32(((uint32 *)tbl_inst->base_addr)[elem_idx]);
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_TABLE_SET):
{
uint32 tbl_idx, elem_idx, val;
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);
val = POP_I32();
elem_idx = POP_I32();
if (elem_idx >= tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
((uint32 *)(tbl_inst->base_addr))[elem_idx] = val;
HANDLE_OP_END();
}
HANDLE_OP (WASM_OP_REF_NULL):
{
uint32 ref_type;
read_leb_uint32(frame_ip, frame_ip_end, ref_type);
PUSH_I32(NULL_REF);
(void)ref_type;
HANDLE_OP_END();
}
HANDLE_OP (WASM_OP_REF_IS_NULL):
{
uint32 val;
val = POP_I32();
PUSH_I32(val == NULL_REF ? 1 : 0);
HANDLE_OP_END();
}
HANDLE_OP (WASM_OP_REF_FUNC):
{
uint32 func_idx;
read_leb_uint32(frame_ip, frame_ip_end, func_idx);
PUSH_I32(func_idx);
HANDLE_OP_END();
}
#endif /* WASM_ENABLE_REF_TYPES */
/* variable instructions */
HANDLE_OP (WASM_OP_GET_LOCAL):
{
@ -1209,6 +1296,10 @@ label_pop_csp_n:
switch (local_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
#if WASM_ENABLE_REF_TYPES != 0
case VALUE_TYPE_FUNCREF:
case VALUE_TYPE_EXTERNREF:
#endif
PUSH_I32(*(int32*)(frame_lp + local_offset));
break;
case VALUE_TYPE_I64:
@ -1240,6 +1331,10 @@ label_pop_csp_n:
switch (local_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
#if WASM_ENABLE_REF_TYPES != 0
case VALUE_TYPE_FUNCREF:
case VALUE_TYPE_EXTERNREF:
#endif
*(int32*)(frame_lp + local_offset) = POP_I32();
break;
case VALUE_TYPE_I64:
@ -1271,6 +1366,10 @@ label_pop_csp_n:
switch (local_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
#if WASM_ENABLE_REF_TYPES != 0
case VALUE_TYPE_FUNCREF:
case VALUE_TYPE_EXTERNREF:
#endif
*(int32*)(frame_lp + local_offset) = *(int32*)(frame_sp - 1);
break;
case VALUE_TYPE_I64:
@ -2586,10 +2685,173 @@ label_pop_csp_n:
break;
}
#endif /* WASM_ENABLE_BULK_MEMORY */
#if WASM_ENABLE_REF_TYPES != 0
case WASM_OP_TABLE_INIT:
{
uint32 tbl_idx, elem_idx;
uint64 n, s, d;
WASMTableInstance *tbl_inst;
read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
bh_assert(elem_idx < module->module->table_seg_count);
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
bh_assert(tbl_idx < module->module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
n = (uint32)POP_I32();
s = (uint32)POP_I32();
d = (uint32)POP_I32();
/* TODO: what if the element is not passive? */
if (!n) {
break;
}
if (n + s > module->module->table_segments[elem_idx].function_count
|| d + n > tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
if (module->module->table_segments[elem_idx].is_dropped) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
if (!wasm_elem_is_passive(
module->module->table_segments[elem_idx].mode)) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
bh_memcpy_s(
(uint8 *)(tbl_inst)
+ offsetof(WASMTableInstance, base_addr) + d * sizeof(uint32),
(tbl_inst->cur_size - d) * sizeof(uint32),
module->module->table_segments[elem_idx].func_indexes + s,
n * sizeof(uint32));
break;
}
case WASM_OP_ELEM_DROP:
{
uint32 elem_idx;
read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
bh_assert(elem_idx < module->module->table_seg_count);
module->module->table_segments[elem_idx].is_dropped = true;
break;
}
case WASM_OP_TABLE_COPY:
{
uint32 src_tbl_idx, dst_tbl_idx;
uint64 n, s, d;
WASMTableInstance *src_tbl_inst, *dst_tbl_inst;
read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx);
bh_assert(dst_tbl_idx < module->table_count);
dst_tbl_inst = wasm_get_table_inst(module, dst_tbl_idx);
read_leb_uint32(frame_ip, frame_ip_end, src_tbl_idx);
bh_assert(src_tbl_idx < module->table_count);
src_tbl_inst = wasm_get_table_inst(module, src_tbl_idx);
n = (uint32)POP_I32();
s = (uint32)POP_I32();
d = (uint32)POP_I32();
if (s + n > dst_tbl_inst->cur_size
|| d + n > src_tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
/* if s >= d, copy from front to back */
/* if s < d, copy from back to front */
/* merge all together */
bh_memcpy_s(
(uint8 *)(dst_tbl_inst) + offsetof(WASMTableInstance, base_addr)
+ d * sizeof(uint32),
(dst_tbl_inst->cur_size - d) * sizeof(uint32),
(uint8 *)(src_tbl_inst) + offsetof(WASMTableInstance, base_addr)
+ s * sizeof(uint32),
n * sizeof(uint32));
break;
}
case WASM_OP_TABLE_GROW:
{
uint32 tbl_idx, n, init_val, orig_tbl_sz;
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);
orig_tbl_sz = tbl_inst->cur_size;
n = POP_I32();
init_val = POP_I32();
if (!wasm_enlarge_table(module, tbl_idx, n, init_val)) {
PUSH_I32(-1);
}
else {
PUSH_I32(orig_tbl_sz);
}
break;
}
case WASM_OP_TABLE_SIZE:
{
uint32 tbl_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);
PUSH_I32(tbl_inst->cur_size);
break;
}
case WASM_OP_TABLE_FILL:
{
uint32 tbl_idx, n, val, i;
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);
n = POP_I32();
val = POP_I32();
i = POP_I32();
/* TODO: what if the element is not passive? */
/* TODO: what if the element is dropped? */
if (i + n > tbl_inst->cur_size) {
/* TODO: verify warning content */
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
for (; n != 0; i++, n--) {
((uint32 *)(tbl_inst->base_addr))[i] = val;
}
break;
}
#endif /* WASM_ENABLE_REF_TYPES */
default:
wasm_set_exception(module, "unsupported opcode");
goto got_exception;
break;
goto got_exception;
}
HANDLE_OP_END ();
}
@ -2946,6 +3208,17 @@ label_pop_csp_n:
#if WASM_ENABLE_TAIL_CALL == 0
HANDLE_OP (WASM_OP_RETURN_CALL):
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
#endif
#if WASM_ENABLE_SHARED_MEMORY == 0
HANDLE_OP (WASM_OP_ATOMIC_PREFIX):
#endif
#if WASM_ENABLE_REF_TYPES == 0
HANDLE_OP (WASM_OP_SELECT_T):
HANDLE_OP (WASM_OP_TABLE_GET):
HANDLE_OP (WASM_OP_TABLE_SET):
HANDLE_OP (WASM_OP_REF_NULL):
HANDLE_OP (WASM_OP_REF_IS_NULL):
HANDLE_OP (WASM_OP_REF_FUNC):
#endif
HANDLE_OP (WASM_OP_UNUSED_0x14):
HANDLE_OP (WASM_OP_UNUSED_0x15):
@ -2953,10 +3226,7 @@ label_pop_csp_n:
HANDLE_OP (WASM_OP_UNUSED_0x17):
HANDLE_OP (WASM_OP_UNUSED_0x18):
HANDLE_OP (WASM_OP_UNUSED_0x19):
HANDLE_OP (WASM_OP_UNUSED_0x1c):
HANDLE_OP (WASM_OP_UNUSED_0x1d):
HANDLE_OP (WASM_OP_UNUSED_0x1e):
HANDLE_OP (WASM_OP_UNUSED_0x1f):
HANDLE_OP (WASM_OP_UNUSED_0x27):
/* Used by fast interpreter */
HANDLE_OP (EXT_OP_SET_LOCAL_FAST_I64):
HANDLE_OP (EXT_OP_TEE_LOCAL_FAST_I64):

View File

@ -991,7 +991,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint8 *global_data = module->global_data;
uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals, *global;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
WASMInterpFrame *frame = NULL;
@ -1150,7 +1149,8 @@ recover_br_info:
#endif
{
WASMType *cur_type, *cur_func_type;
WASMTableInstance *cur_table_inst;
WASMTableInstance *tbl_inst;
uint32 tbl_idx;
#if WASM_ENABLE_TAIL_CALL != 0
GET_OPCODE();
@ -1160,40 +1160,36 @@ recover_br_info:
#endif
tidx = read_uint32(frame_ip);
cur_type = module->module->types[tidx];
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
val = GET_OPERAND(uint32, I32, 0);
frame_ip += 2;
if (tidx >= module->module->type_count) {
wasm_set_exception(module, "type index is overflow");
goto got_exception;
}
cur_type = module->module->types[tidx];
/* careful, it might be a table in another module */
cur_table_inst = table;
#if WASM_ENABLE_MULTI_MODULE != 0
if (table->table_inst_linked) {
cur_table_inst = table->table_inst_linked;
}
#endif
if (val < 0 || val >= (int32)cur_table_inst->cur_size) {
if (val < 0 || val >= (int32)tbl_inst->cur_size) {
wasm_set_exception(module, "undefined element");
goto got_exception;
}
fidx = ((uint32*)cur_table_inst->base_addr)[val];
fidx = ((uint32*)tbl_inst->base_addr)[val];
if (fidx == (uint32)-1) {
wasm_set_exception(module, "uninitialized element");
goto got_exception;
}
#if WASM_ENABLE_MULTI_MODULE != 0
/*
* we might be using a table injected by host or
* another module. in that case, we don't validate
* the elem value while loading
*/
if (fidx >= module->function_count) {
wasm_set_exception(module, "unknown function");
goto got_exception;
}
#endif
/* always call module own functions */
cur_func = module->functions + fidx;
@ -1252,6 +1248,70 @@ recover_br_info:
HANDLE_OP_END ();
}
#if WASM_ENABLE_REF_TYPES != 0
HANDLE_OP (WASM_OP_TABLE_GET):
{
uint32 tbl_idx, elem_idx;
WASMTableInstance *tbl_inst;
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
elem_idx = POP_I32();
if (elem_idx >= tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
PUSH_I32(((uint32 *)tbl_inst->base_addr)[elem_idx]);
HANDLE_OP_END();
}
HANDLE_OP (WASM_OP_TABLE_SET):
{
uint32 tbl_idx, elem_idx, val;
WASMTableInstance *tbl_inst;
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
val = POP_I32();
elem_idx = POP_I32();
if (elem_idx >= tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
((uint32 *)tbl_inst->base_addr)[elem_idx] = val;
HANDLE_OP_END ();
}
HANDLE_OP (WASM_OP_REF_NULL):
{
PUSH_I32(NULL_REF);
HANDLE_OP_END();
}
HANDLE_OP (WASM_OP_REF_IS_NULL):
{
uint32 val;
val = POP_I32();
PUSH_I32(val == NULL_REF ? 1 : 0);
HANDLE_OP_END();
}
HANDLE_OP (WASM_OP_REF_FUNC):
{
uint32 func_idx = read_uint32(frame_ip);
PUSH_I32(func_idx);
HANDLE_OP_END();
}
#endif /* WASM_ENABLE_REF_TYPES */
/* variable instructions */
HANDLE_OP (EXT_OP_SET_LOCAL_FAST):
HANDLE_OP (EXT_OP_TEE_LOCAL_FAST):
@ -2605,10 +2665,165 @@ recover_br_info:
break;
}
#endif /* WASM_ENABLE_BULK_MEMORY */
#if WASM_ENABLE_REF_TYPES != 0
case WASM_OP_TABLE_INIT:
{
uint32 tbl_idx, elem_idx;
uint64 n, s, d;
WASMTableInstance *tbl_inst;
elem_idx = read_uint32(frame_ip);
bh_assert(elem_idx < module->module->table_seg_count);
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
n = (uint32)POP_I32();
s = (uint32)POP_I32();
d = (uint32)POP_I32();
if (!n) {
break;
}
if (n + s > module->module->table_segments[elem_idx].function_count
|| d + n > tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
if (module->module->table_segments[elem_idx].is_dropped) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
if (!wasm_elem_is_passive(
module->module->table_segments[elem_idx].mode)) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
bh_memcpy_s(
(uint8 *)tbl_inst + offsetof(WASMTableInstance, base_addr)
+ d * sizeof(uint32),
(tbl_inst->cur_size - d) * sizeof(uint32),
module->module->table_segments[elem_idx].func_indexes + s,
n * sizeof(uint32));
break;
}
case WASM_OP_ELEM_DROP:
{
uint32 elem_idx = read_uint32(frame_ip);
bh_assert(elem_idx < module->module->table_seg_count);
module->module->table_segments[elem_idx].is_dropped = true;
break;
}
case WASM_OP_TABLE_COPY:
{
uint32 src_tbl_idx, dst_tbl_idx;
uint64 n, s, d;
WASMTableInstance *src_tbl_inst, *dst_tbl_inst;
dst_tbl_idx = read_uint32(frame_ip);
bh_assert(dst_tbl_idx < module->table_count);
dst_tbl_inst = wasm_get_table_inst(module, dst_tbl_idx);
src_tbl_idx = read_uint32(frame_ip);
bh_assert(src_tbl_idx < module->table_count);
src_tbl_inst = wasm_get_table_inst(module, src_tbl_idx);
n = (uint32)POP_I32();
s = (uint32)POP_I32();
d = (uint32)POP_I32();
if (s + n > dst_tbl_inst->cur_size
|| d + n > src_tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
/* if s >= d, copy from front to back */
/* if s < d, copy from back to front */
/* merge all together */
bh_memcpy_s(
(uint8 *)dst_tbl_inst + offsetof(WASMTableInstance, base_addr)
+ d * sizeof(uint32),
(dst_tbl_inst->cur_size - d) * sizeof(uint32),
(uint8 *)src_tbl_inst
+ offsetof(WASMTableInstance, base_addr) + s * sizeof(uint32),
n * sizeof(uint32));
break;
}
case WASM_OP_TABLE_GROW:
{
uint32 tbl_idx, n, init_val, orig_tbl_sz;
WASMTableInstance *tbl_inst;
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
orig_tbl_sz = tbl_inst->cur_size;
n = POP_I32();
init_val = POP_I32();
if (!wasm_enlarge_table(module, tbl_idx, n, init_val)) {
PUSH_I32(-1);
} else {
PUSH_I32(orig_tbl_sz);
}
break;
}
case WASM_OP_TABLE_SIZE:
{
uint32 tbl_idx;
WASMTableInstance *tbl_inst;
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
PUSH_I32(tbl_inst->cur_size);
break;
}
case WASM_OP_TABLE_FILL:
{
uint32 tbl_idx, n, val, i;
WASMTableInstance *tbl_inst;
tbl_idx = read_uint32(frame_ip);
bh_assert(tbl_idx < module->table_count);
tbl_inst = wasm_get_table_inst(module, tbl_idx);
n = POP_I32();
val = POP_I32();
i = POP_I32();
if (i + n > tbl_inst->cur_size) {
wasm_set_exception(module, "out of bounds table access");
goto got_exception;
}
for (; n != 0; i++, n--) {
((uint32 *)(tbl_inst->base_addr))[i] = val;
}
break;
}
#endif /* WASM_ENABLE_REF_TYPES */
default:
wasm_set_exception(module, "unsupported opcode");
goto got_exception;
break;
goto got_exception;
}
HANDLE_OP_END ();
}
@ -2992,16 +3207,25 @@ recover_br_info:
HANDLE_OP (WASM_OP_RETURN_CALL):
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
#endif
#if WASM_ENABLE_SHARED_MEMORY == 0
HANDLE_OP (WASM_OP_ATOMIC_PREFIX):
#endif
#if WASM_ENABLE_REF_TYPES == 0
HANDLE_OP (WASM_OP_TABLE_GET):
HANDLE_OP (WASM_OP_TABLE_SET):
HANDLE_OP (WASM_OP_REF_NULL):
HANDLE_OP (WASM_OP_REF_IS_NULL):
HANDLE_OP (WASM_OP_REF_FUNC):
#endif
/* SELECT_T is converted to SELECT or SELECT_64 */
HANDLE_OP (WASM_OP_SELECT_T):
HANDLE_OP (WASM_OP_UNUSED_0x14):
HANDLE_OP (WASM_OP_UNUSED_0x15):
HANDLE_OP (WASM_OP_UNUSED_0x16):
HANDLE_OP (WASM_OP_UNUSED_0x17):
HANDLE_OP (WASM_OP_UNUSED_0x18):
HANDLE_OP (WASM_OP_UNUSED_0x19):
HANDLE_OP (WASM_OP_UNUSED_0x1c):
HANDLE_OP (WASM_OP_UNUSED_0x1d):
HANDLE_OP (WASM_OP_UNUSED_0x1e):
HANDLE_OP (WASM_OP_UNUSED_0x1f):
HANDLE_OP (WASM_OP_UNUSED_0x27):
/* optimized op code */
HANDLE_OP (WASM_OP_F32_STORE):
HANDLE_OP (WASM_OP_F64_STORE):

File diff suppressed because it is too large Load Diff

View File

@ -70,6 +70,14 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
uint8 **p_else_addr,
uint8 **p_end_addr);
#if WASM_ENABLE_REF_TYPES != 0
void
wasm_set_ref_types_flag(bool enable);
bool
wasm_get_ref_types_flag();
#endif
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -47,11 +47,11 @@ typedef enum WASMOpcode {
/* parametric instructions */
WASM_OP_DROP = 0x1a, /* drop */
WASM_OP_SELECT = 0x1b, /* select */
WASM_OP_SELECT_T = 0x1c, /* select t */
WASM_OP_UNUSED_0x1c = 0x1c,
WASM_OP_UNUSED_0x1d = 0x1d,
WASM_OP_UNUSED_0x1e = 0x1e,
WASM_OP_UNUSED_0x1f = 0x1f,
WASM_OP_GET_GLOBAL_64 = 0x1d,
WASM_OP_SET_GLOBAL_64 = 0x1e,
WASM_OP_SET_GLOBAL_AUX_STACK = 0x1f,
/* variable instructions */
WASM_OP_GET_LOCAL = 0x20, /* get_local */
@ -60,9 +60,9 @@ typedef enum WASMOpcode {
WASM_OP_GET_GLOBAL = 0x23, /* get_global */
WASM_OP_SET_GLOBAL = 0x24, /* set_global */
WASM_OP_GET_GLOBAL_64 = 0x25,
WASM_OP_SET_GLOBAL_64 = 0x26,
WASM_OP_SET_GLOBAL_AUX_STACK = 0x27,
WASM_OP_TABLE_GET = 0x25, /* table.get */
WASM_OP_TABLE_SET = 0x26, /* table.set */
WASM_OP_UNUSED_0x27 = 0x27,
/* memory instructions */
WASM_OP_I32_LOAD = 0x28, /* i32.load */
@ -256,10 +256,16 @@ typedef enum WASMOpcode {
EXT_OP_COPY_STACK_TOP = 0xcc,
EXT_OP_COPY_STACK_TOP_I64 = 0xcd,
EXT_OP_COPY_STACK_VALUES = 0xce,
EXT_OP_BLOCK = 0xcf, /* block with blocktype */
EXT_OP_LOOP = 0xd0, /* loop with blocktype */
EXT_OP_IF = 0xd1, /* if with blocktype */
WASM_OP_IMPDEP = 0xd2,
WASM_OP_IMPDEP = 0xcf,
WASM_OP_REF_NULL = 0xd0, /* ref.null */
WASM_OP_REF_IS_NULL = 0xd1, /* ref.is_null */
WASM_OP_REF_FUNC = 0xd2, /* ref.func */
EXT_OP_BLOCK = 0xd3, /* block with blocktype */
EXT_OP_LOOP = 0xd4, /* loop with blocktype */
EXT_OP_IF = 0xd5, /* if with blocktype */
/* Post-MVP extend op prefix */
WASM_OP_MISC_PREFIX = 0xfc,
@ -276,15 +282,16 @@ typedef enum WASMMiscEXTOpcode {
WASM_OP_I64_TRUNC_SAT_U_F32 = 0x05,
WASM_OP_I64_TRUNC_SAT_S_F64 = 0x06,
WASM_OP_I64_TRUNC_SAT_U_F64 = 0x07,
#if WASM_ENABLE_BULK_MEMORY != 0
WASM_OP_MEMORY_INIT = 0x08,
WASM_OP_DATA_DROP = 0x09,
WASM_OP_MEMORY_COPY = 0x0a,
WASM_OP_MEMORY_FILL = 0x0b,
WASM_OP_TABLE_INIT = 0x0c,
WASM_OP_ELEM_DROP = 0x0d,
WASM_OP_TABLE_COPY = 0x0e
#endif
WASM_OP_TABLE_COPY = 0x0e,
WASM_OP_TABLE_GROW = 0x0f,
WASM_OP_TABLE_SIZE = 0x10,
WASM_OP_TABLE_FILL = 0x11,
} WASMMiscEXTOpcode;
typedef enum WASMSimdEXTOpcode {
@ -594,15 +601,6 @@ typedef enum WASMAtomicEXTOpcode {
}
#endif
/* Opcode prefix controlled by features */
#if WASM_ENABLE_SHARED_MEMORY != 0
#define DEF_ATOMIC_PREFIX_HANDLE(_name) \
_name[WASM_OP_ATOMIC_PREFIX] = \
HANDLE_OPCODE (WASM_OP_ATOMIC_PREFIX); /* 0xfe */
#else
#define DEF_ATOMIC_PREFIX_HANDLE(_name)
#endif
/*
* Macro used to generate computed goto tables for the C interpreter.
*/
@ -638,18 +636,18 @@ static type _name[WASM_INSTRUCTION_NUM] = { \
HANDLE_OPCODE (WASM_OP_UNUSED_0x19), /* 0x19 */ \
HANDLE_OPCODE (WASM_OP_DROP), /* 0x1a */ \
HANDLE_OPCODE (WASM_OP_SELECT), /* 0x1b */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1c), /* 0x1c */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1d), /* 0x1d */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1e), /* 0x1e */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1f), /* 0x1f */ \
HANDLE_OPCODE (WASM_OP_SELECT_T), /* 0x1c */ \
HANDLE_OPCODE (WASM_OP_GET_GLOBAL_64), /* 0x1d */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL_64), /* 0x1e */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL_AUX_STACK), /* 0x1f */ \
HANDLE_OPCODE (WASM_OP_GET_LOCAL), /* 0x20 */ \
HANDLE_OPCODE (WASM_OP_SET_LOCAL), /* 0x21 */ \
HANDLE_OPCODE (WASM_OP_TEE_LOCAL), /* 0x22 */ \
HANDLE_OPCODE (WASM_OP_GET_GLOBAL), /* 0x23 */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL), /* 0x24 */ \
HANDLE_OPCODE (WASM_OP_GET_GLOBAL_64), /* 0x25 */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL_64), /* 0x26 */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL_AUX_STACK), /* 0x27 */ \
HANDLE_OPCODE (WASM_OP_TABLE_GET), /* 0x25 */ \
HANDLE_OPCODE (WASM_OP_TABLE_SET), /* 0x26 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x27), /* 0x27 */ \
HANDLE_OPCODE (WASM_OP_I32_LOAD), /* 0x28 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD), /* 0x29 */ \
HANDLE_OPCODE (WASM_OP_F32_LOAD), /* 0x2a */ \
@ -817,14 +815,19 @@ static type _name[WASM_INSTRUCTION_NUM] = { \
HANDLE_OPCODE (EXT_OP_COPY_STACK_TOP), /* 0xcc */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_TOP_I64), /* 0xcd */ \
HANDLE_OPCODE (EXT_OP_COPY_STACK_VALUES), /* 0xce */ \
HANDLE_OPCODE (EXT_OP_BLOCK), /* 0xcf */ \
HANDLE_OPCODE (EXT_OP_LOOP), /* 0xd0 */ \
HANDLE_OPCODE (EXT_OP_IF), /* 0xd1 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xd2 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP), /* 0xcf */ \
HANDLE_OPCODE (WASM_OP_REF_NULL), /* 0xd0 */ \
HANDLE_OPCODE (WASM_OP_REF_IS_NULL), /* 0xd1 */ \
HANDLE_OPCODE (WASM_OP_REF_FUNC), /* 0xd2 */ \
HANDLE_OPCODE (EXT_OP_BLOCK), /* 0xd3 */ \
HANDLE_OPCODE (EXT_OP_LOOP), /* 0xd4 */ \
HANDLE_OPCODE (EXT_OP_IF), /* 0xd5 */ \
}; \
do { \
_name[WASM_OP_MISC_PREFIX] = \
HANDLE_OPCODE (WASM_OP_MISC_PREFIX); /* 0xfc */ \
DEF_ATOMIC_PREFIX_HANDLE(_name) \
_name[WASM_OP_ATOMIC_PREFIX] = \
HANDLE_OPCODE (WASM_OP_ATOMIC_PREFIX); /* 0xfe */ \
} while (0)
#endif /* end of _WASM_OPCODE_H */

View File

@ -499,9 +499,12 @@ tables_instantiate(const WASMModule *module,
else
#endif
{
/* it is a built-in table */
total_size = offsetof(WASMTableInstance, base_addr)
+ sizeof(uint32) * (uint64)import->u.table.init_size;
/* it is a built-in table, every module has its own */
total_size = offsetof(WASMTableInstance, base_addr);
total_size +=
import->u.table.possible_grow
? sizeof(uint32) * (uint64)import->u.table.max_size
: sizeof(uint32) * (uint64)import->u.table.init_size;
}
if (!(table = tables[table_index++] = runtime_malloc
@ -530,8 +533,15 @@ tables_instantiate(const WASMModule *module,
/* instantiate tables from table section */
for (i = 0; i < module->table_count; i++) {
total_size = offsetof(WASMTableInstance, base_addr) +
sizeof(uint32) * (uint64)module->tables[i].init_size;
total_size = offsetof(WASMTableInstance, base_addr);
#if WASM_ENABLE_MULTI_MODULE != 0
/* in case, a module which imports this table will grow it */
total_size += sizeof(uint32) * (uint64)module->tables[i].max_size;
#else
total_size += module->tables[i].possible_grow
? sizeof(uint32) * (uint64)module->tables[i].max_size
: sizeof(uint32) * (uint64)module->tables[i].init_size;
#endif
if (!(table = tables[table_index++] = runtime_malloc
(total_size, error_buf, error_buf_size))) {
tables_deinstantiate(tables, table_count);
@ -764,6 +774,11 @@ globals_instantiate(const WASMModule *module,
&(globals[init_expr->u.global_index].initial_value),
sizeof(globals[init_expr->u.global_index].initial_value));
}
#if WASM_ENABLE_REF_TYPES != 0
else if (init_expr->init_expr_type == INIT_EXPR_TYPE_REFNULL_CONST) {
global->initial_value.u32 = (uint32)NULL_REF;
}
#endif
else {
bh_memcpy_s(&(global->initial_value), sizeof(WASMValue),
&(init_expr->u), sizeof(init_expr->u));
@ -1216,6 +1231,10 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
switch (global->type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
#if WASM_ENABLE_REF_TYPES != 0
case VALUE_TYPE_FUNCREF:
case VALUE_TYPE_EXTERNREF:
#endif
*(int32*)global_data = global->initial_value.i32;
global_data += sizeof(int32);
break;
@ -1285,13 +1304,18 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
.initial_value.i32;
}
/* check offset since length might negative */
/* check offset */
base_offset = (uint32)data_seg->base_offset.u.i32;
if (base_offset > memory_size) {
LOG_DEBUG("base_offset(%d) > memory_size(%d)", base_offset,
memory_size);
#if WASM_ENABLE_REF_TYPES != 0
set_error_buf(error_buf, error_buf_size,
"out of bounds memory access");
#else
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
#endif
goto fail;
}
@ -1300,8 +1324,13 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if (base_offset + length > memory_size) {
LOG_DEBUG("base_offset(%d) + length(%d) > memory_size(%d)",
base_offset, length, memory_size);
#if WASM_ENABLE_REF_TYPES != 0
set_error_buf(error_buf, error_buf_size,
"out of bounds memory access");
#else
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
#endif
goto fail;
}
@ -1314,12 +1343,23 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
/* Initialize the table data with table segment section */
module_inst->default_table =
module_inst->table_count ? module_inst->tables[0] : NULL;
for (i = 0; i < module->table_seg_count; i++) {
/* in case there is no table */
for (i = 0; module_inst->table_count > 0 && i < module->table_seg_count;
i++) {
WASMTableSeg *table_seg = module->table_segments + i;
/* has check it in loader */
WASMTableInstance *table = module_inst->tables[table_seg->table_index];
bh_assert(table);
#if WASM_ENABLE_REF_TYPES != 0
if (table->elem_type != VALUE_TYPE_FUNCREF
&& table->elem_type != VALUE_TYPE_EXTERNREF) {
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
goto fail;
}
#endif
uint32 *table_data = (uint32 *)table->base_addr;
#if WASM_ENABLE_MULTI_MODULE != 0
table_data = table->table_inst_linked
@ -1328,11 +1368,20 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
#endif
bh_assert(table_data);
/* init vec(funcidx) */
bh_assert(table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
|| table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL);
#if WASM_ENABLE_REF_TYPES != 0
if (!wasm_elem_is_active(table_seg->mode))
continue;
#endif
/* init vec(funcidx) or vec(expr) */
bh_assert(
table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|| table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
#if WASM_ENABLE_REF_TYPES != 0
|| table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST
|| table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_REFNULL_CONST
#endif
);
if (table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL) {
@ -1349,6 +1398,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
"elements segment does not fit");
goto fail;
}
table_seg->base_offset.u.i32 =
globals[table_seg->base_offset.u.global_index].initial_value.i32;
}
@ -1357,8 +1407,13 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if ((uint32)table_seg->base_offset.u.i32 > table->cur_size) {
LOG_DEBUG("base_offset(%d) > table->cur_size(%d)",
table_seg->base_offset.u.i32, table->cur_size);
#if WASM_ENABLE_REF_TYPES != 0
set_error_buf(error_buf, error_buf_size,
"out of bounds table access");
#else
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
#endif
goto fail;
}
@ -1367,8 +1422,13 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
if ((uint32)table_seg->base_offset.u.i32 + length > table->cur_size) {
LOG_DEBUG("base_offset(%d) + length(%d)> table->cur_size(%d)",
table_seg->base_offset.u.i32, length, table->cur_size);
#if WASM_ENABLE_REF_TYPES != 0
set_error_buf(error_buf, error_buf_size,
"out of bounds table access");
#else
set_error_buf(error_buf, error_buf_size,
"elements segment does not fit");
#endif
goto fail;
}
@ -1510,6 +1570,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
if (module_inst->global_data)
wasm_runtime_free(module_inst->global_data);
#if WASM_ENABLE_REF_TYPES != 0
wasm_externref_cleanup((WASMModuleInstanceCommon*)module_inst);
#endif
wasm_runtime_free(module_inst);
}
@ -1616,8 +1680,16 @@ wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
}
#endif
#if WASM_ENABLE_REF_TYPES != 0
wasm_runtime_prepare_call_function(exec_env, func);
#endif
ret = wasm_call_function(exec_env, func, argc, argv);
#if WASM_ENABLE_REF_TYPES != 0
wasm_runtime_finalize_call_function(exec_env, func, ret, argv);
#endif
#if WASM_ENABLE_THREAD_MGR != 0
/* don't destroy the exec_env if it's searched from the cluster */
if (!existing_exec_env)
@ -2025,8 +2097,47 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
return true;
}
#if WASM_ENABLE_REF_TYPES != 0
bool
wasm_enlarge_table(WASMModuleInstance *module_inst,
uint32 table_idx, uint32 inc_entries, uint32 init_val)
{
uint32 entry_count, *new_table_data_start, i;
WASMTableInstance *table_inst;
if (!inc_entries) {
return true;
}
bh_assert(table_idx < module_inst->table_count);
table_inst = wasm_get_table_inst(module_inst, table_idx);
if (!table_inst) {
return false;
}
entry_count = table_inst->cur_size + inc_entries;
/* prevent from integer overflow */
if (entry_count < table_inst->cur_size
|| entry_count > table_inst->max_size) {
return false;
}
/* fill in */
new_table_data_start =
(uint32 *)((uint8 *)table_inst + offsetof(WASMTableInstance, base_addr))
+ table_inst->cur_size;
for (i = 0; i < inc_entries; ++i) {
new_table_data_start[i] = init_val;
}
table_inst->cur_size = entry_count;
return true;
}
#endif /* WASM_ENABLE_REF_TYPES != 0 */
bool
wasm_call_indirect(WASMExecEnv *exec_env,
uint32_t tbl_idx,
uint32_t element_indices,
uint32_t argc, uint32_t argv[])
{
@ -2039,7 +2150,7 @@ wasm_call_indirect(WASMExecEnv *exec_env,
(WASMModuleInstance*)exec_env->module_inst;
bh_assert(module_inst);
table_inst = module_inst->default_table;
table_inst = module_inst->tables[tbl_idx];
if (!table_inst) {
wasm_set_exception(module_inst, "unknown table");
goto got_exception;
@ -2055,7 +2166,7 @@ wasm_call_indirect(WASMExecEnv *exec_env,
* to another module's table
**/
function_indices = ((uint32_t*)table_inst->base_addr)[element_indices];
if (function_indices == 0xFFFFFFFF) {
if (function_indices == NULL_REF) {
wasm_set_exception(module_inst, "uninitialized element");
goto got_exception;
}
@ -2247,8 +2358,16 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst,
* module_inst->table_count;
for (i = 0; i < module_inst->table_count; i++) {
WASMTableInstance *table = module_inst->tables[i];
size = offsetof(WASMTableInstance, base_addr)
+ sizeof(uint32) * table->cur_size;
#if WASM_ENABLE_MULTI_MODULE != 0
if (table->table_inst_linked) {
size = offsetof(WASMTableInstance, base_addr);
}
else
#endif
{
size = offsetof(WASMTableInstance, base_addr)
+ sizeof(uint32) * table->cur_size;
}
mem_conspn->tables_size += size;
}

View File

@ -60,7 +60,7 @@ struct WASMMemoryInstance {
};
struct WASMTableInstance {
/* The element type, TABLE_ELEM_TYPE_ANY_FUNC currently */
/* The element type, VALUE_TYPE_FUNCREF/EXTERNREF currently */
uint8 elem_type;
/* Current size */
uint32 cur_size;
@ -376,6 +376,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count);
bool
wasm_call_indirect(WASMExecEnv *exec_env,
uint32_t tbl_idx,
uint32_t element_indices,
uint32_t argc, uint32_t argv[]);
@ -397,6 +398,45 @@ void
wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module,
WASMModuleInstMemConsumption *mem_conspn);
#if WASM_ENABLE_REF_TYPES != 0
static inline bool
wasm_elem_is_active(uint32 mode)
{
return (mode & 0x1) == 0x0;
}
static inline bool
wasm_elem_is_passive(uint32 mode)
{
return (mode & 0x1) == 0x1;
}
static inline bool
wasm_elem_is_declarative(uint32 mode)
{
return (mode & 0x3) == 0x3;
}
bool
wasm_enlarge_table(WASMModuleInstance *module_inst,
uint32 table_idx, uint32 inc_entries, uint32 init_val);
#endif /* WASM_ENABLE_REF_TYPES != 0 */
static inline WASMTableInstance *
wasm_get_table_inst(const WASMModuleInstance *module_inst,
const uint32 tbl_idx)
{
/* careful, it might be a table in another module */
WASMTableInstance *tbl_inst = module_inst->tables[tbl_idx];
#if WASM_ENABLE_MULTI_MODULE != 0
if (tbl_inst->table_inst_linked) {
tbl_inst = tbl_inst->table_inst_linked;
}
#endif
bh_assert(tbl_inst);
return tbl_inst;
}
#if WASM_ENABLE_DUMP_CALL_STACK != 0
void
wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env);