mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
Fix loader parse block type and calculate dynamic offset for loop args (#3482)
Fix several issues in wasm loader: - Parse a block's type index with leb int32 instead leb uint32 - Correct dst dynamic offset of loop block arguments for opcode br when copying the stack operands to the arguments of loop block - Free each frame_csp's param_frame_offsets when destroy loader ctx - Fix compilation error in wasm_mini_loader.c - Add test cases of failed issues This PR fixes issue #3467 and #3468.
This commit is contained in:
parent
67638e24f4
commit
23e1d51587
|
@ -1028,7 +1028,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
}
|
||||
else {
|
||||
frame_ip--;
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
read_leb_int32(frame_ip, frame_ip_end, type_index);
|
||||
/* type index was checked in wasm loader */
|
||||
bh_assert(type_index < comp_ctx->comp_data->type_count);
|
||||
func_type =
|
||||
(AOTFuncType *)comp_ctx->comp_data->types[type_index];
|
||||
param_count = func_type->param_count;
|
||||
|
@ -1048,7 +1050,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
read_leb_int32(frame_ip, frame_ip_end, type_index);
|
||||
/* type index was checked in wasm loader */
|
||||
bh_assert(type_index < comp_ctx->comp_data->type_count);
|
||||
func_type =
|
||||
(AOTFuncType *)comp_ctx->comp_data->types[type_index];
|
||||
param_count = func_type->param_count;
|
||||
|
|
|
@ -1510,7 +1510,9 @@ jit_compile_func(JitCompContext *cc)
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
{
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
|
||||
read_leb_int32(frame_ip, frame_ip_end, type_idx);
|
||||
/* type index was checked in wasm loader */
|
||||
bh_assert(type_idx < cc->cur_wasm_module->type_count);
|
||||
func_type = cc->cur_wasm_module->types[type_idx];
|
||||
param_count = func_type->param_count;
|
||||
param_types = func_type->types;
|
||||
|
|
|
@ -7086,7 +7086,8 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
}
|
||||
else {
|
||||
p--;
|
||||
skip_leb_uint32(p, p_end);
|
||||
/* block type */
|
||||
skip_leb_int32(p, p_end);
|
||||
}
|
||||
if (block_nested_depth
|
||||
< sizeof(block_stack) / sizeof(BlockAddr)) {
|
||||
|
@ -7101,7 +7102,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
/* block type */
|
||||
skip_leb_uint32(p, p_end);
|
||||
skip_leb_int32(p, p_end);
|
||||
if (block_nested_depth
|
||||
< sizeof(block_stack) / sizeof(BlockAddr)) {
|
||||
block_stack[block_nested_depth].start_addr = p;
|
||||
|
@ -7850,7 +7851,11 @@ typedef struct BranchBlock {
|
|||
BranchBlockPatch *patch_list;
|
||||
/* This is used to save params frame_offset of of if block */
|
||||
int16 *param_frame_offsets;
|
||||
/* This is used to recover dynamic offset for else branch */
|
||||
/* This is used to recover the dynamic offset for else branch,
|
||||
* and also to remember the start offset of dynamic space which
|
||||
* stores the block arguments for loop block, so we can use it
|
||||
* to copy the stack operands to the loop block's arguments in
|
||||
* wasm_loader_emit_br_info for opcode br. */
|
||||
uint16 start_dynamic_offset;
|
||||
#endif
|
||||
|
||||
|
@ -8001,13 +8006,26 @@ static void
|
|||
free_all_label_patch_lists(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (uint32 i = 0; i < csp_num; i++) {
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
free_label_patch_list(tmp_csp);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_all_label_param_frame_offsets(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
if (tmp_csp->param_frame_offsets)
|
||||
wasm_runtime_free(tmp_csp->param_frame_offsets);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_FAST_INTERP */
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
|
@ -8126,6 +8144,8 @@ wasm_loader_ctx_destroy(WASMLoaderContext *ctx)
|
|||
if (ctx->frame_csp_bottom) {
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
free_all_label_patch_lists(ctx->frame_csp_bottom, ctx->csp_num);
|
||||
free_all_label_param_frame_offsets(ctx->frame_csp_bottom,
|
||||
ctx->csp_num);
|
||||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
wasm_loader_clean_all_local_use_masks(ctx);
|
||||
|
@ -9238,8 +9258,14 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
|
|||
emit_operand(ctx, *(int16 *)(frame_offset));
|
||||
}
|
||||
/* Part e */
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (frame_csp->label_type == LABEL_TYPE_LOOP)
|
||||
/* Use start_dynamic_offset which was set in
|
||||
copy_params_to_dynamic_space */
|
||||
dynamic_offset = frame_csp->start_dynamic_offset
|
||||
+ wasm_get_cell_num(types, arity);
|
||||
else
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (is_br)
|
||||
ctx->dynamic_offset = dynamic_offset;
|
||||
for (i = (int32)arity - 1; i >= 0; i--) {
|
||||
|
@ -10623,8 +10649,8 @@ fail:
|
|||
* Part e: each param's dst offset
|
||||
*/
|
||||
static bool
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
bool ret = false;
|
||||
int16 *frame_offset = NULL;
|
||||
|
@ -10638,6 +10664,7 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
uint32 param_count = block_type->u.type->param_count;
|
||||
int16 condition_offset = 0;
|
||||
bool disable_emit = false;
|
||||
bool is_if_block = (block->label_type == LABEL_TYPE_IF ? true : false);
|
||||
int16 operand_offset = 0;
|
||||
|
||||
uint64 size = (uint64)param_count * (sizeof(*cells) + sizeof(*src_offsets));
|
||||
|
@ -10690,6 +10717,14 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
if (is_if_block)
|
||||
emit_operand(loader_ctx, condition_offset);
|
||||
|
||||
/* Since the start offset to save the block's params and
|
||||
* the start offset to save the block's results may be
|
||||
* different, we remember the dynamic offset for loop block
|
||||
* so that we can use it to copy the stack operands to the
|
||||
* loop block's params in wasm_loader_emit_br_info. */
|
||||
if (block->label_type == LABEL_TYPE_LOOP)
|
||||
block->start_dynamic_offset = loader_ctx->dynamic_offset;
|
||||
|
||||
/* Part e) */
|
||||
/* Push to dynamic space. The push will emit the dst offset. */
|
||||
for (i = 0; i < param_count; i++)
|
||||
|
@ -11062,12 +11097,12 @@ re_scan:
|
|||
#endif /* end of WASM_ENABLE_GC != 0 */
|
||||
}
|
||||
else {
|
||||
uint32 type_index;
|
||||
int32 type_index;
|
||||
/* Resolve the leb128 encoded type index as block type */
|
||||
p--;
|
||||
p_org = p - 1;
|
||||
read_leb_uint32(p, p_end, type_index);
|
||||
if (type_index >= module->type_count) {
|
||||
read_leb_int32(p, p_end, type_index);
|
||||
if ((uint32)type_index >= module->type_count) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"unknown type");
|
||||
goto fail;
|
||||
|
@ -11171,8 +11206,8 @@ re_scan:
|
|||
|
||||
if (BLOCK_HAS_PARAM(block_type)) {
|
||||
/* Make sure params are in dynamic space */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, false, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -11218,8 +11253,8 @@ re_scan:
|
|||
/* skip the if label */
|
||||
skip_label();
|
||||
/* Emit a copy instruction */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, true, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Emit the if instruction */
|
||||
|
|
|
@ -3451,7 +3451,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
|||
case EXT_OP_LOOP:
|
||||
case EXT_OP_IF:
|
||||
/* block type */
|
||||
skip_leb_uint32(p, p_end);
|
||||
skip_leb_int32(p, p_end);
|
||||
if (block_nested_depth
|
||||
< sizeof(block_stack) / sizeof(BlockAddr)) {
|
||||
block_stack[block_nested_depth].start_addr = p;
|
||||
|
@ -3921,7 +3921,11 @@ typedef struct BranchBlock {
|
|||
/* This is used to store available param num for if/else branch, so the else
|
||||
* opcode can know how many parameters should be copied to the stack */
|
||||
uint32 available_param_num;
|
||||
/* This is used to recover dynamic offset for else branch */
|
||||
/* This is used to recover the dynamic offset for else branch,
|
||||
* and also to remember the start offset of dynamic space which
|
||||
* stores the block arguments for loop block, so we can use it
|
||||
* to copy the stack operands to the loop block's arguments in
|
||||
* wasm_loader_emit_br_info for opcode br. */
|
||||
uint16 start_dynamic_offset;
|
||||
#endif
|
||||
|
||||
|
@ -4050,13 +4054,26 @@ static void
|
|||
free_all_label_patch_lists(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (uint32 i = 0; i < csp_num; i++) {
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
free_label_patch_list(tmp_csp);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_all_label_param_frame_offsets(BranchBlock *frame_csp, uint32 csp_num)
|
||||
{
|
||||
BranchBlock *tmp_csp = frame_csp;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < csp_num; i++) {
|
||||
if (tmp_csp->param_frame_offsets)
|
||||
wasm_runtime_free(tmp_csp->param_frame_offsets);
|
||||
tmp_csp++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
|
@ -4120,6 +4137,8 @@ wasm_loader_ctx_destroy(WASMLoaderContext *ctx)
|
|||
if (ctx->frame_csp_bottom) {
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
free_all_label_patch_lists(ctx->frame_csp_bottom, ctx->csp_num);
|
||||
free_all_label_param_frame_offsets(ctx->frame_csp_bottom,
|
||||
ctx->csp_num);
|
||||
#endif
|
||||
wasm_runtime_free(ctx->frame_csp_bottom);
|
||||
}
|
||||
|
@ -4798,8 +4817,14 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
|
|||
emit_operand(ctx, *(int16 *)(frame_offset));
|
||||
}
|
||||
/* Part e */
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (frame_csp->label_type == LABEL_TYPE_LOOP)
|
||||
/* Use start_dynamic_offset which was set in
|
||||
copy_params_to_dynamic_space */
|
||||
dynamic_offset = frame_csp->start_dynamic_offset
|
||||
+ wasm_get_cell_num(types, arity);
|
||||
else
|
||||
dynamic_offset =
|
||||
frame_csp->dynamic_offset + wasm_get_cell_num(types, arity);
|
||||
if (is_br)
|
||||
ctx->dynamic_offset = dynamic_offset;
|
||||
for (i = (int32)arity - 1; i >= 0; i--) {
|
||||
|
@ -5778,8 +5803,8 @@ fail:
|
|||
* Part e: each param's dst offset
|
||||
*/
|
||||
static bool
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
bool ret = false;
|
||||
int16 *frame_offset = NULL;
|
||||
|
@ -5793,6 +5818,7 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
uint32 param_count = block_type->u.type->param_count;
|
||||
int16 condition_offset = 0;
|
||||
bool disable_emit = false;
|
||||
bool is_if_block = (block->label_type == LABEL_TYPE_IF ? true : false);
|
||||
int16 operand_offset = 0;
|
||||
|
||||
uint64 size = (uint64)param_count * (sizeof(*cells) + sizeof(*src_offsets));
|
||||
|
@ -5845,6 +5871,14 @@ copy_params_to_dynamic_space(WASMLoaderContext *loader_ctx, bool is_if_block,
|
|||
if (is_if_block)
|
||||
emit_operand(loader_ctx, condition_offset);
|
||||
|
||||
/* Since the start offset to save the block's params and
|
||||
* the start offset to save the block's results may be
|
||||
* different, we remember the dynamic offset for loop block
|
||||
* so that we can use it to copy the stack operands to the
|
||||
* loop block's params in wasm_loader_emit_br_info. */
|
||||
if (block->label_type == LABEL_TYPE_LOOP)
|
||||
block->start_dynamic_offset = loader_ctx->dynamic_offset;
|
||||
|
||||
/* Part e) */
|
||||
/* Push to dynamic space. The push will emit the dst offset. */
|
||||
for (i = 0; i < param_count; i++)
|
||||
|
@ -6043,11 +6077,11 @@ re_scan:
|
|||
block_type.u.value_type.type = value_type;
|
||||
}
|
||||
else {
|
||||
uint32 type_index;
|
||||
int32 type_index;
|
||||
/* Resolve the leb128 encoded type index as block type */
|
||||
p--;
|
||||
read_leb_uint32(p, p_end, type_index);
|
||||
bh_assert(type_index < module->type_count);
|
||||
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];
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
|
@ -6134,8 +6168,8 @@ re_scan:
|
|||
skip_label();
|
||||
if (BLOCK_HAS_PARAM(block_type)) {
|
||||
/* Make sure params are in dynamic space */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, false, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
}
|
||||
if (opcode == WASM_OP_LOOP) {
|
||||
|
@ -6175,8 +6209,8 @@ re_scan:
|
|||
/* skip the if label */
|
||||
skip_label();
|
||||
/* Emit a copy instruction */
|
||||
if (!copy_params_to_dynamic_space(
|
||||
loader_ctx, true, error_buf, error_buf_size))
|
||||
if (!copy_params_to_dynamic_space(loader_ctx, error_buf,
|
||||
error_buf_size))
|
||||
goto fail;
|
||||
|
||||
/* Emit the if instruction */
|
||||
|
|
BIN
tests/regression/ba-issues/issues/issue-3467/tt_unreachable.wasm
Normal file
BIN
tests/regression/ba-issues/issues/issue-3467/tt_unreachable.wasm
Normal file
Binary file not shown.
BIN
tests/regression/ba-issues/issues/issue-3468/i64.add.wasm
Normal file
BIN
tests/regression/ba-issues/issues/issue-3468/i64.add.wasm
Normal file
Binary file not shown.
|
@ -1674,6 +1674,38 @@
|
|||
"stdout content": "Hello from Kotlin via WASI\nCurrent 'realtime' timestamp is:",
|
||||
"description": "no 'type mismatch: expect (ref null ht) but got other1 unknown type'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"deprecated": false,
|
||||
"ids": [
|
||||
3467
|
||||
],
|
||||
"runtime": "iwasm-default-wasi-disabled",
|
||||
"file": "tt_unreachable.wasm",
|
||||
"mode": "fast-interp",
|
||||
"options": "--heap-size=0 -f to_test",
|
||||
"argument": "",
|
||||
"expected return": {
|
||||
"ret code": 1,
|
||||
"stdout content": "Exception: unreachable",
|
||||
"description": "no '-1.861157e+19:f32'"
|
||||
}
|
||||
},
|
||||
{
|
||||
"deprecated": false,
|
||||
"ids": [
|
||||
3468
|
||||
],
|
||||
"runtime": "iwasm-default-wasi-disabled",
|
||||
"file": "i64.add.wasm",
|
||||
"mode": "fast-interp",
|
||||
"options": "--heap-size=0 -f to_test",
|
||||
"argument": "",
|
||||
"expected return": {
|
||||
"ret code": 255,
|
||||
"stdout content": "WASM module load failed: unknown type",
|
||||
"description": "no '0x0:i64'"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user