| 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 |