diff --git a/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs b/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs index b22a146f..6b284d4b 100644 --- a/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs +++ b/nova_vm/src/ecmascript/abstract_operations/type_conversion.rs @@ -470,9 +470,6 @@ pub(crate) fn to_integer_or_infinity( // Fast path: A safe integer is already an integer. if let Value::Integer(int) = argument { let int = IntegerOrInfinity(int.into_i64()); - // Note: It should be impossible for the integer to be outside of safe - // integer limits. - debug_assert!(int.is_safe_integer()); return Ok(int); } // 1. Let number be ? ToNumber(argument). @@ -481,7 +478,6 @@ pub(crate) fn to_integer_or_infinity( // Fast path: The value might've been eg. parsed into an integer. if let Number::Integer(int) = number { let int = IntegerOrInfinity(int.into_i64()); - debug_assert!(int.is_safe_integer()); return Ok(int); } @@ -532,9 +528,6 @@ pub(crate) fn try_to_integer_or_infinity( // Fast path: A safe integer is already an integer. if let Value::Integer(int) = argument { let int = IntegerOrInfinity(int.into_i64()); - // Note: It should be impossible for the integer to be outside of safe - // integer limits. - debug_assert!(int.is_safe_integer()); return Some(Ok(int)); } // 1. Let number be ? ToNumber(argument). @@ -552,7 +545,6 @@ pub(crate) fn try_to_integer_or_infinity( // Fast path: The value might've been eg. parsed into an integer. if let Number::Integer(int) = number { let int = IntegerOrInfinity(int.into_i64()); - debug_assert!(int.is_safe_integer()); return Some(Ok(int)); } diff --git a/nova_vm/src/ecmascript/builtins/numbers_and_dates/math_object.rs b/nova_vm/src/ecmascript/builtins/numbers_and_dates/math_object.rs index c566bcb7..e6d557a8 100644 --- a/nova_vm/src/ecmascript/builtins/numbers_and_dates/math_object.rs +++ b/nova_vm/src/ecmascript/builtins/numbers_and_dates/math_object.rs @@ -14,7 +14,6 @@ use crate::{ }, engine::context::{GcScope, NoGcScope}, heap::WellKnownSymbolIndexes, - SmallInteger, }; pub(crate) struct MathObject; @@ -1315,11 +1314,20 @@ impl MathObject { let base = base.into_i64(); let exponent = exponent.into_i64(); if let Ok(exponent) = u32::try_from(exponent) { - let result = (base as i128).pow(exponent); - if let Ok(result) = SmallInteger::try_from(result) { - return Ok(Value::Integer(result)); - } else { + if let Some(result) = base.checked_pow(exponent) { + if let Ok(result) = Number::try_from(result) { + return Ok(result.into_value()); + } else { + return Ok(Value::from_f64(agent, gc.into_nogc(), result as f64)); + } + } else if let Some(result) = (base as i128).checked_pow(exponent) { return Ok(Value::from_f64(agent, gc.into_nogc(), result as f64)); + } else { + return Ok(Value::from_f64( + agent, + gc.into_nogc(), + (base as f64).powf(exponent as f64), + )); } } else if let Ok(exponent) = i32::try_from(exponent) { let result = (base as f64).powi(exponent); diff --git a/nova_vm/src/ecmascript/types/language/number.rs b/nova_vm/src/ecmascript/types/language/number.rs index 4ee26489..10ba7ca4 100644 --- a/nova_vm/src/ecmascript/types/language/number.rs +++ b/nova_vm/src/ecmascript/types/language/number.rs @@ -190,6 +190,14 @@ impl TryFrom for Number<'static> { } } +impl TryFrom for Number<'static> { + type Error = (); + + fn try_from(value: u64) -> Result { + Ok(Number::Integer(SmallInteger::try_from(value)?)) + } +} + impl TryFrom for Number<'static> { type Error = (); diff --git a/tests/expectations.json b/tests/expectations.json index 79def6a8..a49b0935 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -23481,9 +23481,6 @@ "language/statements/with/unscopables-inc-dec.js": "CRASH", "language/statements/with/unscopables-not-referenced-for-undef.js": "CRASH", "language/statements/with/unscopables-prop-get-err.js": "CRASH", - "language/types/number/S8.5_A13_T2.js": "CRASH", - "language/types/number/S8.5_A14_T1.js": "CRASH", - "language/types/number/S8.5_A14_T2.js": "CRASH", "language/types/reference/get-value-prop-base-primitive-realm.js": "FAIL", "language/types/reference/put-value-prop-base-primitive-realm.js": "FAIL", "language/types/reference/put-value-prop-base-primitive.js": "CRASH", diff --git a/tests/metrics.json b/tests/metrics.json index 9784ac11..2df48b07 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,8 +1,8 @@ { "results": { "crash": 14782, - "fail": 8755, - "pass": 21706, + "fail": 8752, + "pass": 21709, "skip": 45, "timeout": 3, "unresolved": 0