|
|
@@ -131,7 +131,7 @@ read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
|
|
|
}
|
|
|
else if (sign && maxbits == 32) {
|
|
|
if (shift < maxbits) {
|
|
|
- /* Sign extend, second highest bit is the sign bit */
|
|
|
+ /* Sign extend, second-highest bit is the sign bit */
|
|
|
if ((uint8)byte & 0x40)
|
|
|
result |= (~((uint64)0)) << shift;
|
|
|
}
|
|
|
@@ -146,7 +146,7 @@ read_leb(uint8 **p_buf, const uint8 *buf_end, uint32 maxbits, bool sign,
|
|
|
}
|
|
|
else if (sign && maxbits == 64) {
|
|
|
if (shift < maxbits) {
|
|
|
- /* Sign extend, second highest bit is the sign bit */
|
|
|
+ /* Sign extend, second-highest bit is the sign bit */
|
|
|
if ((uint8)byte & 0x40)
|
|
|
result |= (~((uint64)0)) << shift;
|
|
|
}
|
|
|
@@ -219,7 +219,10 @@ type2str(uint8 type)
|
|
|
static bool
|
|
|
is_32bit_type(uint8 type)
|
|
|
{
|
|
|
- if (type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
|
|
|
+ if (type == VALUE_TYPE_I32
|
|
|
+ || type == VALUE_TYPE_F32
|
|
|
+ /* the operand stack is in polymorphic state */
|
|
|
+ || type == VALUE_TYPE_ANY
|
|
|
#if WASM_ENABLE_REF_TYPES != 0
|
|
|
|| type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
|
|
|
#endif
|
|
|
@@ -5631,7 +5634,7 @@ wasm_loader_push_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
|
|
|
|
|
|
*ctx->frame_ref++ = type;
|
|
|
ctx->stack_cell_num++;
|
|
|
- if (is_32bit_type(type) || type == VALUE_TYPE_ANY)
|
|
|
+ if (is_32bit_type(type))
|
|
|
goto check_stack_and_return;
|
|
|
|
|
|
if (!check_stack_push(ctx, error_buf, error_buf_size))
|
|
|
@@ -7266,7 +7269,7 @@ check_branch_block_for_delegate(WASMLoaderContext *loader_ctx, uint8 **p_buf,
|
|
|
}
|
|
|
frame_csp_tmp = loader_ctx->frame_csp - depth - 2;
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
- emit_br_info(frame_csp_tmp);
|
|
|
+ emit_br_info(frame_csp_tmp, false);
|
|
|
#endif
|
|
|
|
|
|
*p_buf = p;
|
|
|
@@ -8095,8 +8098,10 @@ re_scan:
|
|
|
BlockType block_type;
|
|
|
|
|
|
if (loader_ctx->csp_num < 2
|
|
|
- || (loader_ctx->frame_csp - 1)->label_type
|
|
|
- != LABEL_TYPE_IF) {
|
|
|
+ /* the matched if isn't found */
|
|
|
+ || (loader_ctx->frame_csp - 1)->label_type != LABEL_TYPE_IF
|
|
|
+ /* duplicated else is found */
|
|
|
+ || (loader_ctx->frame_csp - 1)->else_addr) {
|
|
|
set_error_buf(
|
|
|
error_buf, error_buf_size,
|
|
|
"opcode else found without matched opcode if");
|
|
|
@@ -8137,8 +8142,8 @@ re_scan:
|
|
|
bh_memcpy_s(loader_ctx->frame_offset, size,
|
|
|
block->param_frame_offsets, size);
|
|
|
loader_ctx->frame_offset += (size / sizeof(int16));
|
|
|
- loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
|
|
}
|
|
|
+ loader_ctx->dynamic_offset = block->start_dynamic_offset;
|
|
|
#endif
|
|
|
|
|
|
break;
|
|
|
@@ -8247,13 +8252,11 @@ re_scan:
|
|
|
case WASM_OP_BR_TABLE:
|
|
|
{
|
|
|
uint8 *ret_types = NULL;
|
|
|
- uint32 ret_count = 0;
|
|
|
+ uint32 ret_count = 0, depth = 0;
|
|
|
#if WASM_ENABLE_FAST_INTERP == 0
|
|
|
- uint8 *p_depth_begin, *p_depth;
|
|
|
- uint32 depth = 0, j;
|
|
|
BrTableCache *br_table_cache = NULL;
|
|
|
-
|
|
|
- p_org = p - 1;
|
|
|
+ uint8 *p_depth_begin, *p_depth, *p_opcode = p - 1;
|
|
|
+ uint32 j;
|
|
|
#endif
|
|
|
|
|
|
read_leb_uint32(p, p_end, count);
|
|
|
@@ -8262,6 +8265,20 @@ re_scan:
|
|
|
#endif
|
|
|
POP_I32();
|
|
|
|
|
|
+ /* Get each depth and check it */
|
|
|
+ p_org = p;
|
|
|
+ for (i = 0; i <= count; i++) {
|
|
|
+ read_leb_uint32(p, p_end, depth);
|
|
|
+ bh_assert(loader_ctx->csp_num > 0);
|
|
|
+ if (loader_ctx->csp_num - 1 < depth) {
|
|
|
+ set_error_buf(error_buf, error_buf_size,
|
|
|
+ "unknown label, "
|
|
|
+ "unexpected end of section or function");
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ p = p_org;
|
|
|
+
|
|
|
#if WASM_ENABLE_FAST_INTERP == 0
|
|
|
p_depth_begin = p_depth = p;
|
|
|
#endif
|
|
|
@@ -8315,7 +8332,7 @@ re_scan:
|
|
|
/* The depth cannot be stored in one byte,
|
|
|
create br_table cache to store each depth */
|
|
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
|
|
- if (!record_fast_op(module, p_org, *p_org,
|
|
|
+ if (!record_fast_op(module, p_opcode, *p_opcode,
|
|
|
error_buf, error_buf_size)) {
|
|
|
goto fail;
|
|
|
}
|
|
|
@@ -8327,8 +8344,8 @@ re_scan:
|
|
|
error_buf, error_buf_size))) {
|
|
|
goto fail;
|
|
|
}
|
|
|
- *p_org = EXT_OP_BR_TABLE_CACHE;
|
|
|
- br_table_cache->br_table_op_addr = p_org;
|
|
|
+ *p_opcode = EXT_OP_BR_TABLE_CACHE;
|
|
|
+ br_table_cache->br_table_op_addr = p_opcode;
|
|
|
br_table_cache->br_count = count;
|
|
|
/* Copy previous depths which are one byte */
|
|
|
for (j = 0; j < i; j++) {
|
|
|
@@ -8583,8 +8600,7 @@ re_scan:
|
|
|
}
|
|
|
|
|
|
if (available_stack_cell > 0) {
|
|
|
- if (is_32bit_type(*(loader_ctx->frame_ref - 1))
|
|
|
- || *(loader_ctx->frame_ref - 1) == VALUE_TYPE_ANY) {
|
|
|
+ if (is_32bit_type(*(loader_ctx->frame_ref - 1))) {
|
|
|
loader_ctx->frame_ref--;
|
|
|
loader_ctx->stack_cell_num--;
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
@@ -8924,25 +8940,44 @@ re_scan:
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
|
- /* Refer to a forward-declared function */
|
|
|
- if (func_idx >= cur_func_idx + module->import_function_count) {
|
|
|
+ /* Refer to a forward-declared function:
|
|
|
+ the function must be an import, exported, or present in
|
|
|
+ a table elem segment or global initializer to be used as
|
|
|
+ the operand to ref.func */
|
|
|
+ if (func_idx >= module->import_function_count) {
|
|
|
WASMTableSeg *table_seg = module->table_segments;
|
|
|
bool func_declared = false;
|
|
|
uint32 j;
|
|
|
|
|
|
- /* Check whether the function is declared in table segs,
|
|
|
- note that it doesn't matter whether the table seg's mode
|
|
|
- is passive, active or declarative. */
|
|
|
- for (i = 0; i < module->table_seg_count; i++, table_seg++) {
|
|
|
- if (table_seg->elem_type == VALUE_TYPE_FUNCREF) {
|
|
|
- for (j = 0; j < table_seg->function_count; j++) {
|
|
|
- if (table_seg->func_indexes[j] == func_idx) {
|
|
|
- func_declared = true;
|
|
|
- break;
|
|
|
+ for (i = 0; i < module->global_count; i++) {
|
|
|
+ if (module->globals[i].type == VALUE_TYPE_FUNCREF
|
|
|
+ && module->globals[i].init_expr.init_expr_type
|
|
|
+ == INIT_EXPR_TYPE_FUNCREF_CONST
|
|
|
+ && module->globals[i].init_expr.u.u32 == func_idx) {
|
|
|
+ func_declared = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!func_declared) {
|
|
|
+ /* Check whether the function is declared in table segs,
|
|
|
+ note that it doesn't matter whether the table seg's
|
|
|
+ mode is passive, active or declarative. */
|
|
|
+ for (i = 0; i < module->table_seg_count;
|
|
|
+ i++, table_seg++) {
|
|
|
+ if (table_seg->elem_type == VALUE_TYPE_FUNCREF) {
|
|
|
+ for (j = 0; j < table_seg->function_count;
|
|
|
+ j++) {
|
|
|
+ if (table_seg->func_indexes[j]
|
|
|
+ == func_idx) {
|
|
|
+ func_declared = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
if (!func_declared) {
|
|
|
/* Check whether the function is exported */
|
|
|
for (i = 0; i < module->export_count; i++) {
|
|
|
@@ -9424,6 +9459,7 @@ re_scan:
|
|
|
break;
|
|
|
|
|
|
case WASM_OP_F32_CONST:
|
|
|
+ CHECK_BUF(p, p_end, sizeof(float32));
|
|
|
p += sizeof(float32);
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
skip_label();
|
|
|
@@ -9442,6 +9478,7 @@ re_scan:
|
|
|
break;
|
|
|
|
|
|
case WASM_OP_F64_CONST:
|
|
|
+ CHECK_BUF(p, p_end, sizeof(float64));
|
|
|
p += sizeof(float64);
|
|
|
#if WASM_ENABLE_FAST_INTERP != 0
|
|
|
skip_label();
|
|
|
@@ -9763,6 +9800,7 @@ re_scan:
|
|
|
}
|
|
|
case WASM_OP_MEMORY_COPY:
|
|
|
{
|
|
|
+ CHECK_BUF(p, p_end, sizeof(int16));
|
|
|
/* both src and dst memory index should be 0 */
|
|
|
if (*(int16 *)p != 0x0000)
|
|
|
goto fail_zero_byte_expected;
|
|
|
@@ -10448,13 +10486,6 @@ re_scan:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- case SIMD_i32x4_narrow_i64x2_s:
|
|
|
- case SIMD_i32x4_narrow_i64x2_u:
|
|
|
- {
|
|
|
- POP2_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
case SIMD_i32x4_extend_low_i16x8_s:
|
|
|
case SIMD_i32x4_extend_high_i16x8_s:
|
|
|
case SIMD_i32x4_extend_low_i16x8_u:
|
|
|
@@ -10481,7 +10512,6 @@ re_scan:
|
|
|
case SIMD_i32x4_max_s:
|
|
|
case SIMD_i32x4_max_u:
|
|
|
case SIMD_i32x4_dot_i16x8_s:
|
|
|
- case SIMD_i32x4_avgr_u:
|
|
|
case SIMD_i32x4_extmul_low_i16x8_s:
|
|
|
case SIMD_i32x4_extmul_high_i16x8_s:
|
|
|
case SIMD_i32x4_extmul_low_i16x8_u:
|
|
|
@@ -10545,7 +10575,6 @@ re_scan:
|
|
|
/* f32x4 operation */
|
|
|
case SIMD_f32x4_abs:
|
|
|
case SIMD_f32x4_neg:
|
|
|
- case SIMD_f32x4_round:
|
|
|
case SIMD_f32x4_sqrt:
|
|
|
{
|
|
|
POP_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|
|
|
@@ -10568,7 +10597,6 @@ re_scan:
|
|
|
/* f64x2 operation */
|
|
|
case SIMD_f64x2_abs:
|
|
|
case SIMD_f64x2_neg:
|
|
|
- case SIMD_f64x2_round:
|
|
|
case SIMD_f64x2_sqrt:
|
|
|
{
|
|
|
POP_AND_PUSH(VALUE_TYPE_V128, VALUE_TYPE_V128);
|