From 7949df96f4d3a32170fe540ffc581f39af4d2c07 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Wed, 15 May 2024 15:20:21 +0800 Subject: [PATCH] Fix fast interp RECOVER_BR_INFO and local set/tee (#3434) When copying two cells from src offsets to dst offsets in RECOVER_BR_INFO, the offsets may be overlapped and the src data may be overwritten, use GET_I64_FROM_ADDR and then SET_I64_FROM_ADDR instead to resolve it. And handling VALUE_TYPE_FUNCREF/VALUE_TYPE_EXTERNREF for opcode local.set and local.tee when reference types feature is enabled. This PR fixes issue #3401 and #3402. --- core/iwasm/interpreter/wasm_interp_fast.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 1206bd24..df6aa73a 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -973,9 +973,9 @@ fail: } \ } \ else if (cells[0] == 2) { \ - frame_lp[dst_offsets[0]] = frame_lp[src_offsets[0]]; \ - frame_lp[dst_offsets[0] + 1] = \ - frame_lp[src_offsets[0] + 1]; \ + PUT_I64_TO_ADDR( \ + frame_lp + dst_offsets[0], \ + GET_I64_FROM_ADDR(frame_lp + src_offsets[0])); \ /* Ignore constants because they are not reference */ \ if (src_offsets[0] >= 0) { \ CLEAR_FRAME_REF((unsigned)src_offsets[0]); \ @@ -1020,9 +1020,9 @@ fail: if (cells[0] == 1) \ frame_lp[dst_offsets[0]] = frame_lp[src_offsets[0]]; \ else if (cells[0] == 2) { \ - frame_lp[dst_offsets[0]] = frame_lp[src_offsets[0]]; \ - frame_lp[dst_offsets[0] + 1] = \ - frame_lp[src_offsets[0] + 1]; \ + PUT_I64_TO_ADDR( \ + frame_lp + dst_offsets[0], \ + GET_I64_FROM_ADDR(frame_lp + src_offsets[0])); \ } \ } \ else { \ @@ -4868,8 +4868,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, GET_LOCAL_INDEX_TYPE_AND_OFFSET(); addr1 = GET_OFFSET(); - if (local_type == VALUE_TYPE_I32 - || local_type == VALUE_TYPE_F32) { + if (local_type == VALUE_TYPE_I32 || local_type == VALUE_TYPE_F32 +#if WASM_ENABLE_REF_TYPES != 0 && WASM_ENABLE_GC == 0 + || local_type == VALUE_TYPE_FUNCREF + || local_type == VALUE_TYPE_EXTERNREF +#endif + ) { *(int32 *)(frame_lp + local_offset) = frame_lp[addr1]; } else if (local_type == VALUE_TYPE_I64