From 7569994f1f683c4fb43e1c41dc2080edc3802250 Mon Sep 17 00:00:00 2001 From: David Wendt Date: Mon, 15 Nov 2021 20:29:48 -0500 Subject: [PATCH] avm2: Impl `Boolean.toString` and `Boolean.valueOf`. --- core/src/avm2/globals/boolean.rs | 39 +++++++++++++++++- tests/tests/regression_tests.rs | 1 + .../tests/swfs/avm2/boolean_tostring/Test.as | 16 +++++++ .../swfs/avm2/boolean_tostring/output.txt | 8 ++++ .../tests/swfs/avm2/boolean_tostring/test.fla | Bin 0 -> 4024 bytes .../tests/swfs/avm2/boolean_tostring/test.swf | Bin 0 -> 710 bytes 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/tests/swfs/avm2/boolean_tostring/Test.as create mode 100644 tests/tests/swfs/avm2/boolean_tostring/output.txt create mode 100644 tests/tests/swfs/avm2/boolean_tostring/test.fla create mode 100644 tests/tests/swfs/avm2/boolean_tostring/test.swf diff --git a/core/src/avm2/globals/boolean.rs b/core/src/avm2/globals/boolean.rs index 073edc881..6e1497607 100644 --- a/core/src/avm2/globals/boolean.rs +++ b/core/src/avm2/globals/boolean.rs @@ -2,7 +2,7 @@ use crate::avm2::activation::Activation; use crate::avm2::class::Class; -use crate::avm2::method::Method; +use crate::avm2::method::{Method, NativeMethodImpl}; use crate::avm2::names::{Namespace, QName}; use crate::avm2::object::{primitive_allocator, Object, TObject}; use crate::avm2::value::Value; @@ -53,6 +53,39 @@ pub fn class_init<'gc>( Ok(Value::Undefined) } +/// Implements `Boolean.toString` +pub fn to_string<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(this) = this { + if let Some(this) = this.as_primitive() { + match this.coerce_to_boolean() { + true => return Ok("true".into()), + false => return Ok("false".into()), + }; + } + } + + Ok(Value::Undefined) +} + +/// Implements `Boolean.valueOf` +pub fn value_of<'gc>( + _activation: &mut Activation<'_, 'gc, '_>, + this: Option>, + _args: &[Value<'gc>], +) -> Result, Error> { + if let Some(this) = this { + if let Some(this) = this.as_primitive() { + return Ok(this.clone()); + } + } + + Ok(Value::Undefined) +} + /// Construct `Boolean`'s class. pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { let class = Class::new( @@ -71,5 +104,9 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc> mc, )); + const AS3_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = + &[("toString", to_string), ("valueOf", value_of)]; + write.define_as3_builtin_instance_methods(mc, AS3_INSTANCE_METHODS); + class } diff --git a/tests/tests/regression_tests.rs b/tests/tests/regression_tests.rs index 25d9ef3fa..8217556ff 100644 --- a/tests/tests/regression_tests.rs +++ b/tests/tests/regression_tests.rs @@ -742,6 +742,7 @@ swf_tests! { (as3_uint_tostring, "avm2/uint_tostring", 1), #[ignore] (as3_uint_toexponential, "avm2/uint_toexponential", 1), //Ignored because Flash Player has a print routine that adds extraneous zeros to things #[ignore] (as3_uint_toprecision, "avm2/uint_toprecision", 1), //Ignored because Flash Player has a print routine that adds extraneous zeros to things + (as3_boolean_tostring, "avm2/boolean_tostring", 1), } // TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough. diff --git a/tests/tests/swfs/avm2/boolean_tostring/Test.as b/tests/tests/swfs/avm2/boolean_tostring/Test.as new file mode 100644 index 000000000..7581213da --- /dev/null +++ b/tests/tests/swfs/avm2/boolean_tostring/Test.as @@ -0,0 +1,16 @@ +package { + public class Test { + } +} + +trace("//(true).toString()"); +trace((true).toString()); + +trace("//(true).valueOf() === true"); +trace((true).valueOf() === true); + +trace("//(false).toString()"); +trace((false).toString()); + +trace("//(false).valueOf() === false"); +trace((false).valueOf() === false); \ No newline at end of file diff --git a/tests/tests/swfs/avm2/boolean_tostring/output.txt b/tests/tests/swfs/avm2/boolean_tostring/output.txt new file mode 100644 index 000000000..cb4bf3a7a --- /dev/null +++ b/tests/tests/swfs/avm2/boolean_tostring/output.txt @@ -0,0 +1,8 @@ +//(true).toString() +true +//(true).valueOf() === true +true +//(false).toString() +false +//(false).valueOf() === false +true diff --git a/tests/tests/swfs/avm2/boolean_tostring/test.fla b/tests/tests/swfs/avm2/boolean_tostring/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..4b28397763a6124aec965052763d6a472d901bd7 GIT binary patch literal 4024 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