Skip to content

Commit

Permalink
Fix tests and test262 on 32 and 64 bits platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
hansl committed Dec 16, 2024
1 parent 02ae225 commit 442bc60
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 14 deletions.
4 changes: 4 additions & 0 deletions core/engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3199,10 +3199,12 @@ impl Array {
// 2. If relativeStart is -∞, let k be 0.
IntegerOrInfinity::NegativeInfinity => 0,
// 3. Else if relativeStart < 0, let k be max(len + relativeStart, 0).
IntegerOrInfinity::Integer(i) if i <= (isize::MIN as i64) => 0,
IntegerOrInfinity::Integer(i) if i < 0 => {
len.checked_add_signed(i as isize).unwrap_or(0)
}
// 4. Else, let k be min(relativeStart, len).
IntegerOrInfinity::Integer(i) if i as u64 > usize::MAX as u64 => len,
IntegerOrInfinity::Integer(i) => min(i as usize, len),

// Special case - positive infinity. `len` is always smaller than +inf, thus from (4)
Expand All @@ -3228,11 +3230,13 @@ impl Array {
// 2. If relativeEnd is -∞, let final be 0.
IntegerOrInfinity::NegativeInfinity => 0,
// 3. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
IntegerOrInfinity::Integer(i) if i < 0 && i <= isize::MIN as i64 => 0,
IntegerOrInfinity::Integer(i) if i < 0 => {
len.checked_add_signed(i as isize).unwrap_or(0)
}
// 4. Else, let final be min(relativeEnd, len).
// Both `as` casts are safe as both variables are non-negative
IntegerOrInfinity::Integer(i) if i as u64 >= usize::MAX as u64 => len,
IntegerOrInfinity::Integer(i) => min(i as usize, len),

// Special case - positive infinity. `len` is always smaller than +inf, thus from (4)
Expand Down
2 changes: 1 addition & 1 deletion core/engine/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1537,7 +1537,7 @@ impl RegExp {
.to_integer_or_infinity(context)?;

// f. Set position to the result of clamping position between 0 and lengthS.
let position = position.clamp_finite(0, length_s as i64) as usize;
let position = position.clamp_finite(0, length_s);

// g. Let captures be a new empty List.
let mut captures = Vec::new();
Expand Down
18 changes: 10 additions & 8 deletions core/engine/src/builtins/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,9 @@ impl String {
// 3. Let n be ? ToIntegerOrInfinity(count).
match args.get_or_undefined(0).to_integer_or_infinity(context)? {
IntegerOrInfinity::Integer(n)
if n > 0 && (n as usize) * len <= Self::MAX_STRING_LENGTH =>
if n > 0
&& usize::try_from(n).is_ok()
&& (n as usize) * len <= Self::MAX_STRING_LENGTH =>
{
if string.is_empty() {
return Ok(js_string!().into());
Expand Down Expand Up @@ -837,7 +839,7 @@ impl String {
let search_string = search_string.to_string(context)?;

// 6. Let len be the length of S.
let len = string.len() as i64;
let len = string.len();

// 7. If position is undefined, let pos be 0; else let pos be ? ToIntegerOrInfinity(position).
let pos = match args.get_or_undefined(1) {
Expand All @@ -846,7 +848,7 @@ impl String {
};

// 8. Let start be the result of clamping pos between 0 and len.
let start = pos.clamp_finite(0, len) as usize;
let start = pos.clamp_finite(0, len);

// 9. Let searchLength be the length of searchStr.
let search_length = search_string.len();
Expand All @@ -857,10 +859,10 @@ impl String {
}

// 11. Let end be start + searchLength.
let end = start + search_length;
let end = start.saturating_add(search_length);

// 12. If end > len, return false.
if end > len as usize {
if end > len {
Ok(JsValue::new(false))
} else {
// 13. Let substring be the substring of S from start to end.
Expand Down Expand Up @@ -905,16 +907,16 @@ impl String {
};

// 6. Let len be the length of S.
let len = string.len() as i64;
let len = string.len();

// 7. If endPosition is undefined, let pos be len; else let pos be ? ToIntegerOrInfinity(endPosition).
let end = match args.get_or_undefined(1) {
end_position if end_position.is_undefined() => IntegerOrInfinity::Integer(len),
end_position if end_position.is_undefined() => IntegerOrInfinity::Integer(len as i64),
end_position => end_position.to_integer_or_infinity(context)?,
};

// 8. Let end be the result of clamping pos between 0 and len.
let end = end.clamp_finite(0, len) as usize;
let end = end.clamp_finite(0, len);

// 9. Let searchLength be the length of searchStr.
let search_length = search_str.len();
Expand Down
8 changes: 5 additions & 3 deletions core/engine/src/value/integer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use num_traits::{AsPrimitive, FromPrimitive};
use std::cmp::Ordering;

/// Represents the result of the `ToIntegerOrInfinity` operation
Expand All @@ -21,10 +22,11 @@ impl IntegerOrInfinity {
///
/// Panics if `min > max`.
#[must_use]
pub fn clamp_finite(self, min: i64, max: i64) -> i64 {
assert!(min <= max);
pub fn clamp_finite<T: Ord + AsPrimitive<i64> + FromPrimitive>(self, min: T, max: T) -> T {
match self {
Self::Integer(i) => i.clamp(min, max),
Self::Integer(i) => {
T::from_i64(i.clamp(min.as_(), max.as_())).expect("`i` should already be clamped")
}
Self::PositiveInfinity => max,
Self::NegativeInfinity => min,
}
Expand Down
4 changes: 2 additions & 2 deletions core/engine/src/value/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,8 @@ fn to_length() {
assert_eq!(JsValue::new(20.9).to_length(ctx).unwrap(), 20);
assert_eq!(JsValue::new(-20.9).to_length(ctx).unwrap(), 0);
assert_eq!(
JsValue::new(100_000_000_000.0).to_length(ctx).unwrap(),
100_000_000_000
JsValue::new(100_000_000.0).to_length(ctx).unwrap(),
100_000_000
);
assert_eq!(
JsValue::new(4_010_101_101.0).to_length(ctx).unwrap(),
Expand Down

0 comments on commit 442bc60

Please sign in to comment.