From a5e8eb279148e15a0481205074007d9c7f5d5f8c Mon Sep 17 00:00:00 2001 From: joshwd36 Date: Sun, 12 Jul 2020 14:31:33 +0100 Subject: [PATCH 1/5] Add missing Number methods. --- boa/src/builtins/number/mod.rs | 223 +++++++++++++++++++++++++++++++ boa/src/builtins/number/tests.rs | 136 +++++++++++++++++++ 2 files changed, 359 insertions(+) diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index a69e94c5199..a32b4f18b1d 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -555,6 +555,221 @@ impl Number { } } + /// Builtin javascript 'isFinite(number)' function. + /// + /// Converts the argument to a number, throwing a type error if the conversion is invalid. + /// + /// If the number is NaN, +∞, or -∞ false is returned. + /// + /// Otherwise true is returned. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-isfinite-number + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite + pub(crate) fn global_is_finite( + _this: &Value, + args: &[Value], + ctx: &mut Interpreter, + ) -> ResultValue { + if let Some(val) = args.get(0) { + let number = ctx.to_number(val)?; + Ok(Value::Boolean(number.is_finite())) + } else { + Ok(Value::Boolean(false)) + } + } + + /// Builtin javascript 'isNaN(number)' function. + /// + /// Converts the argument to a number, throwing a type error if the conversion is invalid. + /// + /// If the number is NaN true is returned. + /// + /// Otherwise false is returned. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-isnan-number + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN + pub(crate) fn global_is_nan( + _this: &Value, + args: &[Value], + ctx: &mut Interpreter, + ) -> ResultValue { + if let Some(val) = args.get(0) { + let number = ctx.to_number(val)?; + Ok(Value::Boolean(number.is_nan())) + } else { + Ok(Value::Boolean(true)) + } + } + + /// `Number.isFinite( number )` + /// + /// Checks if the argument is a number, returning false if it isn't. + /// + /// If the number is NaN, +∞, or -∞ false is returned. + /// + /// Otherwise true is returned. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-number.isfinite + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite + pub(crate) fn number_is_finite( + _this: &Value, + args: &[Value], + _ctx: &mut Interpreter, + ) -> ResultValue { + Ok(Value::Boolean(if let Some(val) = args.get(0) { + match val { + Value::Integer(_) => true, + Value::Rational(number) => number.is_finite(), + Value::Object(ref obj) => { + let obj = obj.borrow(); + if let Some(number) = obj.as_number() { + number.is_finite() + } else { + false + } + } + _ => false, + } + } else { + false + })) + } + + /// `Number.isInteger( number )` + /// + /// Checks if the argument is an integer. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-number.isinteger + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger + pub(crate) fn number_is_integer( + _this: &Value, + args: &[Value], + _ctx: &mut Interpreter, + ) -> ResultValue { + Ok(Value::Boolean(if let Some(val) = args.get(0) { + Number::is_integer(val).is_some() + } else { + false + })) + } + + /// `Number.isNaN( number )` + /// + /// Checks if the argument is a number, returning false if it isn't. + /// + /// If the number is NaN true is returned. + /// + /// Otherwise false is returned. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-isnan-number + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN + pub(crate) fn number_is_nan( + _this: &Value, + args: &[Value], + _ctx: &mut Interpreter, + ) -> ResultValue { + Ok(Value::Boolean(if let Some(val) = args.get(0) { + match val { + Value::Integer(_) => false, + Value::Rational(number) => number.is_nan(), + Value::Object(ref obj) => { + let obj = obj.borrow(); + if let Some(number) = obj.as_number() { + number.is_nan() + } else { + false + } + } + _ => false, + } + } else { + false + })) + } + + /// `Number.isSafeInteger( number )` + /// + /// Checks if the argument is an integer, returning false if it isn't. + /// + /// If abs(number) ≤ MAX_SAFE_INTEGER true is returned. + /// + /// Otherwise false is returned. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-isnan-number + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN + pub(crate) fn is_safe_integer( + _this: &Value, + args: &[Value], + _ctx: &mut Interpreter, + ) -> ResultValue { + Ok(Value::Boolean(if let Some(val) = args.get(0) { + if let Some(integer) = Number::is_integer(val) { + integer.abs() <= Number::MAX_SAFE_INTEGER + } else { + false + } + } else { + false + })) + } + + /// Checks if the argument is a finite integer Number value. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// + /// [spec]: https://tc39.es/ecma262/#sec-isinteger + #[allow(clippy::float_cmp)] + pub(crate) fn is_integer(val: &Value) -> Option { + match val { + Value::Integer(number) => Some((*number).into()), + Value::Rational(number) => { + if number.is_finite() && number.abs().floor() == number.abs() { + Some(*number) + } else { + None + } + } + Value::Object(obj) => { + let obj = obj.borrow(); + if let Some(number) = obj.as_number() { + if number.abs().floor() == number.abs() { + Some(number) + } else { + None + } + } else { + None + } + } + _ => None, + } + } + /// Initialise the `Number` object on the global object. #[inline] pub(crate) fn init(global: &Value) -> (&str, Value) { @@ -577,6 +792,9 @@ impl Number { PARSE_FLOAT_MAX_ARG_COUNT, ); + make_builtin_fn(Self::global_is_finite, "isFinite", global, 1); + make_builtin_fn(Self::global_is_nan, "isNaN", global, 1); + let number_object = make_constructor_fn( Self::NAME, Self::LENGTH, @@ -586,6 +804,11 @@ impl Number { true, ); + make_builtin_fn(Self::number_is_finite, "isFinite", &number_object, 1); + make_builtin_fn(Self::number_is_nan, "isNaN", &number_object, 1); + make_builtin_fn(Self::is_safe_integer, "isSafeInteger", &number_object, 1); + make_builtin_fn(Self::number_is_integer, "isInteger", &number_object, 1); + // Constants from: // https://tc39.es/ecma262/#sec-properties-of-the-number-constructor { diff --git a/boa/src/builtins/number/tests.rs b/boa/src/builtins/number/tests.rs index b2fcafd0caa..395849fb297 100644 --- a/boa/src/builtins/number/tests.rs +++ b/boa/src/builtins/number/tests.rs @@ -677,3 +677,139 @@ fn parse_float_too_many_args() { assert_eq!(&forward(&mut engine, "parseFloat(\"100.5\", 10)"), "100.5"); } + +#[test] +fn global_is_finite() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + assert_eq!("false", &forward(&mut engine, "isFinite(Infinity)")); + assert_eq!("false", &forward(&mut engine, "isFinite(NaN)")); + assert_eq!("false", &forward(&mut engine, "isFinite(-Infinity)")); + assert_eq!("true", &forward(&mut engine, "isFinite(0)")); + assert_eq!("true", &forward(&mut engine, "isFinite(2e64)")); + assert_eq!("true", &forward(&mut engine, "isFinite(910)")); + assert_eq!("true", &forward(&mut engine, "isFinite(null)")); + assert_eq!("true", &forward(&mut engine, "isFinite('0')")); + assert_eq!("false", &forward(&mut engine, "isFinite()")); +} + +#[test] +fn global_is_nan() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + assert_eq!("true", &forward(&mut engine, "isNaN(NaN)")); + assert_eq!("true", &forward(&mut engine, "isNaN('NaN')")); + assert_eq!("true", &forward(&mut engine, "isNaN(undefined)")); + assert_eq!("true", &forward(&mut engine, "isNaN({})")); + assert_eq!("false", &forward(&mut engine, "isNaN(true)")); + assert_eq!("false", &forward(&mut engine, "isNaN(null)")); + assert_eq!("false", &forward(&mut engine, "isNaN(37)")); + assert_eq!("false", &forward(&mut engine, "isNaN('37')")); + assert_eq!("false", &forward(&mut engine, "isNaN('37.37')")); + assert_eq!("true", &forward(&mut engine, "isNaN('37,5')")); + assert_eq!("true", &forward(&mut engine, "isNaN('123ABC')")); + // Incorrect due to ToNumber implementation inconsistencies. + //assert_eq!("false", &forward(&mut engine, "isNaN('')")); + //assert_eq!("false", &forward(&mut engine, "isNaN(' ')")); + assert_eq!("true", &forward(&mut engine, "isNaN('blabla')")); +} + +#[test] +fn number_is_finite() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + assert_eq!("false", &forward(&mut engine, "Number.isFinite(Infinity)")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite(NaN)")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite(-Infinity)")); + assert_eq!("true", &forward(&mut engine, "Number.isFinite(0)")); + assert_eq!("true", &forward(&mut engine, "Number.isFinite(2e64)")); + assert_eq!("true", &forward(&mut engine, "Number.isFinite(910)")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite(null)")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite('0')")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite()")); +} + +#[test] +fn number_is_integer() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + assert_eq!("true", &forward(&mut engine, "Number.isInteger(0)")); + assert_eq!("true", &forward(&mut engine, "Number.isInteger(1)")); + assert_eq!("true", &forward(&mut engine, "Number.isInteger(-100000)")); + assert_eq!( + "true", + &forward(&mut engine, "Number.isInteger(99999999999999999999999)") + ); + assert_eq!("false", &forward(&mut engine, "Number.isInteger(0.1)")); + assert_eq!("false", &forward(&mut engine, "Number.isInteger(Math.PI)")); + assert_eq!("false", &forward(&mut engine, "Number.isInteger(NaN)")); + assert_eq!("false", &forward(&mut engine, "Number.isInteger(Infinity)")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isInteger(-Infinity)") + ); + assert_eq!("false", &forward(&mut engine, "Number.isInteger('10')")); + assert_eq!("false", &forward(&mut engine, "Number.isInteger(true)")); + assert_eq!("false", &forward(&mut engine, "Number.isInteger(false)")); + assert_eq!("false", &forward(&mut engine, "Number.isInteger([1])")); + assert_eq!("true", &forward(&mut engine, "Number.isInteger(5.0)")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isInteger(5.000000000000001)") + ); + assert_eq!( + "true", + &forward(&mut engine, "Number.isInteger(5.0000000000000001)") + ); +} + +#[test] +fn number_is_nan() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + assert_eq!("true", &forward(&mut engine, "Number.isNaN(NaN)")); + assert_eq!("true", &forward(&mut engine, "Number.isNaN(Number.NaN)")); + assert_eq!("true", &forward(&mut engine, "Number.isNaN(0 / 0)")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN(undefined)")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN({})")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN(true)")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN(null)")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN(37)")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN('37')")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN('37.37')")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN('37,5')")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN('123ABC')")); + // Incorrect due to ToNumber implementation inconsistencies. + //assert_eq!("false", &forward(&mut engine, "Number.isNaN('')")); + //assert_eq!("false", &forward(&mut engine, "Number.isNaN(' ')")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN('blabla')")); +} + +#[test] +fn number_is_safe_integer() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + assert_eq!("true", &forward(&mut engine, "Number.isSafeInteger(3)")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isSafeInteger(Math.pow(2, 53))") + ); + assert_eq!( + "true", + &forward(&mut engine, "Number.isSafeInteger(Math.pow(2, 53) - 1)") + ); + assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger(NaN)")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isSafeInteger(Infinity)") + ); + assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger('3')")); + assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger(3.1)")); + assert_eq!("true", &forward(&mut engine, "Number.isSafeInteger(3.0)")); +} From 3eca810e09f86d958d034ff39d3fc4cc625a17dd Mon Sep 17 00:00:00 2001 From: joshwd36 Date: Sun, 12 Jul 2020 15:51:21 +0100 Subject: [PATCH 2/5] Add some more tests. --- boa/src/builtins/number/tests.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/boa/src/builtins/number/tests.rs b/boa/src/builtins/number/tests.rs index 395849fb297..4017096bbf0 100644 --- a/boa/src/builtins/number/tests.rs +++ b/boa/src/builtins/number/tests.rs @@ -730,6 +730,9 @@ fn number_is_finite() { assert_eq!("false", &forward(&mut engine, "Number.isFinite(null)")); assert_eq!("false", &forward(&mut engine, "Number.isFinite('0')")); assert_eq!("false", &forward(&mut engine, "Number.isFinite()")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite({})")); + assert_eq!("true", &forward(&mut engine, "Number.isFinite(Number(5))")); + assert_eq!("false", &forward(&mut engine, "Number.isFinite(BigInt(5))")); } #[test] @@ -765,6 +768,15 @@ fn number_is_integer() { "true", &forward(&mut engine, "Number.isInteger(5.0000000000000001)") ); + assert_eq!( + "false", + &forward(&mut engine, "Number.isInteger(Number(5.000000000000001))") + ); + assert_eq!( + "true", + &forward(&mut engine, "Number.isInteger(Number(5.0000000000000001))") + ); + assert_eq!("false", &forward(&mut engine, "Number.isInteger()")); } #[test] @@ -788,6 +800,9 @@ fn number_is_nan() { //assert_eq!("false", &forward(&mut engine, "Number.isNaN('')")); //assert_eq!("false", &forward(&mut engine, "Number.isNaN(' ')")); assert_eq!("false", &forward(&mut engine, "Number.isNaN('blabla')")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN(Number(5))")); + assert_eq!("true", &forward(&mut engine, "Number.isNaN(Number(NaN))")); + assert_eq!("false", &forward(&mut engine, "Number.isNaN(BigInt(5))")); } #[test] From 6fae6f88059ebd0b04a7ea0e8a704bab95c8d5f7 Mon Sep 17 00:00:00 2001 From: joshwd36 Date: Sun, 12 Jul 2020 17:00:16 +0100 Subject: [PATCH 3/5] Methods shouldn't allow Number objects. --- boa/src/builtins/number/mod.rs | 71 +++++++++----------------------- boa/src/builtins/number/tests.rs | 24 +++++++++++ 2 files changed, 43 insertions(+), 52 deletions(-) diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index a32b4f18b1d..56e89f74ead 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -632,14 +632,6 @@ impl Number { match val { Value::Integer(_) => true, Value::Rational(number) => number.is_finite(), - Value::Object(ref obj) => { - let obj = obj.borrow(); - if let Some(number) = obj.as_number() { - number.is_finite() - } else { - false - } - } _ => false, } } else { @@ -662,11 +654,7 @@ impl Number { args: &[Value], _ctx: &mut Interpreter, ) -> ResultValue { - Ok(Value::Boolean(if let Some(val) = args.get(0) { - Number::is_integer(val).is_some() - } else { - false - })) + Ok(args.get(0).map_or(false, Self::is_integer).into()) } /// `Number.isNaN( number )` @@ -692,14 +680,6 @@ impl Number { match val { Value::Integer(_) => false, Value::Rational(number) => number.is_nan(), - Value::Object(ref obj) => { - let obj = obj.borrow(); - if let Some(number) = obj.as_number() { - number.is_nan() - } else { - false - } - } _ => false, } } else { @@ -726,15 +706,14 @@ impl Number { args: &[Value], _ctx: &mut Interpreter, ) -> ResultValue { - Ok(Value::Boolean(if let Some(val) = args.get(0) { - if let Some(integer) = Number::is_integer(val) { - integer.abs() <= Number::MAX_SAFE_INTEGER - } else { - false + Ok((match args.get(0) { + Some(Value::Integer(_)) => true, + Some(Value::Rational(number)) if Self::is_float_integer(*number) => { + number.abs() <= Number::MAX_SAFE_INTEGER } - } else { - false - })) + _ => false, + }) + .into()) } /// Checks if the argument is a finite integer Number value. @@ -743,33 +722,21 @@ impl Number { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-isinteger - #[allow(clippy::float_cmp)] - pub(crate) fn is_integer(val: &Value) -> Option { + pub(crate) fn is_integer(val: &Value) -> bool { match val { - Value::Integer(number) => Some((*number).into()), - Value::Rational(number) => { - if number.is_finite() && number.abs().floor() == number.abs() { - Some(*number) - } else { - None - } - } - Value::Object(obj) => { - let obj = obj.borrow(); - if let Some(number) = obj.as_number() { - if number.abs().floor() == number.abs() { - Some(number) - } else { - None - } - } else { - None - } - } - _ => None, + Value::Integer(_) => true, + Value::Rational(number) => Number::is_float_integer(*number), + _ => false, } } + /// Checks if the float argument is an integer. + #[inline] + #[allow(clippy::float_cmp)] + pub(crate) fn is_float_integer(number: f64) -> bool { + number.is_finite() && number.abs().floor() == number.abs() + } + /// Initialise the `Number` object on the global object. #[inline] pub(crate) fn init(global: &Value) -> (&str, Value) { diff --git a/boa/src/builtins/number/tests.rs b/boa/src/builtins/number/tests.rs index 4017096bbf0..4e7baf1cf86 100644 --- a/boa/src/builtins/number/tests.rs +++ b/boa/src/builtins/number/tests.rs @@ -732,6 +732,14 @@ fn number_is_finite() { assert_eq!("false", &forward(&mut engine, "Number.isFinite()")); assert_eq!("false", &forward(&mut engine, "Number.isFinite({})")); assert_eq!("true", &forward(&mut engine, "Number.isFinite(Number(5))")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isFinite(new Number(5))") + ); + assert_eq!( + "false", + &forward(&mut engine, "Number.isFinite(new Number(NaN))") + ); assert_eq!("false", &forward(&mut engine, "Number.isFinite(BigInt(5))")); } @@ -777,6 +785,10 @@ fn number_is_integer() { &forward(&mut engine, "Number.isInteger(Number(5.0000000000000001))") ); assert_eq!("false", &forward(&mut engine, "Number.isInteger()")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isInteger(new Number(5))") + ); } #[test] @@ -803,6 +815,14 @@ fn number_is_nan() { assert_eq!("false", &forward(&mut engine, "Number.isNaN(Number(5))")); assert_eq!("true", &forward(&mut engine, "Number.isNaN(Number(NaN))")); assert_eq!("false", &forward(&mut engine, "Number.isNaN(BigInt(5))")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isNaN(new Number(5))") + ); + assert_eq!( + "false", + &forward(&mut engine, "Number.isNaN(new Number(NaN))") + ); } #[test] @@ -827,4 +847,8 @@ fn number_is_safe_integer() { assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger('3')")); assert_eq!("false", &forward(&mut engine, "Number.isSafeInteger(3.1)")); assert_eq!("true", &forward(&mut engine, "Number.isSafeInteger(3.0)")); + assert_eq!( + "false", + &forward(&mut engine, "Number.isSafeInteger(new Number(5))") + ); } From 0111896562e2535f5e0ee9a3511c51e2d49f8401 Mon Sep 17 00:00:00 2001 From: joshwd36 Date: Mon, 13 Jul 2020 00:44:57 +0100 Subject: [PATCH 4/5] Use from/into for creating Value types. --- boa/src/builtins/number/mod.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index 56e89f74ead..9c4ce5e1487 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -576,9 +576,9 @@ impl Number { ) -> ResultValue { if let Some(val) = args.get(0) { let number = ctx.to_number(val)?; - Ok(Value::Boolean(number.is_finite())) + Ok(number.is_finite().into()) } else { - Ok(Value::Boolean(false)) + Ok(false.into()) } } @@ -603,9 +603,9 @@ impl Number { ) -> ResultValue { if let Some(val) = args.get(0) { let number = ctx.to_number(val)?; - Ok(Value::Boolean(number.is_nan())) + Ok(number.is_nan().into()) } else { - Ok(Value::Boolean(true)) + Ok(true.into()) } } @@ -628,7 +628,7 @@ impl Number { args: &[Value], _ctx: &mut Interpreter, ) -> ResultValue { - Ok(Value::Boolean(if let Some(val) = args.get(0) { + Ok(Value::from(if let Some(val) = args.get(0) { match val { Value::Integer(_) => true, Value::Rational(number) => number.is_finite(), @@ -676,7 +676,7 @@ impl Number { args: &[Value], _ctx: &mut Interpreter, ) -> ResultValue { - Ok(Value::Boolean(if let Some(val) = args.get(0) { + Ok(Value::from(if let Some(val) = args.get(0) { match val { Value::Integer(_) => false, Value::Rational(number) => number.is_nan(), @@ -706,14 +706,13 @@ impl Number { args: &[Value], _ctx: &mut Interpreter, ) -> ResultValue { - Ok((match args.get(0) { + Ok(Value::from(match args.get(0) { Some(Value::Integer(_)) => true, Some(Value::Rational(number)) if Self::is_float_integer(*number) => { number.abs() <= Number::MAX_SAFE_INTEGER } _ => false, - }) - .into()) + })) } /// Checks if the argument is a finite integer Number value. From 1f8e4f88f583155d141b4ab2a0c947f03d43fc2e Mon Sep 17 00:00:00 2001 From: joshwd36 Date: Mon, 13 Jul 2020 02:30:39 +0100 Subject: [PATCH 5/5] Inline is_integer --- boa/src/builtins/number/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/boa/src/builtins/number/mod.rs b/boa/src/builtins/number/mod.rs index 9c4ce5e1487..788901250c0 100644 --- a/boa/src/builtins/number/mod.rs +++ b/boa/src/builtins/number/mod.rs @@ -721,6 +721,7 @@ impl Number { /// - [ECMAScript reference][spec] /// /// [spec]: https://tc39.es/ecma262/#sec-isinteger + #[inline] pub(crate) fn is_integer(val: &Value) -> bool { match val { Value::Integer(_) => true,