mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-12 04:31:14 +00:00
wasm loader: Fix handling if block without op else (#3404)
If there is no else branch, make a virtual else opcode for easier integrity check and to copy the correct results to the block return address for fast-interp mode: change if block from `if ... end` to `if ... else end`. Reported in issue #3386, #3387, #3388.
This commit is contained in:
parent
ea13d47a41
commit
a6c0cb74c9
|
@ -11333,6 +11333,7 @@ re_scan:
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_EXCE_HANDLING != 0 */
|
#endif /* end of WASM_ENABLE_EXCE_HANDLING != 0 */
|
||||||
case WASM_OP_ELSE:
|
case WASM_OP_ELSE:
|
||||||
|
handle_op_else:
|
||||||
{
|
{
|
||||||
BranchBlock *block = NULL;
|
BranchBlock *block = NULL;
|
||||||
BlockType block_type;
|
BlockType block_type;
|
||||||
|
@ -11405,57 +11406,21 @@ re_scan:
|
||||||
error_buf_size))
|
error_buf_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* if no else branch, and return types do not match param types,
|
/* if there is no else branch, make a virtual else opcode for
|
||||||
report failure */
|
easier integrity check and to copy the correct results to
|
||||||
|
the block return address for fast-interp mode:
|
||||||
|
change if block from `if ... end` to `if ... else end` */
|
||||||
if (cur_block->label_type == LABEL_TYPE_IF
|
if (cur_block->label_type == LABEL_TYPE_IF
|
||||||
&& !cur_block->else_addr) {
|
&& !cur_block->else_addr) {
|
||||||
uint32 block_param_count = 0, block_ret_count = 0;
|
opcode = WASM_OP_ELSE;
|
||||||
uint8 *block_param_types = NULL, *block_ret_types = NULL;
|
p--;
|
||||||
BlockType *cur_block_type = &cur_block->block_type;
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
#if WASM_ENABLE_GC != 0
|
p_org = p;
|
||||||
uint32 block_param_reftype_map_count;
|
skip_label();
|
||||||
uint32 block_ret_reftype_map_count;
|
disable_emit = false;
|
||||||
WASMRefTypeMap *block_param_reftype_maps;
|
emit_label(opcode);
|
||||||
WASMRefTypeMap *block_ret_reftype_maps;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
block_param_count = block_type_get_param_types(
|
|
||||||
cur_block_type, &block_param_types
|
|
||||||
#if WASM_ENABLE_GC != 0
|
|
||||||
,
|
|
||||||
&block_param_reftype_maps,
|
|
||||||
&block_param_reftype_map_count
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
block_ret_count = block_type_get_result_types(
|
|
||||||
cur_block_type, &block_ret_types
|
|
||||||
#if WASM_ENABLE_GC != 0
|
|
||||||
,
|
|
||||||
&block_ret_reftype_maps, &block_ret_reftype_map_count
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
if (block_param_count != block_ret_count
|
|
||||||
|| (block_param_count
|
|
||||||
&& memcmp(block_param_types, block_ret_types,
|
|
||||||
block_param_count))) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"type mismatch: else branch missing");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
#if WASM_ENABLE_GC != 0
|
|
||||||
if (block_param_reftype_map_count
|
|
||||||
!= block_ret_reftype_map_count
|
|
||||||
|| (block_param_reftype_map_count
|
|
||||||
&& memcmp(block_param_reftype_maps,
|
|
||||||
block_ret_reftype_maps,
|
|
||||||
sizeof(WASMRefTypeMap)
|
|
||||||
* block_param_reftype_map_count))) {
|
|
||||||
set_error_buf(error_buf, error_buf_size,
|
|
||||||
"type mismatch: else branch missing");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
goto handle_op_else;
|
||||||
}
|
}
|
||||||
|
|
||||||
POP_CSP();
|
POP_CSP();
|
||||||
|
|
|
@ -6213,6 +6213,7 @@ re_scan:
|
||||||
}
|
}
|
||||||
|
|
||||||
case WASM_OP_ELSE:
|
case WASM_OP_ELSE:
|
||||||
|
handle_op_else:
|
||||||
{
|
{
|
||||||
BranchBlock *block = NULL;
|
BranchBlock *block = NULL;
|
||||||
BlockType block_type = (loader_ctx->frame_csp - 1)->block_type;
|
BlockType block_type = (loader_ctx->frame_csp - 1)->block_type;
|
||||||
|
@ -6272,26 +6273,21 @@ re_scan:
|
||||||
error_buf_size))
|
error_buf_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* if no else branch, and return types do not match param types,
|
/* if there is no else branch, make a virtual else opcode for
|
||||||
* fail */
|
easier integrity check and to copy the correct results to
|
||||||
|
the block return address for fast-interp mode:
|
||||||
|
change if block from `if ... end` to `if ... else end` */
|
||||||
if (cur_block->label_type == LABEL_TYPE_IF
|
if (cur_block->label_type == LABEL_TYPE_IF
|
||||||
&& !cur_block->else_addr) {
|
&& !cur_block->else_addr) {
|
||||||
uint32 block_param_count = 0, block_ret_count = 0;
|
opcode = WASM_OP_ELSE;
|
||||||
uint8 *block_param_types = NULL, *block_ret_types = NULL;
|
p--;
|
||||||
BlockType *cur_block_type = &cur_block->block_type;
|
#if WASM_ENABLE_FAST_INTERP != 0
|
||||||
|
p_org = p;
|
||||||
block_param_count = block_type_get_param_types(
|
skip_label();
|
||||||
cur_block_type, &block_param_types);
|
disable_emit = false;
|
||||||
block_ret_count = block_type_get_result_types(
|
emit_label(opcode);
|
||||||
cur_block_type, &block_ret_types);
|
#endif
|
||||||
bh_assert(block_param_count == block_ret_count
|
goto handle_op_else;
|
||||||
&& (!block_param_count
|
|
||||||
|| !memcmp(block_param_types, block_ret_types,
|
|
||||||
block_param_count)));
|
|
||||||
(void)block_ret_types;
|
|
||||||
(void)block_ret_count;
|
|
||||||
(void)block_param_types;
|
|
||||||
(void)block_param_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
POP_CSP();
|
POP_CSP();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user