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

ref-types: Correct default value for function local variables (#3397)

In classic interpreter, fast interpreter and fast-jit running modes, set the local
variables' default value to NULL_REF (0xFFFFFFFF) rather than 0 if they are type
of externref or funcref.

The issue was reported in #3390 and #3391.
TianlongLiang 1 год назад
Родитель
Сommit
ea13d47a41

+ 15 - 0
core/iwasm/fast-jit/jit_frontend.c

@@ -1243,6 +1243,21 @@ init_func_translation(JitCompContext *cc)
                  NEW_CONST(I32, local_off));
                  NEW_CONST(I32, local_off));
     }
     }
 
 
+#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
+    /* externref/funcref should be NULL_REF rather than 0 */
+    local_off = (uint32)offsetof(WASMInterpFrame, lp)
+                + cur_wasm_func->param_cell_num * 4;
+    for (i = 0; i < cur_wasm_func->local_count; i++) {
+        if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
+            || cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
+            GEN_INSN(STI32, NEW_CONST(I32, NULL_REF), cc->fp_reg,
+                     NEW_CONST(I32, local_off));
+        }
+        local_off +=
+            4 * wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
+    }
+#endif
+
     return jit_frame;
     return jit_frame;
 }
 }
 
 

+ 16 - 0
core/iwasm/interpreter/wasm_interp_classic.c

@@ -6487,6 +6487,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             WASMFuncType *func_type = cur_wasm_func->func_type;
             WASMFuncType *func_type = cur_wasm_func->func_type;
             uint32 max_stack_cell_num = cur_wasm_func->max_stack_cell_num;
             uint32 max_stack_cell_num = cur_wasm_func->max_stack_cell_num;
             uint32 cell_num_of_local_stack;
             uint32 cell_num_of_local_stack;
+#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
+            uint32 local_cell_idx;
+#endif
 
 
 #if WASM_ENABLE_EXCE_HANDLING != 0
 #if WASM_ENABLE_EXCE_HANDLING != 0
             /* account for exception handlers, bundle them here */
             /* account for exception handlers, bundle them here */
@@ -6546,6 +6549,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             memset(frame_lp + cur_func->param_cell_num, 0,
             memset(frame_lp + cur_func->param_cell_num, 0,
                    (uint32)(cur_func->local_cell_num * 4));
                    (uint32)(cur_func->local_cell_num * 4));
 
 
+#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
+            /* externref/funcref should be NULL_REF rather than 0 */
+            local_cell_idx = cur_func->param_cell_num;
+            for (i = 0; i < cur_wasm_func->local_count; i++) {
+                if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
+                    || cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
+                    *(frame_lp + local_cell_idx) = NULL_REF;
+                }
+                local_cell_idx +=
+                    wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
+            }
+#endif
+
             /* Push function block as first block */
             /* Push function block as first block */
             cell_num = func_type->ret_cell_num;
             cell_num = func_type->ret_cell_num;
             PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1);
             PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1);

+ 16 - 0
core/iwasm/interpreter/wasm_interp_fast.c

@@ -5905,6 +5905,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         else {
         else {
             WASMFunction *cur_wasm_func = cur_func->u.func;
             WASMFunction *cur_wasm_func = cur_func->u.func;
             uint32 cell_num_of_local_stack;
             uint32 cell_num_of_local_stack;
+#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
+            uint32 i, local_cell_idx;
+#endif
 
 
             cell_num_of_local_stack = cur_func->param_cell_num
             cell_num_of_local_stack = cur_func->param_cell_num
                                       + cur_func->local_cell_num
                                       + cur_func->local_cell_num
@@ -5947,6 +5950,19 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
             memset(frame_lp + cur_func->param_cell_num, 0,
             memset(frame_lp + cur_func->param_cell_num, 0,
                    (uint32)(cur_func->local_cell_num * 4));
                    (uint32)(cur_func->local_cell_num * 4));
 
 
+#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0
+            /* externref/funcref should be NULL_REF rather than 0 */
+            local_cell_idx = cur_func->param_cell_num;
+            for (i = 0; i < cur_wasm_func->local_count; i++) {
+                if (cur_wasm_func->local_types[i] == VALUE_TYPE_EXTERNREF
+                    || cur_wasm_func->local_types[i] == VALUE_TYPE_FUNCREF) {
+                    *(frame_lp + local_cell_idx) = NULL_REF;
+                }
+                local_cell_idx +=
+                    wasm_value_type_cell_num(cur_wasm_func->local_types[i]);
+            }
+#endif
+
 #if WASM_ENABLE_GC != 0
 #if WASM_ENABLE_GC != 0
             /* frame->ip is used during GC root set enumeration, so we must
             /* frame->ip is used during GC root set enumeration, so we must
              * initialized this field here */
              * initialized this field here */