avm2: Impl `Array.toLocaleString`.

This commit is contained in:
David Wendt 2020-09-02 19:28:55 -04:00 committed by Mike Welsh
parent 2ae3b6445b
commit ca4982029b
6 changed files with 80 additions and 7 deletions

View File

@ -130,12 +130,15 @@ fn resolve_array_hole<'gc>(
})
}
/// Implements `Array.join`
pub fn join<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
pub fn join_inner<'gc, 'a, 'ctxt, C>(
activation: &mut Activation<'a, 'gc, 'ctxt>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
mut conv: C,
) -> Result<Value<'gc>, Error>
where
C: for<'b> FnMut(Value<'gc>, &'b mut Activation<'a, 'gc, 'ctxt>) -> Result<Value<'gc>, Error>,
{
let mut separator = args.get(0).cloned().unwrap_or(Value::Undefined);
if separator == Value::Undefined {
separator = ",".into();
@ -149,7 +152,11 @@ pub fn join<'gc>(
for (i, item) in array.iter().enumerate() {
let item = resolve_array_hole(activation, this, i, item)?;
accum.push(item.coerce_to_string(activation)?.to_string());
accum.push(
conv(item, activation)?
.coerce_to_string(activation)?
.to_string(),
);
}
return Ok(AvmString::new(
@ -163,13 +170,42 @@ pub fn join<'gc>(
Ok(Value::Undefined)
}
/// Implements `Array.join`
pub fn join<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
join_inner(activation, this, args, |v, _act| Ok(v))
}
/// Implements `Array.toString`
pub fn to_string<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
join(activation, this, &[",".into()])
join_inner(activation, this, &[",".into()], |v, _act| Ok(v))
}
/// Implements `Array.toLocaleString`
pub fn to_locale_string<'gc>(
act: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
join_inner(act, this, &[",".into()], |v, activation| {
let mut o = v.coerce_to_object(activation)?;
let tls = o.get_property(
o,
&QName::new(Namespace::public_namespace(), "toLocaleString"),
activation,
)?;
tls.coerce_to_object(activation)?
.call(Some(o), &[], activation, o.proto())
})
}
/// Implements `Array.valueOf`
@ -178,7 +214,7 @@ pub fn value_of<'gc>(
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
join(activation, this, &[",".into()])
join_inner(activation, this, &[",".into()], |v, _act| Ok(v))
}
/// An iterator that allows iterating over the contents of an array whilst also
@ -758,6 +794,11 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
Method::from_builtin(to_string),
));
class.write(mc).define_instance_trait(Trait::from_method(
QName::new(Namespace::public_namespace(), "toLocaleString"),
Method::from_builtin(to_locale_string),
));
class.write(mc).define_instance_trait(Trait::from_method(
QName::new(Namespace::public_namespace(), "valueOf"),
Method::from_builtin(value_of),

View File

@ -362,6 +362,7 @@ swf_tests! {
(as3_array_literal, "avm2/array_literal", 1),
(as3_array_concat, "avm2/array_concat", 1),
(as3_array_tostring, "avm2/array_tostring", 1),
(as3_array_tolocalestring, "avm2/array_tolocalestring", 1),
(as3_array_valueof, "avm2/array_valueof", 1),
(as3_array_join, "avm2/array_join", 1),
(as3_array_foreach, "avm2/array_foreach", 1),

View File

@ -0,0 +1,22 @@
package {
public class Test {
}
}
trace("//var a = new Array(\"a\", \"b\", \"c\");");
var a = new Array("a", "b", "c");
trace("//var b = new Array(1, 2, 3);");
var b = new Array(1, 2, 3);
trace("//var c = new Array(a, b);");
var c = new Array(a, b);
trace("//a.toLocaleString();");
trace(a.toLocaleString());
trace("//b.toLocaleString();");
trace(b.toLocaleString());
trace("//c.toLocaleString();");
trace(c.toLocaleString());

View File

@ -0,0 +1,9 @@
//var a = new Array("a", "b", "c");
//var b = new Array(1, 2, 3);
//var c = new Array(a, b);
//a.toLocaleString();
[object String],[object String],[object String]
//b.toLocaleString();
1,2,3
//c.toLocaleString();
[object String],[object String],[object String],1,2,3

Binary file not shown.

Binary file not shown.