From d5bd7c2dd861070ab22b9c1a6796bf9fefe9b0ed Mon Sep 17 00:00:00 2001 From: Mike Welsh Date: Sun, 29 Mar 2020 18:44:28 -0700 Subject: [PATCH] avm1: Math.round rounds towards infinity --- core/src/avm1/globals/math.rs | 41 +++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/core/src/avm1/globals/math.rs b/core/src/avm1/globals/math.rs index 11f1a5bd0..e4a5de255 100644 --- a/core/src/avm1/globals/math.rs +++ b/core/src/avm1/globals/math.rs @@ -63,6 +63,22 @@ fn pow<'gc>( Ok(NAN.into()) } +fn round<'gc>( + avm: &mut Avm1<'gc>, + context: &mut UpdateContext<'_, 'gc, '_>, + _this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error> { + if let Some(x) = args.get(0) { + let x = x.as_number(avm, context)?; + // Note that Flash Math.round always rounds toward infinity, + // unlike Rust f32::round which rounds away from zero. + let ret = (x + 0.5).floor(); + return Ok(ret.into()); + } + Ok(NAN.into()) +} + fn max<'gc>( avm: &mut Avm1<'gc>, context: &mut UpdateContext<'_, 'gc, '_>, @@ -187,7 +203,6 @@ pub fn create<'gc>( "cos" => f64::cos, "exp" => f64::exp, "floor" => f64::floor, - "round" => f64::round, "sin" => f64::sin, "sqrt" => f64::sqrt, "tan" => f64::tan, @@ -229,6 +244,13 @@ pub fn create<'gc>( DontDelete | ReadOnly | DontEnum, fn_proto, ); + math.force_set_function( + "round", + round, + gc_context, + DontDelete | ReadOnly | DontEnum, + fn_proto, + ); math.into() } @@ -334,8 +356,23 @@ mod tests { [19] => { [] => NAN, [Value::Null] => NAN, + [Value::Undefined] => NAN, [12.5] => 13.0, - [23.2] => 23.0 + [23.2] => 23.0, + [23.5] => 24.0, + [23.7] => 24.0, + [-23.2] => -23.0, + [-23.5] => -23.0, + [-23.7] => -24.0, + [std::f64::NAN] => std::f64::NAN, + [std::f64::INFINITY] => std::f64::INFINITY, + [std::f64::NEG_INFINITY] => std::f64::NEG_INFINITY + }, + [5, 6] => { + [] => NAN, + [Value::Null] => 0.0, + [Value::Undefined] => 0.0, + [std::f64::NAN] => std::f64::NAN } );