[mjsunit] Make Array deepEquals respect holes
Don't let holes compare equal to undefined, to avoid tests accidentally succeeding when operating on the wrong holeyness. Change-Id: I5fe1eea8b3e718389b46d542be45cca578a1080c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4091024 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/main@{#84769}
This commit is contained in:
parent
292c0a637a
commit
c5dc2fc9c1
@ -12,6 +12,6 @@ var obj = {
|
||||
obj[Symbol.isConcatSpreadable] = true;
|
||||
var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
|
||||
var arr = ["X", "Y", "Z"];
|
||||
assertEquals([void 0, "A", void 0, "B", void 0, "C",
|
||||
assertEquals([, "A", , "B", , "C",
|
||||
{ "length": 3, "0": "0", "1": "1", "2": "2" },
|
||||
"X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
|
||||
|
@ -12,6 +12,6 @@ var obj = {
|
||||
obj[Symbol.isConcatSpreadable] = true;
|
||||
var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
|
||||
var arr = ["X", "Y", "Z"];
|
||||
assertEquals([void 0, "A", void 0, "B", void 0, "C",
|
||||
assertEquals([, "A", , "B", , "C",
|
||||
{ "length": 3, "0": "0", "1": "1", "2": "2" },
|
||||
"X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
|
||||
|
@ -7,5 +7,5 @@ var arr = [];
|
||||
arr[4] = "Item 4";
|
||||
arr[8] = "Item 8";
|
||||
var arr2 = [".", "!", "?"];
|
||||
assertEquals([void 0, void 0, void 0, void 0, "Item 4", void 0, void 0,
|
||||
void 0, "Item 8", ".", "!", "?"], arr.concat(arr2));
|
||||
assertEquals(
|
||||
[, , , , 'Item 4', , , , 'Item 8', '.', '!', '?'], arr.concat(arr2));
|
||||
|
@ -5,4 +5,4 @@
|
||||
var args = (function(a) { return arguments; })(1,2,3);
|
||||
delete args[1];
|
||||
args[Symbol.isConcatSpreadable] = true;
|
||||
assertEquals([1, void 0, 3, 1, void 0, 3], [].concat(args, args));
|
||||
assertEquals([1, , 3, 1, , 3], [].concat(args, args));
|
||||
|
@ -7,4 +7,4 @@ args[Symbol.isConcatSpreadable] = true;
|
||||
assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
|
||||
|
||||
Object.defineProperty(args, "length", { value: 6 });
|
||||
assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
|
||||
assertEquals([1, 2, 3, , , ,], [].concat(args));
|
||||
|
@ -7,4 +7,4 @@ args[Symbol.isConcatSpreadable] = true;
|
||||
assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
|
||||
|
||||
Object.defineProperty(args, "length", { value: 6 });
|
||||
assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
|
||||
assertEquals([1, 2, 3, , ,, ], [].concat(args));
|
||||
|
@ -14,7 +14,7 @@ assertEquals([1, 2, 3], [].concat(fn));
|
||||
|
||||
Function.prototype[Symbol.isConcatSpreadable] = true;
|
||||
// Functions may be concat-spreadable
|
||||
assertEquals([void 0, void 0, void 0], [].concat(function(a,b,c) {}));
|
||||
assertEquals(new Array(3), [].concat(function(a,b,c) {}));
|
||||
Function.prototype[0] = 1;
|
||||
Function.prototype[1] = 2;
|
||||
Function.prototype[2] = 3;
|
||||
|
@ -36,7 +36,7 @@ assertEquals(["get", target, "length", obj], log[1]);
|
||||
target.length = 3;
|
||||
|
||||
log.length = 0;
|
||||
assertEquals(["a", "b", undefined], [].concat(obj));
|
||||
assertEquals(["a", "b", ,], [].concat(obj));
|
||||
assertEquals(7, log.length);
|
||||
for (var i in log) assertSame(target, log[i][1]);
|
||||
assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
|
||||
@ -48,7 +48,7 @@ assertEquals(["get", target, "1", obj], log[5]);
|
||||
assertEquals(["has", target, "2"], log[6]);
|
||||
|
||||
log.length = 0;
|
||||
assertEquals(["a", "b", undefined], Array.prototype.concat.apply(obj));
|
||||
assertEquals(["a", "b", ,], Array.prototype.concat.apply(obj));
|
||||
assertEquals(7, log.length);
|
||||
for (var i in log) assertSame(target, log[i][1]);
|
||||
assertEquals(["get", target, Symbol.isConcatSpreadable, obj], log[0]);
|
||||
|
@ -16,7 +16,7 @@ assertEquals([1, 2, 3], [].concat(re));
|
||||
RegExp.prototype[Symbol.isConcatSpreadable] = true;
|
||||
RegExp.prototype.length = 3;
|
||||
|
||||
assertEquals([void 0, void 0, void 0], [].concat(/abc/));
|
||||
assertEquals(new Array(3), [].concat(/abc/));
|
||||
RegExp.prototype[0] = 1;
|
||||
RegExp.prototype[1] = 2;
|
||||
RegExp.prototype[2] = 3;
|
||||
|
@ -5,7 +5,7 @@
|
||||
"use strict";
|
||||
var obj = { length: 5 };
|
||||
obj[Symbol.isConcatSpreadable] = true;
|
||||
assertEquals([void 0, void 0, void 0, void 0, void 0], [].concat(obj));
|
||||
assertEquals(new Array(5), [].concat(obj));
|
||||
|
||||
obj.length = 4000;
|
||||
assertEquals(new Array(4000), [].concat(obj));
|
||||
|
@ -7,4 +7,4 @@ args[Symbol.isConcatSpreadable] = true;
|
||||
assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
|
||||
|
||||
Object.defineProperty(args, "length", { value: 6 });
|
||||
assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
|
||||
assertEquals([1, 2, 3, , , ,], [].concat(args));
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
var a = [, 2];
|
||||
|
||||
assertEquals([, 2], [...a]);
|
||||
assertEquals([undefined, 2], [...a]);
|
||||
assertTrue([...a].hasOwnProperty(0));
|
||||
assertTrue([2, ...a].hasOwnProperty(1));
|
||||
|
||||
|
@ -142,7 +142,7 @@ var group = () => {
|
||||
}
|
||||
|
||||
assertEquals(group(), [
|
||||
['undefined', [,]],
|
||||
['undefined', [undefined]],
|
||||
]);
|
||||
|
||||
array.__proto__.push(6);
|
||||
|
@ -147,7 +147,7 @@ var groupToMap = () => {
|
||||
}
|
||||
|
||||
assertEquals(groupToMap(), [
|
||||
[undefined, [,]],
|
||||
[undefined, [undefined]],
|
||||
]);
|
||||
array.__proto__.push(6);
|
||||
assertEquals(groupToMap(), [
|
||||
|
@ -7,32 +7,39 @@
|
||||
assertEquals(1, Array.prototype.toSorted.length);
|
||||
assertEquals("toSorted", Array.prototype.toSorted.name);
|
||||
|
||||
function TerribleCopy(input) {
|
||||
function TerribleCopy(input, fillHoles) {
|
||||
let copy;
|
||||
if (Array.isArray(input)) {
|
||||
copy = [...input];
|
||||
copy = new Array(input.length);
|
||||
} else {
|
||||
copy = { length: input.length };
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
}
|
||||
for (let i = 0; i < input.length; ++i) {
|
||||
if (i in input) {
|
||||
copy[i] = input[i];
|
||||
} else if (fillHoles) {
|
||||
copy[i] = undefined;
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
function AssertToSortedAndSortSameResult(input, ...args) {
|
||||
const orig = TerribleCopy(input);
|
||||
const orig = TerribleCopy(input, false);
|
||||
const s = Array.prototype.toSorted.apply(input, args);
|
||||
const copy = TerribleCopy(input);
|
||||
const copy = TerribleCopy(input, true);
|
||||
Array.prototype.sort.apply(copy, args);
|
||||
|
||||
// The in-place sorted version should be pairwise equal to the toSorted,
|
||||
// modulo being an actual Array if the input is generic.
|
||||
// modulo being an actual Array if the input is generic, and holes should
|
||||
// be filled with undefined.
|
||||
if (Array.isArray(input)) {
|
||||
assertEquals(copy, s);
|
||||
} else {
|
||||
assertEquals(copy.length, s.length);
|
||||
for (let i = 0; i < copy.length; i++) {
|
||||
assertTrue(i in copy);
|
||||
assertTrue(i in s);
|
||||
assertEquals(copy[i], s[i]);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
function f1() {
|
||||
const x = [,];
|
||||
x[1] = 42;
|
||||
assertEquals([undefined, 42], x);
|
||||
assertEquals([, 42], x);
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(f1);
|
||||
|
@ -70,6 +70,8 @@ function testAssertEquals(a, b) {
|
||||
testAssertEquals(new Array(1), new Array(1));
|
||||
testAssertNotEquals(new Array(1), new Array(2));
|
||||
testAssertEquals([,,], new Array(2));
|
||||
// The difference between empty and undefined is not ignored.
|
||||
testAssertNotEquals([undefined], new Array(1));
|
||||
})();
|
||||
|
||||
(function TestAssertEqualsArraysNested() {
|
||||
@ -80,9 +82,7 @@ function testAssertEquals(a, b) {
|
||||
})();
|
||||
|
||||
(function TestAssertEqualsArrayProperties() {
|
||||
// Difference between empty and undefined is ignored by the assert
|
||||
// implementation as well as additional properties.
|
||||
testAssertEquals([undefined], new Array(1));
|
||||
// Array properties are ignored.
|
||||
let arrWithProp = new Array();
|
||||
arrWithProp.myProperty = 'Additional property';
|
||||
testAssertEquals([], arrWithProp);
|
||||
|
@ -432,6 +432,7 @@ var prettyPrinted;
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if ((i in a) !== (i in b)) return false;
|
||||
if (!deepEquals(a[i], b[i])) return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// Make sure that packed and unpacked array slices are still properly handled
|
||||
var holey_array = [1, 2, 3, 4, 5,,,,,,];
|
||||
assertEquals([undefined], holey_array.slice(6, 7));
|
||||
assertEquals(new Array(1), holey_array.slice(6, 7));
|
||||
assertEquals(undefined, holey_array.slice(6, 7)[0]);
|
||||
assertEquals([], holey_array.slice(2, 1));
|
||||
assertEquals(3, holey_array.slice(2, 3)[0]);
|
||||
|
@ -25,7 +25,7 @@
|
||||
}
|
||||
b = Array.of.call(f,1,2);
|
||||
b[4] = 1;
|
||||
assertEquals(b, [1, 2, undefined, undefined, 1]);
|
||||
assertEquals(b, [1, 2, , , 1]);
|
||||
})();
|
||||
|
||||
// Tests that using Array.of with a constructor returning an object with an
|
||||
|
@ -373,8 +373,7 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
|
||||
const fixedLength = new ctor(rab, 0, 4);
|
||||
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||
return 0; }};
|
||||
assertEquals([undefined, undefined, undefined, undefined],
|
||||
sliceHelper(fixedLength, evil));
|
||||
assertEquals(new Array(4), sliceHelper(fixedLength, evil));
|
||||
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
|
||||
}
|
||||
for (let ctor of ctors) {
|
||||
@ -401,8 +400,7 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
|
||||
const fixedLength = new ctor(rab, 0, 4);
|
||||
const evil = { valueOf: () => { %ArrayBufferDetach(rab);
|
||||
return 0; }};
|
||||
assertEquals([undefined, undefined, undefined, undefined],
|
||||
sliceHelper(fixedLength, evil));
|
||||
assertEquals(new Array(4), sliceHelper(fixedLength, evil));
|
||||
assertEquals(0, rab.byteLength);
|
||||
}
|
||||
for (let ctor of ctors) {
|
||||
@ -414,8 +412,9 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
|
||||
}
|
||||
const evil = { valueOf: () => { %ArrayBufferDetach(rab);
|
||||
return 0; }};
|
||||
assertEquals([undefined, undefined, undefined, undefined],
|
||||
ToNumbers(sliceHelper(lengthTracking, evil)));
|
||||
assertEquals(
|
||||
[undefined, undefined, undefined, undefined],
|
||||
ToNumbers(sliceHelper(lengthTracking, evil)));
|
||||
assertEquals(0, rab.byteLength);
|
||||
}
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user