Skip to content

Commit 12c8ec8

Browse files
committed
ZJIT: Check for size >= expected in expandarray
Turns out `a, b = [1, 2, 3, 4]` is perfectly valid and just assigns `a = 1` and `b = 2` (and drops the rest). optcarrot relies on this. Allow it.
1 parent f4909ab commit 12c8ec8

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

zjit/src/hir.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7449,7 +7449,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
74497449
let val = state.stack_pop()?;
74507450
let array = fun.push_insn(block, Insn::GuardType { val, guard_type: types::ArrayExact, state: exit_id, });
74517451
let length = fun.push_insn(block, Insn::ArrayLength { array });
7452-
fun.push_insn(block, Insn::GuardBitEquals { val: length, expected: Const::CInt64(num as i64), reason: SideExitReason::ExpandArray, state: exit_id });
7452+
let expected = fun.push_insn(block, Insn::Const { val: Const::CInt64(num as i64) });
7453+
fun.push_insn(block, Insn::GuardGreaterEq { left: length, right: expected, reason: SideExitReason::ExpandArray, state: exit_id });
74537454
for i in (0..num).rev() {
74547455
// We do not emit a length guard here because in-bounds is already
74557456
// ensured by the expandarray length check above.

zjit/src/hir/tests.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3834,11 +3834,12 @@ pub mod hir_build_tests {
38343834
bb2(v12:BasicObject, v13:BasicObject, v14:NilClass, v15:NilClass):
38353835
v21:ArrayExact = GuardType v13, ArrayExact
38363836
v22:CInt64 = ArrayLength v21
3837-
v23:CInt64[2] = GuardBitEquals v22, CInt64(2)
3838-
v24:CInt64[1] = Const CInt64(1)
3839-
v25:BasicObject = ArrayAref v21, v24
3840-
v26:CInt64[0] = Const CInt64(0)
3841-
v27:BasicObject = ArrayAref v21, v26
3837+
v23:CInt64[2] = Const CInt64(2)
3838+
v24:CInt64 = GuardGreaterEq v22, v23
3839+
v25:CInt64[1] = Const CInt64(1)
3840+
v26:BasicObject = ArrayAref v21, v25
3841+
v27:CInt64[0] = Const CInt64(0)
3842+
v28:BasicObject = ArrayAref v21, v27
38423843
PatchPoint NoEPEscape(test)
38433844
CheckInterrupts
38443845
Return v13

0 commit comments

Comments
 (0)