Refine read leb int wasm loader of fast interpreter (#4017)
This commit is contained in:
@ -6048,6 +6048,86 @@ fail:
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
|
||||
#define pb_read_leb_uint32 read_leb_uint32
|
||||
#define pb_read_leb_int32 read_leb_int32
|
||||
#define pb_read_leb_int64 read_leb_int64
|
||||
#define pb_read_leb_memarg read_leb_memarg
|
||||
#define pb_read_leb_mem_offset read_leb_mem_offset
|
||||
#define pb_read_leb_memidx read_leb_memidx
|
||||
|
||||
#else
|
||||
|
||||
/* Read leb without malformed format check */
|
||||
static uint64
|
||||
read_leb_quick(uint8 **p_buf, uint32 maxbits, bool sign)
|
||||
{
|
||||
uint8 *buf = *p_buf;
|
||||
uint64 result = 0, byte = 0;
|
||||
uint32 shift = 0;
|
||||
|
||||
do {
|
||||
byte = *buf++;
|
||||
result |= ((byte & 0x7f) << shift);
|
||||
shift += 7;
|
||||
} while (byte & 0x80);
|
||||
|
||||
if (sign && (shift < maxbits) && (byte & 0x40)) {
|
||||
/* Sign extend */
|
||||
result |= (~((uint64)0)) << shift;
|
||||
}
|
||||
|
||||
*p_buf = buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
#define pb_read_leb_uint32(p, p_end, res) \
|
||||
do { \
|
||||
if (!loader_ctx->p_code_compiled) \
|
||||
/* Enable format check in the first scan */ \
|
||||
read_leb_uint32(p, p_end, res); \
|
||||
else \
|
||||
/* Disable format check in the second scan */ \
|
||||
res = (uint32)read_leb_quick(&p, 32, false); \
|
||||
} while (0)
|
||||
|
||||
#define pb_read_leb_int32(p, p_end, res) \
|
||||
do { \
|
||||
if (!loader_ctx->p_code_compiled) \
|
||||
/* Enable format check in the first scan */ \
|
||||
read_leb_int32(p, p_end, res); \
|
||||
else \
|
||||
/* Disable format check in the second scan */ \
|
||||
res = (int32)read_leb_quick(&p, 32, true); \
|
||||
} while (0)
|
||||
|
||||
#define pb_read_leb_int64(p, p_end, res) \
|
||||
do { \
|
||||
if (!loader_ctx->p_code_compiled) \
|
||||
/* Enable format check in the first scan */ \
|
||||
read_leb_int64(p, p_end, res); \
|
||||
else \
|
||||
/* Disable format check in the second scan */ \
|
||||
res = (int64)read_leb_quick(&p, 64, true); \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
#define pb_read_leb_memarg read_leb_memarg
|
||||
#else
|
||||
#define pb_read_leb_memarg pb_read_leb_uint32
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
#define pb_read_leb_mem_offset read_leb_mem_offset
|
||||
#else
|
||||
#define pb_read_leb_mem_offset pb_read_leb_uint32
|
||||
#endif
|
||||
|
||||
#define pb_read_leb_memidx pb_read_leb_uint32
|
||||
|
||||
#endif /* end of WASM_ENABLE_FAST_INTERP != 0 */
|
||||
|
||||
static bool
|
||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
uint32 cur_func_idx, char *error_buf,
|
||||
@ -6195,7 +6275,7 @@ re_scan:
|
||||
int32 type_index;
|
||||
/* Resolve the leb128 encoded type index as block type */
|
||||
p--;
|
||||
read_leb_int32(p, p_end, type_index);
|
||||
pb_read_leb_int32(p, p_end, type_index);
|
||||
bh_assert((uint32)type_index < module->type_count);
|
||||
block_type.is_value_type = false;
|
||||
block_type.u.type = module->types[type_index];
|
||||
@ -6508,7 +6588,7 @@ re_scan:
|
||||
uint32 j;
|
||||
#endif
|
||||
|
||||
read_leb_uint32(p, p_end, count);
|
||||
pb_read_leb_uint32(p, p_end, count);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, count);
|
||||
#endif
|
||||
@ -6517,7 +6597,7 @@ re_scan:
|
||||
/* Get each depth and check it */
|
||||
p_org = p;
|
||||
for (i = 0; i <= count; i++) {
|
||||
read_leb_uint32(p, p_end, depth);
|
||||
pb_read_leb_uint32(p, p_end, depth);
|
||||
bh_assert(loader_ctx->csp_num > 0);
|
||||
bh_assert(loader_ctx->csp_num - 1 >= depth);
|
||||
(void)depth;
|
||||
@ -6615,7 +6695,7 @@ re_scan:
|
||||
uint32 func_idx;
|
||||
int32 idx;
|
||||
|
||||
read_leb_uint32(p, p_end, func_idx);
|
||||
pb_read_leb_uint32(p, p_end, func_idx);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
/* we need to emit func_idx before arguments */
|
||||
emit_uint32(loader_ctx, func_idx);
|
||||
@ -6688,10 +6768,10 @@ re_scan:
|
||||
|
||||
bh_assert(module->import_table_count + module->table_count > 0);
|
||||
|
||||
read_leb_uint32(p, p_end, type_idx);
|
||||
pb_read_leb_uint32(p, p_end, type_idx);
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
read_leb_uint32(p, p_end, table_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_idx);
|
||||
#else
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
table_idx = read_uint8(p);
|
||||
@ -6931,7 +7011,7 @@ re_scan:
|
||||
uint8 *p_code_compiled_tmp = loader_ctx->p_code_compiled;
|
||||
#endif
|
||||
|
||||
read_leb_uint32(p, p_end, vec_len);
|
||||
pb_read_leb_uint32(p, p_end, vec_len);
|
||||
if (vec_len != 1) {
|
||||
/* typed select must have exactly one result */
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
@ -7006,7 +7086,7 @@ re_scan:
|
||||
uint8 decl_ref_type;
|
||||
uint32 table_idx;
|
||||
|
||||
read_leb_uint32(p, p_end, table_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_idx);
|
||||
if (!get_table_elem_type(module, table_idx, &decl_ref_type,
|
||||
error_buf, error_buf_size))
|
||||
goto fail;
|
||||
@ -7100,7 +7180,7 @@ re_scan:
|
||||
case WASM_OP_REF_FUNC:
|
||||
{
|
||||
uint32 func_idx = 0;
|
||||
read_leb_uint32(p, p_end, func_idx);
|
||||
pb_read_leb_uint32(p, p_end, func_idx);
|
||||
|
||||
if (!check_function_index(module, func_idx, error_buf,
|
||||
error_buf_size)) {
|
||||
@ -7317,7 +7397,7 @@ re_scan:
|
||||
case WASM_OP_GET_GLOBAL:
|
||||
{
|
||||
p_org = p - 1;
|
||||
read_leb_uint32(p, p_end, global_idx);
|
||||
pb_read_leb_uint32(p, p_end, global_idx);
|
||||
bh_assert(global_idx < global_count);
|
||||
|
||||
global_type = global_idx < module->import_global_count
|
||||
@ -7351,7 +7431,7 @@ re_scan:
|
||||
bool is_mutable = false;
|
||||
|
||||
p_org = p - 1;
|
||||
read_leb_uint32(p, p_end, global_idx);
|
||||
pb_read_leb_uint32(p, p_end, global_idx);
|
||||
bh_assert(global_idx < global_count);
|
||||
|
||||
is_mutable = global_idx < module->import_global_count
|
||||
@ -7448,8 +7528,8 @@ re_scan:
|
||||
}
|
||||
#endif
|
||||
CHECK_MEMORY();
|
||||
read_leb_memarg(p, p_end, align); /* align */
|
||||
read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
pb_read_leb_memarg(p, p_end, align); /* align */
|
||||
pb_read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, mem_offset);
|
||||
#endif
|
||||
@ -7510,7 +7590,7 @@ re_scan:
|
||||
|
||||
case WASM_OP_MEMORY_SIZE:
|
||||
CHECK_MEMORY();
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
pb_read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
PUSH_PAGE_COUNT();
|
||||
|
||||
@ -7522,7 +7602,7 @@ re_scan:
|
||||
|
||||
case WASM_OP_MEMORY_GROW:
|
||||
CHECK_MEMORY();
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
pb_read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
POP_AND_PUSH(mem_offset_type, mem_offset_type);
|
||||
|
||||
@ -7537,7 +7617,7 @@ re_scan:
|
||||
break;
|
||||
|
||||
case WASM_OP_I32_CONST:
|
||||
read_leb_int32(p, p_end, i32_const);
|
||||
pb_read_leb_int32(p, p_end, i32_const);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
skip_label();
|
||||
disable_emit = true;
|
||||
@ -7555,7 +7635,7 @@ re_scan:
|
||||
break;
|
||||
|
||||
case WASM_OP_I64_CONST:
|
||||
read_leb_int64(p, p_end, i64_const);
|
||||
pb_read_leb_int64(p, p_end, i64_const);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
skip_label();
|
||||
disable_emit = true;
|
||||
@ -7837,7 +7917,7 @@ re_scan:
|
||||
{
|
||||
uint32 opcode1;
|
||||
|
||||
read_leb_uint32(p, p_end, opcode1);
|
||||
pb_read_leb_uint32(p, p_end, opcode1);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_byte(loader_ctx, ((uint8)opcode1));
|
||||
#endif
|
||||
@ -7862,11 +7942,11 @@ re_scan:
|
||||
case WASM_OP_MEMORY_INIT:
|
||||
{
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, segment_index);
|
||||
pb_read_leb_uint32(p, p_end, segment_index);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, segment_index);
|
||||
#endif
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
pb_read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
|
||||
bh_assert(segment_index < module->data_seg_count);
|
||||
@ -7882,7 +7962,7 @@ re_scan:
|
||||
}
|
||||
case WASM_OP_DATA_DROP:
|
||||
{
|
||||
read_leb_uint32(p, p_end, segment_index);
|
||||
pb_read_leb_uint32(p, p_end, segment_index);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, segment_index);
|
||||
#endif
|
||||
@ -7898,9 +7978,9 @@ re_scan:
|
||||
CHECK_MEMORY();
|
||||
CHECK_BUF(p, p_end, sizeof(int16));
|
||||
/* check both src and dst memory index */
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
pb_read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
pb_read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
|
||||
POP_MEM_OFFSET();
|
||||
@ -7914,7 +7994,7 @@ re_scan:
|
||||
case WASM_OP_MEMORY_FILL:
|
||||
{
|
||||
CHECK_MEMORY();
|
||||
read_leb_memidx(p, p_end, memidx);
|
||||
pb_read_leb_memidx(p, p_end, memidx);
|
||||
check_memidx(module, memidx);
|
||||
|
||||
POP_MEM_OFFSET();
|
||||
@ -7932,8 +8012,8 @@ re_scan:
|
||||
uint8 seg_ref_type, tbl_ref_type;
|
||||
uint32 table_seg_idx, table_idx;
|
||||
|
||||
read_leb_uint32(p, p_end, table_seg_idx);
|
||||
read_leb_uint32(p, p_end, table_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_seg_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_idx);
|
||||
|
||||
if (!get_table_elem_type(module, table_idx,
|
||||
&tbl_ref_type, error_buf,
|
||||
@ -7968,7 +8048,7 @@ re_scan:
|
||||
case WASM_OP_ELEM_DROP:
|
||||
{
|
||||
uint32 table_seg_idx;
|
||||
read_leb_uint32(p, p_end, table_seg_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_seg_idx);
|
||||
if (!get_table_seg_elem_type(module, table_seg_idx,
|
||||
NULL, error_buf,
|
||||
error_buf_size))
|
||||
@ -7984,13 +8064,13 @@ re_scan:
|
||||
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);
|
||||
pb_read_leb_uint32(p, p_end, src_tbl_idx);
|
||||
if (!get_table_elem_type(module, src_tbl_idx,
|
||||
&src_ref_type, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
|
||||
read_leb_uint32(p, p_end, dst_tbl_idx);
|
||||
pb_read_leb_uint32(p, p_end, dst_tbl_idx);
|
||||
if (!get_table_elem_type(module, dst_tbl_idx,
|
||||
&dst_ref_type, error_buf,
|
||||
error_buf_size))
|
||||
@ -8037,7 +8117,7 @@ re_scan:
|
||||
{
|
||||
uint32 table_idx;
|
||||
|
||||
read_leb_uint32(p, p_end, table_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_idx);
|
||||
/* TODO: shall we create a new function to check
|
||||
table idx instead of using below function? */
|
||||
if (!get_table_elem_type(module, table_idx, NULL,
|
||||
@ -8062,7 +8142,7 @@ re_scan:
|
||||
uint8 decl_ref_type;
|
||||
uint32 table_idx;
|
||||
|
||||
read_leb_uint32(p, p_end, table_idx);
|
||||
pb_read_leb_uint32(p, p_end, table_idx);
|
||||
if (!get_table_elem_type(module, table_idx,
|
||||
&decl_ref_type, error_buf,
|
||||
error_buf_size))
|
||||
@ -8114,15 +8194,15 @@ re_scan:
|
||||
{
|
||||
uint32 opcode1;
|
||||
|
||||
read_leb_uint32(p, p_end, opcode1);
|
||||
pb_read_leb_uint32(p, p_end, opcode1);
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_byte(loader_ctx, opcode1);
|
||||
#endif
|
||||
if (opcode1 != WASM_OP_ATOMIC_FENCE) {
|
||||
CHECK_MEMORY();
|
||||
read_leb_uint32(p, p_end, align); /* align */
|
||||
read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
pb_read_leb_uint32(p, p_end, align); /* align */
|
||||
pb_read_leb_mem_offset(p, p_end, mem_offset); /* offset */
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
emit_uint32(loader_ctx, mem_offset);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user