Commit 70625046 authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[rab/gsab] Tests for Array.p methods, part 8

In this part: slice

Bug: v8:11111
Change-Id: I66236039454ba50899a7c600b9a3df5fb5f7fc6f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3749582Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81629}
parent f8e4c4aa
...@@ -189,3 +189,46 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js'); ...@@ -189,3 +189,46 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
} }
} }
})(); })();
(function ArraySlice() {
const sliceHelper = ArraySliceHelper;
for (let ctor of ctors) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const fixedLength = new ctor(gsab, 0, 4);
const fixedLengthWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT, 2);
const lengthTracking = new ctor(gsab, 0);
const lengthTrackingWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT);
// Write some data into the array.
const taWrite = new ctor(gsab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(taWrite, i, i);
}
const fixedLengthSlice = sliceHelper(fixedLength);
assertEquals([0, 1, 2, 3], ToNumbers(fixedLengthSlice));
const fixedLengthWithOffsetSlice = sliceHelper(fixedLengthWithOffset);
assertEquals([2, 3], ToNumbers(fixedLengthWithOffsetSlice));
const lengthTrackingSlice = sliceHelper(lengthTracking);
assertEquals([0, 1, 2, 3], ToNumbers(lengthTrackingSlice));
const lengthTrackingWithOffsetSlice = sliceHelper(lengthTrackingWithOffset);
assertEquals([2, 3], ToNumbers(lengthTrackingWithOffsetSlice));
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
assertEquals([0, 1, 2, 3], ToNumbers(sliceHelper(fixedLength)));
assertEquals([2, 3], ToNumbers(sliceHelper(fixedLengthWithOffset)));
assertEquals([0, 1, 2, 3, 0, 0], ToNumbers(sliceHelper(lengthTracking)));
assertEquals([2, 3, 0, 0],
ToNumbers(sliceHelper(lengthTrackingWithOffset)));
// Verify that the previously created slices aren't affected by the growing.
assertEquals([0, 1, 2, 3], ToNumbers(fixedLengthSlice));
assertEquals([2, 3], ToNumbers(fixedLengthWithOffsetSlice));
assertEquals([0, 1, 2, 3], ToNumbers(lengthTrackingSlice));
assertEquals([2, 3], ToNumbers(lengthTrackingWithOffsetSlice));
}
})();
...@@ -808,6 +808,8 @@ TestFill(ArrayFillHelper); ...@@ -808,6 +808,8 @@ TestFill(ArrayFillHelper);
} }
})(); })();
// The corresponding tests for Array.prototype.slice are in
// typedarray-growablesharedarraybuffer-array-methods.js.
(function Slice() { (function Slice() {
for (let ctor of ctors) { for (let ctor of ctors) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
...@@ -862,6 +864,25 @@ TestFill(ArrayFillHelper); ...@@ -862,6 +864,25 @@ TestFill(ArrayFillHelper);
} }
})(); })();
function SliceParameterConversionGrows(sliceHelper) {
for (let ctor of ctors) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(gsab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(lengthTracking, i, i + 1);
}
const evil = { valueOf: () => { gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertEquals([1, 2, 3, 4], ToNumbers(sliceHelper(lengthTracking, evil)));
assertEquals(6 * ctor.BYTES_PER_ELEMENT, gsab.byteLength);
}
}
SliceParameterConversionGrows(TypedArraySliceHelper);
SliceParameterConversionGrows(ArraySliceHelper);
// The corresponding test for Array.prototype.slice is not possible, since it
// doesn't call the species constructor if the "original array" is not an Array.
(function SliceSpeciesCreateResizes() { (function SliceSpeciesCreateResizes() {
for (let ctor of ctors) { for (let ctor of ctors) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
...@@ -1002,7 +1023,7 @@ function TestCopyWithin(helper) { ...@@ -1002,7 +1023,7 @@ function TestCopyWithin(helper) {
assertEquals([3, 4, 5, 5], ToNumbers(lengthTrackingWithOffset)); assertEquals([3, 4, 5, 5], ToNumbers(lengthTrackingWithOffset));
} }
} }
TestCopyWithin(CopyWithinHelper); TestCopyWithin(TypedArrayCopyWithinHelper);
TestCopyWithin(ArrayCopyWithinHelper); TestCopyWithin(ArrayCopyWithinHelper);
function CopyWithinParameterConversionGrows(helper) { function CopyWithinParameterConversionGrows(helper) {
...@@ -1026,7 +1047,7 @@ function CopyWithinParameterConversionGrows(helper) { ...@@ -1026,7 +1047,7 @@ function CopyWithinParameterConversionGrows(helper) {
assertEquals([2, 3, 2, 3, 4, 5], ToNumbers(lengthTracking)); assertEquals([2, 3, 2, 3, 4, 5], ToNumbers(lengthTracking));
} }
} }
CopyWithinParameterConversionGrows(CopyWithinHelper); CopyWithinParameterConversionGrows(TypedArrayCopyWithinHelper);
CopyWithinParameterConversionGrows(ArrayCopyWithinHelper); CopyWithinParameterConversionGrows(ArrayCopyWithinHelper);
function EntriesKeysValues(keysHelper, valuesFromEntries, valuesFromValues) { function EntriesKeysValues(keysHelper, valuesFromEntries, valuesFromValues) {
......
...@@ -433,7 +433,7 @@ function AssertAtomicsOperationsThrow(ta, index, error) { ...@@ -433,7 +433,7 @@ function AssertAtomicsOperationsThrow(ta, index, error) {
assertThrows(() => { Atomics.xor(ta, index, one); }, error); assertThrows(() => { Atomics.xor(ta, index, one); }, error);
} }
const CopyWithinHelper = (ta, ...rest) => { ta.copyWithin(...rest); }; const TypedArrayCopyWithinHelper = (ta, ...rest) => { ta.copyWithin(...rest); };
const ArrayCopyWithinHelper = (ta, ...rest) => { const ArrayCopyWithinHelper = (ta, ...rest) => {
Array.prototype.copyWithin.call(ta, ...rest); }; Array.prototype.copyWithin.call(ta, ...rest); };
...@@ -443,3 +443,7 @@ const ArrayReverseHelper = (ta) => { Array.prototype.reverse.call(ta); }; ...@@ -443,3 +443,7 @@ const ArrayReverseHelper = (ta) => { Array.prototype.reverse.call(ta); };
const TypedArraySortHelper = (ta, ...rest) => { ta.sort(...rest); } const TypedArraySortHelper = (ta, ...rest) => { ta.sort(...rest); }
const ArraySortHelper = (ta, ...rest) => { const ArraySortHelper = (ta, ...rest) => {
Array.prototype.sort.call(ta, ...rest); }; Array.prototype.sort.call(ta, ...rest); };
const TypedArraySliceHelper = (ta, ...rest) => { return ta.slice(...rest); }
const ArraySliceHelper = (ta, ...rest) => {
return Array.prototype.slice.call(ta, ...rest); };
...@@ -286,3 +286,135 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js'); ...@@ -286,3 +286,135 @@ d8.file.execute('test/mjsunit/typedarray-helpers.js');
testAllFuncsThrow(); testAllFuncsThrow();
} }
})(); })();
(function ArraySlice() {
const sliceHelper = ArraySliceHelper;
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const fixedLength = new ctor(rab, 0, 4);
const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 2);
const lengthTracking = new ctor(rab, 0);
const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT);
// Write some data into the array.
const taWrite = new ctor(rab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(taWrite, i, i);
}
const fixedLengthSlice = sliceHelper(fixedLength);
assertEquals([0, 1, 2, 3], ToNumbers(fixedLengthSlice));
assertTrue(fixedLengthSlice instanceof Array);
const fixedLengthWithOffsetSlice = sliceHelper(fixedLengthWithOffset);
assertEquals([2, 3], ToNumbers(fixedLengthWithOffsetSlice));
assertTrue(fixedLengthWithOffsetSlice instanceof Array);
const lengthTrackingSlice = sliceHelper(lengthTracking);
assertEquals([0, 1, 2, 3], ToNumbers(lengthTrackingSlice));
assertTrue(lengthTrackingSlice instanceof Array);
const lengthTrackingWithOffsetSlice = sliceHelper(lengthTrackingWithOffset);
assertEquals([2, 3], ToNumbers(lengthTrackingWithOffsetSlice));
assertTrue(lengthTrackingWithOffsetSlice instanceof Array);
// Shrink so that fixed length TAs go out of bounds.
rab.resize(3 * ctor.BYTES_PER_ELEMENT);
assertEquals([], ToNumbers(sliceHelper(fixedLength)));
assertEquals([], ToNumbers(sliceHelper(fixedLengthWithOffset)));
assertEquals([0, 1, 2], ToNumbers(sliceHelper(lengthTracking)));
assertEquals([2], ToNumbers(sliceHelper(lengthTrackingWithOffset)));
// Shrink so that the TAs with offset go out of bounds.
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
assertEquals([], sliceHelper(fixedLength));
assertEquals([], sliceHelper(fixedLengthWithOffset));
assertEquals([], sliceHelper(lengthTrackingWithOffset));
assertEquals([0], ToNumbers(sliceHelper(lengthTracking)));
// Shrink to zero.
rab.resize(0);
assertEquals([], sliceHelper(fixedLength));
assertEquals([], sliceHelper(fixedLengthWithOffset));
assertEquals([], sliceHelper(lengthTrackingWithOffset));
assertEquals([], sliceHelper(lengthTracking));
// Verify that the previously created slices aren't affected by the
// shrinking.
assertEquals([0, 1, 2, 3], ToNumbers(fixedLengthSlice));
assertEquals([2, 3], ToNumbers(fixedLengthWithOffsetSlice));
assertEquals([0, 1, 2, 3], ToNumbers(lengthTrackingSlice));
assertEquals([2, 3], ToNumbers(lengthTrackingWithOffsetSlice));
// Grow so that all TAs are back in-bounds. New memory is zeroed.
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
assertEquals([0, 0, 0, 0], ToNumbers(sliceHelper(fixedLength)));
assertEquals([0, 0], ToNumbers(sliceHelper(fixedLengthWithOffset)));
assertEquals([0, 0, 0, 0, 0, 0], ToNumbers(sliceHelper(lengthTracking)));
assertEquals([0, 0, 0, 0],
ToNumbers(sliceHelper(lengthTrackingWithOffset)));
}
})();
(function ArraySliceParameterConversionShrinks() {
const sliceHelper = ArraySliceHelper;
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
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(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(rab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(lengthTracking, i, i + 1);
}
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertEquals([1, 2, undefined, undefined],
ToNumbers(sliceHelper(lengthTracking, evil)));
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
})();
(function ArraySliceParameterConversionDetaches() {
const sliceHelper = ArraySliceHelper;
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
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(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(rab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(lengthTracking, i, i + 1);
}
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertEquals([1, 2, undefined, undefined],
ToNumbers(sliceHelper(lengthTracking, evil)));
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
})();
...@@ -1628,3 +1628,29 @@ SortCallbackDetaches(ArraySortHelper); ...@@ -1628,3 +1628,29 @@ SortCallbackDetaches(ArraySortHelper);
assertEquals([], ToNumbers(func.apply(null, lengthTrackingWithOffset))); assertEquals([], ToNumbers(func.apply(null, lengthTrackingWithOffset)));
} }
})(); })();
// The corresponding tests for Array.prototype.slice are in
// typedarray-resizablearraybuffer-array-methods.js.
(function SliceParameterConversionDetaches() {
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const fixedLength = new ctor(rab, 0, 4);
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertThrows(() => { fixedLength.slice(evil); }, TypeError);
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(rab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(lengthTracking, i, i + 1);
}
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertEquals([1, 2, 0, 0], ToNumbers(lengthTracking.slice(evil)));
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
})();
...@@ -1373,6 +1373,8 @@ TestFill(ArrayFillHelper, false); ...@@ -1373,6 +1373,8 @@ TestFill(ArrayFillHelper, false);
} }
})(); })();
// The corresponding tests for Array.prototype.slice are in
// typedarray-resizablearraybuffer-array-methods.js.
(function Slice() { (function Slice() {
for (let ctor of ctors) { for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
...@@ -1444,6 +1446,51 @@ TestFill(ArrayFillHelper, false); ...@@ -1444,6 +1446,51 @@ TestFill(ArrayFillHelper, false);
} }
})(); })();
// The corresponding tests for Array.prototype.slice are in
// typedarray-resizablearraybuffer-array-methods.js.
(function SliceParameterConversionShrinks() {
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const fixedLength = new ctor(rab, 0, 4);
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertThrows(() => { fixedLength.slice(evil); }, TypeError);
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(rab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(lengthTracking, i, i + 1);
}
const evil = { valueOf: () => { rab.resize(2 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertEquals([1, 2, 0, 0], ToNumbers(lengthTracking.slice(evil)));
assertEquals(2 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
})();
function SliceParameterConversionGrows(sliceHelper) {
for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(rab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(lengthTracking, i, i + 1);
}
const evil = { valueOf: () => { rab.resize(6 * ctor.BYTES_PER_ELEMENT);
return 0; }};
assertEquals([1, 2, 3, 4], ToNumbers(sliceHelper(lengthTracking, evil)));
assertEquals(6 * ctor.BYTES_PER_ELEMENT, rab.byteLength);
}
}
SliceParameterConversionGrows(TypedArraySliceHelper);
SliceParameterConversionGrows(ArraySliceHelper);
// The corresponding test for Array.prototype.slice is not possible, since it
// doesn't call the species constructor if the "original array" is not an Array.
(function SliceSpeciesCreateResizes() { (function SliceSpeciesCreateResizes() {
for (let ctor of ctors) { for (let ctor of ctors) {
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
...@@ -1698,7 +1745,7 @@ function TestCopyWithin(helper, oobThrows) { ...@@ -1698,7 +1745,7 @@ function TestCopyWithin(helper, oobThrows) {
assertEquals([3, 4, 5, 5], ToNumbers(lengthTrackingWithOffset)); assertEquals([3, 4, 5, 5], ToNumbers(lengthTrackingWithOffset));
} }
} }
TestCopyWithin(CopyWithinHelper, true); TestCopyWithin(TypedArrayCopyWithinHelper, true);
TestCopyWithin(ArrayCopyWithinHelper, false); TestCopyWithin(ArrayCopyWithinHelper, false);
(function CopyWithinParameterConversionShrinks() { (function CopyWithinParameterConversionShrinks() {
......
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