diff --git a/core/src/avm2/globals/object.rs b/core/src/avm2/globals/object.rs index db0c1e4e3..84dbda66e 100644 --- a/core/src/avm2/globals/object.rs +++ b/core/src/avm2/globals/object.rs @@ -46,7 +46,7 @@ fn to_locale_string<'gc>( _: &[Value<'gc>], ) -> Result, Error> { Ok(this - .map(|t| t.to_string(activation.context.gc_context)) + .map(|t| t.to_locale_string(activation.context.gc_context)) .unwrap_or(Ok(Value::Undefined))?) } diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index e0e294f82..740093311 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -673,6 +673,23 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + Clone + Copy /// coercions. fn to_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error>; + /// Implement the result of calling `Object.prototype.toLocaleString` on this + /// object class. + /// + /// `toLocaleString` is a method used to request an object be coerced to a + /// locale-dependent string value. The default implementation appears to + /// generate a debug-style string based on the name of the class this + /// object is, in the format of `[object Class]` (where `Class` is the name + /// of the class that created this object). + fn to_locale_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { + let class_name = self + .as_proto_class() + .map(|c| c.read().name().local_name()) + .unwrap_or_else(|| "Object".into()); + + Ok(AvmString::new(mc, format!("[object {}]", class_name)).into()) + } + /// Implement the result of calling `Object.prototype.valueOf` on this /// object class. /// diff --git a/core/src/avm2/object/function_object.rs b/core/src/avm2/object/function_object.rs index 2606dd56f..81b0e73c4 100644 --- a/core/src/avm2/object/function_object.rs +++ b/core/src/avm2/object/function_object.rs @@ -288,6 +288,10 @@ impl<'gc> TObject<'gc> for FunctionObject<'gc> { } } + fn to_locale_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { + self.to_string(mc) + } + fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result, Error> { Ok(Value::Object(Object::from(*self))) } diff --git a/core/src/avm2/object/primitive_object.rs b/core/src/avm2/object/primitive_object.rs index be31c2f4c..7880b0861 100644 --- a/core/src/avm2/object/primitive_object.rs +++ b/core/src/avm2/object/primitive_object.rs @@ -79,6 +79,20 @@ impl<'gc> TObject<'gc> for PrimitiveObject<'gc> { Ok(self.0.read().primitive.clone()) } + fn to_locale_string(&self, mc: MutationContext<'gc, '_>) -> Result, Error> { + match self.0.read().primitive.clone() { + val @ Value::Integer(_) | val @ Value::Unsigned(_) => Ok(val), + _ => { + let class_name = self + .as_proto_class() + .map(|c| c.read().name().local_name()) + .unwrap_or_else(|| "Object".into()); + + Ok(AvmString::new(mc, format!("[object {}]", class_name)).into()) + } + } + } + fn value_of(&self, _mc: MutationContext<'gc, '_>) -> Result, Error> { Ok(self.0.read().primitive.clone()) }