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();