Fix dynamic offset not updated in op_br for block with ret type (#3269)

The PR #3259 reverted PR #3192, it fixes #3210 but makes #3170 failed again.

The workaround is that we should update `ctx->dynamic_offset` only for opcode br
and should not update it for opcode br_if. This PR fixes both issue #3170 and #3210.
This commit is contained in:
Wenyong Huang 2024-04-01 15:40:20 +08:00 committed by GitHub
parent b1502258ea
commit 6ee71000f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 38 deletions

View File

@ -8448,11 +8448,11 @@ fail:
wasm_loader_emit_ptr(loader_ctx, NULL); \
} while (0)
#define emit_br_info(frame_csp) \
do { \
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \
error_buf_size)) \
goto fail; \
#define emit_br_info(frame_csp, is_br) \
do { \
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
error_buf_size)) \
goto fail; \
} while (0)
#define LAST_OP_OUTPUT_I32() \
@ -8846,7 +8846,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
static bool
wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
char *error_buf, uint32 error_buf_size)
bool is_br, char *error_buf, uint32 error_buf_size)
{
/* br info layout:
* a) arity of target block
@ -8907,6 +8907,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
/* Part e */
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--) {
cell = (uint8)wasm_value_type_cell_num(types[i]);
dynamic_offset -= cell;
@ -9774,8 +9776,8 @@ check_memory_align_equal(uint8 opcode, uint32 align, char *error_buf,
#endif /* end of WASM_ENABLE_SHARED_MEMORY */
static bool
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
bool is_br_table, char *error_buf, uint32 error_buf_size)
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
char *error_buf, uint32 error_buf_size)
{
BranchBlock *target_block, *cur_block;
BlockType *target_block_type;
@ -9872,7 +9874,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
/* Backup stack data since it may be changed in the below
push operations, and the stack data may be used when
checking other target blocks of opcode br_table */
if (is_br_table) {
if (opcode == WASM_OP_BR_TABLE) {
uint64 total_size;
frame_ref_after_popped = loader_ctx->frame_ref;
@ -9936,13 +9938,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
}
#if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block);
emit_br_info(target_block, opcode == WASM_OP_BR);
#endif
/* Restore the stack data, note that frame_ref_bottom,
frame_reftype_map_bottom, frame_offset_bottom may be
re-allocated in the above push operations */
if (is_br_table) {
if (opcode == WASM_OP_BR_TABLE) {
uint32 total_size;
/* The stack operand num should not be smaller than before
@ -10033,7 +10035,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
}
#if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block);
emit_br_info(target_block, opcode == WASM_OP_BR);
#endif
ret = true;
@ -10056,14 +10058,14 @@ fail:
static BranchBlock *
check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
bool is_br_table, char *error_buf, uint32 error_buf_size)
uint8 opcode, char *error_buf, uint32 error_buf_size)
{
uint8 *p = *p_buf, *p_end = buf_end;
BranchBlock *frame_csp_tmp;
uint32 depth;
read_leb_uint32(p, p_end, depth);
if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf,
if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
error_buf_size)) {
goto fail;
}
@ -10980,7 +10982,7 @@ re_scan:
/* check the target catching block: LABEL_TYPE_CATCH */
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size)))
goto fail;
@ -11267,7 +11269,7 @@ re_scan:
case WASM_OP_BR:
{
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size)))
goto fail;
@ -11281,7 +11283,7 @@ re_scan:
POP_I32();
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size)))
goto fail;
@ -11351,7 +11353,7 @@ re_scan:
}
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, true,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) {
goto fail;
}
@ -12256,7 +12258,7 @@ re_scan:
if (opcode == WASM_OP_BR_ON_NULL) {
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) {
goto fail;
}
@ -12303,7 +12305,7 @@ re_scan:
PUSH_REF(type);
}
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size))) {
goto fail;
}
@ -13785,7 +13787,7 @@ re_scan:
}
PUSH_REF(type_tmp);
if (!(frame_csp_tmp = check_branch_block(
loader_ctx, &p, p_end, false, error_buf,
loader_ctx, &p, p_end, opcode, error_buf,
error_buf_size))) {
goto fail;
}

View File

@ -4260,11 +4260,11 @@ wasm_loader_pop_frame_csp(WASMLoaderContext *ctx, char *error_buf,
wasm_loader_emit_ptr(loader_ctx, NULL); \
} while (0)
#define emit_br_info(frame_csp) \
do { \
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, error_buf, \
error_buf_size)) \
goto fail; \
#define emit_br_info(frame_csp, is_br) \
do { \
if (!wasm_loader_emit_br_info(loader_ctx, frame_csp, is_br, error_buf, \
error_buf_size)) \
goto fail; \
} while (0)
#define LAST_OP_OUTPUT_I32() \
@ -4649,7 +4649,7 @@ apply_label_patch(WASMLoaderContext *ctx, uint8 depth, uint8 patch_type)
static bool
wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
char *error_buf, uint32 error_buf_size)
bool is_br, char *error_buf, uint32 error_buf_size)
{
/* br info layout:
* a) arity of target block
@ -4698,6 +4698,8 @@ wasm_loader_emit_br_info(WASMLoaderContext *ctx, BranchBlock *frame_csp,
/* Part e */
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--) {
cell = (uint8)wasm_value_type_cell_num(types[i]);
dynamic_offset -= cell;
@ -5382,8 +5384,8 @@ fail:
} while (0)
static bool
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
bool is_br_table, char *error_buf, uint32 error_buf_size)
wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth, uint8 opcode,
char *error_buf, uint32 error_buf_size)
{
BranchBlock *target_block, *cur_block;
BlockType *target_block_type;
@ -5441,7 +5443,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
/* Backup stack data since it may be changed in the below
push operations, and the stack data may be used when
checking other target blocks of opcode br_table */
if (is_br_table) {
if (opcode == WASM_OP_BR_TABLE) {
uint64 total_size;
frame_ref_after_popped = loader_ctx->frame_ref;
@ -5479,13 +5481,13 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
}
#if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block);
emit_br_info(target_block, opcode == WASM_OP_BR);
#endif
/* Restore the stack data, note that frame_ref_bottom,
frame_reftype_map_bottom, frame_offset_bottom may be
re-allocated in the above push operations */
if (is_br_table) {
if (opcode == WASM_OP_BR_TABLE) {
uint32 total_size;
/* The stack operand num should not be smaller than before
@ -5529,7 +5531,7 @@ wasm_loader_check_br(WASMLoaderContext *loader_ctx, uint32 depth,
}
#if WASM_ENABLE_FAST_INTERP != 0
emit_br_info(target_block);
emit_br_info(target_block, opcode == WASM_OP_BR);
#endif
ret = true;
@ -5548,14 +5550,14 @@ fail:
static BranchBlock *
check_branch_block(WASMLoaderContext *loader_ctx, uint8 **p_buf, uint8 *buf_end,
bool is_br_table, char *error_buf, uint32 error_buf_size)
uint8 opcode, char *error_buf, uint32 error_buf_size)
{
uint8 *p = *p_buf, *p_end = buf_end;
BranchBlock *frame_csp_tmp;
uint32 depth;
read_leb_uint32(p, p_end, depth);
if (!wasm_loader_check_br(loader_ctx, depth, is_br_table, error_buf,
if (!wasm_loader_check_br(loader_ctx, depth, opcode, error_buf,
error_buf_size)) {
goto fail;
}
@ -6179,7 +6181,7 @@ re_scan:
case WASM_OP_BR:
{
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size)))
goto fail;
@ -6193,7 +6195,7 @@ re_scan:
POP_I32();
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, false,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size)))
goto fail;
@ -6223,7 +6225,7 @@ re_scan:
#endif
for (i = 0; i <= count; i++) {
if (!(frame_csp_tmp =
check_branch_block(loader_ctx, &p, p_end, true,
check_branch_block(loader_ctx, &p, p_end, opcode,
error_buf, error_buf_size)))
goto fail;