avm2: Implement String.length
This commit is contained in:
parent
4a87d707f0
commit
2ec21bdd07
|
@ -1,12 +1,12 @@
|
|||
//! `String` impl
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::class::{Class, ClassAttributes};
|
||||
use crate::avm2::method::Method;
|
||||
use crate::avm2::names::{Namespace, QName};
|
||||
use crate::avm2::object::{Object, TObject};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::Error;
|
||||
use crate::avm2::{activation::Activation, traits::Trait};
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
/// Implements `String`'s instance initializer.
|
||||
|
@ -39,13 +39,38 @@ pub fn class_init<'gc>(
|
|||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Implements `length` property's getter
|
||||
fn length<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
this: Option<Object<'gc>>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error> {
|
||||
if let Some(this) = this {
|
||||
if let Value::String(s) = this.value_of(activation.context.gc_context)? {
|
||||
return Ok(s.encode_utf16().count().into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
/// Construct `String`'s class.
|
||||
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
|
||||
Class::new(
|
||||
let class = Class::new(
|
||||
QName::new(Namespace::public(), "String"),
|
||||
Some(QName::new(Namespace::public(), "Object").into()),
|
||||
Method::from_builtin(instance_init),
|
||||
Method::from_builtin(class_init),
|
||||
mc,
|
||||
)
|
||||
);
|
||||
|
||||
let mut write = class.write(mc);
|
||||
write.set_attributes(ClassAttributes::FINAL | ClassAttributes::SEALED);
|
||||
|
||||
write.define_instance_trait(Trait::from_getter(
|
||||
QName::new(Namespace::public(), "length"),
|
||||
Method::from_builtin(length),
|
||||
));
|
||||
|
||||
class
|
||||
}
|
||||
|
|
|
@ -505,6 +505,7 @@ swf_tests! {
|
|||
(as3_movieclip_dispatchevent_target, "avm2/movieclip_dispatchevent_target", 1),
|
||||
(as3_movieclip_dispatchevent_selfadd, "avm2/movieclip_dispatchevent_selfadd", 1),
|
||||
(as3_string_constr, "avm2/string_constr", 1),
|
||||
(as3_string_length, "avm2/string_length", 1),
|
||||
}
|
||||
|
||||
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package {
|
||||
public class Test {}
|
||||
}
|
||||
|
||||
trace("//\"\".length;");
|
||||
trace("".length);
|
||||
trace("//\"\\n\\r\".length;");
|
||||
trace("\n\r".length);
|
||||
trace("//\"\\t\".length;");
|
||||
trace("\t".length);
|
||||
trace("//\"abc012aáâ\".length;");
|
||||
trace("abc012aáâ".length);
|
||||
trace("//\"你好こんにちは\".length;");
|
||||
trace("你好こんにちは".length);
|
||||
trace("//\"مَرحَبًا\".length;");
|
||||
trace("مَرحَبًا".length);
|
||||
trace("//\"😀\".length;");
|
||||
trace("😀".length);
|
||||
trace("//\"👨👨👧👦\".length;");
|
||||
trace("👨👨👧👦".length);
|
|
@ -0,0 +1,16 @@
|
|||
//"".length;
|
||||
0
|
||||
//"\n\r".length;
|
||||
2
|
||||
//"\t".length;
|
||||
1
|
||||
//"abc012aáâ".length;
|
||||
9
|
||||
//"你好こんにちは".length;
|
||||
7
|
||||
//"مَرحَبًا".length;
|
||||
8
|
||||
//"😀".length;
|
||||
2
|
||||
//"👨👨👧👦".length;
|
||||
11
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue