From 3dde047c84e1bec24dde4b2c862ff2b6c6dd0948 Mon Sep 17 00:00:00 2001 From: "Ioanna M. Dimitriou H" Date: Sat, 29 Jun 2024 01:40:39 +0200 Subject: [PATCH] Removing parts in resizableArrayBufferUtils.js and adding it in includes, while applying review changes from PRs for previously tested methods. --- .../coerced-searchelement-fromindex-resize.js | 185 +++++------- .../prototype/includes/resizable-buffer.js | 251 +++++++--------- .../coerced-searchelement-fromindex-resize.js | 185 +++++------- .../resizable-buffer-special-float-values.js | 14 +- .../prototype/includes/resizable-buffer.js | 281 ++++++++---------- 5 files changed, 362 insertions(+), 554 deletions(-) diff --git a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js index 2952b80d11..448709b5af 100644 --- a/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js +++ b/test/built-ins/Array/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -6,129 +6,84 @@ esid: sec-array.prototype.includes description: > Array.p.includes behaves correctly when the receiver is resized during argument coercion +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function ArrayIncludesHelper(array, n, fromIndex) { +function ArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return Array.prototype.includes.call(array, BigInt(n), fromIndex); } return Array.prototype.includes.call(array, n, fromIndex); } -function IncludesParameterConversionResizes() { - 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); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!ArrayIncludesHelper(fixedLength, undefined)); - // The TA is OOB so it includes only "undefined". - assert(ArrayIncludesHelper(fixedLength, undefined, evil)); - } - 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); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(ArrayIncludesHelper(fixedLength, 0)); - // The TA is OOB so it includes only "undefined". - assert(!ArrayIncludesHelper(fixedLength, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - // "includes" iterates until the original length and sees "undefined"s. - assert(ArrayIncludesHelper(lengthTracking, undefined, evil)); - } - 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, 1); +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); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; } - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!ArrayIncludesHelper(lengthTracking, 0)); - // The TA grew but we only look at the data until the original length. - assert(!ArrayIncludesHelper(lengthTracking, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - WriteToTypedArray(lengthTracking, 0, 1); - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return -4; - } - }; - assert(ArrayIncludesHelper(lengthTracking, 1, -4)); - // The TA grew but the start index conversion is done based on the original - // length. - assert(ArrayIncludesHelper(lengthTracking, 1, evil)); - } + }; + assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + // The TA is OOB so it includes only "undefined". + assert(ArrayIncludesNumOrBigInt(fixedLength, undefined, evil)); +} +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); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(ArrayIncludesNumOrBigInt(fixedLength, 0)); + // The TA is OOB so it includes only "undefined". + assert(!ArrayIncludesNumOrBigInt(fixedLength, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + // "includes" iterates until the original length and sees "undefined"s. + assert(ArrayIncludesNumOrBigInt(lengthTracking, undefined, evil)); +} +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, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 0)); + // The TA grew but we only look at the data until the original length. + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + assert(ArrayIncludesNumOrBigInt(lengthTracking, 1, -4)); + // The TA grew but the start index conversion is done based on the original + // length. + assert(ArrayIncludesNumOrBigInt(lengthTracking, 1, evil)); } - -IncludesParameterConversionResizes(); diff --git a/test/built-ins/Array/prototype/includes/resizable-buffer.js b/test/built-ins/Array/prototype/includes/resizable-buffer.js index bd8f6d93c7..49894ef40b 100644 --- a/test/built-ins/Array/prototype/includes/resizable-buffer.js +++ b/test/built-ins/Array/prototype/includes/resizable-buffer.js @@ -6,163 +6,118 @@ esid: sec-array.prototype.includes description: > Array.p.includes behaves correctly when receiver is backed by resizable buffer +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function ArrayIncludesHelper(array, n, fromIndex) { +function ArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return Array.prototype.includes.call(array, BigInt(n), fromIndex); } return Array.prototype.includes.call(array, n, fromIndex); } -function TestIncludes() { - 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); +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, 2 * i); - } - - // Orig. array: [0, 2, 4, 6] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, ...] << lengthTracking - // [4, 6, ...] << lengthTrackingWithOffset - - assert(ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLength, undefined)); - assert(ArrayIncludesHelper(fixedLength, 2, 1)); - assert(!ArrayIncludesHelper(fixedLength, 2, 2)); - assert(ArrayIncludesHelper(fixedLength, 2, -3)); - assert(!ArrayIncludesHelper(fixedLength, 2, -2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4, 0)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 4, 1)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4, -2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 4, -1)); - assert(ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - assert(ArrayIncludesHelper(lengthTracking, 2, 1)); - assert(!ArrayIncludesHelper(lengthTracking, 2, 2)); - assert(ArrayIncludesHelper(lengthTracking, 2, -3)); - assert(!ArrayIncludesHelper(lengthTracking, 2, -2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4, 0)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 4, 1)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4, -2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 4, -1)); - - // Shrink so that fixed length TAs go out of bounds. - rab.resize(3 * ctor.BYTES_PER_ELEMENT); - - // Orig. array: [0, 2, 4] - // [0, 2, 4, ...] << lengthTracking - // [4, ...] << lengthTrackingWithOffset - - assert(!ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - - assert(ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - - // Shrink so that the TAs with offset go out of bounds. - rab.resize(1 * ctor.BYTES_PER_ELEMENT); - assert(!ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - - // Shrink to zero. - rab.resize(0); - assert(!ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - - assert(!ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - - // Grow so that all TAs are back in-bounds. - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - for (let i = 0; i < 6; ++i) { - WriteToTypedArray(taWrite, i, 2 * i); - } - - // Orig. array: [0, 2, 4, 6, 8, 10] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, 8, 10, ...] << lengthTracking - // [4, 6, 8, 10, ...] << lengthTrackingWithOffset - - assert(ArrayIncludesHelper(fixedLength, 2)); - assert(!ArrayIncludesHelper(fixedLength, undefined)); - assert(!ArrayIncludesHelper(fixedLength, 8)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(ArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(!ArrayIncludesHelper(fixedLengthWithOffset, 8)); - assert(ArrayIncludesHelper(lengthTracking, 2)); - assert(!ArrayIncludesHelper(lengthTracking, undefined)); - assert(ArrayIncludesHelper(lengthTracking, 8)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!ArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(ArrayIncludesHelper(lengthTrackingWithOffset, 8)); + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); } -} -TestIncludes(); + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert(ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(ArrayIncludesNumOrBigInt(fixedLength, 2, 1)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2, 2)); + assert(ArrayIncludesNumOrBigInt(fixedLength, 2, -3)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2, -2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 0)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 1)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -1)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2, 1)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2, -3)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2, -2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 0)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 1)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -1)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + + // Shrink to zero. + rab.resize(0); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + + assert(!ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(ArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(!ArrayIncludesNumOrBigInt(fixedLength, 8)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(!ArrayIncludesNumOrBigInt(fixedLengthWithOffset, 8)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!ArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTracking, 8)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(ArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 8)); +} diff --git a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js index 8daa449fc3..63727c8cc5 100644 --- a/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js +++ b/test/built-ins/TypedArray/prototype/includes/coerced-searchelement-fromindex-resize.js @@ -6,129 +6,84 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly when the receiver is resized during argument coercion +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function TypedArrayIncludesHelper(array, n, fromIndex) { +function TypedArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return array.includes(BigInt(n), fromIndex); } return array.includes(n, fromIndex); } -function IncludesParameterConversionResizes() { - 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); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!TypedArrayIncludesHelper(fixedLength, undefined)); - // The TA is OOB so it includes only "undefined". - assert(TypedArrayIncludesHelper(fixedLength, undefined, evil)); - } - 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); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(TypedArrayIncludesHelper(fixedLength, 0)); - // The TA is OOB so it includes only "undefined". - assert(!TypedArrayIncludesHelper(fixedLength, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - let evil = { - valueOf: () => { - rab.resize(2 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - // "includes" iterates until the original length and sees "undefined"s. - assert(TypedArrayIncludesHelper(lengthTracking, undefined, evil)); - } - 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, 1); +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); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; } - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return 0; - } - }; - assert(!TypedArrayIncludesHelper(lengthTracking, 0)); - // The TA grew but we only look at the data until the original length. - assert(!TypedArrayIncludesHelper(lengthTracking, 0, evil)); - } - for (let ctor of ctors) { - const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); - const lengthTracking = new ctor(rab); - WriteToTypedArray(lengthTracking, 0, 1); - let evil = { - valueOf: () => { - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - return -4; - } - }; - assert(TypedArrayIncludesHelper(lengthTracking, 1, -4)); - // The TA grew but the start index conversion is done based on the original - // length. - assert(TypedArrayIncludesHelper(lengthTracking, 1, evil)); - } + }; + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + // The TA is OOB so it includes only "undefined". + assert(TypedArrayIncludesNumOrBigInt(fixedLength, undefined, evil)); +} +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); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 0)); + // The TA is OOB so it includes only "undefined". + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + let evil = { + valueOf: () => { + rab.resize(2 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + // "includes" iterates until the original length and sees "undefined"s. + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, undefined, evil)); +} +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, 1); + } + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return 0; + } + }; + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 0)); + // The TA grew but we only look at the data until the original length. + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 0, evil)); +} +for (let ctor of ctors) { + const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); + const lengthTracking = new ctor(rab); + WriteToTypedArray(lengthTracking, 0, 1); + let evil = { + valueOf: () => { + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + return -4; + } + }; + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 1, -4)); + // The TA grew but the start index conversion is done based on the original + // length. + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 1, evil)); } - -IncludesParameterConversionResizes(); diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js index 19d4b9c4e9..f621d95838 100644 --- a/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer-special-float-values.js @@ -6,22 +6,10 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly for special float values when receiver is a float TypedArray backed by a resizable buffer +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyFloat32Array extends Float32Array { -} - -const floatCtors = [ - Float32Array, - Float64Array, - MyFloat32Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - for (let ctor of floatCtors) { const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT); const lengthTracking = new ctor(rab); diff --git a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js index 284e527682..77fa05960d 100644 --- a/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js +++ b/test/built-ins/TypedArray/prototype/includes/resizable-buffer.js @@ -6,178 +6,133 @@ esid: sec-%typedarray%.prototype.includes description: > TypedArray.p.includes behaves correctly when receiver is backed by resizable buffer +includes: [resizableArrayBufferUtils.js] features: [resizable-arraybuffer, Array.prototype.includes] ---*/ -class MyUint8Array extends Uint8Array { -} - -class MyFloat32Array extends Float32Array { -} - -class MyBigInt64Array extends BigInt64Array { -} - -const builtinCtors = [ - Uint8Array, - Int8Array, - Uint16Array, - Int16Array, - Uint32Array, - Int32Array, - Float32Array, - Float64Array, - Uint8ClampedArray, - BigUint64Array, - BigInt64Array -]; - -const ctors = [ - ...builtinCtors, - MyUint8Array, - MyFloat32Array, - MyBigInt64Array -]; - -function CreateResizableArrayBuffer(byteLength, maxByteLength) { - return new ArrayBuffer(byteLength, { maxByteLength: maxByteLength }); -} - -function WriteToTypedArray(array, index, value) { - if (array instanceof BigInt64Array || array instanceof BigUint64Array) { - array[index] = BigInt(value); - } else { - array[index] = value; - } -} - -function TypedArrayIncludesHelper(array, n, fromIndex) { +function TypedArrayIncludesNumOrBigInt(array, n, fromIndex) { if (typeof n == 'number' && (array instanceof BigInt64Array || array instanceof BigUint64Array)) { return array.includes(BigInt(n), fromIndex); } return array.includes(n, fromIndex); } -function TestIncludes() { - 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); +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, 2 * i); - } - - // Orig. array: [0, 2, 4, 6] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, ...] << lengthTracking - // [4, 6, ...] << lengthTrackingWithOffset - - assert(TypedArrayIncludesHelper(fixedLength, 2)); - assert(!TypedArrayIncludesHelper(fixedLength, undefined)); - assert(TypedArrayIncludesHelper(fixedLength, 2, 1)); - assert(!TypedArrayIncludesHelper(fixedLength, 2, 2)); - assert(TypedArrayIncludesHelper(fixedLength, 2, -3)); - assert(!TypedArrayIncludesHelper(fixedLength, 2, -2)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4, 0)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 4, 1)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4, -2)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 4, -1)); - assert(TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - assert(TypedArrayIncludesHelper(lengthTracking, 2, 1)); - assert(!TypedArrayIncludesHelper(lengthTracking, 2, 2)); - assert(TypedArrayIncludesHelper(lengthTracking, 2, -3)); - assert(!TypedArrayIncludesHelper(lengthTracking, 2, -2)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, 0)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, 1)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, -2)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 4, -1)); - - // Shrink so that fixed length TAs go out of bounds. - rab.resize(3 * ctor.BYTES_PER_ELEMENT); - - // Orig. array: [0, 2, 4] - // [0, 2, 4, ...] << lengthTracking - // [4, ...] << lengthTrackingWithOffset - - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLength, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLengthWithOffset, 2); - }); - - assert(TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - - // Shrink so that the TAs with offset go out of bounds. - rab.resize(1 * ctor.BYTES_PER_ELEMENT); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLength, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLengthWithOffset, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(lengthTrackingWithOffset, 2); - }); - - // Shrink to zero. - rab.resize(0); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLength, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(fixedLengthWithOffset, 2); - }); - assert.throws(TypeError, () => { - TypedArrayIncludesHelper(lengthTrackingWithOffset, 2); - }); - assert(!TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - - // Grow so that all TAs are back in-bounds. - rab.resize(6 * ctor.BYTES_PER_ELEMENT); - for (let i = 0; i < 6; ++i) { - WriteToTypedArray(taWrite, i, 2 * i); - } - - // Orig. array: [0, 2, 4, 6, 8, 10] - // [0, 2, 4, 6] << fixedLength - // [4, 6] << fixedLengthWithOffset - // [0, 2, 4, 6, 8, 10, ...] << lengthTracking - // [4, 6, 8, 10, ...] << lengthTrackingWithOffset - - assert(TypedArrayIncludesHelper(fixedLength, 2)); - assert(!TypedArrayIncludesHelper(fixedLength, undefined)); - assert(!TypedArrayIncludesHelper(fixedLength, 8)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 2)); - assert(TypedArrayIncludesHelper(fixedLengthWithOffset, 4)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, undefined)); - assert(!TypedArrayIncludesHelper(fixedLengthWithOffset, 8)); - assert(TypedArrayIncludesHelper(lengthTracking, 2)); - assert(!TypedArrayIncludesHelper(lengthTracking, undefined)); - assert(TypedArrayIncludesHelper(lengthTracking, 8)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, 2)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 4)); - assert(!TypedArrayIncludesHelper(lengthTrackingWithOffset, undefined)); - assert(TypedArrayIncludesHelper(lengthTrackingWithOffset, 8)); + // Write some data into the array. + const taWrite = new ctor(rab); + for (let i = 0; i < 4; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); } -} -TestIncludes(); + // Orig. array: [0, 2, 4, 6] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, ...] << lengthTracking + // [4, 6, ...] << lengthTrackingWithOffset + + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2, 1)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 2, 2)); + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2, -3)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 2, -2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 0)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, 1)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4, -1)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2, 1)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2, -3)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2, -2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 0)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, 1)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4, -1)); + + // Shrink so that fixed length TAs go out of bounds. + rab.resize(3 * ctor.BYTES_PER_ELEMENT); + + // Orig. array: [0, 2, 4] + // [0, 2, 4, ...] << lengthTracking + // [4, ...] << lengthTrackingWithOffset + + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + }); + + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + + // Shrink so that the TAs with offset go out of bounds. + rab.resize(1 * ctor.BYTES_PER_ELEMENT); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2); + }); + + // Shrink to zero. + rab.resize(0); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLength, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2); + }); + assert.throws(TypeError, () => { + TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2); + }); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + + // Grow so that all TAs are back in-bounds. + rab.resize(6 * ctor.BYTES_PER_ELEMENT); + for (let i = 0; i < 6; ++i) { + WriteToTypedArray(taWrite, i, 2 * i); + } + + // Orig. array: [0, 2, 4, 6, 8, 10] + // [0, 2, 4, 6] << fixedLength + // [4, 6] << fixedLengthWithOffset + // [0, 2, 4, 6, 8, 10, ...] << lengthTracking + // [4, 6, 8, 10, ...] << lengthTrackingWithOffset + + assert(TypedArrayIncludesNumOrBigInt(fixedLength, 2)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, undefined)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLength, 8)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, undefined)); + assert(!TypedArrayIncludesNumOrBigInt(fixedLengthWithOffset, 8)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 2)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTracking, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTracking, 8)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 2)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 4)); + assert(!TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, undefined)); + assert(TypedArrayIncludesNumOrBigInt(lengthTrackingWithOffset, 8)); +}