diff --git a/src/array.js b/src/array.js index 93378cfb00..0d25f99efd 100644 --- a/src/array.js +++ b/src/array.js @@ -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; }); diff --git a/src/harmony-typedarray.js b/src/harmony-typedarray.js index 90679e0c1f..59c9a79bd2 100644 --- a/src/harmony-typedarray.js +++ b/src/harmony-typedarray.js @@ -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 diff --git a/test/mjsunit/harmony/typedarray-reverse.js b/test/mjsunit/harmony/typedarray-reverse.js new file mode 100644 index 0000000000..98b738787b --- /dev/null +++ b/test/mjsunit/harmony/typedarray-reverse.js @@ -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); +}