mirror of
https://github.com/tc39/test262.git
synced 2025-09-25 19:18:48 +02:00
Remove unnecessary tests if $262.detachArrayBuffer is defined
This commit is contained in:
parent
11c8fe0a99
commit
61286de40c
@ -8,6 +8,7 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
|
||||
var buffer = new ArrayBuffer(2);
|
||||
var view = new DataView(buffer);
|
||||
|
||||
@ -30,16 +31,13 @@ for (let fun of ['getInt8', 'getInt16']) {
|
||||
assert.sameValue(view[fun](NaN), 0);
|
||||
}
|
||||
|
||||
if ('$262.detachArrayBuffer' in this) {
|
||||
// ToIndex is called before detachment check, so we can tell the difference
|
||||
// between a ToIndex failure and a real out of bounds failure.
|
||||
$262.detachArrayBuffer(buffer);
|
||||
// ToIndex is called before detachment check, so we can tell the difference
|
||||
// between a ToIndex failure and a real out of bounds failure.
|
||||
$262.detachArrayBuffer(buffer);
|
||||
|
||||
check(view);
|
||||
|
||||
assert.throws(TypeError, () => view.getInt8(0));
|
||||
assert.throws(TypeError, () => view.setInt8(0, 0));
|
||||
assert.throws(TypeError, () => view.getInt8(Math.pow(2, 53) - 1));
|
||||
assert.throws(TypeError, () => view.setInt8(Math.pow(2, 53) - 1, 0));
|
||||
}
|
||||
check(view);
|
||||
|
||||
assert.throws(TypeError, () => view.getInt8(0));
|
||||
assert.throws(TypeError, () => view.setInt8(0, 0));
|
||||
assert.throws(TypeError, () => view.getInt8(Math.pow(2, 53) - 1));
|
||||
assert.throws(TypeError, () => view.setInt8(Math.pow(2, 53) - 1, 0));
|
||||
|
@ -9,74 +9,70 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
|
||||
function checkResult(actual, expected)
|
||||
{
|
||||
assert.sameValue(actual.value, expected.value);
|
||||
assert.sameValue(actual.done, expected.done);
|
||||
}
|
||||
|
||||
if (typeof $262.detachArrayBuffer === "function")
|
||||
var iteratorFunction = Uint8Array.prototype[Symbol.iterator];
|
||||
|
||||
var thisGlobal = this;
|
||||
var otherGlobal = $262.createRealm().global;
|
||||
|
||||
var thisNext = new Uint8Array()[Symbol.iterator]().next
|
||||
|
||||
for (const constructor of typedArrayConstructors)
|
||||
{
|
||||
var iteratorFunction = Uint8Array.prototype[Symbol.iterator];
|
||||
assert.sameValue(new constructor()[Symbol.iterator]().next, thisNext);
|
||||
|
||||
var globals =
|
||||
[
|
||||
[thisGlobal, thisGlobal],
|
||||
[thisGlobal, otherGlobal],
|
||||
[otherGlobal, otherGlobal],
|
||||
[otherGlobal, thisGlobal],
|
||||
];
|
||||
|
||||
var thisGlobal = this;
|
||||
var otherGlobal = $262.createRealm().global;
|
||||
|
||||
var thisNext = new Uint8Array()[Symbol.iterator]().next
|
||||
|
||||
for (const constructor of typedArrayConstructors)
|
||||
for (const [arrayGlobal, bufferGlobal] of globals)
|
||||
{
|
||||
assert.sameValue(new constructor()[Symbol.iterator]().next, thisNext);
|
||||
var arr, buffer, iterator;
|
||||
|
||||
var globals =
|
||||
[
|
||||
[thisGlobal, thisGlobal],
|
||||
[thisGlobal, otherGlobal],
|
||||
[otherGlobal, otherGlobal],
|
||||
[otherGlobal, thisGlobal],
|
||||
];
|
||||
|
||||
for (const [arrayGlobal, bufferGlobal] of globals)
|
||||
function arrayBufferIterator()
|
||||
{
|
||||
var arr, buffer, iterator;
|
||||
var byteLength = 2 * constructor.BYTES_PER_ELEMENT;
|
||||
var buf = new bufferGlobal.ArrayBuffer(byteLength);
|
||||
var tarray = new arrayGlobal[constructor.name](buf);
|
||||
|
||||
function arrayBufferIterator()
|
||||
{
|
||||
var byteLength = 2 * constructor.BYTES_PER_ELEMENT;
|
||||
var buf = new bufferGlobal.ArrayBuffer(byteLength);
|
||||
var tarray = new arrayGlobal[constructor.name](buf);
|
||||
tarray[0] = 1;
|
||||
tarray[1] = 2;
|
||||
|
||||
tarray[0] = 1;
|
||||
tarray[1] = 2;
|
||||
|
||||
return [tarray, buf, Reflect.apply(iteratorFunction, tarray, [])];
|
||||
}
|
||||
|
||||
[arr, buffer, iterator] = arrayBufferIterator();
|
||||
checkResult(thisNext.call(iterator), {value: 1, done: false});
|
||||
checkResult(thisNext.call(iterator), {value: 2, done: false});
|
||||
checkResult(thisNext.call(iterator), {value: undefined, done: true});
|
||||
|
||||
// Test an exhausted iterator.
|
||||
bufferGlobal.$262.detachArrayBuffer(buffer);
|
||||
checkResult(thisNext.call(iterator), {value: undefined, done: true});
|
||||
|
||||
// Test an all-but-exhausted iterator.
|
||||
[arr, buffer, iterator] = arrayBufferIterator();
|
||||
checkResult(thisNext.call(iterator), {value: 1, done: false});
|
||||
checkResult(thisNext.call(iterator), {value: 2, done: false});
|
||||
|
||||
bufferGlobal.$262.detachArrayBuffer(buffer);
|
||||
assert.throws(TypeError, () => thisNext.call(iterator));
|
||||
|
||||
// Test an unexhausted iterator.
|
||||
[arr, buffer, iterator] = arrayBufferIterator();
|
||||
checkResult(thisNext.call(iterator), {value: 1, done: false});
|
||||
|
||||
bufferGlobal.$262.detachArrayBuffer(buffer);
|
||||
assert.throws(TypeError, () => thisNext.call(iterator));
|
||||
return [tarray, buf, Reflect.apply(iteratorFunction, tarray, [])];
|
||||
}
|
||||
|
||||
[arr, buffer, iterator] = arrayBufferIterator();
|
||||
checkResult(thisNext.call(iterator), {value: 1, done: false});
|
||||
checkResult(thisNext.call(iterator), {value: 2, done: false});
|
||||
checkResult(thisNext.call(iterator), {value: undefined, done: true});
|
||||
|
||||
// Test an exhausted iterator.
|
||||
bufferGlobal.$262.detachArrayBuffer(buffer);
|
||||
checkResult(thisNext.call(iterator), {value: undefined, done: true});
|
||||
|
||||
// Test an all-but-exhausted iterator.
|
||||
[arr, buffer, iterator] = arrayBufferIterator();
|
||||
checkResult(thisNext.call(iterator), {value: 1, done: false});
|
||||
checkResult(thisNext.call(iterator), {value: 2, done: false});
|
||||
|
||||
bufferGlobal.$262.detachArrayBuffer(buffer);
|
||||
assert.throws(TypeError, () => thisNext.call(iterator));
|
||||
|
||||
// Test an unexhausted iterator.
|
||||
[arr, buffer, iterator] = arrayBufferIterator();
|
||||
checkResult(thisNext.call(iterator), {value: 1, done: false});
|
||||
|
||||
bufferGlobal.$262.detachArrayBuffer(buffer);
|
||||
assert.throws(TypeError, () => thisNext.call(iterator));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
|
||||
// Tests for detached ArrayBuffer checks in %TypedArray%.prototype.set(array|typedArray, offset).
|
||||
|
||||
function* createTypedArrays(lengths = [0, 1, 4, 4096]) {
|
||||
@ -19,255 +20,252 @@ function* createTypedArrays(lengths = [0, 1, 4, 4096]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
class ExpectedError extends Error {}
|
||||
class ExpectedError extends Error {}
|
||||
|
||||
// No detached check on function entry.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
// No detached check on function entry.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
|
||||
assert.throws(ExpectedError, () => typedArray.set(null, {
|
||||
assert.throws(ExpectedError, () => typedArray.set(null, {
|
||||
valueOf() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// Check for detached buffer after calling ToInteger(offset). Test with:
|
||||
// - valid offset,
|
||||
// - too large offset,
|
||||
// - and negative offset.
|
||||
for (let [offset, error] of [[0, TypeError], [1000000, TypeError], [-1, RangeError]]) {
|
||||
for (let source of [[], [0], new Int32Array(0), new Int32Array(1)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
assert.throws(error, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return offset;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests when called with detached typed array as source.
|
||||
for (let {typedArray} of createTypedArrays()) {
|
||||
for (let {typedArray: source, buffer: sourceBuffer} of createTypedArrays()) {
|
||||
$262.detachArrayBuffer(sourceBuffer);
|
||||
|
||||
assert.throws(ExpectedError, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Check for detached buffer after calling ToInteger(offset). Test with:
|
||||
// - valid offset,
|
||||
// - too large offset,
|
||||
// - and negative offset.
|
||||
for (let [offset, error] of [[0, TypeError], [1000000, TypeError], [-1, RangeError]]) {
|
||||
for (let source of [[], [0], new Int32Array(0), new Int32Array(1)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
assert.throws(error, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return offset;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests when called with detached typed array as source.
|
||||
// Check when detaching source buffer in ToInteger(offset). Test with:
|
||||
// - valid offset,
|
||||
// - too large offset,
|
||||
// - and negative offset.
|
||||
for (let [offset, error] of [[0, TypeError], [1000000, TypeError], [-1, RangeError]]) {
|
||||
for (let {typedArray} of createTypedArrays()) {
|
||||
for (let {typedArray: source, buffer: sourceBuffer} of createTypedArrays()) {
|
||||
$262.detachArrayBuffer(sourceBuffer);
|
||||
|
||||
assert.throws(ExpectedError, () => typedArray.set(source, {
|
||||
assert.throws(error, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
throw new ExpectedError();
|
||||
$262.detachArrayBuffer(sourceBuffer);
|
||||
return offset;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Check when detaching source buffer in ToInteger(offset). Test with:
|
||||
// - valid offset,
|
||||
// - too large offset,
|
||||
// - and negative offset.
|
||||
for (let [offset, error] of [[0, TypeError], [1000000, TypeError], [-1, RangeError]]) {
|
||||
for (let {typedArray} of createTypedArrays()) {
|
||||
for (let {typedArray: source, buffer: sourceBuffer} of createTypedArrays()) {
|
||||
assert.throws(error, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(sourceBuffer);
|
||||
return offset;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test when target and source use the same underlying buffer and
|
||||
// ToInteger(offset) detaches the buffer. Test with:
|
||||
// - same typed array,
|
||||
// - different typed array, but same element type,
|
||||
// - and different element type.
|
||||
for (let src of [ta => ta, ta => new Int32Array(ta.buffer), ta => new Float32Array(ta.buffer)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = src(typedArray);
|
||||
assert.throws(TypeError, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Test when Get(src, "length") detaches the buffer, but srcLength is 0.
|
||||
// Also use different offsets to ensure bounds checks use the typed array's
|
||||
// length value from before detaching the buffer.
|
||||
for (let offset of [() => 0, ta => Math.min(1, ta.length), ta => Math.max(0, ta.length - 1)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
get length() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
typedArray.set(source, offset(typedArray));
|
||||
}
|
||||
}
|
||||
|
||||
// Test when ToLength(Get(src, "length")) detaches the buffer, but
|
||||
// srcLength is 0. Also use different offsets to ensure bounds checks use
|
||||
// the typed array's length value from before detaching the buffer.
|
||||
for (let offset of [() => 0, ta => Math.min(1, ta.length), ta => Math.max(0, ta.length - 1)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
typedArray.set(source, offset(typedArray));
|
||||
}
|
||||
}
|
||||
|
||||
// Test no TypeError is thrown when the typed array is detached and
|
||||
// srcLength > 0.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (typedArray.length === 0) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
typedArray.set(source);
|
||||
}
|
||||
}
|
||||
|
||||
// Same as above, but with side-effect when executing Get(src, "0").
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
get 0() {
|
||||
throw new ExpectedError();
|
||||
},
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
let err = typedArray.length === 0 ? RangeError : ExpectedError;
|
||||
assert.throws(err, () => typedArray.set(source));
|
||||
}
|
||||
|
||||
// Same as above, but with side-effect when executing ToNumber(Get(src, "0")).
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
get 0() {
|
||||
return {
|
||||
valueOf() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
};
|
||||
},
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
let err = typedArray.length === 0 ? RangeError : ExpectedError;
|
||||
assert.throws(err, () => typedArray.set(source));
|
||||
}
|
||||
|
||||
// Side-effects when getting the source elements detach the buffer.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = Object.defineProperties([], {
|
||||
0: {
|
||||
get() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (typedArray.length === 0) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
typedArray.set(source);
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effects when getting the source elements detach the buffer. Also
|
||||
// ensure other elements are accessed.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let accessed = false;
|
||||
let source = Object.defineProperties([], {
|
||||
0: {
|
||||
get() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
1: {
|
||||
get() {
|
||||
assert.sameValue(accessed, false);
|
||||
accessed = true;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (typedArray.length <= 1) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
assert.sameValue(accessed, false);
|
||||
typedArray.set(source);
|
||||
assert.sameValue(accessed, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effects when converting the source elements detach the buffer.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = [{
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}];
|
||||
if (typedArray.length === 0) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
typedArray.set(source);
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effects when converting the source elements detach the buffer. Also
|
||||
// ensure other elements are accessed.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let accessed = false;
|
||||
let source = [{
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}, {
|
||||
valueOf() {
|
||||
assert.sameValue(accessed, false);
|
||||
accessed = true;
|
||||
return 2;
|
||||
}
|
||||
}];
|
||||
if (typedArray.length <= 1) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
assert.sameValue(accessed, false);
|
||||
typedArray.set(source);
|
||||
assert.sameValue(accessed, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test when target and source use the same underlying buffer and
|
||||
// ToInteger(offset) detaches the buffer. Test with:
|
||||
// - same typed array,
|
||||
// - different typed array, but same element type,
|
||||
// - and different element type.
|
||||
for (let src of [ta => ta, ta => new Int32Array(ta.buffer), ta => new Float32Array(ta.buffer)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = src(typedArray);
|
||||
assert.throws(TypeError, () => typedArray.set(source, {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Test when Get(src, "length") detaches the buffer, but srcLength is 0.
|
||||
// Also use different offsets to ensure bounds checks use the typed array's
|
||||
// length value from before detaching the buffer.
|
||||
for (let offset of [() => 0, ta => Math.min(1, ta.length), ta => Math.max(0, ta.length - 1)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
get length() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
typedArray.set(source, offset(typedArray));
|
||||
}
|
||||
}
|
||||
|
||||
// Test when ToLength(Get(src, "length")) detaches the buffer, but
|
||||
// srcLength is 0. Also use different offsets to ensure bounds checks use
|
||||
// the typed array's length value from before detaching the buffer.
|
||||
for (let offset of [() => 0, ta => Math.min(1, ta.length), ta => Math.max(0, ta.length - 1)]) {
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
typedArray.set(source, offset(typedArray));
|
||||
}
|
||||
}
|
||||
|
||||
// Test no TypeError is thrown when the typed array is detached and
|
||||
// srcLength > 0.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (typedArray.length === 0) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
typedArray.set(source);
|
||||
}
|
||||
}
|
||||
|
||||
// Same as above, but with side-effect when executing Get(src, "0").
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
get 0() {
|
||||
throw new ExpectedError();
|
||||
},
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
let err = typedArray.length === 0 ? RangeError : ExpectedError;
|
||||
assert.throws(err, () => typedArray.set(source));
|
||||
}
|
||||
|
||||
// Same as above, but with side-effect when executing ToNumber(Get(src, "0")).
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = {
|
||||
get 0() {
|
||||
return {
|
||||
valueOf() {
|
||||
throw new ExpectedError();
|
||||
}
|
||||
};
|
||||
},
|
||||
length: {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
let err = typedArray.length === 0 ? RangeError : ExpectedError;
|
||||
assert.throws(err, () => typedArray.set(source));
|
||||
}
|
||||
|
||||
// Side-effects when getting the source elements detach the buffer.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = Object.defineProperties([], {
|
||||
0: {
|
||||
get() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (typedArray.length === 0) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
typedArray.set(source);
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effects when getting the source elements detach the buffer. Also
|
||||
// ensure other elements are accessed.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let accessed = false;
|
||||
let source = Object.defineProperties([], {
|
||||
0: {
|
||||
get() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
1: {
|
||||
get() {
|
||||
assert.sameValue(accessed, false);
|
||||
accessed = true;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (typedArray.length <= 1) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
assert.sameValue(accessed, false);
|
||||
typedArray.set(source);
|
||||
assert.sameValue(accessed, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effects when converting the source elements detach the buffer.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let source = [{
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}];
|
||||
if (typedArray.length === 0) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
typedArray.set(source);
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effects when converting the source elements detach the buffer. Also
|
||||
// ensure other elements are accessed.
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
let accessed = false;
|
||||
let source = [{
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 1;
|
||||
}
|
||||
}, {
|
||||
valueOf() {
|
||||
assert.sameValue(accessed, false);
|
||||
accessed = true;
|
||||
return 2;
|
||||
}
|
||||
}];
|
||||
if (typedArray.length <= 1) {
|
||||
assert.throws(RangeError, () => typedArray.set(source));
|
||||
} else {
|
||||
assert.sameValue(accessed, false);
|
||||
typedArray.set(source);
|
||||
assert.sameValue(accessed, true);
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ for (var constructor of anyTypedArrayConstructors) {
|
||||
assert.sameValue(Object.hasOwn(receiver, 10), false);
|
||||
|
||||
// Detached
|
||||
if (typeof $262.detachArrayBuffer === "function" &&
|
||||
!isSharedConstructor(constructor))
|
||||
{
|
||||
if (!isSharedConstructor(constructor)) {
|
||||
$262.detachArrayBuffer(ta.buffer)
|
||||
|
||||
assert.sameValue(ta[0], undefined);
|
||||
|
@ -9,6 +9,7 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
|
||||
// Test %TypedArray%.prototype.set(typedArray, offset) when called with wrapped
|
||||
// typed array.
|
||||
|
||||
@ -35,53 +36,52 @@ for (var TA of anyTypedArrayConstructors) {
|
||||
}
|
||||
|
||||
// Detachment checks are also applied correctly for wrapped typed arrays.
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
// Create typed array from different global (explicit constructor call).
|
||||
for (var TA of typedArrayConstructors) {
|
||||
var target = new TA(4);
|
||||
var source = new otherGlobal[TA.name](1);
|
||||
taintLengthProperty(source);
|
||||
|
||||
// Called with wrapped typed array, array buffer already detached.
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
assert.throws(TypeError, () => target.set(source));
|
||||
// Create typed array from different global (explicit constructor call).
|
||||
for (var TA of typedArrayConstructors) {
|
||||
var target = new TA(4);
|
||||
var source = new otherGlobal[TA.name](1);
|
||||
taintLengthProperty(source);
|
||||
|
||||
var source = new otherGlobal[TA.name](1);
|
||||
taintLengthProperty(source);
|
||||
// Called with wrapped typed array, array buffer already detached.
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
assert.throws(TypeError, () => target.set(source));
|
||||
|
||||
// Called with wrapped typed array, array buffer detached when
|
||||
// processing offset parameter.
|
||||
var offset = {
|
||||
valueOf() {
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, () => target.set(source, offset));
|
||||
}
|
||||
var source = new otherGlobal[TA.name](1);
|
||||
taintLengthProperty(source);
|
||||
|
||||
// Create typed array from different global (implictly created when
|
||||
// ArrayBuffer is a CCW).
|
||||
for (var TA of typedArrayConstructors) {
|
||||
var target = new TA(4);
|
||||
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
||||
taintLengthProperty(source);
|
||||
|
||||
// Called with wrapped typed array, array buffer already detached.
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
assert.throws(TypeError, () => target.set(source));
|
||||
|
||||
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
||||
taintLengthProperty(source);
|
||||
|
||||
// Called with wrapped typed array, array buffer detached when
|
||||
// processing offset parameter.
|
||||
var offset = {
|
||||
valueOf() {
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, () => target.set(source, offset));
|
||||
}
|
||||
// Called with wrapped typed array, array buffer detached when
|
||||
// processing offset parameter.
|
||||
var offset = {
|
||||
valueOf() {
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, () => target.set(source, offset));
|
||||
}
|
||||
|
||||
// Create typed array from different global (implictly created when
|
||||
// ArrayBuffer is a CCW).
|
||||
for (var TA of typedArrayConstructors) {
|
||||
var target = new TA(4);
|
||||
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
||||
taintLengthProperty(source);
|
||||
|
||||
// Called with wrapped typed array, array buffer already detached.
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
assert.throws(TypeError, () => target.set(source));
|
||||
|
||||
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
||||
taintLengthProperty(source);
|
||||
|
||||
// Called with wrapped typed array, array buffer detached when
|
||||
// processing offset parameter.
|
||||
var offset = {
|
||||
valueOf() {
|
||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
assert.throws(TypeError, () => target.set(source, offset));
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
|
||||
// Tests for detached ArrayBuffer checks in %TypedArray%.prototype.slice ( start, end ).
|
||||
|
||||
function* createTypedArrays(lengths = [0, 1, 4, 4096]) {
|
||||
@ -27,85 +28,82 @@ function* createTypedArrays(lengths = [0, 1, 4, 4096]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
// ArrayBuffer is detached when entering slice().
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(0);
|
||||
}, "ArrayBuffer is detached on function entry");
|
||||
}
|
||||
|
||||
// ArrayBuffer is detached when computing ToInteger(start).
|
||||
for (let {typedArray, length, buffer} of createTypedArrays()) {
|
||||
let detached = false;
|
||||
let start = {
|
||||
valueOf() {
|
||||
assert.sameValue(detached, false);
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.sameValue(detached, false);
|
||||
detached = true;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Doesn't throw an error when no bytes are copied.
|
||||
if (length === 0) {
|
||||
typedArray.slice(start);
|
||||
} else {
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(start);
|
||||
}, "ArrayBuffer is detached in ToInteger(start)");
|
||||
}
|
||||
assert.sameValue(detached, true, "$262.detachArrayBuffer was called");
|
||||
}
|
||||
|
||||
// ArrayBuffer is detached when computing ToInteger(end).
|
||||
for (let {typedArray, length, buffer} of createTypedArrays()) {
|
||||
let detached = false;
|
||||
let end = {
|
||||
valueOf() {
|
||||
assert.sameValue(detached, false);
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.sameValue(detached, false);
|
||||
detached = true;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
// Doesn't throw an error when no bytes are copied.
|
||||
if (length === 0) {
|
||||
typedArray.slice(0, end);
|
||||
} else {
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(0, end);
|
||||
}, "ArrayBuffer is detached in ToInteger(end)");
|
||||
}
|
||||
assert.sameValue(detached, true, "$262.detachArrayBuffer was called");
|
||||
}
|
||||
|
||||
// ArrayBuffer is detached in species constructor.
|
||||
for (let {typedArray, length, buffer} of createTypedArrays()) {
|
||||
let detached = false;
|
||||
typedArray.constructor = {
|
||||
[Symbol.species]: function(...args) {
|
||||
assert.sameValue(detached, false);
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.sameValue(detached, false);
|
||||
detached = true;
|
||||
return new Int32Array(...args);
|
||||
}
|
||||
};
|
||||
|
||||
// Doesn't throw an error when no bytes are copied.
|
||||
if (length === 0) {
|
||||
typedArray.slice(0);
|
||||
} else {
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(0);
|
||||
}, "ArrayBuffer is detached in TypedArraySpeciesCreate(...)");
|
||||
}
|
||||
assert.sameValue(detached, true, "$262.detachArrayBuffer was called");
|
||||
}
|
||||
// ArrayBuffer is detached when entering slice().
|
||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(0);
|
||||
}, "ArrayBuffer is detached on function entry");
|
||||
}
|
||||
|
||||
// ArrayBuffer is detached when computing ToInteger(start).
|
||||
for (let {typedArray, length, buffer} of createTypedArrays()) {
|
||||
let detached = false;
|
||||
let start = {
|
||||
valueOf() {
|
||||
assert.sameValue(detached, false);
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.sameValue(detached, false);
|
||||
detached = true;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Doesn't throw an error when no bytes are copied.
|
||||
if (length === 0) {
|
||||
typedArray.slice(start);
|
||||
} else {
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(start);
|
||||
}, "ArrayBuffer is detached in ToInteger(start)");
|
||||
}
|
||||
assert.sameValue(detached, true, "$262.detachArrayBuffer was called");
|
||||
}
|
||||
|
||||
// ArrayBuffer is detached when computing ToInteger(end).
|
||||
for (let {typedArray, length, buffer} of createTypedArrays()) {
|
||||
let detached = false;
|
||||
let end = {
|
||||
valueOf() {
|
||||
assert.sameValue(detached, false);
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.sameValue(detached, false);
|
||||
detached = true;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
// Doesn't throw an error when no bytes are copied.
|
||||
if (length === 0) {
|
||||
typedArray.slice(0, end);
|
||||
} else {
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(0, end);
|
||||
}, "ArrayBuffer is detached in ToInteger(end)");
|
||||
}
|
||||
assert.sameValue(detached, true, "$262.detachArrayBuffer was called");
|
||||
}
|
||||
|
||||
// ArrayBuffer is detached in species constructor.
|
||||
for (let {typedArray, length, buffer} of createTypedArrays()) {
|
||||
let detached = false;
|
||||
typedArray.constructor = {
|
||||
[Symbol.species]: function(...args) {
|
||||
assert.sameValue(detached, false);
|
||||
$262.detachArrayBuffer(buffer());
|
||||
assert.sameValue(detached, false);
|
||||
detached = true;
|
||||
return new Int32Array(...args);
|
||||
}
|
||||
};
|
||||
|
||||
// Doesn't throw an error when no bytes are copied.
|
||||
if (length === 0) {
|
||||
typedArray.slice(0);
|
||||
} else {
|
||||
assert.throws(TypeError, () => {
|
||||
typedArray.slice(0);
|
||||
}, "ArrayBuffer is detached in TypedArraySpeciesCreate(...)");
|
||||
}
|
||||
assert.sameValue(detached, true, "$262.detachArrayBuffer was called");
|
||||
}
|
||||
|
@ -8,18 +8,17 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
|
||||
// Ensure that TypedArrays throw when attempting to sort a detached ArrayBuffer
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
assert.throws(TypeError, () => {
|
||||
let buffer = new ArrayBuffer(32);
|
||||
let array = new Int32Array(buffer);
|
||||
$262.detachArrayBuffer(buffer);
|
||||
array.sort();
|
||||
});
|
||||
}
|
||||
assert.throws(TypeError, () => {
|
||||
let buffer = new ArrayBuffer(32);
|
||||
let array = new Int32Array(buffer);
|
||||
$262.detachArrayBuffer(buffer);
|
||||
array.sort();
|
||||
});
|
||||
|
||||
// Ensure detaching buffer in comparator doesn't throw an error.
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
{
|
||||
let detached = false;
|
||||
let ta = new Int32Array(3);
|
||||
ta.sort(function(a, b) {
|
||||
@ -43,7 +42,7 @@ let otherGlobal = $262.createRealm().global;
|
||||
}
|
||||
|
||||
// Ensure detaching buffer in comparator doesn't throw an error when the typed array is wrapped.
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
{
|
||||
let detached = false;
|
||||
let ta = new Int32Array(3);
|
||||
otherGlobal.Int32Array.prototype.sort.call(ta, function(a,b) {
|
||||
|
@ -9,30 +9,27 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
// Bug 1291003
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
const elementSize = constructor.BYTES_PER_ELEMENT;
|
||||
|
||||
let targetOffset;
|
||||
let buffer = new ArrayBuffer(2 * elementSize);
|
||||
let typedArray = new constructor(buffer, 1 * elementSize, 1);
|
||||
typedArray.constructor = {
|
||||
[Symbol.species]: function(ab, offset, length) {
|
||||
targetOffset = offset;
|
||||
return new constructor(1);
|
||||
}
|
||||
};
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
const elementSize = constructor.BYTES_PER_ELEMENT;
|
||||
|
||||
let beginIndex = {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
typedArray.subarray(beginIndex);
|
||||
let targetOffset;
|
||||
let buffer = new ArrayBuffer(2 * elementSize);
|
||||
let typedArray = new constructor(buffer, 1 * elementSize, 1);
|
||||
typedArray.constructor = {
|
||||
[Symbol.species]: function(ab, offset, length) {
|
||||
targetOffset = offset;
|
||||
return new constructor(1);
|
||||
}
|
||||
};
|
||||
|
||||
assert.sameValue(targetOffset, 1 * elementSize);
|
||||
}
|
||||
let beginIndex = {
|
||||
valueOf() {
|
||||
$262.detachArrayBuffer(buffer);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
typedArray.subarray(beginIndex);
|
||||
|
||||
assert.sameValue(targetOffset, 1 * elementSize);
|
||||
}
|
||||
|
||||
|
@ -9,39 +9,37 @@ description: |
|
||||
pending
|
||||
esid: pending
|
||||
---*/
|
||||
if (typeof $262.detachArrayBuffer === "function") {
|
||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||
|
||||
// Throws if array buffer is detached.
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
let typedArray = new constructor(42);
|
||||
$262.detachArrayBuffer(typedArray.buffer);
|
||||
assert.throws(TypeError, () => typedArray.toLocaleString());
|
||||
}
|
||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||
|
||||
// Doesn't throw a TypeError if detached in Number.prototype.toLocaleString.
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
"use strict";
|
||||
if (!detached) {
|
||||
$262.detachArrayBuffer(typedArray.buffer);
|
||||
detached = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
// No error for single element arrays.
|
||||
let detached = false;
|
||||
let typedArray = new constructor(1);
|
||||
assert.sameValue(typedArray.toLocaleString(), "0");
|
||||
assert.sameValue(detached, true);
|
||||
|
||||
// And no error if more than one element is present.
|
||||
detached = false;
|
||||
typedArray = new constructor(2);
|
||||
assert.sameValue(typedArray.toLocaleString(), "0,");
|
||||
assert.sameValue(detached, true);
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
// Throws if array buffer is detached.
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
let typedArray = new constructor(42);
|
||||
$262.detachArrayBuffer(typedArray.buffer);
|
||||
assert.throws(TypeError, () => typedArray.toLocaleString());
|
||||
}
|
||||
|
||||
// Doesn't throw a TypeError if detached in Number.prototype.toLocaleString.
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
Number.prototype.toLocaleString = function() {
|
||||
"use strict";
|
||||
if (!detached) {
|
||||
$262.detachArrayBuffer(typedArray.buffer);
|
||||
detached = true;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
// No error for single element arrays.
|
||||
let detached = false;
|
||||
let typedArray = new constructor(1);
|
||||
assert.sameValue(typedArray.toLocaleString(), "0");
|
||||
assert.sameValue(detached, true);
|
||||
|
||||
// And no error if more than one element is present.
|
||||
detached = false;
|
||||
typedArray = new constructor(2);
|
||||
assert.sameValue(typedArray.toLocaleString(), "0,");
|
||||
assert.sameValue(detached, true);
|
||||
}
|
||||
Number.prototype.toLocaleString = originalNumberToLocaleString;
|
||||
|
Loading…
x
Reference in New Issue
Block a user