diff options
| author | Max Bernstein <ruby@bernsteinbear.com> | 2026-03-25 09:59:07 -0400 |
|---|---|---|
| committer | Max Bernstein <tekknolagi@gmail.com> | 2026-03-25 14:02:09 -0400 |
| commit | be783db2c2bb73456f808291aa4f72fa02861641 (patch) | |
| tree | 6565ccfa17b5a69ab12d9dddc6a53d498ba7bfdd /zjit | |
| parent | 17cd9bffd37710dbcd746a62b3d49ea7213095ed (diff) | |
ZJIT: Support negative indices in more places
Diffstat (limited to 'zjit')
| -rw-r--r-- | zjit/src/cruby_methods.rs | 3 | ||||
| -rw-r--r-- | zjit/src/hir/opt_tests.rs | 47 |
2 files changed, 29 insertions, 21 deletions
diff --git a/zjit/src/cruby_methods.rs b/zjit/src/cruby_methods.rs index bd4310e084..767f6499e8 100644 --- a/zjit/src/cruby_methods.rs +++ b/zjit/src/cruby_methods.rs @@ -379,6 +379,7 @@ fn inline_array_aset(fun: &mut hir::Function, block: hir::BlockId, recv: hir::In let index = fun.push_insn(block, hir::Insn::UnboxFixnum { val: index }); let length = fun.push_insn(block, hir::Insn::ArrayLength { array: recv }); let index = fun.push_insn(block, hir::Insn::GuardLess { left: index, right: length, state }); + let index = fun.push_insn(block, hir::Insn::AdjustBounds { index, length }); let zero = fun.push_insn(block, hir::Insn::Const { val: hir::Const::CInt64(0) }); use crate::hir::SideExitReason; let index = fun.push_insn(block, hir::Insn::GuardGreaterEq { left: index, right: zero, reason: SideExitReason::GuardGreaterEq, state }); @@ -476,6 +477,7 @@ fn inline_string_getbyte(fun: &mut hir::Function, block: hir::BlockId, recv: hir // // This is unlike most other guards. let unboxed_index = fun.push_insn(block, hir::Insn::GuardLess { left: unboxed_index, right: len, state }); + let unboxed_index = fun.push_insn(block, hir::Insn::AdjustBounds { index: unboxed_index, length: len }); let zero = fun.push_insn(block, hir::Insn::Const { val: hir::Const::CInt64(0) }); use crate::hir::SideExitReason; let _ = fun.push_insn(block, hir::Insn::GuardGreaterEq { left: unboxed_index, right: zero, reason: SideExitReason::GuardGreaterEq, state }); @@ -499,6 +501,7 @@ fn inline_string_setbyte(fun: &mut hir::Function, block: hir::BlockId, recv: hir return_type: types::CInt64, }); let unboxed_index = fun.push_insn(block, hir::Insn::GuardLess { left: unboxed_index, right: len, state }); + let unboxed_index = fun.push_insn(block, hir::Insn::AdjustBounds { index: unboxed_index, length: len }); let zero = fun.push_insn(block, hir::Insn::Const { val: hir::Const::CInt64(0) }); use crate::hir::SideExitReason; let _ = fun.push_insn(block, hir::Insn::GuardGreaterEq { left: unboxed_index, right: zero, reason: SideExitReason::GuardGreaterEq, state }); diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index db3889449f..af438c361b 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -9062,9 +9062,9 @@ mod hir_opt_tests { v34:CUInt64 = LoadField v33, :_rbasic_flags@0x1040 v35:CUInt64 = GuardNoBitsSet v34, RUBY_FL_FREEZE=CUInt64(2048) v37:CUInt64 = GuardNoBitsSet v34, RUBY_ELTS_SHARED=CUInt64(4096) - v45:CInt64[1] = Const CInt64(1) + v46:CInt64[1] = Const CInt64(1) v39:CInt64 = ArrayLength v33 - v40:CInt64[1] = GuardLess v45, v39 + v40:CInt64[1] = GuardLess v46, v39 ArrayAset v33, v40, v19 WriteBarrier v33, v19 CheckInterrupts @@ -9108,9 +9108,10 @@ mod hir_opt_tests { v43:CInt64 = UnboxFixnum v38 v44:CInt64 = ArrayLength v37 v45:CInt64 = GuardLess v43, v44 - v46:CInt64[0] = Const CInt64(0) - v47:CInt64 = GuardGreaterEq v45, v46 - ArrayAset v37, v47, v16 + v46:CInt64 = AdjustBounds v45, v44 + v47:CInt64[0] = Const CInt64(0) + v48:CInt64 = GuardGreaterEq v46, v47 + ArrayAset v37, v48, v16 WriteBarrier v37, v16 CheckInterrupts Return v16 @@ -9533,11 +9534,12 @@ mod hir_opt_tests { v30:CInt64 = UnboxFixnum v29 v31:CInt64 = LoadField v28, :len@0x1040 v32:CInt64 = GuardLess v30, v31 - v33:CInt64[0] = Const CInt64(0) - v34:CInt64 = GuardGreaterEq v32, v33 - v35:Fixnum = StringGetbyte v28, v32 + v33:CInt64 = AdjustBounds v32, v31 + v34:CInt64[0] = Const CInt64(0) + v35:CInt64 = GuardGreaterEq v33, v34 + v36:Fixnum = StringGetbyte v28, v33 CheckInterrupts - Return v35 + Return v36 "); } @@ -9573,8 +9575,9 @@ mod hir_opt_tests { v34:CInt64 = UnboxFixnum v33 v35:CInt64 = LoadField v32, :len@0x1040 v36:CInt64 = GuardLess v34, v35 - v37:CInt64[0] = Const CInt64(0) - v38:CInt64 = GuardGreaterEq v36, v37 + v37:CInt64 = AdjustBounds v36, v35 + v38:CInt64[0] = Const CInt64(0) + v39:CInt64 = GuardGreaterEq v37, v38 v23:Fixnum[5] = Const Value(5) CheckInterrupts Return v23 @@ -9615,11 +9618,12 @@ mod hir_opt_tests { v35:CInt64 = UnboxFixnum v33 v36:CInt64 = LoadField v32, :len@0x1040 v37:CInt64 = GuardLess v35, v36 - v38:CInt64[0] = Const CInt64(0) - v39:CInt64 = GuardGreaterEq v37, v38 - v40:CUInt64 = LoadField v32, :_rbasic_flags@0x1041 - v41:CUInt64 = GuardNoBitsSet v40, RUBY_FL_FREEZE=CUInt64(2048) - v42:Fixnum = StringSetbyteFixnum v32, v33, v34 + v38:CInt64 = AdjustBounds v37, v36 + v39:CInt64[0] = Const CInt64(0) + v40:CInt64 = GuardGreaterEq v38, v39 + v41:CUInt64 = LoadField v32, :_rbasic_flags@0x1041 + v42:CUInt64 = GuardNoBitsSet v41, RUBY_FL_FREEZE=CUInt64(2048) + v43:Fixnum = StringSetbyteFixnum v32, v33, v34 CheckInterrupts Return v34 "); @@ -9661,11 +9665,12 @@ mod hir_opt_tests { v35:CInt64 = UnboxFixnum v33 v36:CInt64 = LoadField v32, :len@0x1040 v37:CInt64 = GuardLess v35, v36 - v38:CInt64[0] = Const CInt64(0) - v39:CInt64 = GuardGreaterEq v37, v38 - v40:CUInt64 = LoadField v32, :_rbasic_flags@0x1041 - v41:CUInt64 = GuardNoBitsSet v40, RUBY_FL_FREEZE=CUInt64(2048) - v42:Fixnum = StringSetbyteFixnum v32, v33, v34 + v38:CInt64 = AdjustBounds v37, v36 + v39:CInt64[0] = Const CInt64(0) + v40:CInt64 = GuardGreaterEq v38, v39 + v41:CUInt64 = LoadField v32, :_rbasic_flags@0x1041 + v42:CUInt64 = GuardNoBitsSet v41, RUBY_FL_FREEZE=CUInt64(2048) + v43:Fixnum = StringSetbyteFixnum v32, v33, v34 CheckInterrupts Return v34 "); |
