From a653746b7bea358251805b98e3ea824152659608 Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:55:43 +0800 Subject: [PATCH] Check whether related table has funcref elem in opcode call_indirect (#3999) * check whether table has funcref elem in call_indirect * check whether table has funcref elem in call_indirect when gc is enabled --- core/iwasm/interpreter/wasm_loader.c | 41 +++++++++++++++++++++++ core/iwasm/interpreter/wasm_mini_loader.c | 9 +++++ 2 files changed, 50 insertions(+) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 533538adc..8065173a4 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -12103,6 +12103,10 @@ re_scan: { int32 idx; WASMFuncType *func_type; + uint32 tbl_elem_type; +#if WASM_ENABLE_GC != 0 + WASMRefType *elem_ref_type = NULL; +#endif read_leb_uint32(p, p_end, type_idx); #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 @@ -12125,6 +12129,43 @@ re_scan: error_buf_size)) { goto fail; } + tbl_elem_type = + table_idx < module->import_table_count + ? module->import_tables[table_idx] + .u.table.table_type.elem_type + : module->tables[table_idx - module->import_table_count] + .table_type.elem_type; + +#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 + if (tbl_elem_type != VALUE_TYPE_FUNCREF) { + set_error_buf_v(error_buf, error_buf_size, + "type mismatch: instruction requires table " + "of functions but table %u has externref", + table_idx); + goto fail; + } +#elif WASM_ENABLE_GC != 0 + /* Table element must match type ref null func */ + elem_ref_type = + table_idx < module->import_table_count + ? module->import_tables[table_idx] + .u.table.table_type.elem_ref_type + : module->tables[table_idx - module->import_table_count] + .table_type.elem_ref_type; + + if (!wasm_reftype_is_subtype_of( + tbl_elem_type, elem_ref_type, REF_TYPE_FUNCREF, NULL, + module->types, module->type_count)) { + set_error_buf_v(error_buf, error_buf_size, + "type mismatch: instruction requires " + "reference type t match type ref null func" + "in table %u", + table_idx); + goto fail; + } +#else + (void)tbl_elem_type; +#endif #if WASM_ENABLE_FAST_INTERP != 0 /* we need to emit before arguments */ diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index e83a20045..f994f0def 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -6700,6 +6700,15 @@ re_scan: goto fail; } + bh_assert( + (table_idx < module->import_table_count + ? module->import_tables[table_idx] + .u.table.table_type.elem_type + : module + ->tables[table_idx - module->import_table_count] + .table_type.elem_type) + == VALUE_TYPE_FUNCREF); + #if WASM_ENABLE_FAST_INTERP != 0 /* we need to emit before arguments */ emit_uint32(loader_ctx, type_idx);