mirror of https://github.com/tc39/test262.git
RAB: Integrate helper to rest of the tests (#4198)
Co-authored-by: Philip Chimento <philip.chimento@gmail.com>
This commit is contained in:
parent
a4443793b9
commit
3acb672d11
|
@ -0,0 +1,99 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-function.prototype.apply
|
||||||
|
description: >
|
||||||
|
Function.p.apply behaves correctly when the argument array is a
|
||||||
|
TypedArray backed by resizable buffer
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
const taWrite = new ctor(rab);
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
WriteToTypedArray(taWrite, i, i);
|
||||||
|
}
|
||||||
|
function func(...args) {
|
||||||
|
return [...args];
|
||||||
|
}
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLength)), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), [
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), [
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Shrink so that fixed length TAs go out of bounds.
|
||||||
|
rab.resize(3 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLength)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), [2]);
|
||||||
|
|
||||||
|
// Shrink so that the TAs with offset go out of bounds.
|
||||||
|
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLength)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [0]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), []);
|
||||||
|
|
||||||
|
// Shrink to zero.
|
||||||
|
rab.resize(0);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLength)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), []);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), []);
|
||||||
|
|
||||||
|
// Grow so that all TAs are back in-bounds. New memory is zeroed.
|
||||||
|
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLength)), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, fixedLengthWithOffset)), [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTracking)), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(func.apply(null, lengthTrackingWithOffset)), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-object.defineproperties
|
||||||
|
description: >
|
||||||
|
Object.defineProperties behaves correctly on TypedArrays backed by
|
||||||
|
resizable buffers
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function MayNeedBigInt(ta, value) {
|
||||||
|
if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) {
|
||||||
|
return BigInt(value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function DefinePropertiesMayNeedBigInt(ta, index, value) {
|
||||||
|
const values = {};
|
||||||
|
values[index] = { value: MayNeedBigInt(ta, value) };
|
||||||
|
Object.defineProperties(ta, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
const taFull = new ctor(rab, 0);
|
||||||
|
|
||||||
|
// Orig. array: [0, 0, 0, 0]
|
||||||
|
// [0, 0, 0, 0] << fixedLength
|
||||||
|
// [0, 0] << fixedLengthWithOffset
|
||||||
|
// [0, 0, 0, 0, ...] << lengthTracking
|
||||||
|
// [0, 0, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 0, 1);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 2);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 1, 3);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 1, 4);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 4, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 2, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 4, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 2, 8);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Shrink so that fixed length TAs go out of bounds.
|
||||||
|
rab.resize(3 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
|
||||||
|
// Orig. array: [1, 3, 2]
|
||||||
|
// [1, 3, 2, ...] << lengthTracking
|
||||||
|
// [2, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 0, 5);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
5,
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 0, 6);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
5,
|
||||||
|
3,
|
||||||
|
6
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Shrink so that the TAs with offset go out of bounds.
|
||||||
|
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), [5]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 0, 7);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [7]);
|
||||||
|
|
||||||
|
// Shrink to zero.
|
||||||
|
rab.resize(0);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), []);
|
||||||
|
|
||||||
|
// Grow so that all TAs are back in-bounds.
|
||||||
|
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 0, 9);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 0, 10);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
0,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 1, 11);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 2, 12);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
12,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Trying to define properties out of the fixed-length bounds throws.
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLength, 5, 13);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertiesMayNeedBigInt(fixedLengthWithOffset, 3, 13);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
12,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTracking, 4, 14);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
14,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertiesMayNeedBigInt(lengthTrackingWithOffset, 3, 15);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
14,
|
||||||
|
15
|
||||||
|
]);
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-object.defineproperty
|
||||||
|
description: >
|
||||||
|
Object.defineProperty behaves correctly when the object is a
|
||||||
|
TypedArray backed by a resizable buffer that's grown during argument
|
||||||
|
coercion
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function MayNeedBigInt(ta, value) {
|
||||||
|
if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) {
|
||||||
|
return BigInt(value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixed length.
|
||||||
|
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);
|
||||||
|
// Make fixedLength go OOB.
|
||||||
|
rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const evil = {
|
||||||
|
toString: () => {
|
||||||
|
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(fixedLength, evil, { value: MayNeedBigInt(fixedLength, 8) });
|
||||||
|
assert.compareArray(ToNumbers(fixedLength), [
|
||||||
|
8,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length tracking.
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const lengthTracking = new ctor(rab, 0);
|
||||||
|
const evil = {
|
||||||
|
toString: () => {
|
||||||
|
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
return 4; // Index valid after resize.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(lengthTracking, evil, { value: MayNeedBigInt(lengthTracking, 8) });
|
||||||
|
assert.compareArray(ToNumbers(lengthTracking), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
8,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-object.defineproperty
|
||||||
|
description: >
|
||||||
|
Object.defineProperty behaves correctly when the object is a
|
||||||
|
TypedArray backed by a resizable buffer that's shrunk during argument
|
||||||
|
coercion
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function MayNeedBigInt(ta, value) {
|
||||||
|
if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) {
|
||||||
|
return BigInt(value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixed length.
|
||||||
|
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 = {
|
||||||
|
toString: () => {
|
||||||
|
rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
Object.defineProperty(fixedLength, evil, { value: MayNeedBigInt(fixedLength, 8) });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length tracking.
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const lengthTracking = new ctor(rab, 0);
|
||||||
|
const evil = {
|
||||||
|
toString: () => {
|
||||||
|
rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
return 3; // Index too large after resize.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
Object.defineProperty(lengthTracking, evil, { value: MayNeedBigInt(lengthTracking, 8) });
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,214 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-object.defineproperty
|
||||||
|
description: >
|
||||||
|
Object.defineProperty behaves correctly on TypedArrays backed by
|
||||||
|
resizable buffers
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function MayNeedBigInt(ta, value) {
|
||||||
|
if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) {
|
||||||
|
return BigInt(value);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function DefinePropertyMayNeedBigInt(ta, index, value) {
|
||||||
|
Object.defineProperty(ta, index, { value: MayNeedBigInt(ta, value) });
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
const taFull = new ctor(rab, 0);
|
||||||
|
|
||||||
|
// Orig. array: [0, 0, 0, 0]
|
||||||
|
// [0, 0, 0, 0] << fixedLength
|
||||||
|
// [0, 0] << fixedLengthWithOffset
|
||||||
|
// [0, 0, 0, 0, ...] << lengthTracking
|
||||||
|
// [0, 0, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 0, 1);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 2);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 1, 3);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 1, 4);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 4, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 2, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 4, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 2, 8);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Shrink so that fixed length TAs go out of bounds.
|
||||||
|
rab.resize(3 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
|
||||||
|
// Orig. array: [1, 3, 2]
|
||||||
|
// [1, 3, 2, ...] << lengthTracking
|
||||||
|
// [2, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 0, 5);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
5,
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 0, 6);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
5,
|
||||||
|
3,
|
||||||
|
6
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Shrink so that the TAs with offset go out of bounds.
|
||||||
|
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), [5]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 0, 7);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [7]);
|
||||||
|
|
||||||
|
// Shrink to zero.
|
||||||
|
rab.resize(0);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 0, 8);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 0, 8);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), []);
|
||||||
|
|
||||||
|
// Grow so that all TAs are back in-bounds.
|
||||||
|
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 0, 9);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 0, 10);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
0,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 1, 11);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 2, 12);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
12,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Trying to define properties out of the fixed-length bounds throws.
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLength, 5, 13);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
DefinePropertyMayNeedBigInt(fixedLengthWithOffset, 3, 13);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
12,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTracking, 4, 14);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
14,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
DefinePropertyMayNeedBigInt(lengthTrackingWithOffset, 3, 15);
|
||||||
|
assert.compareArray(ToNumbers(taFull), [
|
||||||
|
9,
|
||||||
|
11,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
14,
|
||||||
|
15
|
||||||
|
]);
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-object.freeze
|
||||||
|
description: >
|
||||||
|
Object.freeze throws on non-0-length TypedArrays backed by resizable
|
||||||
|
buffers but do not throw on 0-length ones
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// Freezing non-OOB non-zero-length TAs throws.
|
||||||
|
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);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
Object.freeze(fixedLength);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
Object.freeze(fixedLengthWithOffset);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
Object.freeze(lengthTracking);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
Object.freeze(lengthTrackingWithOffset);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Freezing zero-length TAs doesn't throw.
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const fixedLength = new ctor(rab, 0, 0);
|
||||||
|
const fixedLengthWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT, 0);
|
||||||
|
const lengthTrackingWithOffset = new ctor(rab, 4 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
Object.freeze(fixedLength);
|
||||||
|
Object.freeze(fixedLengthWithOffset);
|
||||||
|
Object.freeze(lengthTrackingWithOffset);
|
||||||
|
}
|
||||||
|
// If the buffer has been resized to make length-tracking TAs zero-length,
|
||||||
|
// freezing them also doesn't throw.
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 8 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const lengthTracking = new ctor(rab);
|
||||||
|
const lengthTrackingWithOffset = new ctor(rab, 2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
Object.freeze(lengthTrackingWithOffset);
|
||||||
|
rab.resize(0 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
Object.freeze(lengthTracking);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-isvalidintegerindex
|
||||||
|
description: >
|
||||||
|
TypedArrays backed by resizable buffers that are out-of-bounds behave
|
||||||
|
as if they were detached
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const rab = CreateResizableArrayBuffer(16, 40);
|
||||||
|
const i8a = new Int8Array(rab, 0, 4);
|
||||||
|
i8a.__proto__ = { 2: 'wrong value' };
|
||||||
|
i8a[2] = 10;
|
||||||
|
assert.sameValue(i8a[2], 10);
|
||||||
|
assert(2 in i8a);
|
||||||
|
rab.resize(0);
|
||||||
|
assert.sameValue(i8a[2], undefined);
|
||||||
|
assert(!(2 in i8a));
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-isvalidintegerindex
|
||||||
|
description: >
|
||||||
|
Getting and setting in-bounds and out-of-bounds indices on TypedArrays backed
|
||||||
|
by resizable buffers.
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function MayNeedBigInt(ta, num) {
|
||||||
|
if (ta instanceof BigInt64Array || ta instanceof BigUint64Array) {
|
||||||
|
return BigInt(num);
|
||||||
|
} else {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 40 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const array = new ctor(rab, 0, 4);
|
||||||
|
// Initial values
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert.sameValue(Convert(array[i]), 0);
|
||||||
|
}
|
||||||
|
// Within-bounds write
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
array[i] = MayNeedBigInt(array, i);
|
||||||
|
}
|
||||||
|
// Within-bounds read
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert.sameValue(Convert(array[i]), i, `${ctor} array fails within-bounds read`);
|
||||||
|
}
|
||||||
|
rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
// OOB read. If the RAB isn't large enough to fit the entire TypedArray,
|
||||||
|
// the length of the TypedArray is treated as 0.
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert.sameValue(array[i], undefined);
|
||||||
|
}
|
||||||
|
// OOB write (has no effect)
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
array[i] = MayNeedBigInt(array, 10);
|
||||||
|
}
|
||||||
|
rab.resize(4 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
// Within-bounds read
|
||||||
|
for (let i = 0; i < 2; ++i) {
|
||||||
|
assert.sameValue(array[i], MayNeedBigInt(array, i));
|
||||||
|
}
|
||||||
|
// The shrunk-and-regrown part got zeroed.
|
||||||
|
for (let i = 2; i < 4; ++i) {
|
||||||
|
assert.sameValue(array[i], MayNeedBigInt(array, 0));
|
||||||
|
}
|
||||||
|
rab.resize(40 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
// Within-bounds read
|
||||||
|
for (let i = 0; i < 2; ++i) {
|
||||||
|
assert.sameValue(array[i], MayNeedBigInt(array, i));
|
||||||
|
}
|
||||||
|
for (let i = 2; i < 4; ++i) {
|
||||||
|
assert.sameValue(array[i], MayNeedBigInt(array, 0));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-isvalidintegerindex
|
||||||
|
description: >
|
||||||
|
In-bound indices are testable with `in` on TypedArrays backed by resizable buffers.
|
||||||
|
info: |
|
||||||
|
IsValidIntegerIndex ( O, index )
|
||||||
|
...
|
||||||
|
6. Let length be IntegerIndexedObjectLength(O, getBufferByteLength).
|
||||||
|
7. If length is out-of-bounds or ℝ(index) < 0 or ℝ(index) ≥ length, return false.
|
||||||
|
...
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * ctor.BYTES_PER_ELEMENT, 40 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
const array = new ctor(rab, 0, 4);
|
||||||
|
// Within-bounds read
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert(i in array);
|
||||||
|
}
|
||||||
|
rab.resize(2 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
// OOB read. If the RAB isn't large enough to fit the entire TypedArray,
|
||||||
|
// the length of the TypedArray is treated as 0.
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert(!(i in array));
|
||||||
|
}
|
||||||
|
rab.resize(4 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
// Within-bounds read
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert(i in array);
|
||||||
|
}
|
||||||
|
rab.resize(40 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
// Within-bounds read
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
assert(i in array);
|
||||||
|
}
|
||||||
|
}
|
19
test/built-ins/TypedArray/prototype/resizable-and-fixed-have-same-prototype.js
vendored
Normal file
19
test/built-ins/TypedArray/prototype/resizable-and-fixed-have-same-prototype.js
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-%typedarray%.prototype
|
||||||
|
description: >
|
||||||
|
TypedArrays that are backed by resizable buffers have the same prototypes
|
||||||
|
as those backed by fixed-length buffers
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const rab = CreateResizableArrayBuffer(40, 80);
|
||||||
|
const ab = new ArrayBuffer(80);
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const ta_rab = new ctor(rab, 0, 3);
|
||||||
|
const ta_ab = new ctor(ab, 0, 3);
|
||||||
|
assert.sameValue(ta_ab.__proto__, ta_rab.__proto__);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
Basic functionality of length-tracking TypedArrays backed by resizable
|
||||||
|
buffers
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const rab = CreateResizableArrayBuffer(16, 40);
|
||||||
|
let tas = [];
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
tas.push(new ctor(rab));
|
||||||
|
}
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 16 / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 16);
|
||||||
|
}
|
||||||
|
rab.resize(40);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 40 / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 40);
|
||||||
|
}
|
||||||
|
// Resize to a number which is not a multiple of all byte_lengths.
|
||||||
|
rab.resize(19);
|
||||||
|
for (let ta of tas) {
|
||||||
|
const expected_length = Math.floor(19 / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.length, expected_length);
|
||||||
|
assert.sameValue(ta.byteLength, expected_length * ta.BYTES_PER_ELEMENT);
|
||||||
|
}
|
||||||
|
rab.resize(1);
|
||||||
|
for (let ta of tas) {
|
||||||
|
if (ta.BYTES_PER_ELEMENT == 1) {
|
||||||
|
assert.sameValue(ta.length, 1);
|
||||||
|
assert.sameValue(ta.byteLength, 1);
|
||||||
|
} else {
|
||||||
|
assert.sameValue(ta.length, 0);
|
||||||
|
assert.sameValue(ta.byteLength, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rab.resize(0);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 0);
|
||||||
|
assert.sameValue(ta.byteLength, 0);
|
||||||
|
}
|
||||||
|
rab.resize(8);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 8 / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 8);
|
||||||
|
}
|
||||||
|
rab.resize(40);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 40 / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 40);
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
Length-tracking TypedArrays backed by resizable buffers with offsets
|
||||||
|
behave correctly
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// length-tracking-1 but with offsets.
|
||||||
|
|
||||||
|
const rab = CreateResizableArrayBuffer(16, 40);
|
||||||
|
const offset = 8;
|
||||||
|
let tas = [];
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
tas.push(new ctor(rab, offset));
|
||||||
|
}
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, (16 - offset) / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 16 - offset);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
}
|
||||||
|
rab.resize(40);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, (40 - offset) / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 40 - offset);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
}
|
||||||
|
// Resize to a number which is not a multiple of all byte_lengths.
|
||||||
|
rab.resize(20);
|
||||||
|
for (let ta of tas) {
|
||||||
|
const expected_length = Math.floor((20 - offset) / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.length, expected_length);
|
||||||
|
assert.sameValue(ta.byteLength, expected_length * ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
}
|
||||||
|
// Resize so that all TypedArrays go out of bounds (because of the offset).
|
||||||
|
rab.resize(7);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 0);
|
||||||
|
assert.sameValue(ta.byteLength, 0);
|
||||||
|
assert.sameValue(ta.byteOffset, 0);
|
||||||
|
}
|
||||||
|
rab.resize(0);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 0);
|
||||||
|
assert.sameValue(ta.byteLength, 0);
|
||||||
|
assert.sameValue(ta.byteOffset, 0);
|
||||||
|
}
|
||||||
|
rab.resize(8);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, 0);
|
||||||
|
assert.sameValue(ta.byteLength, 0);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
}
|
||||||
|
// Resize so that the TypedArrays which have element size > 1 go out of bounds
|
||||||
|
// (because less than 1 full element would fit).
|
||||||
|
rab.resize(offset + 1);
|
||||||
|
for (let ta of tas) {
|
||||||
|
if (ta.BYTES_PER_ELEMENT == 1) {
|
||||||
|
assert.sameValue(ta.length, 1);
|
||||||
|
assert.sameValue(ta.byteLength, 1);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
} else {
|
||||||
|
assert.sameValue(ta.length, 0);
|
||||||
|
assert.sameValue(ta.byteLength, 0);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rab.resize(40);
|
||||||
|
for (let ta of tas) {
|
||||||
|
assert.sameValue(ta.length, (40 - offset) / ta.BYTES_PER_ELEMENT);
|
||||||
|
assert.sameValue(ta.byteLength, 40 - offset);
|
||||||
|
assert.sameValue(ta.byteOffset, offset);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-initializetypedarrayfromarraybuffer
|
||||||
|
description: >
|
||||||
|
Creating a TypedArray from a resizable buffer with invalid bounds
|
||||||
|
throw RangedError
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
const rab = CreateResizableArrayBuffer(40, 80);
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
// Length too big.
|
||||||
|
assert.throws(RangeError, () => {
|
||||||
|
new ctor(rab, 0, 40 / ctor.BYTES_PER_ELEMENT + 1);
|
||||||
|
});
|
||||||
|
// Offset too close to the end.
|
||||||
|
assert.throws(RangeError, () => {
|
||||||
|
new ctor(rab, 40 - ctor.BYTES_PER_ELEMENT, 2);
|
||||||
|
});
|
||||||
|
// Offset beyond end.
|
||||||
|
assert.throws(RangeError, () => {
|
||||||
|
new ctor(rab, 40, 1);
|
||||||
|
});
|
||||||
|
if (ctor.BYTES_PER_ELEMENT > 1) {
|
||||||
|
// Offset not a multiple of the byte size.
|
||||||
|
assert.throws(RangeError, () => {
|
||||||
|
new ctor(rab, 1, 1);
|
||||||
|
});
|
||||||
|
assert.throws(RangeError, () => {
|
||||||
|
new ctor(rab, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-initializetypedarrayfromtypedarray
|
||||||
|
description: >
|
||||||
|
Initializing a TypedArray from another TypedArray that is backed by a
|
||||||
|
resizable buffer
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function IsBigIntTypedArray(ta) {
|
||||||
|
return ta instanceof BigInt64Array || ta instanceof BigUint64Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function AllBigIntMatchedCtorCombinations(test) {
|
||||||
|
for (let targetCtor of ctors) {
|
||||||
|
for (let sourceCtor of ctors) {
|
||||||
|
if (IsBigIntTypedArray(new targetCtor()) != IsBigIntTypedArray(new sourceCtor())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
test(targetCtor, sourceCtor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AllBigIntMatchedCtorCombinations((targetCtor, sourceCtor) => {
|
||||||
|
const rab = CreateResizableArrayBuffer(4 * sourceCtor.BYTES_PER_ELEMENT, 8 * sourceCtor.BYTES_PER_ELEMENT);
|
||||||
|
const fixedLength = new sourceCtor(rab, 0, 4);
|
||||||
|
const fixedLengthWithOffset = new sourceCtor(rab, 2 * sourceCtor.BYTES_PER_ELEMENT, 2);
|
||||||
|
const lengthTracking = new sourceCtor(rab, 0);
|
||||||
|
const lengthTrackingWithOffset = new sourceCtor(rab, 2 * sourceCtor.BYTES_PER_ELEMENT);
|
||||||
|
|
||||||
|
// Write some data into the array.
|
||||||
|
const taFull = new sourceCtor(rab);
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
WriteToTypedArray(taFull, i, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orig. array: [1, 2, 3, 4]
|
||||||
|
// [1, 2, 3, 4] << fixedLength
|
||||||
|
// [3, 4] << fixedLengthWithOffset
|
||||||
|
// [1, 2, 3, 4, ...] << lengthTracking
|
||||||
|
// [3, 4, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(fixedLength)), [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(fixedLengthWithOffset)), [
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTrackingWithOffset)), [
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Shrink so that fixed length TAs go out of bounds.
|
||||||
|
rab.resize(3 * sourceCtor.BYTES_PER_ELEMENT);
|
||||||
|
|
||||||
|
// Orig. array: [1, 2, 3]
|
||||||
|
// [1, 2, 3, ...] << lengthTracking
|
||||||
|
// [3, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(fixedLength);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(fixedLengthWithOffset);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTrackingWithOffset)), [3]);
|
||||||
|
|
||||||
|
// Shrink so that the TAs with offset go out of bounds.
|
||||||
|
rab.resize(1 * sourceCtor.BYTES_PER_ELEMENT);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(fixedLength);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(fixedLengthWithOffset);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [1]);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(lengthTrackingWithOffset);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Shrink to zero.
|
||||||
|
rab.resize(0);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(fixedLength);
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(fixedLengthWithOffset);
|
||||||
|
});
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), []);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
new targetCtor(lengthTrackingWithOffset);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Grow so that all TAs are back in-bounds.
|
||||||
|
rab.resize(6 * sourceCtor.BYTES_PER_ELEMENT);
|
||||||
|
for (let i = 0; i < 6; ++i) {
|
||||||
|
WriteToTypedArray(taFull, i, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orig. array: [1, 2, 3, 4, 5, 6]
|
||||||
|
// [1, 2, 3, 4] << fixedLength
|
||||||
|
// [3, 4] << fixedLengthWithOffset
|
||||||
|
// [1, 2, 3, 4, 5, 6, ...] << lengthTracking
|
||||||
|
// [3, 4, 5, 6, ...] << lengthTrackingWithOffset
|
||||||
|
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(fixedLength)), [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(fixedLengthWithOffset)), [
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTracking)), [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6
|
||||||
|
]);
|
||||||
|
assert.compareArray(ToNumbers(new targetCtor(lengthTrackingWithOffset)), [
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6
|
||||||
|
]);
|
||||||
|
});
|
|
@ -0,0 +1,199 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
Destructuring assignment on TypedArrays backed by resizable buffer
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
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.
|
||||||
|
let ta_write = new ctor(rab);
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
WriteToTypedArray(ta_write, i, i);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c, d, e] = fixedLength;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.sameValue(e, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c] = fixedLengthWithOffset;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
]), [
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.sameValue(c, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c, d, e] = lengthTracking;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.sameValue(e, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c] = lengthTrackingWithOffset;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
]), [
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]);
|
||||||
|
assert.sameValue(c, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shrink so that fixed length TAs go out of bounds.
|
||||||
|
rab.resize(3 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = fixedLength;
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = fixedLengthWithOffset;
|
||||||
|
});
|
||||||
|
{
|
||||||
|
let [a, b, c, d] = lengthTracking;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
assert.sameValue(d, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b] = lengthTrackingWithOffset;
|
||||||
|
assert.compareArray(ToNumbers([a]), [2]);
|
||||||
|
assert.sameValue(b, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shrink so that the TAs with offset go out of bounds.
|
||||||
|
rab.resize(1 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = fixedLength;
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = fixedLengthWithOffset;
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = lengthTrackingWithOffset;
|
||||||
|
});
|
||||||
|
{
|
||||||
|
let [a, b] = lengthTracking;
|
||||||
|
assert.compareArray(ToNumbers([a]), [0]);
|
||||||
|
assert.sameValue(b, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shrink to 0.
|
||||||
|
rab.resize(0);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = fixedLength;
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = fixedLengthWithOffset;
|
||||||
|
});
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
let [a, b, c] = lengthTrackingWithOffset;
|
||||||
|
});
|
||||||
|
{
|
||||||
|
let [a] = lengthTracking;
|
||||||
|
assert.sameValue(a, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grow so that all TAs are back in-bounds. The new memory is zeroed.
|
||||||
|
rab.resize(6 * ctor.BYTES_PER_ELEMENT);
|
||||||
|
{
|
||||||
|
let [a, b, c, d, e] = fixedLength;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.sameValue(e, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c] = fixedLengthWithOffset;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.sameValue(c, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c, d, e, f, g] = lengthTracking;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d,
|
||||||
|
e,
|
||||||
|
f
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.sameValue(g, undefined);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let [a, b, c, d, e] = lengthTrackingWithOffset;
|
||||||
|
assert.compareArray(ToNumbers([
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c,
|
||||||
|
d
|
||||||
|
]), [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]);
|
||||||
|
assert.sameValue(e, undefined);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
Indices of TypedArrays backed by resizable buffers are enumerable with
|
||||||
|
for-in
|
||||||
|
includes: [resizableArrayBufferUtils.js]
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let rab = CreateResizableArrayBuffer(100, 200);
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const ta = new ctor(rab, 0, 3);
|
||||||
|
let keys = '';
|
||||||
|
for (const key in ta) {
|
||||||
|
keys += key;
|
||||||
|
}
|
||||||
|
assert.sameValue(keys, '012');
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
TypedArrays backed by resizable buffers are iterable with for-of and behave
|
||||||
|
correctly when the buffer is grown during iteration
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function CreateRab(buffer_byte_length, ctor) {
|
||||||
|
const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length);
|
||||||
|
let ta_write = new ctor(rab);
|
||||||
|
for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) {
|
||||||
|
WriteToTypedArray(ta_write, i, i % 128);
|
||||||
|
}
|
||||||
|
return rab;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to recreate the RAB between all TA tests, since we grow it.
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const no_elements = 10;
|
||||||
|
const offset = 2;
|
||||||
|
const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT;
|
||||||
|
const byte_offset = offset * ctor.BYTES_PER_ELEMENT;
|
||||||
|
|
||||||
|
// Create various different styles of TypedArrays with the RAB as the
|
||||||
|
// backing store and iterate them.
|
||||||
|
|
||||||
|
let rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta = new ctor(rab);
|
||||||
|
{
|
||||||
|
let expected = [];
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
expected.push(i % 128);
|
||||||
|
}
|
||||||
|
// After resizing, the new memory contains zeros.
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
expected.push(0);
|
||||||
|
}
|
||||||
|
TestIterationAndResize(length_tracking_ta, expected, rab, no_elements, buffer_byte_length * 2);
|
||||||
|
}
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta_with_offset = new ctor(rab, byte_offset);
|
||||||
|
{
|
||||||
|
let expected = [];
|
||||||
|
for (let i = offset; i < no_elements; ++i) {
|
||||||
|
expected.push(i % 128);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
expected.push(0);
|
||||||
|
}
|
||||||
|
TestIterationAndResize(length_tracking_ta_with_offset, expected, rab, no_elements - offset, buffer_byte_length * 2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
TypedArrays backed by resizable buffers are iterable with for-of and behave
|
||||||
|
correctly when the buffer is grown during iteration
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function CreateRab(buffer_byte_length, ctor) {
|
||||||
|
const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length);
|
||||||
|
let ta_write = new ctor(rab);
|
||||||
|
for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) {
|
||||||
|
WriteToTypedArray(ta_write, i, i % 128);
|
||||||
|
}
|
||||||
|
return rab;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const no_elements = 10;
|
||||||
|
const offset = 2;
|
||||||
|
const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT;
|
||||||
|
const byte_offset = offset * ctor.BYTES_PER_ELEMENT;
|
||||||
|
|
||||||
|
// Create various different styles of TypedArrays with the RAB as the
|
||||||
|
// backing store and iterate them.
|
||||||
|
|
||||||
|
// Fixed-length TAs aren't affected by resizing.
|
||||||
|
let rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta = new ctor(rab, 0, 3);
|
||||||
|
TestIterationAndResize(ta, [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
], rab, 2, buffer_byte_length * 2);
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta_with_offset = new ctor(rab, byte_offset, 3);
|
||||||
|
TestIterationAndResize(ta_with_offset, [
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
], rab, 2, buffer_byte_length * 2);
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta = new ctor(rab);
|
||||||
|
{
|
||||||
|
let expected = [];
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
expected.push(i % 128);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
// After resizing, the new memory contains zeros.
|
||||||
|
expected.push(0);
|
||||||
|
}
|
||||||
|
TestIterationAndResize(length_tracking_ta, expected, rab, 2, buffer_byte_length * 2);
|
||||||
|
}
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta_with_offset = new ctor(rab, byte_offset);
|
||||||
|
{
|
||||||
|
let expected = [];
|
||||||
|
for (let i = offset; i < no_elements; ++i) {
|
||||||
|
expected.push(i % 128);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
expected.push(0);
|
||||||
|
}
|
||||||
|
TestIterationAndResize(length_tracking_ta_with_offset, expected, rab, 2, buffer_byte_length * 2);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
TypedArrays backed by resizable buffers are iterable with for-of and behave
|
||||||
|
correctly when the buffer is shrunk during iteration
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function CreateRab(buffer_byte_length, ctor) {
|
||||||
|
const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length);
|
||||||
|
let ta_write = new ctor(rab);
|
||||||
|
for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) {
|
||||||
|
WriteToTypedArray(ta_write, i, i % 128);
|
||||||
|
}
|
||||||
|
return rab;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const no_elements = 10;
|
||||||
|
const offset = 2;
|
||||||
|
const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT;
|
||||||
|
const byte_offset = offset * ctor.BYTES_PER_ELEMENT;
|
||||||
|
|
||||||
|
// Create various different styles of TypedArrays with the RAB as the
|
||||||
|
// backing store and iterate them.
|
||||||
|
|
||||||
|
// Fixed-length TAs aren't affected by shrinking if they stay in-bounds.
|
||||||
|
// They appear detached after shrinking out of bounds.
|
||||||
|
let rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta1 = new ctor(rab, 0, 3);
|
||||||
|
TestIterationAndResize(ta1, [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
], rab, 2, buffer_byte_length / 2);
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta2 = new ctor(rab, 0, 3);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
TestIterationAndResize(ta2, null, rab, 2, 1);
|
||||||
|
});
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta_with_offset1 = new ctor(rab, byte_offset, 3);
|
||||||
|
TestIterationAndResize(ta_with_offset1, [
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
], rab, 2, buffer_byte_length / 2);
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta_with_offset2 = new ctor(rab, byte_offset, 3);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
TestIterationAndResize(ta_with_offset2, null, rab, 2, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Length-tracking TA with offset 0 doesn't throw, but its length gracefully
|
||||||
|
// reduces too.
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta = new ctor(rab);
|
||||||
|
TestIterationAndResize(length_tracking_ta, [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
], rab, 2, buffer_byte_length / 2);
|
||||||
|
|
||||||
|
// Length-tracking TA appears detached when the buffer is resized beyond the
|
||||||
|
// offset.
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta_with_offset = new ctor(rab, byte_offset);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
TestIterationAndResize(length_tracking_ta_with_offset, null, rab, 2, byte_offset / 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Length-tracking TA reduces its length gracefully when the buffer is
|
||||||
|
// resized to barely cover the offset.
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta_with_offset2 = new ctor(rab, byte_offset);
|
||||||
|
TestIterationAndResize(length_tracking_ta_with_offset2, [
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
], rab, 2, byte_offset);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
TypedArrays backed by resizable buffers are iterable with for-of and behave
|
||||||
|
correctly when the buffer is shrunk during iteration
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function CreateRab(buffer_byte_length, ctor) {
|
||||||
|
const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length);
|
||||||
|
let ta_write = new ctor(rab);
|
||||||
|
for (let i = 0; i < buffer_byte_length / ctor.BYTES_PER_ELEMENT; ++i) {
|
||||||
|
WriteToTypedArray(ta_write, i, i % 128);
|
||||||
|
}
|
||||||
|
return rab;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const no_elements = 10;
|
||||||
|
const offset = 2;
|
||||||
|
const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT;
|
||||||
|
const byte_offset = offset * ctor.BYTES_PER_ELEMENT;
|
||||||
|
|
||||||
|
// Create various different styles of TypedArrays with the RAB as the
|
||||||
|
// backing store and iterate them.
|
||||||
|
|
||||||
|
// Fixed-length TAs appear detached after shrinking out of bounds.
|
||||||
|
let rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta = new ctor(rab, 0, 3);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
TestIterationAndResize(ta, null, rab, 2, 0);
|
||||||
|
});
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const ta_with_offset = new ctor(rab, byte_offset, 3);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
TestIterationAndResize(ta_with_offset, null, rab, 2, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Length-tracking TA with offset 0 doesn't throw, but its length gracefully
|
||||||
|
// goes to zero too.
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta = new ctor(rab);
|
||||||
|
TestIterationAndResize(length_tracking_ta, [
|
||||||
|
0,
|
||||||
|
1
|
||||||
|
], rab, 2, 0);
|
||||||
|
|
||||||
|
// Length-tracking TA which is resized beyond the offset appars detached.
|
||||||
|
rab = CreateRab(buffer_byte_length, ctor);
|
||||||
|
const length_tracking_ta_with_offset = new ctor(rab, byte_offset);
|
||||||
|
assert.throws(TypeError, () => {
|
||||||
|
TestIterationAndResize(length_tracking_ta_with_offset, null, rab, 2, 0);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2023 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-arraybuffer-length
|
||||||
|
description: >
|
||||||
|
TypedArrays backed by resizable buffers are iterable with for-of
|
||||||
|
features: [resizable-arraybuffer]
|
||||||
|
includes: [compareArray.js, resizableArrayBufferUtils.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function CollectValues(ta) {
|
||||||
|
let values = [];
|
||||||
|
for (const value of ta) {
|
||||||
|
values.push(Number(value));
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
for (let ctor of ctors) {
|
||||||
|
const no_elements = 10;
|
||||||
|
const offset = 2;
|
||||||
|
const buffer_byte_length = no_elements * ctor.BYTES_PER_ELEMENT;
|
||||||
|
// We can use the same RAB for all the TAs below, since we won't modify it
|
||||||
|
// after writing the initial values.
|
||||||
|
const rab = CreateResizableArrayBuffer(buffer_byte_length, 2 * buffer_byte_length);
|
||||||
|
const byte_offset = offset * ctor.BYTES_PER_ELEMENT;
|
||||||
|
|
||||||
|
// Write some data into the array.
|
||||||
|
let ta_write = new ctor(rab);
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
WriteToTypedArray(ta_write, i, i % 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create various different styles of TypedArrays with the RAB as the
|
||||||
|
// backing store and iterate them.
|
||||||
|
const ta = new ctor(rab, 0, 3);
|
||||||
|
assert.compareArray(CollectValues(ta), [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]);
|
||||||
|
const empty_ta = new ctor(rab, 0, 0);
|
||||||
|
assert.compareArray(CollectValues(empty_ta), []);
|
||||||
|
const ta_with_offset = new ctor(rab, byte_offset, 3);
|
||||||
|
assert.compareArray(CollectValues(ta_with_offset), [
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
]);
|
||||||
|
const empty_ta_with_offset = new ctor(rab, byte_offset, 0);
|
||||||
|
assert.compareArray(CollectValues(empty_ta_with_offset), []);
|
||||||
|
const length_tracking_ta = new ctor(rab);
|
||||||
|
{
|
||||||
|
let expected = [];
|
||||||
|
for (let i = 0; i < no_elements; ++i) {
|
||||||
|
expected.push(i % 128);
|
||||||
|
}
|
||||||
|
assert.compareArray(CollectValues(length_tracking_ta), expected);
|
||||||
|
}
|
||||||
|
const length_tracking_ta_with_offset = new ctor(rab, byte_offset);
|
||||||
|
{
|
||||||
|
let expected = [];
|
||||||
|
for (let i = offset; i < no_elements; ++i) {
|
||||||
|
expected.push(i % 128);
|
||||||
|
}
|
||||||
|
assert.compareArray(CollectValues(length_tracking_ta_with_offset), expected);
|
||||||
|
}
|
||||||
|
const empty_length_tracking_ta_with_offset = new ctor(rab, buffer_byte_length);
|
||||||
|
assert.compareArray(CollectValues(empty_length_tracking_ta_with_offset), []);
|
||||||
|
}
|
Loading…
Reference in New Issue