Implement %TypedArray%.reverse

This patch adds the reverse method to TypedArrays, together with a
test. The test also runs for normal Arrays, since I didn't see a
test for reversing dense arrays.

BUG=v8:3578
LOG=Y
R=arv@chromium.org

Review URL: https://codereview.chromium.org/1132723008

Patch from Daniel Ehrenberg <dehrenberg@chromium.org>.

Cr-Commit-Position: refs/heads/master@{#28493}
This commit is contained in:
Daniel Ehrenberg 2015-05-19 17:38:59 -07:00 committed by Adam Klein
parent 65141b68ca
commit cc74268d30
3 changed files with 86 additions and 13 deletions

View File

@ -12,6 +12,7 @@ var $arraySplice;
var $arrayUnshift;
var $innerArrayForEach;
var $innerArrayEvery;
var $innerArrayReverse;
(function(global, shared, exports) {
@ -564,18 +565,7 @@ function SparseReverse(array, len) {
}
function ArrayReverse() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
var array = TO_OBJECT_INLINE(this);
var len = TO_UINT32(array.length);
if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
%NormalizeElements(array);
SparseReverse(array, len);
return array;
}
function InnerArrayReverse(array, len) {
var j = len - 1;
for (var i = 0; i < j; i++, j--) {
var current_i = array[i];
@ -600,6 +590,22 @@ function ArrayReverse() {
}
function ArrayReverse() {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reverse");
var array = TO_OBJECT_INLINE(this);
var len = TO_UINT32(array.length);
if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
%NormalizeElements(array);
SparseReverse(array, len);
return array;
}
return InnerArrayReverse(array, len);
}
function ObservedArrayShift(len) {
var first = this[0];
@ -1609,5 +1615,6 @@ $arrayUnshift = ArrayUnshift;
$innerArrayForEach = InnerArrayForEach;
$innerArrayEvery = InnerArrayEvery;
$innerArrayReverse = InnerArrayReverse;
});

View File

@ -90,6 +90,15 @@ function TypedArrayFindIndex(predicate, thisArg) {
}
%FunctionSetLength(TypedArrayFindIndex, 1);
// ES6 draft 05-18-15, section 22.2.3.21
function TypedArrayReverse() {
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
var length = %_TypedArrayGetLength(this);
return $innerArrayReverse(this, length);
}
// ES6 draft 08-24-14, section 22.2.2.2
function TypedArrayOf() {
@ -140,7 +149,8 @@ macro EXTEND_TYPED_ARRAY(NAME)
"forEach", TypedArrayForEach,
"find", TypedArrayFind,
"findIndex", TypedArrayFindIndex,
"fill", TypedArrayFill
"fill", TypedArrayFill,
"reverse", TypedArrayReverse
]);
endmacro

View File

@ -0,0 +1,56 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-arrays
function ArrayMaker(x) {
return x;
}
ArrayMaker.prototype = Array.prototype;
var arrayConstructors = [
Uint8Array,
Int8Array,
Uint16Array,
Int16Array,
Uint32Array,
Int32Array,
Uint8ClampedArray,
Float32Array,
Float64Array,
ArrayMaker // Also test arrays
];
function assertArrayLikeEquals(value, expected, type) {
assertEquals(value.__proto__, type.prototype);
assertEquals(expected.length, value.length);
for (var i = 0; i < value.length; ++i) {
assertEquals(expected[i], value[i]);
}
}
for (var constructor of arrayConstructors) {
// Test reversing both even and odd length arrays
var a = new constructor([1, 2, 3]);
assertArrayLikeEquals(a.reverse(), [3, 2, 1], constructor);
assertArrayLikeEquals(a, [3, 2, 1], constructor);
a = new constructor([1, 2, 3, 4]);
assertArrayLikeEquals(a.reverse(), [4, 3, 2, 1], constructor);
assertArrayLikeEquals(a, [4, 3, 2, 1], constructor);
if (constructor != ArrayMaker) {
// Cannot be called on objects which are not TypedArrays
assertThrows(function () { a.reverse.call({ length: 0 }); }, TypeError);
} else {
// Array.reverse works on array-like objects
var x = { length: 2, 1: 5 };
a.reverse.call(x);
assertEquals(2, x.length);
assertFalse(Object.hasOwnProperty(x, '1'));
assertEquals(5, x[0]);
}
assertEquals(0, a.reverse.length);
}