From 4bc31ef75eb14c81ec3d852f256d794c1cea0828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Wed, 24 Jun 2020 23:04:38 +0200 Subject: [PATCH 01/10] add `Math.clz32` method (#524) --- boa/src/builtins/math/mod.rs | 21 +++++++++++++++++++++ boa/src/builtins/math/tests.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 152797f7c24..2704bea8cb4 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -19,6 +19,7 @@ use crate::{ exec::Interpreter, BoaProfiler, }; +use num_traits::cast::ToPrimitive; use std::f64; #[cfg(test)] @@ -165,6 +166,25 @@ impl Math { Ok(args.get(0).map_or(f64::NAN, |x| f64::from(x).ceil()).into()) } + /// Get the number of leading zeros in the 32 bit representation of a number + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-math.exp + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp + pub(crate) fn clz32(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + Ok(args + .get(0) + .and_then(|x| f64::from(x).to_u32()) + .map_or(32usize, |u| { + let s = format!("{:032b}", u); + s.chars().take_while(|x| *x == '0').count() + }) + .into()) + } + /// Get the cosine of a number. /// /// More information: @@ -485,6 +505,7 @@ impl Math { make_builtin_fn(Self::atan2, "atan2", &math, 2); make_builtin_fn(Self::cbrt, "cbrt", &math, 1); make_builtin_fn(Self::ceil, "ceil", &math, 1); + make_builtin_fn(Self::clz32, "clz32", &math, 1); make_builtin_fn(Self::cos, "cos", &math, 1); make_builtin_fn(Self::cosh, "cosh", &math, 1); make_builtin_fn(Self::exp, "exp", &math, 1); diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index a733946d690..6def35beacb 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -183,6 +183,36 @@ fn ceil() { assert_eq!(c.to_number(), -7_f64); } +#[test] +fn clz32() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + let init = r#" + var a = Math.clz32(); + var b = Math.clz32({}); + var c = Math.clz32(1); + var d = Math.clz32("1"); + var e = Math.clz32(4); + var f = Math.clz32(Infinity); + "#; + + eprintln!("{}", forward(&mut engine, init)); + + let a = forward_val(&mut engine, "a").unwrap(); + let b = forward_val(&mut engine, "b").unwrap(); + let c = forward_val(&mut engine, "c").unwrap(); + let d = forward_val(&mut engine, "d").unwrap(); + let e = forward_val(&mut engine, "e").unwrap(); + let f = forward_val(&mut engine, "f").unwrap(); + + assert_eq!(a.to_number(), 32_f64); + assert_eq!(b.to_number(), 32_f64); + assert_eq!(c.to_number(), 31_f64); + assert_eq!(d.to_number(), 31_f64); + assert_eq!(e.to_number(), 29_f64); + assert_eq!(f.to_number(), 32_f64); +} + #[test] fn cos() { let realm = Realm::create(); From 034b613d05bcf6df6fd532e6fbed0a4333d00ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Wed, 24 Jun 2020 23:12:31 +0200 Subject: [PATCH 02/10] fix doc urls for clz32 --- boa/src/builtins/math/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 2704bea8cb4..f49e76db48a 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -172,8 +172,8 @@ impl Math { /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] /// - /// [spec]: https://tc39.es/ecma262/#sec-math.exp - /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp + /// [spec]: https://tc39.es/ecma262/#sec-math.clz32 + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 pub(crate) fn clz32(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { Ok(args .get(0) From 37af5fc04d355612e9cd3b694c1e957579ad5f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 18:07:51 +0200 Subject: [PATCH 03/10] [#524] optimize impl for `Math.clz32` --- boa/src/builtins/math/mod.rs | 12 +++++++----- boa/src/builtins/math/tests.rs | 14 ++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index f49e76db48a..9379318bb64 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -19,7 +19,6 @@ use crate::{ exec::Interpreter, BoaProfiler, }; -use num_traits::cast::ToPrimitive; use std::f64; #[cfg(test)] @@ -177,11 +176,14 @@ impl Math { pub(crate) fn clz32(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { Ok(args .get(0) - .and_then(|x| f64::from(x).to_u32()) - .map_or(32usize, |u| { - let s = format!("{:032b}", u); - s.chars().take_while(|x| *x == '0').count() + .and_then(|x| { + if f64::from(x).is_normal() { + Some(i32::from(x).leading_zeros() as usize) + } else { + None + } }) + .unwrap_or(32usize) .into()) } diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index 6def35beacb..e661148135d 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -190,10 +190,12 @@ fn clz32() { let init = r#" var a = Math.clz32(); var b = Math.clz32({}); - var c = Math.clz32(1); + var c = Math.clz32(-173); var d = Math.clz32("1"); - var e = Math.clz32(4); + var e = Math.clz32(2147483647); var f = Math.clz32(Infinity); + var g = Math.clz32(true); + var h = Math.clz32(0); "#; eprintln!("{}", forward(&mut engine, init)); @@ -204,13 +206,17 @@ fn clz32() { let d = forward_val(&mut engine, "d").unwrap(); let e = forward_val(&mut engine, "e").unwrap(); let f = forward_val(&mut engine, "f").unwrap(); + let g = forward_val(&mut engine, "g").unwrap(); + let h = forward_val(&mut engine, "h").unwrap(); assert_eq!(a.to_number(), 32_f64); assert_eq!(b.to_number(), 32_f64); - assert_eq!(c.to_number(), 31_f64); + assert_eq!(c.to_number(), 0_f64); assert_eq!(d.to_number(), 31_f64); - assert_eq!(e.to_number(), 29_f64); + assert_eq!(e.to_number(), 1_f64); assert_eq!(f.to_number(), 32_f64); + assert_eq!(g.to_number(), 31_f64); + assert_eq!(h.to_number(), 32_f64); } #[test] From 419f409db8a4195a58354a6e3d0c1aac26d2984f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 19:06:21 +0200 Subject: [PATCH 04/10] [#524] add implementation for `Math.expm1()` --- boa/src/builtins/math/mod.rs | 18 ++++++++++++++++++ boa/src/builtins/math/tests.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 9379318bb64..0bb3bd848f0 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -223,6 +223,23 @@ impl Math { Ok(args.get(0).map_or(f64::NAN, |x| f64::from(x).exp()).into()) } + /// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of + /// the natural logarithms. The result is computed in a way that is accurate even when the + /// value of x is close 0 + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-math.expm1 + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 + pub(crate) fn expm1(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + Ok(args + .get(0) + .map_or(f64::NAN, |x| f64::from(x).exp_m1()) + .into()) + } + /// Get the highest integer below a number. /// /// More information: @@ -511,6 +528,7 @@ impl Math { make_builtin_fn(Self::cos, "cos", &math, 1); make_builtin_fn(Self::cosh, "cosh", &math, 1); make_builtin_fn(Self::exp, "exp", &math, 1); + make_builtin_fn(Self::expm1, "expm1", &math, 1); make_builtin_fn(Self::floor, "floor", &math, 1); make_builtin_fn(Self::log, "log", &math, 1); make_builtin_fn(Self::log10, "log10", &math, 1); diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index e661148135d..6b68c3046d7 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -279,6 +279,36 @@ fn exp() { assert_eq!(c.to_number(), 7.389_056_098_930_65); } +#[test] +fn expm1() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + let init = r#" + var a = Math.expm1(); + var b = Math.expm1({}); + var c = Math.expm1(1); + var d = Math.expm1(-1); + var e = Math.expm1(0); + var f = Math.expm1(2); + "#; + + eprintln!("{}", forward(&mut engine, init)); + + let a = forward(&mut engine, "a"); + let b = forward(&mut engine, "b"); + let c = forward_val(&mut engine, "c").unwrap(); + let d = forward_val(&mut engine, "d").unwrap(); + let e = forward_val(&mut engine, "e").unwrap(); + let f = forward_val(&mut engine, "f").unwrap(); + + assert_eq!(a, String::from("NaN")); + assert_eq!(b, String::from("NaN")); + assert_eq!(c.to_number(), 1.718_281_828_459_045); + assert_eq!(d.to_number(), -0.632_120_558_828_557_7); + assert_eq!(e.to_number(), 0_f64); + assert_eq!(f.to_number(), 6.389_056_098_930_65); +} + #[test] fn floor() { let realm = Realm::create(); From 509a587786bc91fdc796342c4d2e4fd7f7a0b7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 19:46:38 +0200 Subject: [PATCH 05/10] [#524] add implementation for `Math.fround()` --- boa/src/builtins/math/mod.rs | 16 ++++++++++++++++ boa/src/builtins/math/tests.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 0bb3bd848f0..210ff4504b7 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -255,6 +255,21 @@ impl Math { .into()) } + /// Get the nearest 32-bit single precision float representation of a number. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-math.fround + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround + pub(crate) fn fround(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + Ok(args + .get(0) + .map_or(f64::NAN, |x| (f64::from(x) as f32) as f64) + .into()) + } + /// Get the natural logarithm of a number. /// /// More information: @@ -530,6 +545,7 @@ impl Math { make_builtin_fn(Self::exp, "exp", &math, 1); make_builtin_fn(Self::expm1, "expm1", &math, 1); make_builtin_fn(Self::floor, "floor", &math, 1); + make_builtin_fn(Self::fround, "fround", &math, 1); make_builtin_fn(Self::log, "log", &math, 1); make_builtin_fn(Self::log10, "log10", &math, 1); make_builtin_fn(Self::log2, "log2", &math, 1); diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index 6b68c3046d7..d469637c110 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -330,6 +330,36 @@ fn floor() { assert_eq!(c.to_number(), 3_f64); } +#[test] +fn fround() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + let init = r#" + var a = Math.fround(NaN); + var b = Math.fround(Infinity); + var c = Math.fround(5); + var d = Math.fround(5.5); + var e = Math.fround(5.05); + var f = Math.fround(-5.05); + "#; + + eprintln!("{}", forward(&mut engine, init)); + + let a = forward(&mut engine, "a"); + let b = forward(&mut engine, "b"); + let c = forward_val(&mut engine, "c").unwrap(); + let d = forward_val(&mut engine, "d").unwrap(); + let e = forward_val(&mut engine, "e").unwrap(); + let f = forward_val(&mut engine, "f").unwrap(); + + assert_eq!(a, String::from("NaN")); + assert_eq!(b, String::from("Infinity")); + assert_eq!(c.to_number(), 5f64); + assert_eq!(d.to_number(), 5.5f64); + assert_eq!(e.to_number(), 5.050_000_190_734_863); + assert_eq!(f.to_number(), -5.050_000_190_734_863); +} + #[test] fn log() { let realm = Realm::create(); From c061b69d1609305465e544ecd543eb228d11d2b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 20:30:36 +0200 Subject: [PATCH 06/10] [#524] implement `Math.hypot()` --- boa/src/builtins/math/mod.rs | 13 +++++++++++++ boa/src/builtins/math/tests.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 210ff4504b7..d39a8328e9c 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -270,6 +270,18 @@ impl Math { .into()) } + /// Get an approximation of the square root of the sum of squares of all arguments. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-math.hypot + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot + pub(crate) fn hypot(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + Ok(args.iter().fold(0f64, |x, v| f64::from(v).hypot(x)).into()) + } + /// Get the natural logarithm of a number. /// /// More information: @@ -546,6 +558,7 @@ impl Math { make_builtin_fn(Self::expm1, "expm1", &math, 1); make_builtin_fn(Self::floor, "floor", &math, 1); make_builtin_fn(Self::fround, "fround", &math, 1); + make_builtin_fn(Self::hypot, "hypot", &math, 1); make_builtin_fn(Self::log, "log", &math, 1); make_builtin_fn(Self::log10, "log10", &math, 1); make_builtin_fn(Self::log2, "log2", &math, 1); diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index d469637c110..3e0f2e731d3 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -360,6 +360,36 @@ fn fround() { assert_eq!(f.to_number(), -5.050_000_190_734_863); } +#[test] +fn hypot() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + let init = r#" + var a = Math.hypot(); + var b = Math.hypot(3, 4); + var c = Math.hypot(5, 12); + var d = Math.hypot(3, 4, -5); + var e = Math.hypot(4, [5], 6); + var f = Math.hypot(3, Infinity); + "#; + + eprintln!("{}", forward(&mut engine, init)); + + let a = forward_val(&mut engine, "a").unwrap(); + let b = forward_val(&mut engine, "b").unwrap(); + let c = forward_val(&mut engine, "c").unwrap(); + let d = forward_val(&mut engine, "d").unwrap(); + let e = forward(&mut engine, "e"); + let f = forward(&mut engine, "f"); + + assert_eq!(a.to_number(), 0f64); + assert_eq!(b.to_number(), 5f64); + assert_eq!(c.to_number(), 13f64); + assert_eq!(d.to_number(), 7.071_067_811_865_475_5); + assert_eq!(e, String::from("NaN")); + assert_eq!(f, String::from("Infinity")); +} + #[test] fn log() { let realm = Realm::create(); From c6642c046d5d779604ee99290c7e82b66673ca67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 21:08:34 +0200 Subject: [PATCH 07/10] [#524] implement `Math.log1p()` --- boa/src/builtins/math/mod.rs | 16 ++++++++++++++++ boa/src/builtins/math/tests.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index d39a8328e9c..cb7db3c6751 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -304,6 +304,21 @@ impl Math { .into()) } + /// Get approximation to the natural logarithm of 1 + x. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-math.log1p + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p + pub(crate) fn log1p(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + Ok(args + .get(0) + .map_or(f64::NAN, |x| f64::from(x).ln_1p()) + .into()) + } + /// Get the base 10 logarithm of the number. /// /// More information: @@ -560,6 +575,7 @@ impl Math { make_builtin_fn(Self::fround, "fround", &math, 1); make_builtin_fn(Self::hypot, "hypot", &math, 1); make_builtin_fn(Self::log, "log", &math, 1); + make_builtin_fn(Self::log1p, "log1p", &math, 1); make_builtin_fn(Self::log10, "log10", &math, 1); make_builtin_fn(Self::log2, "log2", &math, 1); make_builtin_fn(Self::max, "max", &math, 2); diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index 3e0f2e731d3..e5b8ea4f570 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -370,7 +370,7 @@ fn hypot() { var c = Math.hypot(5, 12); var d = Math.hypot(3, 4, -5); var e = Math.hypot(4, [5], 6); - var f = Math.hypot(3, Infinity); + var f = Math.hypot(3, -Infinity); "#; eprintln!("{}", forward(&mut engine, init)); @@ -411,6 +411,36 @@ fn log() { assert_eq!(c, String::from("NaN")); } +#[test] +fn log1p() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + let init = r#" + var a = Math.log1p(1); + var b = Math.log1p(0); + var c = Math.log1p(-0.9999999999999999); + var d = Math.log1p(-1); + var e = Math.log1p(-1.000000000000001); + var f = Math.log1p(-2); + "#; + + eprintln!("{}", forward(&mut engine, init)); + + let a = forward_val(&mut engine, "a").unwrap(); + let b = forward_val(&mut engine, "b").unwrap(); + let c = forward_val(&mut engine, "c").unwrap(); + let d = forward(&mut engine, "d"); + let e = forward(&mut engine, "e"); + let f = forward(&mut engine, "f"); + + assert_eq!(a.to_number(), f64::consts::LN_2); + assert_eq!(b.to_number(), 0f64); + assert_eq!(c.to_number(), -36.736_800_569_677_1); + assert_eq!(d, "-Infinity"); + assert_eq!(e, String::from("NaN")); + assert_eq!(f, String::from("NaN")); +} + #[test] fn log10() { let realm = Realm::create(); From 041f330d59323f840f545c4e3bb81d7642337cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 23:13:51 +0200 Subject: [PATCH 08/10] [#524] implement `Math.imul()` --- boa/src/builtins/math/mod.rs | 15 +++++++++++++++ boa/src/builtins/math/tests.rs | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index cb7db3c6751..23da02e37ac 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -282,6 +282,20 @@ impl Math { Ok(args.iter().fold(0f64, |x, v| f64::from(v).hypot(x)).into()) } + /// Get the result of the C-like 32-bit multiplication of the two parameters. + /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// + /// [spec]: https://tc39.es/ecma262/#sec-math.imul + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul + pub(crate) fn imul(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + let a = args.get(0).map_or(0f64, f64::from); + let b = args.get(1).map_or(0f64, f64::from); + Ok(((a as u32).wrapping_mul(b as u32) as i32).into()) + } + /// Get the natural logarithm of a number. /// /// More information: @@ -574,6 +588,7 @@ impl Math { make_builtin_fn(Self::floor, "floor", &math, 1); make_builtin_fn(Self::fround, "fround", &math, 1); make_builtin_fn(Self::hypot, "hypot", &math, 1); + make_builtin_fn(Self::imul, "imul", &math, 1); make_builtin_fn(Self::log, "log", &math, 1); make_builtin_fn(Self::log1p, "log1p", &math, 1); make_builtin_fn(Self::log10, "log10", &math, 1); diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index e5b8ea4f570..b88b6b789ba 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -390,6 +390,30 @@ fn hypot() { assert_eq!(f, String::from("Infinity")); } +#[test] +fn imul() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + let init = r#" + var a = Math.imul(3, 4); + var b = Math.imul(-5, 12); + var c = Math.imul(0xffffffff, 5); + var d = Math.imul(0xfffffffe, 5); + "#; + + eprintln!("{}", forward(&mut engine, init)); + + let a = forward_val(&mut engine, "a").unwrap(); + let b = forward_val(&mut engine, "b").unwrap(); + let c = forward_val(&mut engine, "c").unwrap(); + let d = forward_val(&mut engine, "d").unwrap(); + + assert_eq!(a.to_number(), 12f64); + assert_eq!(b.to_number(), -60f64); + assert_eq!(c.to_number(), -5f64); + assert_eq!(d.to_number(), -10f64); +} + #[test] fn log() { let realm = Realm::create(); From 23591495ba38401e694c21f9a08595c387940946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Thu, 25 Jun 2020 23:28:57 +0200 Subject: [PATCH 09/10] improve `Math.clz32()` implementation --- boa/src/builtins/math/mod.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/boa/src/builtins/math/mod.rs b/boa/src/builtins/math/mod.rs index 23da02e37ac..cd171d67409 100644 --- a/boa/src/builtins/math/mod.rs +++ b/boa/src/builtins/math/mod.rs @@ -176,14 +176,7 @@ impl Math { pub(crate) fn clz32(_: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue { Ok(args .get(0) - .and_then(|x| { - if f64::from(x).is_normal() { - Some(i32::from(x).leading_zeros() as usize) - } else { - None - } - }) - .unwrap_or(32usize) + .map_or(32i32, |x| (f64::from(x) as u32).leading_zeros() as i32) .into()) } From e51ee81abce087b5374894672c6aab5a8d8e6a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Te-j=C3=A9=20Rodgers?= Date: Fri, 26 Jun 2020 18:36:51 +0200 Subject: [PATCH 10/10] [#524] add tests for more states --- boa/src/builtins/math/tests.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/boa/src/builtins/math/tests.rs b/boa/src/builtins/math/tests.rs index b88b6b789ba..99f4387889f 100644 --- a/boa/src/builtins/math/tests.rs +++ b/boa/src/builtins/math/tests.rs @@ -341,6 +341,7 @@ fn fround() { var d = Math.fround(5.5); var e = Math.fround(5.05); var f = Math.fround(-5.05); + var g = Math.fround(); "#; eprintln!("{}", forward(&mut engine, init)); @@ -351,6 +352,7 @@ fn fround() { let d = forward_val(&mut engine, "d").unwrap(); let e = forward_val(&mut engine, "e").unwrap(); let f = forward_val(&mut engine, "f").unwrap(); + let g = forward(&mut engine, "g"); assert_eq!(a, String::from("NaN")); assert_eq!(b, String::from("Infinity")); @@ -358,6 +360,7 @@ fn fround() { assert_eq!(d.to_number(), 5.5f64); assert_eq!(e.to_number(), 5.050_000_190_734_863); assert_eq!(f.to_number(), -5.050_000_190_734_863); + assert_eq!(g, String::from("NaN")); } #[test] @@ -371,6 +374,7 @@ fn hypot() { var d = Math.hypot(3, 4, -5); var e = Math.hypot(4, [5], 6); var f = Math.hypot(3, -Infinity); + var g = Math.hypot(12); "#; eprintln!("{}", forward(&mut engine, init)); @@ -381,6 +385,7 @@ fn hypot() { let d = forward_val(&mut engine, "d").unwrap(); let e = forward(&mut engine, "e"); let f = forward(&mut engine, "f"); + let g = forward_val(&mut engine, "g").unwrap(); assert_eq!(a.to_number(), 0f64); assert_eq!(b.to_number(), 5f64); @@ -388,6 +393,7 @@ fn hypot() { assert_eq!(d.to_number(), 7.071_067_811_865_475_5); assert_eq!(e, String::from("NaN")); assert_eq!(f, String::from("Infinity")); + assert_eq!(g.to_number(), 12f64); } #[test] @@ -399,6 +405,8 @@ fn imul() { var b = Math.imul(-5, 12); var c = Math.imul(0xffffffff, 5); var d = Math.imul(0xfffffffe, 5); + var e = Math.imul(12); + var f = Math.imul(); "#; eprintln!("{}", forward(&mut engine, init)); @@ -407,11 +415,15 @@ fn imul() { let b = forward_val(&mut engine, "b").unwrap(); let c = forward_val(&mut engine, "c").unwrap(); let d = forward_val(&mut engine, "d").unwrap(); + let e = forward_val(&mut engine, "e").unwrap(); + let f = forward_val(&mut engine, "f").unwrap(); assert_eq!(a.to_number(), 12f64); assert_eq!(b.to_number(), -60f64); assert_eq!(c.to_number(), -5f64); assert_eq!(d.to_number(), -10f64); + assert_eq!(e.to_number(), 0f64); + assert_eq!(f.to_number(), 0f64); } #[test] @@ -446,6 +458,7 @@ fn log1p() { var d = Math.log1p(-1); var e = Math.log1p(-1.000000000000001); var f = Math.log1p(-2); + var g = Math.log1p(); "#; eprintln!("{}", forward(&mut engine, init)); @@ -456,6 +469,7 @@ fn log1p() { let d = forward(&mut engine, "d"); let e = forward(&mut engine, "e"); let f = forward(&mut engine, "f"); + let g = forward(&mut engine, "g"); assert_eq!(a.to_number(), f64::consts::LN_2); assert_eq!(b.to_number(), 0f64); @@ -463,6 +477,7 @@ fn log1p() { assert_eq!(d, "-Infinity"); assert_eq!(e, String::from("NaN")); assert_eq!(f, String::from("NaN")); + assert_eq!(g, String::from("NaN")); } #[test] @@ -514,7 +529,7 @@ fn max() { let init = r#" var a = Math.max(10, 20); var b = Math.max(-10, -20); - var c = Math.max(-10, 20); + var c = Math.max(-10, 20); "#; eprintln!("{}", forward(&mut engine, init)); @@ -535,7 +550,7 @@ fn min() { let init = r#" var a = Math.min(10, 20); var b = Math.min(-10, -20); - var c = Math.min(-10, 20); + var c = Math.min(-10, 20); "#; eprintln!("{}", forward(&mut engine, init)); @@ -598,7 +613,7 @@ fn sign() { let init = r#" var a = Math.sign(3); var b = Math.sign(-3); - var c = Math.sign(0); + var c = Math.sign(0); "#; eprintln!("{}", forward(&mut engine, init));