| diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h | |
| index 48bd217..2bd0951 100644 | |
| --- a/core/iwasm/common/wasm_memory.h | |
| +++ b/core/iwasm/common/wasm_memory.h | |
| @@ -37,8 +37,13 @@ SET_LINEAR_MEMORY_SIZE(WASMMemoryInstance *memory, uint64 size) | |
| SHARED_MEMORY_UNLOCK(memory); | |
| } | |
| #else | |
| -#define GET_LINEAR_MEMORY_SIZE(memory) memory->memory_data_size | |
| -#define SET_LINEAR_MEMORY_SIZE(memory, size) memory->memory_data_size = size | |
| +/* rive patch: a nested call can enlarge memory; a plain field read lets the | |
| + compiler fold repeated checks into one hoisted register that goes stale | |
| + in frames resumed after the growth. Force a real load per check. */ | |
| +#define GET_LINEAR_MEMORY_SIZE(memory) \ | |
| + (*(volatile uint64 *)&memory->memory_data_size) | |
| +#define SET_LINEAR_MEMORY_SIZE(memory, size) \ | |
| + (*(volatile uint64 *)&memory->memory_data_size) = size | |
| #endif | |
| #if WASM_ENABLE_INTERP != 0 | |
| diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c | |
| index 1c744f9..2c369c7 100644 | |
| --- a/core/iwasm/interpreter/wasm_interp_fast.c | |
| +++ b/core/iwasm/interpreter/wasm_interp_fast.c | |
| @@ -41,6 +41,14 @@ typedef float64 CellType_F64; | |
| #define get_linear_mem_size() GET_LINEAR_MEMORY_SIZE(memory) | |
| #endif | |
| +/* rive patch: OOB diagnostics stay out of the hot handlers' cold blocks | |
| + unless a debugging build asks for them. */ | |
| +#ifdef RIVE_WAMR_OOB_DIAGNOSTICS | |
| +#define RIVE_OOB_DIAG(...) fprintf(stderr, __VA_ARGS__) | |
| +#else | |
| +#define RIVE_OOB_DIAG(...) (void)0 | |
| +#endif | |
| + | |
| #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ | |
| || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 | |
| #define CHECK_MEMORY_OVERFLOW(bytes) \ | |
| @@ -51,8 +59,16 @@ typedef float64 CellType_F64; | |
| /* If offset1 is in valid range, maddr must also \ | |
| be in valid range, no need to check it again. */ \ | |
| maddr = memory->memory_data + offset1; \ | |
| - else \ | |
| + else { \ | |
| + RIVE_OOB_DIAG( \ | |
| + "[wamr-oob] plain off=%llu bytes=%llu size=%llu " \ | |
| + "mem=%p inst0=%p inst0size=%llu\\n", \ | |
| + (unsigned long long)offset1, (unsigned long long)(bytes), \ | |
| + (unsigned long long)get_linear_mem_size(), (void *)memory, \ | |
| + (void *)module->memories[0], \ | |
| + (unsigned long long)module->memories[0]->memory_data_size);\ | |
| goto out_of_bounds; \ | |
| + } \ | |
| } while (0) | |
| #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ | |
| @@ -63,8 +79,13 @@ typedef float64 CellType_F64; | |
| /* App heap space is not valid space for \ | |
| bulk memory operation */ \ | |
| maddr = memory->memory_data + offset1; \ | |
| - else \ | |
| + else { \ | |
| + RIVE_OOB_DIAG( \ | |
| + "[wamr-oob] bulk off=%llu bytes=%llu size=%llu\\n", \ | |
| + (unsigned long long)offset1, (unsigned long long)(bytes), \ | |
| + (unsigned long long)get_linear_mem_size()); \ | |
| goto out_of_bounds; \ | |
| + } \ | |
| } while (0) | |
| #else | |
| #define CHECK_MEMORY_OVERFLOW(bytes) \ | |
| @@ -5153,9 +5174,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |
| offset = (uint64)(uint32)POP_I32(); | |
| addr = POP_I32(); | |
| -#if WASM_ENABLE_THREAD_MGR != 0 | |
| - linear_mem_size = get_linear_mem_size(); | |
| -#endif | |
| + /* rive patch: a callee may have enlarged memory | |
| + since this frame cached the size; bulk bounds | |
| + must never use a stale value. */ | |
| + linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); | |
| #ifndef OS_ENABLE_HW_BOUND_CHECK | |
| CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); | |
| @@ -5209,9 +5231,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |
| src = POP_I32(); | |
| dst = POP_I32(); | |
| -#if WASM_ENABLE_THREAD_MGR != 0 | |
| - linear_mem_size = get_linear_mem_size(); | |
| -#endif | |
| + /* rive patch: a callee may have enlarged memory | |
| + since this frame cached the size; bulk bounds | |
| + must never use a stale value. */ | |
| + linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); | |
| #ifndef OS_ENABLE_HW_BOUND_CHECK | |
| CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc); | |
| @@ -5267,9 +5290,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |
| fill_val = POP_I32(); | |
| dst = POP_I32(); | |
| -#if WASM_ENABLE_THREAD_MGR != 0 | |
| - linear_mem_size = get_linear_mem_size(); | |
| -#endif | |
| + /* rive patch: a callee may have enlarged memory | |
| + since this frame cached the size; bulk bounds | |
| + must never use a stale value. */ | |
| + linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); | |
| #ifndef OS_ENABLE_HW_BOUND_CHECK | |
| CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); | |
| @@ -7792,6 +7816,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |
| return; | |
| RECOVER_CONTEXT(prev_frame); | |
| + /* rive patch: the callee may have enlarged memory; refresh the | |
| + recovered frame's cached size or bulk ops bound-check against | |
| + the stale pre-grow value. */ | |
| +#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ | |
| + || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ | |
| + || WASM_ENABLE_BULK_MEMORY != 0 | |
| + if (memory) | |
| + linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); | |
| +#endif | |
| #if WASM_ENABLE_GC != 0 | |
| local_cell_num = cur_func->param_cell_num + cur_func->local_cell_num; | |
| #endif |