avm2: Impl `Vector.reverse`

This commit is contained in:
David Wendt 2021-07-09 21:27:59 -04:00 committed by kmeisthax
parent aa2d729a44
commit 077fd87842
7 changed files with 543 additions and 0 deletions

View File

@ -678,6 +678,23 @@ pub fn remove_at<'gc>(
Ok(Value::Undefined)
}
/// Implements `Vector.reverse`
pub fn reverse<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(this) = this {
if let Some(mut vs) = this.as_vector_storage_mut(activation.context.gc_context) {
vs.reverse();
return Ok(this.into());
}
}
Ok(Value::Undefined)
}
/// Construct `Vector`'s class.
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
let class = Class::new(
@ -720,6 +737,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
("unshift", unshift),
("insertAt", insert_at),
("removeAt", remove_at),
("reverse", reverse),
];
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);

View File

@ -293,6 +293,11 @@ impl<'gc> VectorStorage<'gc> {
}
}
/// Reverse the vector's storage.
pub fn reverse(&mut self) {
self.storage.reverse();
}
/// Iterate over vector values.
pub fn iter<'a>(
&'a self,

View File

@ -645,6 +645,7 @@ swf_tests! {
(as3_vector_shiftunshift, "avm2/vector_shiftunshift", 1),
(as3_vector_insertat, "avm2/vector_insertat", 1),
(as3_vector_removeat, "avm2/vector_removeat", 1),
(as3_vector_reverse, "avm2/vector_reverse", 1),
}
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.

View File

@ -0,0 +1,287 @@
package {
public class Test {
}
}
function trace_vector(v: Vector.<*>) {
trace(v.length, "elements");
for (var i = 0; i < v.length; i += 1) {
trace(v[i]);
}
}
trace("/// var a_bool: Vector.<Boolean> = new <Boolean>[true, false];");
var a_bool:Vector.<Boolean> = new <Boolean>[true, false];
trace("/// var b_bool: Vector.<Boolean> = new <Boolean>[false, true, false];");
var b_bool:Vector.<Boolean> = new <Boolean>[false, true, false];
trace("/// var c_bool: Vector.<Boolean> = new <Boolean>[];");
var c_bool:Vector.<Boolean> = new <Boolean>[];
trace("/// a_bool.reverse();");
trace(a_bool.reverse());
trace("/// (contents of a_bool...)");
trace_vector(a_bool);
trace("/// a_bool.reverse();");
trace(a_bool.reverse());
trace("/// (contents of a_bool...)");
trace_vector(a_bool);
trace("/// b_bool.reverse();");
trace(b_bool.reverse());
trace("/// (contents of b_bool...)");
trace_vector(b_bool);
trace("/// b_bool.reverse();");
trace(b_bool.reverse());
trace("/// (contents of b_bool...)");
trace_vector(b_bool);
trace("/// c_bool.reverse();");
trace(c_bool.reverse());
trace("/// (contents of c_bool...)");
trace_vector(c_bool);
class Superclass {
}
class Subclass extends Superclass {
}
trace("/// var a0_class = new Superclass();");
var a0_class = new Superclass();
trace("/// var a1_class = new Subclass();");
var a1_class = new Subclass();
trace("/// var a_class: Vector.<Superclass> = new <Superclass>[a0_class, a1_class];");
var a_class:Vector.<Superclass> = new <Superclass>[a0_class, a1_class];
trace("/// var b_class: Vector.<Subclass> = new <Subclass>[];");
var b_class:Vector.<Subclass> = new <Subclass>[];
trace("/// b_class.length = 1;");
b_class.length = 1;
trace("/// b_class[0] = new Subclass();");
b_class[0] = new Subclass();
trace("/// a_class.reverse();");
trace(a_class.reverse());
trace("/// a1_class === a_class[0];");
trace(a1_class === a_class[0]);
trace("/// a0_class === a_class[1];");
trace(a0_class === a_class[1]);
trace("/// b_class.reverse();");
trace(b_class.reverse());
trace("/// (contents of b_class...)");
trace_vector(b_class);
function trace_vector_int(v: Vector.<int>) {
trace(v.length, "elements");
for (var i = 0; i < v.length; i += 1) {
trace(v[i]);
}
}
trace("/// var a_int: Vector.<int> = new <int>[1,2];");
var a_int:Vector.<int> = new <int>[1,2];
trace("/// var b_int: Vector.<int> = new <int>[5,16];");
var b_int:Vector.<int> = new <int>[5,16];
trace("/// a_int.reverse();");
trace(a_int.reverse());
trace("/// (contents of a_int)...");
trace_vector_int(a_int);
trace("/// a_int.reverse();");
trace(a_int.reverse());
trace("/// (contents of a_int)...");
trace_vector_int(a_int);
trace("/// b_int.reverse();");
trace(b_int.reverse());
trace("/// (contents of b_int)...");
trace_vector_int(b_int);
trace("/// b_int.reverse();");
trace(b_int.reverse());
trace("/// (contents of b_int)...");
trace_vector_int(b_int);
function trace_vector_number(v: Vector.<Number>) {
trace(v.length, "elements");
for (var i = 0; i < v.length; i += 1) {
trace(v[i]);
}
}
trace("/// var a_number: Vector.<Number> = new <Number>[1,2,3,4];");
var a_number:Vector.<Number> = new <Number>[1,2,3,4];
trace("/// var b_number: Vector.<Number> = new <Number>[5, NaN, -5, 0];");
var b_number:Vector.<Number> = new <Number>[5, NaN, -5, 0];
trace("/// a_number.reverse();");
trace(a_number.reverse());
trace("/// (contents of a_number...)");
trace_vector_number(a_number);
trace("/// a_number.reverse();");
trace(a_number.reverse());
trace("/// (contents of a_number...)");
trace_vector_number(a_number);
trace("/// b_number.reverse();");
trace(b_number.reverse());
trace("/// (contents of b_number...)");
trace_vector_number(b_number);
trace("/// b_number.reverse();");
trace(b_number.reverse());
trace("/// (contents of b_number...)");
trace_vector_number(b_number);
function trace_vector_string(v: Vector.<String>) {
trace(v.length, "elements");
for (var i = 0; i < v.length; i += 1) {
trace(v[i]);
}
}
trace("/// var a_string: Vector.<String> = new <String>[\"a\",\"c\",\"d\",\"f\"];");
var a_string:Vector.<String> = new <String>["a", "c", "d", "f"];
trace("/// var b_string: Vector.<String> = new <String>[\"986\",\"B4\",\"Q\",\"rrr\"];");
var b_string:Vector.<String> = new <String>["986", "B4", "Q", "rrr"];
trace("/// a_string.reverse();");
trace(a_string.reverse());
trace("/// (contents of a_string...)");
trace_vector_string(a_string);
trace("/// a_string.reverse();");
trace(a_string.reverse());
trace("/// (contents of a_string...)");
trace_vector_string(a_string);
trace("/// b_string.reverse();");
trace(b_string.reverse());
trace("/// (contents of b_string...)");
trace_vector_string(b_string);
trace("/// b_string.reverse();");
trace(b_string.reverse());
trace("/// (contents of b_string...)");
trace_vector_string(b_string);
function trace_vector_uint(v: Vector.<uint>) {
trace(v.length, "elements");
for (var i = 0; i < v.length; i += 1) {
trace(v[i]);
}
}
trace("/// var a_uint: Vector.<uint> = new <uint>[1,2];");
var a_uint:Vector.<uint> = new <uint>[1,2];
trace("/// var b_uint: Vector.<uint> = new <uint>[5,16];");
var b_uint:Vector.<uint> = new <uint>[5,16];
trace("/// a_uint.reverse();");
trace(a_uint.reverse());
trace("/// (contents of a_uint...)");
trace_vector_uint(a_uint);
trace("/// a_uint.reverse();");
trace(a_uint.reverse());
trace("/// (contents of a_uint...)");
trace_vector_uint(a_uint);
trace("/// b_uint.reverse();");
trace(b_uint.reverse());
trace("/// (contents of b_uint...)");
trace_vector_uint(b_uint);
trace("/// b_uint.reverse();");
trace(b_uint.reverse());
trace("/// (contents of b_uint...)");
trace_vector_uint(b_uint);
function trace_vector_vector(v) {
trace(v.length, "elements");
for (var i = 0; i < v.length; i += 1) {
if (v[i] is Vector.<int>) {
trace("/// (contents of index", i, ")");
trace_vector_vector(v[i]);
} else {
trace(v[i]);
}
}
}
trace("/// var a_vector:Vector.<Vector.<int>> = new <Vector.<int>>[new <int>[1,2], new <int>[4,3]];");
var a_vector:Vector.<Vector.<int>> = new <Vector.<int>>[new <int>[1,2], new <int>[4,3]];
trace("/// var b_vector:Vector.<Vector.<int>> = new <Vector.<int>>[new <int>[5,16], new <int>[19,8]];");
var b_vector:Vector.<Vector.<int>> = new <Vector.<int>>[new <int>[5,16], new <int>[19,8]];
trace("/// a_vector.reverse();");
trace(a_vector.reverse());
trace("/// (contents of a_vector...)");
trace_vector_vector(a_vector);
trace("/// a_vector.reverse();");
trace(a_vector.reverse());
trace("/// (contents of a_vector...)");
trace_vector_vector(a_vector);
trace("/// b_vector.reverse();");
trace(b_vector.reverse());
trace("/// (contents of b_vector...)");
trace_vector_vector(b_vector);
trace("/// b_vector.reverse();");
trace(b_vector.reverse());
trace("/// (contents of b_vector...)");
trace_vector_vector(b_vector);
trace("/// (contents of b_vector.reverse()...)");
trace_vector_vector(b_vector.reverse());
trace("/// b_vector === b_vector.reverse()");
trace(b_vector === b_vector.reverse());

View File

@ -0,0 +1,232 @@
/// var a_bool: Vector.<Boolean> = new <Boolean>[true, false];
/// var b_bool: Vector.<Boolean> = new <Boolean>[false, true, false];
/// var c_bool: Vector.<Boolean> = new <Boolean>[];
/// a_bool.reverse();
false,true
/// (contents of a_bool...)
2 elements
false
true
/// a_bool.reverse();
true,false
/// (contents of a_bool...)
2 elements
true
false
/// b_bool.reverse();
false,true,false
/// (contents of b_bool...)
3 elements
false
true
false
/// b_bool.reverse();
false,true,false
/// (contents of b_bool...)
3 elements
false
true
false
/// c_bool.reverse();
/// (contents of c_bool...)
0 elements
/// var a0_class = new Superclass();
/// var a1_class = new Subclass();
/// var a_class: Vector.<Superclass> = new <Superclass>[a0_class, a1_class];
/// var b_class: Vector.<Subclass> = new <Subclass>[];
/// b_class.length = 1;
/// b_class[0] = new Subclass();
/// a_class.reverse();
[object Subclass],[object Superclass]
/// a1_class === a_class[0];
true
/// a0_class === a_class[1];
true
/// b_class.reverse();
[object Subclass]
/// (contents of b_class...)
1 elements
[object Subclass]
/// var a_int: Vector.<int> = new <int>[1,2];
/// var b_int: Vector.<int> = new <int>[5,16];
/// a_int.reverse();
2,1
/// (contents of a_int)...
2 elements
2
1
/// a_int.reverse();
1,2
/// (contents of a_int)...
2 elements
1
2
/// b_int.reverse();
16,5
/// (contents of b_int)...
2 elements
16
5
/// b_int.reverse();
5,16
/// (contents of b_int)...
2 elements
5
16
/// var a_number: Vector.<Number> = new <Number>[1,2,3,4];
/// var b_number: Vector.<Number> = new <Number>[5, NaN, -5, 0];
/// a_number.reverse();
4,3,2,1
/// (contents of a_number...)
4 elements
4
3
2
1
/// a_number.reverse();
1,2,3,4
/// (contents of a_number...)
4 elements
1
2
3
4
/// b_number.reverse();
0,-5,NaN,5
/// (contents of b_number...)
4 elements
0
-5
NaN
5
/// b_number.reverse();
5,NaN,-5,0
/// (contents of b_number...)
4 elements
5
NaN
-5
0
/// var a_string: Vector.<String> = new <String>["a","c","d","f"];
/// var b_string: Vector.<String> = new <String>["986","B4","Q","rrr"];
/// a_string.reverse();
f,d,c,a
/// (contents of a_string...)
4 elements
f
d
c
a
/// a_string.reverse();
a,c,d,f
/// (contents of a_string...)
4 elements
a
c
d
f
/// b_string.reverse();
rrr,Q,B4,986
/// (contents of b_string...)
4 elements
rrr
Q
B4
986
/// b_string.reverse();
986,B4,Q,rrr
/// (contents of b_string...)
4 elements
986
B4
Q
rrr
/// var a_uint: Vector.<uint> = new <uint>[1,2];
/// var b_uint: Vector.<uint> = new <uint>[5,16];
/// a_uint.reverse();
2,1
/// (contents of a_uint...)
2 elements
2
1
/// a_uint.reverse();
1,2
/// (contents of a_uint...)
2 elements
1
2
/// b_uint.reverse();
16,5
/// (contents of b_uint...)
2 elements
16
5
/// b_uint.reverse();
5,16
/// (contents of b_uint...)
2 elements
5
16
/// var a_vector:Vector.<Vector.<int>> = new <Vector.<int>>[new <int>[1,2], new <int>[4,3]];
/// var b_vector:Vector.<Vector.<int>> = new <Vector.<int>>[new <int>[5,16], new <int>[19,8]];
/// a_vector.reverse();
4,3,1,2
/// (contents of a_vector...)
2 elements
/// (contents of index 0 )
2 elements
4
3
/// (contents of index 1 )
2 elements
1
2
/// a_vector.reverse();
1,2,4,3
/// (contents of a_vector...)
2 elements
/// (contents of index 0 )
2 elements
1
2
/// (contents of index 1 )
2 elements
4
3
/// b_vector.reverse();
19,8,5,16
/// (contents of b_vector...)
2 elements
/// (contents of index 0 )
2 elements
19
8
/// (contents of index 1 )
2 elements
5
16
/// b_vector.reverse();
5,16,19,8
/// (contents of b_vector...)
2 elements
/// (contents of index 0 )
2 elements
5
16
/// (contents of index 1 )
2 elements
19
8
/// (contents of b_vector.reverse()...)
2 elements
/// (contents of index 0 )
2 elements
19
8
/// (contents of index 1 )
2 elements
5
16
/// b_vector === b_vector.reverse()
true

Binary file not shown.

Binary file not shown.