From 3da27279e0cc585f9605ce35a6684d8ddf61bef1 Mon Sep 17 00:00:00 2001 From: Xenia Lu Date: Wed, 24 Sep 2025 09:14:14 +0800 Subject: [PATCH 1/3] loader: fix block/loop ref params type checking --- core/iwasm/interpreter/wasm_loader.c | 26 +++++++++++++++ .../ba-issues/issues/issue-4646/test.wasm | Bin 0 -> 157 bytes .../ba-issues/issues/issue-4646/test.wat | 31 ++++++++++++++++++ .../regression/ba-issues/running_config.json | 16 +++++++++ 4 files changed, 73 insertions(+) create mode 100644 tests/regression/ba-issues/issues/issue-4646/test.wasm create mode 100644 tests/regression/ba-issues/issues/issue-4646/test.wat diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 19ca249496..c7301fc669 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -12050,9 +12050,25 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, WASMFuncType *wasm_type = block_type.u.type; BranchBlock *cur_block = loader_ctx->frame_csp - 1; +#if WASM_ENABLE_GC != 0 + WASMRefType *ref_type; + uint32 j = 0; +#endif #if WASM_ENABLE_FAST_INTERP != 0 uint32 cell_num; available_params = block_type.u.type->param_count; +#endif +#if WASM_ENABLE_GC != 0 + /* find the index of the last param + * in wasm_type->ref_type_maps as j */ + for (i = 0; i < block_type.u.type->param_count; i++) { + if (wasm_is_type_multi_byte_type(wasm_type->types[i])) { + j += 1; + } + } + if (j > 0) { + j -= 1; + } #endif for (i = 0; i < block_type.u.type->param_count; i++) { @@ -12066,6 +12082,16 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, #endif break; } +#if WASM_ENABLE_GC != 0 + if (wasm_is_type_multi_byte_type(wasm_type->types[wasm_type->param_count - i - 1])) { + bh_assert(wasm_type->ref_type_maps[j].index == wasm_type->param_count - i - 1); + ref_type = wasm_type->ref_type_maps[j].ref_type; + bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType), + ref_type, + wasm_reftype_struct_size(ref_type)); + j--; + } +#endif POP_TYPE( wasm_type->types[wasm_type->param_count - i - 1]); diff --git a/tests/regression/ba-issues/issues/issue-4646/test.wasm b/tests/regression/ba-issues/issues/issue-4646/test.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e163405eec49af2539875c7c9b672d1d0afe4aa5 GIT binary patch literal 157 zcmXxWF%E(-7zWVq`&+=ks1u2CFwUN#UZhmY;80AU4lecz9>jxq5O2{%7T)yW=0E`4 z7nX^ZFIq{5~@ptN&zQv~W0k1)0QAp>T2`7(o|+lBdv id8-U*+6HGmx-hUJba1y(9~3rooF09&j_a literal 0 HcmV?d00001 diff --git a/tests/regression/ba-issues/issues/issue-4646/test.wat b/tests/regression/ba-issues/issues/issue-4646/test.wat new file mode 100644 index 0000000000..da12347d20 --- /dev/null +++ b/tests/regression/ba-issues/issues/issue-4646/test.wat @@ -0,0 +1,31 @@ +;; 定义不同的引用类型 +(type $struct_a (struct (field (mut i32)))) +(type $struct_b (struct (field (mut i64)))) +(type $struct_c (struct (field (mut i32)) (field (mut i32)))) + +(func $main + ;; 准备参数:i32, ref_a, i32, ref_b + (i32.const 10) + (struct.new $struct_a (i32.const 100)) + (i32.const 20) + (struct.new $struct_b (i64.const 200)) + + ;; 带交错参数的block:i32, ref_a, i32, ref_b -> ref_c + (block (param i32 (ref $struct_a) i32 (ref $struct_b)) (result (ref $struct_c)) + ;; 清理栈中的参数 + drop ;; 丢弃 ref_b + drop ;; 丢弃 i32 + drop ;; 丢弃 ref_a + drop ;; 丢弃 i32 + ;; 返回新的第三种类型引用 + + (struct.new $struct_c (i32.const 300) (i32.const 400)) + ) + + ;; 丢弃返回值 + drop +) + +(memory 1) +(export "memory" (memory 0)) +(export "_start" (func $main)) \ No newline at end of file diff --git a/tests/regression/ba-issues/running_config.json b/tests/regression/ba-issues/running_config.json index decc6861aa..bc62c54915 100644 --- a/tests/regression/ba-issues/running_config.json +++ b/tests/regression/ba-issues/running_config.json @@ -1770,6 +1770,22 @@ "stdout content": "", "description": "no 'invalid local type'" } + }, + { + "deprecated": false, + "ids": [ + 4646 + ], + "runtime": "iwasm-default-gc-enabled", + "file": "test.wasm", + "mode": "classic-interp", + "options": "-f _start", + "argument": "", + "expected return": { + "ret code": 0, + "stdout content": "", + "description": "load successfully" + } } ] } From 1d57bd7b276009f17af3df9a3bd978d3a8467fb3 Mon Sep 17 00:00:00 2001 From: Xenia Lu Date: Wed, 24 Sep 2025 09:19:42 +0800 Subject: [PATCH 2/3] clang-format --- core/iwasm/interpreter/wasm_loader.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index c7301fc669..5874931e05 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -12083,8 +12083,11 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, break; } #if WASM_ENABLE_GC != 0 - if (wasm_is_type_multi_byte_type(wasm_type->types[wasm_type->param_count - i - 1])) { - bh_assert(wasm_type->ref_type_maps[j].index == wasm_type->param_count - i - 1); + if (wasm_is_type_multi_byte_type( + wasm_type + ->types[wasm_type->param_count - i - 1])) { + bh_assert(wasm_type->ref_type_maps[j].index + == wasm_type->param_count - i - 1); ref_type = wasm_type->ref_type_maps[j].ref_type; bh_memcpy_s(&wasm_ref_type, sizeof(WASMRefType), ref_type, From d4d9b02e8bb8239a38eda8a629acc50d61aa358a Mon Sep 17 00:00:00 2001 From: Xenia Lu Date: Wed, 24 Sep 2025 15:19:28 +0800 Subject: [PATCH 3/3] Rewrite comments in English --- .../ba-issues/issues/issue-4646/test.wat | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/regression/ba-issues/issues/issue-4646/test.wat b/tests/regression/ba-issues/issues/issue-4646/test.wat index da12347d20..3fd503c550 100644 --- a/tests/regression/ba-issues/issues/issue-4646/test.wat +++ b/tests/regression/ba-issues/issues/issue-4646/test.wat @@ -1,28 +1,28 @@ -;; 定义不同的引用类型 +;; define different reference types (type $struct_a (struct (field (mut i32)))) (type $struct_b (struct (field (mut i64)))) (type $struct_c (struct (field (mut i32)) (field (mut i32)))) (func $main - ;; 准备参数:i32, ref_a, i32, ref_b + ;; prepare parameters: i32, ref_a, i32, ref_b (i32.const 10) (struct.new $struct_a (i32.const 100)) (i32.const 20) (struct.new $struct_b (i64.const 200)) - ;; 带交错参数的block:i32, ref_a, i32, ref_b -> ref_c + ;; block with interleaved parameters: i32, ref_a, i32, ref_b -> ref_c (block (param i32 (ref $struct_a) i32 (ref $struct_b)) (result (ref $struct_c)) - ;; 清理栈中的参数 - drop ;; 丢弃 ref_b - drop ;; 丢弃 i32 - drop ;; 丢弃 ref_a - drop ;; 丢弃 i32 - ;; 返回新的第三种类型引用 + ;; clean up parameters from stack + drop ;; drop ref_b + drop ;; drop i32 + drop ;; drop ref_a + drop ;; drop i32 + ;; return new type reference struct_c (struct.new $struct_c (i32.const 300) (i32.const 400)) ) - ;; 丢弃返回值 + ;; drop return value drop )