From 0c6a0e80af93854e3a678ac4b4c643b3f800c68e Mon Sep 17 00:00:00 2001 From: Lord-McSweeney Date: Fri, 20 Oct 2023 18:44:39 -0700 Subject: [PATCH] avm2: Add class call handlers for Boolean, Number, and (u)int --- core/src/avm2/globals/boolean.rs | 18 ++++++++++++++++++ core/src/avm2/globals/int.rs | 14 ++++++++++++++ core/src/avm2/globals/number.rs | 18 ++++++++++++++++++ core/src/avm2/globals/uint.rs | 18 ++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/core/src/avm2/globals/boolean.rs b/core/src/avm2/globals/boolean.rs index 57017ccbe..4315b9e88 100644 --- a/core/src/avm2/globals/boolean.rs +++ b/core/src/avm2/globals/boolean.rs @@ -82,6 +82,19 @@ fn class_init<'gc>( Ok(Value::Undefined) } +pub fn call_handler<'gc>( + _activation: &mut Activation<'_, 'gc>, + _this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(args + .get(0) + .cloned() + .unwrap_or(Value::Bool(false)) + .coerce_to_boolean() + .into()) +} + /// Implements `Boolean.toString` fn to_string<'gc>( _activation: &mut Activation<'_, 'gc>, @@ -131,6 +144,11 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl "", mc, )); + write.set_call_handler(Method::from_builtin( + call_handler, + "", + mc, + )); const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("toString", to_string), ("valueOf", value_of)]; diff --git a/core/src/avm2/globals/int.rs b/core/src/avm2/globals/int.rs index 0a0daaf31..262332d5a 100644 --- a/core/src/avm2/globals/int.rs +++ b/core/src/avm2/globals/int.rs @@ -135,6 +135,19 @@ fn class_init<'gc>( Ok(Value::Undefined) } +pub fn call_handler<'gc>( + activation: &mut Activation<'_, 'gc>, + _this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(args + .get(0) + .cloned() + .unwrap_or(Value::Integer(0)) + .coerce_to_i32(activation)? + .into()) +} + /// Implements `int.toExponential` use crate::avm2::globals::number::to_exponential; @@ -228,6 +241,7 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl "", mc, )); + write.set_call_handler(Method::from_builtin(call_handler, "", mc)); // 'length' is a weird undocumented constant in int. // We need to define it, since it shows up in 'describeType' diff --git a/core/src/avm2/globals/number.rs b/core/src/avm2/globals/number.rs index 4e33e8a5f..eea1b96dc 100644 --- a/core/src/avm2/globals/number.rs +++ b/core/src/avm2/globals/number.rs @@ -135,6 +135,19 @@ fn class_init<'gc>( Ok(Value::Undefined) } +pub fn call_handler<'gc>( + activation: &mut Activation<'_, 'gc>, + _this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(args + .get(0) + .cloned() + .unwrap_or(Value::Number(0.0)) + .coerce_to_number(activation)? + .into()) +} + /// Implements `Number.toExponential` pub fn to_exponential<'gc>( activation: &mut Activation<'_, 'gc>, @@ -373,6 +386,11 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl "", mc, )); + write.set_call_handler(Method::from_builtin( + call_handler, + "", + mc, + )); const CLASS_CONSTANTS_NUMBER: &[(&str, f64)] = &[ ("MAX_VALUE", f64::MAX), diff --git a/core/src/avm2/globals/uint.rs b/core/src/avm2/globals/uint.rs index 056cf145d..604aacbe4 100644 --- a/core/src/avm2/globals/uint.rs +++ b/core/src/avm2/globals/uint.rs @@ -135,6 +135,19 @@ fn class_init<'gc>( Ok(Value::Undefined) } +pub fn call_handler<'gc>( + activation: &mut Activation<'_, 'gc>, + _this: Object<'gc>, + args: &[Value<'gc>], +) -> Result, Error<'gc>> { + Ok(args + .get(0) + .cloned() + .unwrap_or(Value::Integer(0)) + .coerce_to_u32(activation)? + .into()) +} + /// Implements `uint.toExponential` use crate::avm2::globals::number::to_exponential; @@ -229,6 +242,11 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl "", mc, )); + write.set_call_handler(Method::from_builtin( + call_handler, + "", + mc, + )); const CLASS_CONSTANTS_UINT: &[(&str, u32)] = &[("MAX_VALUE", u32::MAX), ("MIN_VALUE", u32::MIN)];