mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1111869 - Implement %TypedArray%.prototype.includes. r=till
This commit is contained in:
parent
d23a9bd047
commit
8dc8822499
@ -582,7 +582,7 @@ function ArrayFill(value, start = 0, end = undefined) {
|
||||
}
|
||||
|
||||
// Proposed for ES7:
|
||||
// https://github.com/domenic/Array.prototype.includes/blob/master/spec.md
|
||||
// https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md
|
||||
function ArrayIncludes(searchElement, fromIndex = 0) {
|
||||
// Steps 1-2.
|
||||
var O = ToObject(this);
|
||||
|
@ -235,3 +235,53 @@ function TypedArrayReverse() {
|
||||
// Step 9.
|
||||
return O;
|
||||
}
|
||||
|
||||
// Proposed for ES7:
|
||||
// https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md
|
||||
function TypedArrayIncludes(searchElement, fromIndex = 0) {
|
||||
// This function is not generic.
|
||||
if (!IsObject(this) || !IsTypedArray(this)) {
|
||||
return callFunction(CallTypedArrayMethodIfWrapped, this, searchElement,
|
||||
fromIndex, "TypedArrayIncludes");
|
||||
}
|
||||
|
||||
// Steps 1-2.
|
||||
var O = this;
|
||||
|
||||
// Steps 3-4.
|
||||
var len = TypedArrayLength(O);
|
||||
|
||||
// Step 5.
|
||||
if (len === 0)
|
||||
return false;
|
||||
|
||||
// Steps 6-7.
|
||||
var n = ToInteger(fromIndex);
|
||||
|
||||
var k;
|
||||
// Step 8.
|
||||
if (n >= 0) {
|
||||
k = n;
|
||||
}
|
||||
// Step 9.
|
||||
else {
|
||||
// Step a.
|
||||
k = len + n;
|
||||
// Step b.
|
||||
if (k < 0)
|
||||
k = 0;
|
||||
}
|
||||
|
||||
// Step 10.
|
||||
while (k < len) {
|
||||
// Steps a-c.
|
||||
if (SameValueZero(searchElement, O[k]))
|
||||
return true;
|
||||
|
||||
// Step d.
|
||||
k++;
|
||||
}
|
||||
|
||||
// Step 11.
|
||||
return false;
|
||||
}
|
||||
|
@ -53,14 +53,14 @@ for (var constructor of constructors) {
|
||||
}
|
||||
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var nonTypedArrays = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
|
||||
/* new Proxy(new constructor(), {}) // This probably should throw */
|
||||
];
|
||||
nonTypedArrays.forEach(nonTypedArray => {
|
||||
assertThrowsInstanceOf(function() {
|
||||
constructor.prototype.fill.call(nonTypedArray, 1);
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./]
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.fill.call(invalidReceiver, 1);
|
||||
}, TypeError);
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.fill.call(new Proxy(new constructor(), {}));
|
||||
|
||||
// Test that the length getter is never called.
|
||||
Object.defineProperty(new constructor([1, 2, 3]), "length", {
|
||||
|
56
js/src/tests/ecma_6/TypedArray/includes.js
Normal file
56
js/src/tests/ecma_6/TypedArray/includes.js
Normal file
@ -0,0 +1,56 @@
|
||||
const constructors = [
|
||||
Int8Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
Int16Array,
|
||||
Uint16Array,
|
||||
Int32Array,
|
||||
Uint32Array,
|
||||
Float32Array,
|
||||
Float64Array
|
||||
];
|
||||
|
||||
for (var constructor of constructors) {
|
||||
if (!("includes" in constructor.prototype))
|
||||
break;
|
||||
|
||||
assertEq(constructor.prototype.includes.length, 1);
|
||||
|
||||
assertEq(new constructor([1, 2, 3]).includes(1), true);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2), true);
|
||||
assertEq(new constructor([1, 2, 3]).includes(3), true);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2, 1), true);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2, -2), true);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2, -100), true);
|
||||
|
||||
assertEq(new constructor([1, 2, 3]).includes("2"), false);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2, 2), false);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2, -1), false);
|
||||
assertEq(new constructor([1, 2, 3]).includes(2, 100), false);
|
||||
|
||||
// Called from other globals.
|
||||
if (typeof newGlobal === "function") {
|
||||
var includes = newGlobal()[constructor.name].prototype.includes;
|
||||
assertEq(includes.call(new constructor([1, 2, 3]), 2), true);
|
||||
}
|
||||
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.includes.call(invalidReceiver);
|
||||
}, TypeError, "Assert that reverse fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.includes.call(new Proxy(new constructor(), {}));
|
||||
|
||||
// Test that the length getter is never called.
|
||||
assertEq(Object.defineProperty(new constructor([1, 2, 3]), "length", {
|
||||
get() {
|
||||
throw new Error("length accessor called");
|
||||
}
|
||||
}).includes(2), true);
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
@ -10,12 +10,11 @@ const constructors = [
|
||||
Float64Array
|
||||
];
|
||||
|
||||
// Tests for TypedArray#indexOf
|
||||
// Tests for TypedArray#indexOf.
|
||||
for (var constructor of constructors) {
|
||||
|
||||
assertEq(constructor.prototype.indexOf.length, 1);
|
||||
|
||||
// works with one argument
|
||||
// Works with one argument.
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(0), -1);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1), 0);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(5), 4);
|
||||
@ -33,7 +32,7 @@ for (var constructor of constructors) {
|
||||
assertEq(new constructor([NaN, 0, -0]).indexOf(-0), 0);
|
||||
}
|
||||
|
||||
// works with two arguments
|
||||
// Works with two arguments.
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1, 1), -1);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(1, -100), 0);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).indexOf(3, 100), -1);
|
||||
@ -41,15 +40,15 @@ for (var constructor of constructors) {
|
||||
assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1, 2), 2);
|
||||
assertEq(new constructor([1, 2, 1, 2, 1]).indexOf(1, -2), 4);
|
||||
|
||||
// throws if `this` isn't a TypedArray
|
||||
var nonTypedArrays = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
|
||||
/* new Proxy(new constructor(), {}) // this probably should throw */
|
||||
];
|
||||
nonTypedArrays.forEach(nonTypedArray => {
|
||||
assertThrowsInstanceOf(function() {
|
||||
constructor.prototype.indexOf.call(nonTypedArray);
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.indexOf.call(invalidReceiver);
|
||||
}, TypeError, "Assert that indexOf fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.indexOf.call(new Proxy(new constructor(), {}));
|
||||
|
||||
// test that this.length is never called
|
||||
assertEq(Object.defineProperty(new constructor([0, 1, 2, 3, 5]), "length", {
|
||||
@ -63,12 +62,12 @@ assertEq(new Float32Array([.1, .2, .3]).indexOf(.2), -1);
|
||||
assertEq(new Float32Array([.1, .2, .3]).indexOf(Math.fround(.2)), 1);
|
||||
assertEq(new Float64Array([.1, .2, .3]).indexOf(.2), 1);
|
||||
|
||||
// Tests for TypedArray#lastIndexOf
|
||||
// Tests for TypedArray#lastIndexOf.
|
||||
for (var constructor of constructors) {
|
||||
|
||||
assertEq(constructor.prototype.lastIndexOf.length, 1);
|
||||
|
||||
// works with one argument
|
||||
// Works with one arguments.
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(0), -1);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1), 0);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(5), 4);
|
||||
@ -80,13 +79,13 @@ for (var constructor of constructors) {
|
||||
assertEq(new constructor([NaN, 0, -0]).lastIndexOf(0), 2);
|
||||
assertEq(new constructor([NaN, 0, -0]).lastIndexOf(-0), 2);
|
||||
} else {
|
||||
// [NaN, 0, -0] will be coerced to [0, 0, 0]
|
||||
// [NaN, 0, -0] will be coerced to [0, 0, 0].
|
||||
assertEq(new constructor([NaN, 0, -0]).lastIndexOf(NaN), -1);
|
||||
assertEq(new constructor([NaN, 0, -0]).lastIndexOf(0), 2);
|
||||
assertEq(new constructor([NaN, 0, -0]).lastIndexOf(-0), 2);
|
||||
}
|
||||
|
||||
// works with two arguments
|
||||
// Works with two arguments.
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1, 1), 0);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(1, -100), -1);
|
||||
assertEq(new constructor([1, 2, 3, 4, 5]).lastIndexOf(3, 100), 2);
|
||||
@ -94,17 +93,17 @@ for (var constructor of constructors) {
|
||||
assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1, 2), 2);
|
||||
assertEq(new constructor([1, 2, 1, 2, 1]).lastIndexOf(1, -2), 2);
|
||||
|
||||
// throws if `this` isn't a TypedArray
|
||||
var nonTypedArrays = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
|
||||
/* new Proxy(new constructor(), {}) // this probably should throw */
|
||||
];
|
||||
nonTypedArrays.forEach(nonTypedArray => {
|
||||
assertThrowsInstanceOf(function() {
|
||||
constructor.prototype.lastIndexOf.call(nonTypedArray);
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.lastIndexOf.call(invalidReceiver);
|
||||
}, TypeError, "Assert that lastIndexOf fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.lastIndexOf.call(new Proxy(new constructor(), {}));
|
||||
|
||||
// test that this.length is never called
|
||||
// Test that the length getter is never called.
|
||||
assertEq(Object.defineProperty(new constructor([0, 1, 2, 3, 5]), "length", {
|
||||
get() {
|
||||
throw new Error("length accessor called");
|
||||
|
@ -11,7 +11,6 @@ const constructors = [
|
||||
];
|
||||
|
||||
for (var constructor of constructors) {
|
||||
|
||||
assertDeepEq(constructor.prototype.reverse.length, 0);
|
||||
|
||||
assertDeepEq(new constructor().reverse(), new constructor());
|
||||
@ -24,23 +23,23 @@ for (var constructor of constructors) {
|
||||
assertDeepEq(new constructor([1, 2, 3, 4, 5]).reverse(), new constructor([5, 4, 3, 2, 1]));
|
||||
assertDeepEq(new constructor([.1, .2, .3]).reverse(), new constructor([.3, .2, .1]));
|
||||
|
||||
// called from other globals
|
||||
// Called from other globals.
|
||||
if (typeof newGlobal === "function") {
|
||||
var reverse = newGlobal()[constructor.name].prototype.reverse;
|
||||
assertDeepEq(reverse.call(new constructor([3, 2, 1])), new constructor([1, 2, 3]));
|
||||
}
|
||||
|
||||
// throws if `this` isn't a TypedArray
|
||||
var nonTypedArrays = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
|
||||
/* new Proxy(new constructor(), {}) // this probably should throw */
|
||||
];
|
||||
nonTypedArrays.forEach(nonTypedArray => {
|
||||
assertThrowsInstanceOf(function() {
|
||||
constructor.prototype.reverse.call(nonTypedArray);
|
||||
// Throws if `this` isn't a TypedArray.
|
||||
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./];
|
||||
invalidReceivers.forEach(invalidReceiver => {
|
||||
assertThrowsInstanceOf(() => {
|
||||
constructor.prototype.reverse.call(invalidReceiver);
|
||||
}, TypeError, "Assert that reverse fails if this value is not a TypedArray");
|
||||
});
|
||||
// FIXME: Should throw exception if `this` is a proxy, see bug 1115361.
|
||||
constructor.prototype.reverse.call(new Proxy(new constructor(), {}));
|
||||
|
||||
// test that this.length is never called
|
||||
// Test that the length getter is never called.
|
||||
Object.defineProperty(new constructor([1, 2, 3]), "length", {
|
||||
get() {
|
||||
throw new Error("length accessor called");
|
||||
|
@ -787,6 +787,9 @@ TypedArrayObject::protoFunctions[] = {
|
||||
JS_SELF_HOSTED_FN("indexOf", "TypedArrayIndexOf", 2, 0),
|
||||
JS_SELF_HOSTED_FN("lastIndexOf", "TypedArrayLastIndexOf", 2, 0),
|
||||
JS_SELF_HOSTED_FN("reverse", "TypedArrayReverse", 0, 0),
|
||||
#ifdef NIGHTLY_BUILD
|
||||
JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0),
|
||||
#endif
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
@ -181,7 +181,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
|
||||
gPrototypeProperties['TypedArray'] =
|
||||
["length", "buffer", "byteLength", "byteOffset", kIteratorSymbol, "subarray",
|
||||
"set", "copyWithin", "find", "findIndex", "indexOf", "lastIndexOf", "reverse"];
|
||||
|
||||
if (isNightlyBuild) {
|
||||
gPrototypeProperties['TypedArray'].push('includes');
|
||||
}
|
||||
for (var c of errorObjectClasses) {
|
||||
gPrototypeProperties[c] = ["constructor", "name",
|
||||
// We don't actually resolve these empty data properties
|
||||
|
Loading…
Reference in New Issue
Block a user