From dd85211ee8009383ecdfdada7d035a8fb50ae4d8 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 25 Mar 2026 10:48:28 +0100 Subject: [PATCH 1/4] respect need_check for RISC-V Singlepass --- lib/compiler-singlepass/src/machine_riscv.rs | 318 ++++++++++++------- tests/ignores.txt | 6 +- 2 files changed, 211 insertions(+), 113 deletions(-) diff --git a/lib/compiler-singlepass/src/machine_riscv.rs b/lib/compiler-singlepass/src/machine_riscv.rs index 21407583160a..51f24ecbe232 100644 --- a/lib/compiler-singlepass/src/machine_riscv.rs +++ b/lib/compiler-singlepass/src/machine_riscv.rs @@ -899,6 +899,7 @@ impl MachineRiscv { memarg: &MemArg, check_alignment: bool, value_size: usize, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -938,23 +939,25 @@ impl MachineRiscv { self.emit_relaxed_load(Size::S64, false, Location::GPR(tmp_base), base_loc)?; // Load bound into temporary register. - self.emit_relaxed_load(Size::S64, false, Location::GPR(tmp_bound), bound_loc)?; + if need_check { + self.emit_relaxed_load(Size::S64, false, Location::GPR(tmp_bound), bound_loc)?; - // Wasm -> Effective. - // Assuming we never underflow - should always be true on Linux/macOS and Windows >=8, - // since the first page from 0x0 to 0x1000 is not accepted by mmap. - self.assembler.emit_add( - Size::S64, - Location::GPR(tmp_bound), - Location::GPR(tmp_base), - Location::GPR(tmp_bound), - )?; - self.assembler.emit_sub( - Size::S64, - Location::GPR(tmp_bound), - Location::Imm64(value_size as _), - Location::GPR(tmp_bound), - )?; + // Wasm -> Effective. + // Assuming we never underflow - should always be true on Linux/macOS and Windows >=8, + // since the first page from 0x0 to 0x1000 is not accepted by mmap. + self.assembler.emit_add( + Size::S64, + Location::GPR(tmp_bound), + Location::GPR(tmp_base), + Location::GPR(tmp_bound), + )?; + self.assembler.emit_sub( + Size::S64, + Location::GPR(tmp_bound), + Location::Imm64(value_size as _), + Location::GPR(tmp_bound), + )?; + } // Load effective address. // `base_loc` and `bound_loc` becomes INVALID after this line, because `tmp_addr` @@ -1016,17 +1019,22 @@ impl MachineRiscv { // tmp_base is already unused let cond = tmp_base; - // Trap if the end address of the requested area is above that of the linear memory. - self.assembler.emit_cmp( - Condition::Le, - Location::GPR(tmp_addr), - Location::GPR(tmp_bound), - Location::GPR(cond), - )?; + if need_check { + // Trap if the end address of the requested area is above that of the linear memory. + self.assembler.emit_cmp( + Condition::Le, + Location::GPR(tmp_addr), + Location::GPR(tmp_bound), + Location::GPR(cond), + )?; - // `tmp_bound` is inclusive. So trap only if `tmp_addr > tmp_bound`. - self.assembler - .emit_on_false_label_far(Location::GPR(cond), heap_access_oob, jmp_tmp)?; + // `tmp_bound` is inclusive. So trap only if `tmp_addr > tmp_bound`. + self.assembler.emit_on_false_label_far( + Location::GPR(cond), + heap_access_oob, + jmp_tmp, + )?; + } self.release_gpr(tmp_bound); self.release_gpr(cond); @@ -3249,7 +3257,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3260,6 +3268,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3272,7 +3281,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3283,6 +3292,7 @@ impl Machine for MachineRiscv { memarg, false, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3295,7 +3305,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3306,6 +3316,7 @@ impl Machine for MachineRiscv { memarg, false, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3318,7 +3329,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3329,6 +3340,7 @@ impl Machine for MachineRiscv { memarg, false, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3341,7 +3353,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3352,6 +3364,7 @@ impl Machine for MachineRiscv { memarg, false, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3364,7 +3377,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3375,6 +3388,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3387,7 +3401,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3398,6 +3412,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3410,7 +3425,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3421,6 +3436,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3433,7 +3449,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3444,6 +3460,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3456,7 +3473,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3467,6 +3484,7 @@ impl Machine for MachineRiscv { memarg, false, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3479,7 +3497,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3490,6 +3508,7 @@ impl Machine for MachineRiscv { memarg, false, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3502,7 +3521,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3513,6 +3532,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3526,7 +3546,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3537,6 +3557,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3550,7 +3571,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3561,6 +3582,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3575,7 +3597,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3586,6 +3608,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3601,7 +3624,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3612,6 +3635,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3627,7 +3651,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3638,6 +3662,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3653,7 +3678,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3664,6 +3689,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3679,7 +3705,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3690,6 +3716,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3705,7 +3732,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3716,6 +3743,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3731,7 +3759,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3742,6 +3770,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3757,7 +3786,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3768,6 +3797,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3783,7 +3813,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3794,6 +3824,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3809,7 +3840,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3820,6 +3851,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3835,7 +3867,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3846,6 +3878,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3861,7 +3894,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3872,6 +3905,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3887,7 +3921,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3898,6 +3932,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3913,7 +3948,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3924,6 +3959,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -3939,7 +3975,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3950,6 +3986,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -3965,7 +4002,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -3976,6 +4013,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -3991,7 +4029,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4002,6 +4040,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4017,7 +4056,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4028,6 +4067,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4044,7 +4084,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4055,6 +4095,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -4069,7 +4110,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4080,6 +4121,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4094,7 +4136,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4105,6 +4147,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4510,7 +4553,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4521,6 +4564,7 @@ impl Machine for MachineRiscv { memarg, false, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -4533,7 +4577,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4544,6 +4588,7 @@ impl Machine for MachineRiscv { memarg, false, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4556,7 +4601,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4567,6 +4612,7 @@ impl Machine for MachineRiscv { memarg, false, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4579,7 +4625,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4590,6 +4636,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -4602,7 +4649,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4613,6 +4660,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -4625,7 +4673,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4636,6 +4684,7 @@ impl Machine for MachineRiscv { memarg, false, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4648,7 +4697,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4659,6 +4708,7 @@ impl Machine for MachineRiscv { memarg, false, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4671,7 +4721,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4682,6 +4732,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -4694,7 +4745,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4705,6 +4756,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4717,7 +4769,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4728,6 +4780,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4740,7 +4793,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4751,6 +4804,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -4763,7 +4817,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4774,6 +4828,7 @@ impl Machine for MachineRiscv { memarg, false, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -4786,7 +4841,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4797,6 +4852,7 @@ impl Machine for MachineRiscv { memarg, false, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4809,7 +4865,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4820,6 +4876,7 @@ impl Machine for MachineRiscv { memarg, false, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4832,7 +4889,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4843,6 +4900,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -4855,7 +4913,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4866,6 +4924,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -4879,7 +4938,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4890,6 +4949,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -4903,7 +4963,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4914,6 +4974,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -4927,7 +4988,7 @@ impl Machine for MachineRiscv { value: Location, memarg: &MemArg, addr: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4938,6 +4999,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -4952,7 +5014,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4963,6 +5025,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -4978,7 +5041,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -4989,6 +5052,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5004,7 +5068,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5015,6 +5079,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5030,7 +5095,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5041,6 +5106,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5056,7 +5122,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5067,6 +5133,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5082,7 +5149,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5093,6 +5160,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5108,7 +5176,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5119,6 +5187,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5134,7 +5203,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5145,6 +5214,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5160,7 +5230,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5171,6 +5241,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5186,7 +5257,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5197,6 +5268,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5212,7 +5284,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5223,6 +5295,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5238,7 +5311,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5249,6 +5322,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5264,7 +5338,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5275,6 +5349,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5290,7 +5365,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5301,6 +5376,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5316,7 +5392,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5327,6 +5403,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5342,7 +5419,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5353,6 +5430,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5368,7 +5446,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5379,6 +5457,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5394,7 +5473,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5405,6 +5484,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5420,7 +5500,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5431,6 +5511,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5446,7 +5527,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5457,6 +5538,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5472,7 +5554,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5483,6 +5565,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5498,7 +5581,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5509,6 +5592,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5524,7 +5608,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5535,6 +5619,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5550,7 +5635,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5561,6 +5646,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5577,7 +5663,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5588,6 +5674,7 @@ impl Machine for MachineRiscv { memarg, true, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5602,7 +5689,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5613,6 +5700,7 @@ impl Machine for MachineRiscv { memarg, true, 1, + need_check, imported_memories, offset, heap_access_oob, @@ -5627,7 +5715,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5638,6 +5726,7 @@ impl Machine for MachineRiscv { memarg, true, 2, + need_check, imported_memories, offset, heap_access_oob, @@ -5652,7 +5741,7 @@ impl Machine for MachineRiscv { target: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5663,6 +5752,7 @@ impl Machine for MachineRiscv { memarg, true, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5675,7 +5765,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5686,6 +5776,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5699,7 +5790,7 @@ impl Machine for MachineRiscv { memarg: &MemArg, addr: Location, canonicalize: bool, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5710,6 +5801,7 @@ impl Machine for MachineRiscv { memarg, false, 4, + need_check, imported_memories, offset, heap_access_oob, @@ -5728,7 +5820,7 @@ impl Machine for MachineRiscv { addr: Location, memarg: &MemArg, ret: Location, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5739,6 +5831,7 @@ impl Machine for MachineRiscv { memarg, false, 8, + need_check, imported_memories, offset, heap_access_oob, @@ -5752,7 +5845,7 @@ impl Machine for MachineRiscv { memarg: &MemArg, addr: Location, canonicalize: bool, - _need_check: bool, + need_check: bool, imported_memories: bool, offset: i32, heap_access_oob: Label, @@ -5763,6 +5856,7 @@ impl Machine for MachineRiscv { memarg, false, 8, + need_check, imported_memories, offset, heap_access_oob, diff --git a/tests/ignores.txt b/tests/ignores.txt index c9526787ba0d..0b0420b61d0c 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -125,10 +125,14 @@ llvm+loongarch64 spec::simd_splat::llvm # Windows doesn't overcommit and fails to allocate 4GB of memory windows wasmer::max_size_of_memory -# Some AARCH64 CPU have issue with segfault writin 64bits on border page, where the 1 32bits might be written. +# Some AARCH64 CPU have issue with segfaults writin 64bits on border page, where the 1 32bits might be written. aarch64+linux spec::align aarch64+linux spec::memory_trap +# Similarly for RISC-V +riscv64+singlepass spec::align +riscv64+singlepass spec::memory_trap + spec::instance # TODO: #5816 From b5e3d6c24c662224a63df57f804b900992af0712 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 25 Mar 2026 11:43:11 +0100 Subject: [PATCH 2/4] add strict_memory_boundary_checks Singlepass config option --- lib/compiler-singlepass/README.md | 10 ++++-- lib/compiler-singlepass/src/codegen.rs | 9 ++--- lib/compiler-singlepass/src/config.rs | 17 ++++++++++ tests/compilers/issues.rs | 47 ++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/lib/compiler-singlepass/README.md b/lib/compiler-singlepass/README.md index 955f7c68dc54..defc7998fd7a 100644 --- a/lib/compiler-singlepass/README.md +++ b/lib/compiler-singlepass/README.md @@ -5,17 +5,23 @@ This crate contains a compiler implementation based on the Singlepass linear com Supported targets: - x86_64 - aarch64 -- riscv64 (experimental) +- riscv64 + ## Usage ```rust use wasmer::{Store, sys::EngineBuilder}; use wasmer_compiler_singlepass::Singlepass; -let compiler = Singlepass::new(); +let mut compiler = Singlepass::new(); +compiler.strict_memory_boundary_checks(true); let mut store = Store::new(compiler); ``` +`strict_memory_boundary_checks(true)` forces Singlepass to emit explicit +memory bounds checks for every memory access, including static memories that +would otherwise use the unchecked fast path. + *Note: you can find a [full working example using Singlepass compiler here][example].* diff --git a/lib/compiler-singlepass/src/codegen.rs b/lib/compiler-singlepass/src/codegen.rs index 2251fdcc61d2..74eeb5bbdc43 100644 --- a/lib/compiler-singlepass/src/codegen.rs +++ b/lib/compiler-singlepass/src/codegen.rs @@ -837,10 +837,11 @@ impl<'a, M: Machine> FuncGen<'a, M> { &mut self, cb: F, ) -> Result<(), CompileError> { - let need_check = match self.memory_styles[MemoryIndex::new(0)] { - MemoryStyle::Static { .. } => false, - MemoryStyle::Dynamic { .. } => true, - }; + let need_check = self.config.strict_memory_boundary_checks + || match self.memory_styles[MemoryIndex::new(0)] { + MemoryStyle::Static { .. } => false, + MemoryStyle::Dynamic { .. } => true, + }; let offset = if self.module.num_imported_memories != 0 { self.vmoffsets diff --git a/lib/compiler-singlepass/src/config.rs b/lib/compiler-singlepass/src/config.rs index 1f4b2fd65fe1..79b53ae5e5fb 100644 --- a/lib/compiler-singlepass/src/config.rs +++ b/lib/compiler-singlepass/src/config.rs @@ -77,6 +77,9 @@ impl SinglepassCallbacks { pub struct Singlepass { pub(crate) enable_nan_canonicalization: bool, + /// Forces strict memory boundary checks for every memory access. + pub(crate) strict_memory_boundary_checks: bool, + /// The middleware chain. pub(crate) middlewares: Vec>, @@ -92,12 +95,26 @@ impl Singlepass { pub fn new() -> Self { Self { enable_nan_canonicalization: true, + strict_memory_boundary_checks: false, middlewares: vec![], callbacks: None, num_threads: std::thread::available_parallelism().unwrap_or(NonZero::new(1).unwrap()), } } + /// Configure whether Singlepass should always emit strict memory boundary + /// checks for memory accesses. + /// + /// When enabled, Singlepass always requests explicit memory bounds checks + /// from `op_memory`, even for static memories that would normally rely + /// on the access violation signal. + pub fn strict_memory_boundary_checks(&mut self, enable: bool) -> &mut Self { + self.strict_memory_boundary_checks = enable; + self + } + + /// Configure whether Singlepass should canonicalize NaNs during code + /// generation. pub fn canonicalize_nans(&mut self, enable: bool) -> &mut Self { self.enable_nan_canonicalization = enable; self diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs index 464fd0069a81..7c3bdf3e01c7 100644 --- a/tests/compilers/issues.rs +++ b/tests/compilers/issues.rs @@ -987,3 +987,50 @@ fn issue_return_call_indirect_import(mut config: crate::Config) -> Result<()> { Ok(()) } + +//#[cfg(feature = "singlepass")] +#[compiler_test(issues)] +fn singlepass_memory_trap(mut config: crate::Config) -> Result<()> { + use tempfile::TempDir; + use wasmer_compiler::EngineBuilder; + + let mut compiler_config = wasmer_compiler_singlepass::Singlepass::default(); + compiler_config.strict_memory_boundary_checks(true); + let mut store = Store::new(EngineBuilder::new(compiler_config)); + + let wasm_bytes = wat2wasm( + r#" +(module + (memory (export "memory") 1) + (data (i32.const 65528) "\01\02\03\04\05\06\07\08") + (func (export "run") + i32.const 65529 + i32.const 0 + i32.const 1 + select + i64.const 0 + i64.store) +) +"# + .as_bytes(), + ) + .expect("wat2wasm must succeed"); + + let module = Module::new(&store, wasm_bytes)?; + let instance = Instance::new(&mut store, &module, &imports! {})?; + let memory = instance.exports.get_memory("memory")?; + let run = instance.exports.get_function("run")?; + + let mut before = [0_u8; 8]; + memory.view(&store).read(65528, &mut before)?; + assert_eq!(before, [1, 2, 3, 4, 5, 6, 7, 8]); + + let trap = run.call(&mut store, &[]); + assert!(trap.is_err(), "expected out-of-bounds store to trap"); + + let mut after = [0_u8; 8]; + memory.view(&store).read(65528, &mut after)?; + assert_eq!(after, before); + + Ok(()) +} From 7659d33a0a8c57c6b8745bc0dda62073e159a228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Li=C5=A1ka?= Date: Wed, 25 Mar 2026 12:12:57 +0100 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- tests/compilers/issues.rs | 5 ++++- tests/ignores.txt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs index 7c3bdf3e01c7..cfe3f3f58c83 100644 --- a/tests/compilers/issues.rs +++ b/tests/compilers/issues.rs @@ -988,9 +988,12 @@ fn issue_return_call_indirect_import(mut config: crate::Config) -> Result<()> { Ok(()) } -//#[cfg(feature = "singlepass")] +#[cfg(feature = "singlepass")] #[compiler_test(issues)] fn singlepass_memory_trap(mut config: crate::Config) -> Result<()> { + if config.compiler != crate::Compiler::Singlepass { + return Ok(()); + } use tempfile::TempDir; use wasmer_compiler::EngineBuilder; diff --git a/tests/ignores.txt b/tests/ignores.txt index 0b0420b61d0c..af27ec8f0d42 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -125,7 +125,7 @@ llvm+loongarch64 spec::simd_splat::llvm # Windows doesn't overcommit and fails to allocate 4GB of memory windows wasmer::max_size_of_memory -# Some AARCH64 CPU have issue with segfaults writin 64bits on border page, where the 1 32bits might be written. +# Some AARCH64 CPU have issue with segfaults writing 64bits on border page, where the 1 32bits might be written. aarch64+linux spec::align aarch64+linux spec::memory_trap From 72828ddbac362985516bf1d72f7aef90bf5f1e47 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 25 Mar 2026 12:14:31 +0100 Subject: [PATCH 4/4] simplify imports --- tests/compilers/issues.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs index cfe3f3f58c83..51ac97bbfda9 100644 --- a/tests/compilers/issues.rs +++ b/tests/compilers/issues.rs @@ -994,12 +994,10 @@ fn singlepass_memory_trap(mut config: crate::Config) -> Result<()> { if config.compiler != crate::Compiler::Singlepass { return Ok(()); } - use tempfile::TempDir; - use wasmer_compiler::EngineBuilder; let mut compiler_config = wasmer_compiler_singlepass::Singlepass::default(); compiler_config.strict_memory_boundary_checks(true); - let mut store = Store::new(EngineBuilder::new(compiler_config)); + let mut store = Store::new(wasmer_compiler::EngineBuilder::new(compiler_config)); let wasm_bytes = wat2wasm( r#"