Commit 8934b9ea authored by domenic's avatar domenic Committed by Commit bot

Add includes method to typed arrays

R=littledan@chromium.org, adamk@chromium.org
BUG=v8:3575
LOG=Y

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

Cr-Commit-Position: refs/heads/master@{#30117}
parent 7a823598
......@@ -14,12 +14,9 @@ var GlobalArray = global.Array;
// Proposed for ES7
// https://github.com/tc39/Array.prototype.includes
// 6e3b78c927aeda20b9d40e81303f9d44596cd904
function ArrayIncludes(searchElement, fromIndex) {
var array = TO_OBJECT(this);
var len = $toLength(array.length);
if (len === 0) {
// 46c7532ec8499dea3e51aeb940d09e07547ed3f5
function InnerArrayIncludes(searchElement, fromIndex, array, length) {
if (length === 0) {
return false;
}
......@@ -29,13 +26,13 @@ function ArrayIncludes(searchElement, fromIndex) {
if (n >= 0) {
k = n;
} else {
k = len + n;
k = length + n;
if (k < 0) {
k = 0;
}
}
while (k < len) {
while (k < length) {
var elementK = array[k];
if ($sameValueZero(searchElement, elementK)) {
return true;
......@@ -47,13 +44,65 @@ function ArrayIncludes(searchElement, fromIndex) {
return false;
}
function ArrayIncludes(searchElement, fromIndex) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.includes");
var array = TO_OBJECT(this);
var length = $toLength(array.length);
return InnerArrayIncludes(searchElement, fromIndex, array, length);
}
function TypedArrayIncludes(searchElement, fromIndex) {
if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
var length = %_TypedArrayGetLength(this);
return InnerArrayIncludes(searchElement, fromIndex, this, length);
}
// -------------------------------------------------------------------
%FunctionSetLength(ArrayIncludes, 1);
%FunctionSetLength(TypedArrayIncludes, 1);
// Set up the non-enumerable functions on the Array prototype object.
// Set up the non-enumerable function on the Array prototype object.
utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
"includes", ArrayIncludes
]);
// Set up the non-enumerable function on the typed array prototypes.
// This duplicates some of the machinery in harmony-typedarray.js in order to
// keep includes behind the separate --harmony-array-includes flag.
// TODO(littledan): Fix the TypedArray proto chain (bug v8:4085).
macro TYPED_ARRAYS(FUNCTION)
// arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
FUNCTION(Uint8Array)
FUNCTION(Int8Array)
FUNCTION(Uint16Array)
FUNCTION(Int16Array)
FUNCTION(Uint32Array)
FUNCTION(Int32Array)
FUNCTION(Float32Array)
FUNCTION(Float64Array)
FUNCTION(Uint8ClampedArray)
endmacro
macro DECLARE_GLOBALS(NAME)
var GlobalNAME = global.NAME;
endmacro
macro EXTEND_TYPED_ARRAY(NAME)
// Set up non-enumerable functions on the prototype object.
utils.InstallFunctions(GlobalNAME.prototype, DONT_ENUM, [
"includes", TypedArrayIncludes
]);
endmacro
TYPED_ARRAYS(DECLARE_GLOBALS)
TYPED_ARRAYS(EXTEND_TYPED_ARRAY)
})
// 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-array-includes
// Largely ported from
// https://github.com/tc39/Array.prototype.includes/tree/master/test/built-ins/TypedArray/prototype/includes
// using https://www.npmjs.org/package/test262-to-mjsunit with further edits
function testTypedArrays(callback) {
[
Uint8Array,
Int8Array,
Uint16Array,
Int16Array,
Uint32Array,
Int32Array,
Uint8ClampedArray,
Float32Array,
Float64Array
]
.forEach(callback);
}
testTypedArrays.floatOnly = function (callback) {
[Float32Array, Float64Array].forEach(callback);
};
// %TypedArray%.prototype.includes throws a TypeError when used on non-typed
// arrays
(function() {
var taIncludes = Uint8Array.prototype.includes;
assertThrows(function() {
taIncludes.call({
length: 2,
0: 1,
1: 2
}, 2);
}, TypeError);
assertThrows(function() {
taIncludes.call([1, 2, 3], 2);
}, TypeError);
assertThrows(function() {
taIncludes.call(null, 2);
}, TypeError);
assertThrows(function() {
taIncludes.call(undefined, 2);
}, TypeError);
})();
// %TypedArray%.prototype.includes should terminate if ToNumber ends up being
// called on a symbol fromIndex
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([1, 2, 3]);
assertThrows(function() {
ta.includes(2, Symbol());
}, TypeError);
});
})();
// %TypedArray%.prototype.includes should terminate if an exception occurs
// converting the fromIndex to a number
(function() {
function Test262Error() {}
var fromIndex = {
valueOf: function() {
throw new Test262Error();
}
};
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([1, 2, 3]);
assertThrows(function() {
ta.includes(2, fromIndex);
}, Test262Error);
});
})();
// %TypedArray%.prototype.includes should search the whole array, as the
// optional second argument fromIndex defaults to 0
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([1, 2, 3]);
assertTrue(ta.includes(1));
assertTrue(ta.includes(2));
assertTrue(ta.includes(3));
});
})();
// %TypedArray%.prototype.includes returns false if fromIndex is greater or
// equal to the length of the array
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([1, 2]);
assertFalse(ta.includes(2, 3));
assertFalse(ta.includes(2, 2));
});
})();
// %TypedArray%.prototype.includes searches the whole array if the computed
// index from the given negative fromIndex argument is less than 0
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([1, 3]);
assertTrue(ta.includes(1, -4));
assertTrue(ta.includes(1, -4));
});
})();
// %TypedArray%.prototype.includes should use a negative value as the offset
// from the end of the array to compute fromIndex
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([12, 13]);
assertTrue(ta.includes(13, -1));
assertFalse(ta.includes(12, -1));
assertTrue(ta.includes(12, -2));
});
})();
// %TypedArray%.prototype.includes converts its fromIndex parameter to an
// integer
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([1, 2, 3]);
assertFalse(ta.includes(1, 3.3));
assertTrue(ta.includes(1, -Infinity));
assertTrue(ta.includes(3, 2.9));
assertTrue(ta.includes(3, NaN));
var numberLike = {
valueOf: function() {
return 2;
}
};
assertFalse(ta.includes(1, numberLike));
assertFalse(ta.includes(1, "2"));
assertTrue(ta.includes(3, numberLike));
assertTrue(ta.includes(3, "2"));
});
})();
// %TypedArray%.prototype.includes should have length 1
(function() {
assertEquals(1, Uint8Array.prototype.includes.length);
})();
// %TypedArray%.prototype.includes should have name property with value
// 'includes'
(function() {
assertEquals("includes", Uint8Array.prototype.includes.name);
})();
// %TypedArray%.prototype.includes should always return false on zero-length
// typed arrays
(function() {
testTypedArrays(function(TypedArrayConstructor) {
var ta = new TypedArrayConstructor([]);
assertFalse(ta.includes(2));
assertFalse(ta.includes());
assertFalse(ta.includes(undefined));
assertFalse(ta.includes(NaN));
});
})();
// %TypedArray%.prototype.includes should use the SameValueZero algorithm to
// compare
(function() {
testTypedArrays.floatOnly(function(FloatArrayConstructor) {
assertTrue(new FloatArrayConstructor([1, 2, NaN]).includes(NaN));
assertTrue(new FloatArrayConstructor([1, 2, -0]).includes(+0));
assertTrue(new FloatArrayConstructor([1, 2, -0]).includes(-0));
assertTrue(new FloatArrayConstructor([1, 2, +0]).includes(-0));
assertTrue(new FloatArrayConstructor([1, 2, +0]).includes(+0));
assertFalse(new FloatArrayConstructor([1, 2, -Infinity]).includes(+Infinity));
assertTrue(new FloatArrayConstructor([1, 2, -Infinity]).includes(-Infinity));
assertFalse(new FloatArrayConstructor([1, 2, +Infinity]).includes(-Infinity));
assertTrue(new FloatArrayConstructor([1, 2, +Infinity]).includes(+Infinity));
});
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment