wasm loader: Fix checks for opcode ref.func and else

This commit is contained in:
Wenyong Huang 2024-04-22 10:00:49 +08:00
parent e7a8b3e743
commit beba30699a
2 changed files with 79 additions and 32 deletions

View File

@ -11335,8 +11335,10 @@ re_scan:
BlockType block_type; BlockType block_type;
if (loader_ctx->csp_num < 2 if (loader_ctx->csp_num < 2
|| (loader_ctx->frame_csp - 1)->label_type /* the matched if isn't found */
!= LABEL_TYPE_IF) { || (loader_ctx->frame_csp - 1)->label_type != LABEL_TYPE_IF
/* duplicated else is found */
|| (loader_ctx->frame_csp - 1)->else_addr) {
set_error_buf( set_error_buf(
error_buf, error_buf_size, error_buf, error_buf_size,
"opcode else found without matched opcode if"); "opcode else found without matched opcode if");
@ -12408,22 +12410,45 @@ re_scan:
goto fail; goto fail;
} }
/* Refer to a forward-declared function */ /* Refer to a forward-declared function:
if (func_idx >= cur_func_idx + module->import_function_count) { 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; WASMTableSeg *table_seg = module->table_segments;
bool func_declared = false; bool func_declared = false;
uint32 j; uint32 j;
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, /* Check whether the function is declared in table segs,
note that it doesn't matter whether the table seg's mode note that it doesn't matter whether the table seg's
is passive, active or declarative. */ mode is passive, active or declarative. */
for (i = 0; i < module->table_seg_count; i++, table_seg++) { for (i = 0; i < module->table_seg_count;
i++, table_seg++) {
if (table_seg->elem_type == VALUE_TYPE_FUNCREF if (table_seg->elem_type == VALUE_TYPE_FUNCREF
#if WASM_ENABLE_GC != 0 #if WASM_ENABLE_GC != 0
|| (table_seg->elem_type == REF_TYPE_HT_NON_NULLABLE /* elem type is (ref null? func) or
&& table_seg->elem_ref_type->ref_ht_common (ref null? $t) */
|| ((table_seg->elem_type
== REF_TYPE_HT_NON_NULLABLE
|| table_seg->elem_type
== REF_TYPE_HT_NULLABLE)
&& (table_seg->elem_ref_type->ref_ht_common
.heap_type .heap_type
== HEAP_TYPE_FUNC) == HEAP_TYPE_FUNC
|| table_seg->elem_ref_type
->ref_ht_common.heap_type
> 0))
#endif #endif
) { ) {
for (j = 0; j < table_seg->value_count; j++) { for (j = 0; j < table_seg->value_count; j++) {
@ -12435,6 +12460,8 @@ re_scan:
} }
} }
} }
}
if (!func_declared) { if (!func_declared) {
/* Check whether the function is exported */ /* Check whether the function is exported */
for (i = 0; i < module->export_count; i++) { for (i = 0; i < module->export_count; i++) {

View File

@ -6203,8 +6203,11 @@ re_scan:
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;
bh_assert(loader_ctx->csp_num >= 2 bh_assert(loader_ctx->csp_num >= 2
/* the matched if is found */
&& (loader_ctx->frame_csp - 1)->label_type && (loader_ctx->frame_csp - 1)->label_type
== LABEL_TYPE_IF); == LABEL_TYPE_IF
/* duplicated else isn't found */
&& !(loader_ctx->frame_csp - 1)->else_addr);
block = loader_ctx->frame_csp - 1; block = loader_ctx->frame_csp - 1;
/* check whether if branch's stack matches its result type */ /* check whether if branch's stack matches its result type */
@ -6916,16 +6919,31 @@ re_scan:
goto fail; goto fail;
} }
/* Refer to a forward-declared function */ /* Refer to a forward-declared function:
if (func_idx >= cur_func_idx + module->import_function_count) { 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; WASMTableSeg *table_seg = module->table_segments;
bool func_declared = false; bool func_declared = false;
uint32 j; uint32 j;
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, /* Check whether the function is declared in table segs,
note that it doesn't matter whether the table seg's mode note that it doesn't matter whether the table seg's
is passive, active or declarative. */ mode is passive, active or declarative. */
for (i = 0; i < module->table_seg_count; i++, table_seg++) { for (i = 0; i < module->table_seg_count;
i++, table_seg++) {
if (table_seg->elem_type == VALUE_TYPE_FUNCREF) { if (table_seg->elem_type == VALUE_TYPE_FUNCREF) {
for (j = 0; j < table_seg->value_count; j++) { for (j = 0; j < table_seg->value_count; j++) {
if (table_seg->init_values[j].u.ref_index if (table_seg->init_values[j].u.ref_index
@ -6936,6 +6954,8 @@ re_scan:
} }
} }
} }
}
if (!func_declared) { if (!func_declared) {
/* Check whether the function is exported */ /* Check whether the function is exported */
for (i = 0; i < module->export_count; i++) { for (i = 0; i < module->export_count; i++) {