mirror of
https://github.com/tc39/test262.git
synced 2025-09-26 03:28:50 +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
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
var buffer = new ArrayBuffer(2);
|
var buffer = new ArrayBuffer(2);
|
||||||
var view = new DataView(buffer);
|
var view = new DataView(buffer);
|
||||||
|
|
||||||
@ -30,16 +31,13 @@ for (let fun of ['getInt8', 'getInt16']) {
|
|||||||
assert.sameValue(view[fun](NaN), 0);
|
assert.sameValue(view[fun](NaN), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('$262.detachArrayBuffer' in this) {
|
// ToIndex is called before detachment check, so we can tell the difference
|
||||||
// ToIndex is called before detachment check, so we can tell the difference
|
// between a ToIndex failure and a real out of bounds failure.
|
||||||
// between a ToIndex failure and a real out of bounds failure.
|
$262.detachArrayBuffer(buffer);
|
||||||
$262.detachArrayBuffer(buffer);
|
|
||||||
|
|
||||||
check(view);
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function checkResult(actual, expected)
|
function checkResult(actual, expected)
|
||||||
{
|
{
|
||||||
assert.sameValue(actual.value, expected.value);
|
assert.sameValue(actual.value, expected.value);
|
||||||
assert.sameValue(actual.done, expected.done);
|
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;
|
for (const [arrayGlobal, bufferGlobal] of globals)
|
||||||
var otherGlobal = $262.createRealm().global;
|
|
||||||
|
|
||||||
var thisNext = new Uint8Array()[Symbol.iterator]().next
|
|
||||||
|
|
||||||
for (const constructor of typedArrayConstructors)
|
|
||||||
{
|
{
|
||||||
assert.sameValue(new constructor()[Symbol.iterator]().next, thisNext);
|
var arr, buffer, iterator;
|
||||||
|
|
||||||
var globals =
|
function arrayBufferIterator()
|
||||||
[
|
|
||||||
[thisGlobal, thisGlobal],
|
|
||||||
[thisGlobal, otherGlobal],
|
|
||||||
[otherGlobal, otherGlobal],
|
|
||||||
[otherGlobal, thisGlobal],
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const [arrayGlobal, bufferGlobal] of globals)
|
|
||||||
{
|
{
|
||||||
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()
|
tarray[0] = 1;
|
||||||
{
|
tarray[1] = 2;
|
||||||
var byteLength = 2 * constructor.BYTES_PER_ELEMENT;
|
|
||||||
var buf = new bufferGlobal.ArrayBuffer(byteLength);
|
|
||||||
var tarray = new arrayGlobal[constructor.name](buf);
|
|
||||||
|
|
||||||
tarray[0] = 1;
|
return [tarray, buf, Reflect.apply(iteratorFunction, tarray, [])];
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[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
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Tests for detached ArrayBuffer checks in %TypedArray%.prototype.set(array|typedArray, offset).
|
// Tests for detached ArrayBuffer checks in %TypedArray%.prototype.set(array|typedArray, offset).
|
||||||
|
|
||||||
function* createTypedArrays(lengths = [0, 1, 4, 4096]) {
|
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.
|
// No detached check on function entry.
|
||||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||||
$262.detachArrayBuffer(buffer);
|
$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() {
|
valueOf() {
|
||||||
throw new ExpectedError();
|
throw new ExpectedError();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for detached buffer after calling ToInteger(offset). Test with:
|
// Check when detaching source buffer in ToInteger(offset). Test with:
|
||||||
// - valid offset,
|
// - valid offset,
|
||||||
// - too large offset,
|
// - too large offset,
|
||||||
// - and negative offset.
|
// - and negative offset.
|
||||||
for (let [offset, error] of [[0, TypeError], [1000000, TypeError], [-1, RangeError]]) {
|
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} of createTypedArrays()) {
|
||||||
for (let {typedArray: source, buffer: sourceBuffer} of createTypedArrays()) {
|
for (let {typedArray: source, buffer: sourceBuffer} of createTypedArrays()) {
|
||||||
$262.detachArrayBuffer(sourceBuffer);
|
assert.throws(error, () => typedArray.set(source, {
|
||||||
|
|
||||||
assert.throws(ExpectedError, () => typedArray.set(source, {
|
|
||||||
valueOf() {
|
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);
|
assert.sameValue(Object.hasOwn(receiver, 10), false);
|
||||||
|
|
||||||
// Detached
|
// Detached
|
||||||
if (typeof $262.detachArrayBuffer === "function" &&
|
if (!isSharedConstructor(constructor)) {
|
||||||
!isSharedConstructor(constructor))
|
|
||||||
{
|
|
||||||
$262.detachArrayBuffer(ta.buffer)
|
$262.detachArrayBuffer(ta.buffer)
|
||||||
|
|
||||||
assert.sameValue(ta[0], undefined);
|
assert.sameValue(ta[0], undefined);
|
||||||
|
@ -9,6 +9,7 @@ description: |
|
|||||||
pending
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Test %TypedArray%.prototype.set(typedArray, offset) when called with wrapped
|
// Test %TypedArray%.prototype.set(typedArray, offset) when called with wrapped
|
||||||
// typed array.
|
// typed array.
|
||||||
|
|
||||||
@ -35,53 +36,52 @@ for (var TA of anyTypedArrayConstructors) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Detachment checks are also applied correctly for wrapped typed arrays.
|
// 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.
|
// Create typed array from different global (explicit constructor call).
|
||||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
for (var TA of typedArrayConstructors) {
|
||||||
assert.throws(TypeError, () => target.set(source));
|
var target = new TA(4);
|
||||||
|
var source = new otherGlobal[TA.name](1);
|
||||||
|
taintLengthProperty(source);
|
||||||
|
|
||||||
var source = new otherGlobal[TA.name](1);
|
// Called with wrapped typed array, array buffer already detached.
|
||||||
taintLengthProperty(source);
|
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||||
|
assert.throws(TypeError, () => target.set(source));
|
||||||
|
|
||||||
// Called with wrapped typed array, array buffer detached when
|
var source = new otherGlobal[TA.name](1);
|
||||||
// processing offset parameter.
|
taintLengthProperty(source);
|
||||||
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
|
// Called with wrapped typed array, array buffer detached when
|
||||||
// ArrayBuffer is a CCW).
|
// processing offset parameter.
|
||||||
for (var TA of typedArrayConstructors) {
|
var offset = {
|
||||||
var target = new TA(4);
|
valueOf() {
|
||||||
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||||
taintLengthProperty(source);
|
return 0;
|
||||||
|
}
|
||||||
// Called with wrapped typed array, array buffer already detached.
|
};
|
||||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
assert.throws(TypeError, () => target.set(source, offset));
|
||||||
assert.throws(TypeError, () => target.set(source));
|
}
|
||||||
|
|
||||||
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
// Create typed array from different global (implictly created when
|
||||||
taintLengthProperty(source);
|
// ArrayBuffer is a CCW).
|
||||||
|
for (var TA of typedArrayConstructors) {
|
||||||
// Called with wrapped typed array, array buffer detached when
|
var target = new TA(4);
|
||||||
// processing offset parameter.
|
var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
|
||||||
var offset = {
|
taintLengthProperty(source);
|
||||||
valueOf() {
|
|
||||||
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
// Called with wrapped typed array, array buffer already detached.
|
||||||
return 0;
|
otherGlobal.$262.detachArrayBuffer(source.buffer);
|
||||||
}
|
assert.throws(TypeError, () => target.set(source));
|
||||||
};
|
|
||||||
assert.throws(TypeError, () => target.set(source, offset));
|
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
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Tests for detached ArrayBuffer checks in %TypedArray%.prototype.slice ( start, end ).
|
// Tests for detached ArrayBuffer checks in %TypedArray%.prototype.slice ( start, end ).
|
||||||
|
|
||||||
function* createTypedArrays(lengths = [0, 1, 4, 4096]) {
|
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().
|
||||||
// ArrayBuffer is detached when entering slice().
|
for (let {typedArray, buffer} of createTypedArrays()) {
|
||||||
for (let {typedArray, buffer} of createTypedArrays()) {
|
$262.detachArrayBuffer(buffer());
|
||||||
$262.detachArrayBuffer(buffer());
|
assert.throws(TypeError, () => {
|
||||||
assert.throws(TypeError, () => {
|
typedArray.slice(0);
|
||||||
typedArray.slice(0);
|
}, "ArrayBuffer is detached on function entry");
|
||||||
}, "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 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
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Ensure that TypedArrays throw when attempting to sort a detached ArrayBuffer
|
// Ensure that TypedArrays throw when attempting to sort a detached ArrayBuffer
|
||||||
if (typeof $262.detachArrayBuffer === "function") {
|
assert.throws(TypeError, () => {
|
||||||
assert.throws(TypeError, () => {
|
let buffer = new ArrayBuffer(32);
|
||||||
let buffer = new ArrayBuffer(32);
|
let array = new Int32Array(buffer);
|
||||||
let array = new Int32Array(buffer);
|
$262.detachArrayBuffer(buffer);
|
||||||
$262.detachArrayBuffer(buffer);
|
array.sort();
|
||||||
array.sort();
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure detaching buffer in comparator doesn't throw an error.
|
// Ensure detaching buffer in comparator doesn't throw an error.
|
||||||
if (typeof $262.detachArrayBuffer === "function") {
|
{
|
||||||
let detached = false;
|
let detached = false;
|
||||||
let ta = new Int32Array(3);
|
let ta = new Int32Array(3);
|
||||||
ta.sort(function(a, b) {
|
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.
|
// 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 detached = false;
|
||||||
let ta = new Int32Array(3);
|
let ta = new Int32Array(3);
|
||||||
otherGlobal.Int32Array.prototype.sort.call(ta, function(a,b) {
|
otherGlobal.Int32Array.prototype.sort.call(ta, function(a,b) {
|
||||||
|
@ -9,30 +9,27 @@ description: |
|
|||||||
pending
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
// Bug 1291003
|
|
||||||
if (typeof $262.detachArrayBuffer === "function") {
|
|
||||||
for (let constructor of typedArrayConstructors) {
|
|
||||||
const elementSize = constructor.BYTES_PER_ELEMENT;
|
|
||||||
|
|
||||||
let targetOffset;
|
for (let constructor of typedArrayConstructors) {
|
||||||
let buffer = new ArrayBuffer(2 * elementSize);
|
const elementSize = constructor.BYTES_PER_ELEMENT;
|
||||||
let typedArray = new constructor(buffer, 1 * elementSize, 1);
|
|
||||||
typedArray.constructor = {
|
|
||||||
[Symbol.species]: function(ab, offset, length) {
|
|
||||||
targetOffset = offset;
|
|
||||||
return new constructor(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let beginIndex = {
|
let targetOffset;
|
||||||
valueOf() {
|
let buffer = new ArrayBuffer(2 * elementSize);
|
||||||
$262.detachArrayBuffer(buffer);
|
let typedArray = new constructor(buffer, 1 * elementSize, 1);
|
||||||
return 0;
|
typedArray.constructor = {
|
||||||
}
|
[Symbol.species]: function(ab, offset, length) {
|
||||||
};
|
targetOffset = offset;
|
||||||
typedArray.subarray(beginIndex);
|
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
|
pending
|
||||||
esid: pending
|
esid: pending
|
||||||
---*/
|
---*/
|
||||||
if (typeof $262.detachArrayBuffer === "function") {
|
|
||||||
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
|
||||||
|
|
||||||
// Throws if array buffer is detached.
|
const originalNumberToLocaleString = Number.prototype.toLocaleString;
|
||||||
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.
|
// Throws if array buffer is detached.
|
||||||
for (let constructor of typedArrayConstructors) {
|
for (let constructor of typedArrayConstructors) {
|
||||||
Number.prototype.toLocaleString = function() {
|
let typedArray = new constructor(42);
|
||||||
"use strict";
|
$262.detachArrayBuffer(typedArray.buffer);
|
||||||
if (!detached) {
|
assert.throws(TypeError, () => typedArray.toLocaleString());
|
||||||
$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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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