Просмотр исходного кода

loader: fix block/loop ref params type checking (#4647)

* loader: fix block/loop ref params type checking
Xenia Lu 2 месяцев назад
Родитель
Сommit
3bf08a0eda

+ 29 - 0
core/iwasm/interpreter/wasm_loader.c

@@ -12050,9 +12050,25 @@ re_scan:
                     WASMFuncType *wasm_type = block_type.u.type;
                     WASMFuncType *wasm_type = block_type.u.type;
 
 
                     BranchBlock *cur_block = loader_ctx->frame_csp - 1;
                     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
 #if WASM_ENABLE_FAST_INTERP != 0
                     uint32 cell_num;
                     uint32 cell_num;
                     available_params = block_type.u.type->param_count;
                     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
 #endif
                     for (i = 0; i < block_type.u.type->param_count; i++) {
                     for (i = 0; i < block_type.u.type->param_count; i++) {
 
 
@@ -12066,6 +12082,19 @@ re_scan:
 #endif
 #endif
                             break;
                             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(
                         POP_TYPE(
                             wasm_type->types[wasm_type->param_count - i - 1]);
                             wasm_type->types[wasm_type->param_count - i - 1]);

BIN
tests/regression/ba-issues/issues/issue-4646/test.wasm


+ 31 - 0
tests/regression/ba-issues/issues/issue-4646/test.wat

@@ -0,0 +1,31 @@
+;; 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
+  ;; 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 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))
+    ;; 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
+)
+
+(memory 1)
+(export "memory" (memory 0))
+(export "_start" (func $main))

+ 16 - 0
tests/regression/ba-issues/running_config.json

@@ -1770,6 +1770,22 @@
                 "stdout content": "",
                 "stdout content": "",
                 "description": "no 'invalid local type'"
                 "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"
+            }
         }
         }
     ]
     ]
 }
 }