Skip to content

Commit f4283c6

Browse files
tekknolagik0kubun
authored andcommitted
Fix VALUE/isize conversion
Coming out of VALUE did not work for negative numbers; they came out as huge numbers instead. Add more tests.
1 parent 6ec411a commit f4283c6

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

zjit/src/cruby.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ impl VALUE {
487487

488488
pub fn as_fixnum(self) -> i64 {
489489
assert!(self.fixnum_p());
490-
(self.0 >> 1) as i64
490+
(self.0 as i64) >> 1
491491
}
492492

493493
pub fn as_isize(self) -> isize {
@@ -572,6 +572,13 @@ impl VALUE {
572572
let k: usize = item.wrapping_add(item.wrapping_add(1));
573573
VALUE(k)
574574
}
575+
576+
pub const fn fixnum_from_isize(item: isize) -> Self {
577+
assert!(item >= RUBY_FIXNUM_MIN);
578+
assert!(item <= RUBY_FIXNUM_MAX);
579+
let k: isize = item.wrapping_add(item.wrapping_add(1));
580+
VALUE(k as usize)
581+
}
575582
}
576583

577584
impl From<IseqPtr> for VALUE {
@@ -1074,6 +1081,51 @@ pub mod test_utils {
10741081
eval("raise");
10751082
}
10761083

1084+
#[test]
1085+
fn value_from_fixnum_in_range() {
1086+
assert_eq!(VALUE::fixnum_from_usize(2), VALUE(5));
1087+
assert_eq!(VALUE::fixnum_from_usize(0), VALUE(1));
1088+
assert_eq!(VALUE::fixnum_from_isize(-1), VALUE(0xffffffffffffffff));
1089+
assert_eq!(VALUE::fixnum_from_isize(-2), VALUE(0xfffffffffffffffd));
1090+
assert_eq!(VALUE::fixnum_from_usize(RUBY_FIXNUM_MAX as usize), VALUE(0x7fffffffffffffff));
1091+
assert_eq!(VALUE::fixnum_from_isize(RUBY_FIXNUM_MAX), VALUE(0x7fffffffffffffff));
1092+
assert_eq!(VALUE::fixnum_from_isize(RUBY_FIXNUM_MIN), VALUE(0x8000000000000001));
1093+
}
1094+
1095+
#[test]
1096+
fn value_as_fixnum() {
1097+
assert_eq!(VALUE::fixnum_from_usize(2).as_fixnum(), 2);
1098+
assert_eq!(VALUE::fixnum_from_usize(0).as_fixnum(), 0);
1099+
assert_eq!(VALUE::fixnum_from_isize(-1).as_fixnum(), -1);
1100+
assert_eq!(VALUE::fixnum_from_isize(-2).as_fixnum(), -2);
1101+
assert_eq!(VALUE::fixnum_from_usize(RUBY_FIXNUM_MAX as usize).as_fixnum(), RUBY_FIXNUM_MAX.try_into().unwrap());
1102+
assert_eq!(VALUE::fixnum_from_isize(RUBY_FIXNUM_MAX).as_fixnum(), RUBY_FIXNUM_MAX.try_into().unwrap());
1103+
assert_eq!(VALUE::fixnum_from_isize(RUBY_FIXNUM_MIN).as_fixnum(), RUBY_FIXNUM_MIN.try_into().unwrap());
1104+
}
1105+
1106+
#[test]
1107+
#[should_panic]
1108+
fn value_from_fixnum_too_big_usize() {
1109+
assert_eq!(VALUE::fixnum_from_usize((RUBY_FIXNUM_MAX+1) as usize), VALUE(1));
1110+
}
1111+
1112+
#[test]
1113+
#[should_panic]
1114+
fn value_from_fixnum_too_big_isize() {
1115+
assert_eq!(VALUE::fixnum_from_isize(RUBY_FIXNUM_MAX+1), VALUE(1));
1116+
}
1117+
1118+
#[test]
1119+
#[should_panic]
1120+
fn value_from_fixnum_too_small_usize() {
1121+
assert_eq!(VALUE::fixnum_from_usize((RUBY_FIXNUM_MIN-1) as usize), VALUE(1));
1122+
}
1123+
1124+
#[test]
1125+
#[should_panic]
1126+
fn value_from_fixnum_too_small_isize() {
1127+
assert_eq!(VALUE::fixnum_from_isize(RUBY_FIXNUM_MIN-1), VALUE(1));
1128+
}
10771129
}
10781130
#[cfg(test)]
10791131
pub use test_utils::*;

0 commit comments

Comments
 (0)