From ea13d47a41634a897a0491be2d626565ba4fc4e4 Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Thu, 9 May 2024 16:31:21 +0800 Subject: [PATCH] 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. --- core/iwasm/fast-jit/jit_frontend.c | 15 +++++++++++++++ core/iwasm/interpreter/wasm_interp_classic.c | 16 ++++++++++++++++ core/iwasm/interpreter/wasm_interp_fast.c | 16 ++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/core/iwasm/fast-jit/jit_frontend.c b/core/iwasm/fast-jit/jit_frontend.c index b8d40f97f..092f9c0c7 100644 --- a/core/iwasm/fast-jit/jit_frontend.c +++ b/core/iwasm/fast-jit/jit_frontend.c @@ -1243,6 +1243,21 @@ init_func_translation(JitCompContext *cc) 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; } diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 3bc6d68ce..e742d937c 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/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; uint32 max_stack_cell_num = cur_wasm_func->max_stack_cell_num; 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 /* 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, (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 */ cell_num = func_type->ret_cell_num; PUSH_CSP(LABEL_TYPE_FUNCTION, 0, cell_num, frame_ip_end - 1); diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index b861b271e..1206bd249 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -5905,6 +5905,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, else { WASMFunction *cur_wasm_func = cur_func->u.func; 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 + 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, (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 /* frame->ip is used during GC root set enumeration, so we must * initialized this field here */