avm2: implement string.split for undefined (#5064)

* avm2: implement string.split for undefined

* chore: cargo fmt

* dev: avoid explicit ArrayStorage
This commit is contained in:
Chris Midgley 2021-08-18 17:02:41 +01:00 committed by GitHub
parent 45d2f3fcde
commit 58c907e985
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 12 deletions

View File

@ -143,7 +143,8 @@ To add a test here, create a .swf file that runs `trace()` statements. You can d
* [`mtasc`](http://web.archive.org/web/20210324063628/http://tech.motion-twin.com/mtasc.html) (ActionScript 2 only) * [`mtasc`](http://web.archive.org/web/20210324063628/http://tech.motion-twin.com/mtasc.html) (ActionScript 2 only)
* if you create a file `test.as` with a `class Test` with a `static function main` with the code you want to run, you can compile it using `mtasc -main -header 200:150:30 test.as -swf test.swf` * if you create a file `test.as` with a `class Test` with a `static function main` with the code you want to run, you can compile it using `mtasc -main -header 200:150:30 test.as -swf test.swf`
* [`mxmlc`](https://helpx.adobe.com/air/kb/archived-air-sdk-version.html) (ActionScript 3 only) * [`mxmlc`](https://helpx.adobe.com/air/kb/archived-air-sdk-version.html) (ActionScript 3 only)
* if you create a file `test.as`, you can compile it using `mxmlc test.as`. `mxmlc` is located in the `bin` folder of the downloadable AIR SDK. * if you create a file `test.as` with a `class Test`, you can compile it using `mxmlc Test.as`. `mxmlc` is located in the `bin` folder of the downloadable AIR SDK.
* you may want to use docker instead -- something like `docker run -it --rm -v ${PWD}:/src jeko/airbuild mxmlc ./Test.as` works well
Run the .swf in Flash Player and create a file `output.txt` with the contents of the trace statements. Add the `output.txt`, `test.swf` and either the `test.as` or `test.fla` file to a directory under `core/tests/swfs/avm1` (or `avm2`) named after what your test tests, and add a line in `regression_tests.rs` to have Ruffle run it. Run the .swf in Flash Player and create a file `output.txt` with the contents of the trace statements. Add the `output.txt`, `test.swf` and either the `test.as` or `test.fla` file to a directory under `core/tests/swfs/avm1` (or `avm2`) named after what your test tests, and add a line in `regression_tests.rs` to have Ruffle run it.

View File

@ -11,6 +11,7 @@ use crate::avm2::ArrayObject;
use crate::avm2::Error; use crate::avm2::Error;
use crate::string_utils; use crate::string_utils;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
use std::iter;
/// Implements `String`'s instance initializer. /// Implements `String`'s instance initializer.
pub fn instance_init<'gc>( pub fn instance_init<'gc>(
@ -126,12 +127,16 @@ fn split<'gc>(
args: &[Value<'gc>], args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> { ) -> Result<Value<'gc>, Error> {
if let Some(this) = this { if let Some(this) = this {
if matches!(args.get(0).unwrap_or(&Value::Undefined), Value::Undefined) { let delimiter = args.get(0).unwrap_or(&Value::Undefined);
log::warn!("string.split(undefined) - not implemented"); if matches!(delimiter, Value::Undefined) {
let this = Value::from(this);
return Ok(
ArrayObject::from_storage(activation, iter::once(this).collect())
.unwrap()
.into(),
);
} }
if args if delimiter
.get(0)
.unwrap_or(&Value::Undefined)
.coerce_to_object(activation)? .coerce_to_object(activation)?
.as_regexp() .as_regexp()
.is_some() .is_some()
@ -139,10 +144,7 @@ fn split<'gc>(
log::warn!("string.split(regex) - not implemented"); log::warn!("string.split(regex) - not implemented");
} }
let this = Value::from(this).coerce_to_string(activation)?; let this = Value::from(this).coerce_to_string(activation)?;
let delimiter = args let delimiter = delimiter.coerce_to_string(activation)?;
.get(0)
.unwrap_or(&Value::Undefined)
.coerce_to_string(activation)?;
let limit = match args.get(1).unwrap_or(&Value::Undefined) { let limit = match args.get(1).unwrap_or(&Value::Undefined) {
Value::Undefined => usize::MAX, Value::Undefined => usize::MAX,
limit => limit.coerce_to_i32(activation)?.max(0) as usize, limit => limit.coerce_to_i32(activation)?.max(0) as usize,

View File

@ -5,5 +5,6 @@
a,b,c a,b,c
// text.split("") // text.split("")
a,.,b,.,c a,.,b,.,c
// text.split() - unimplemented // text.split()
a.b.c
// text.split(regex) - unimplemented // text.split(regex) - unimplemented

View File

@ -16,7 +16,8 @@ trace(text.split("."));
trace('// text.split("")'); trace('// text.split("")');
trace(text.split("")); trace(text.split(""));
trace('// text.split() - unimplemented'); trace('// text.split()');
trace(text.split());
trace('// text.split(regex) - unimplemented'); trace('// text.split(regex) - unimplemented');