summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/TypedArray/constructor-buffer-sequence.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/TypedArray/constructor-buffer-sequence.js230
1 files changed, 230 insertions, 0 deletions
diff --git a/js/src/tests/non262/TypedArray/constructor-buffer-sequence.js b/js/src/tests/non262/TypedArray/constructor-buffer-sequence.js
new file mode 100644
index 0000000000..d69478344d
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/constructor-buffer-sequence.js
@@ -0,0 +1,230 @@
+// 22.2.4.5 TypedArray ( buffer [ , byteOffset [ , length ] ] )
+
+// Ensure the various error conditions are tested in the correct order.
+
+const otherGlobal = newGlobal();
+
+function* createBuffers(lengths = [0, 8]) {
+ for (let length of lengths) {
+ let buffer = new ArrayBuffer(length);
+ yield {buffer, detach: () => detachArrayBuffer(buffer)};
+ }
+
+ for (let length of lengths) {
+ let buffer = new otherGlobal.ArrayBuffer(length);
+ yield {buffer, detach: () => otherGlobal.detachArrayBuffer(buffer)};
+ }
+}
+
+const poisonedValue = new Proxy({}, new Proxy({}, {
+ get() {
+ // Throws an exception when any proxy trap is invoked.
+ throw new Error("Poisoned Value");
+ }
+}));
+
+class ExpectedError extends Error { }
+
+function ConstructorWithThrowingPrototype(detach) {
+ return Object.defineProperty(function(){}.bind(null), "prototype", {
+ get() {
+ if (detach)
+ detach();
+ throw new ExpectedError();
+ }
+ });
+}
+
+function ValueThrowing(detach) {
+ return {
+ valueOf() {
+ if (detach)
+ detach();
+ throw new ExpectedError();
+ }
+ };
+}
+
+function ValueReturning(value, detach) {
+ return {
+ valueOf() {
+ if (detach)
+ detach();
+ return value;
+ }
+ };
+}
+
+// Ensure step 4 |AllocateTypedArray| is executed before step 6 |ToIndex(byteOffset)|.
+for (let {buffer} of createBuffers()) {
+ let constructor = ConstructorWithThrowingPrototype();
+
+ assertThrowsInstanceOf(() =>
+ Reflect.construct(Int32Array, [buffer, poisonedValue, 0], constructor), ExpectedError);
+}
+
+// Ensure step 4 |AllocateTypedArray| is executed before step 9 |IsDetachedBuffer(buffer)|.
+for (let {buffer, detach} of createBuffers()) {
+ let constructor = ConstructorWithThrowingPrototype();
+
+ detach();
+ assertThrowsInstanceOf(() =>
+ Reflect.construct(Int32Array, [buffer, 0, 0], constructor), ExpectedError);
+}
+
+// Ensure step 4 |AllocateTypedArray| is executed before step 9 |IsDetachedBuffer(buffer)|.
+// - Variant: Detach buffer dynamically.
+for (let {buffer, detach} of createBuffers()) {
+ let constructor = ConstructorWithThrowingPrototype(detach);
+
+ assertThrowsInstanceOf(() =>
+ Reflect.construct(Int32Array, [buffer, 0, 0], constructor), ExpectedError);
+}
+
+// Ensure step 4 |AllocateTypedArray| is executed before step 8.a |ToIndex(length)|.
+for (let {buffer} of createBuffers()) {
+ let constructor = ConstructorWithThrowingPrototype();
+
+ assertThrowsInstanceOf(() =>
+ Reflect.construct(Int32Array, [buffer, 0, poisonedValue], constructor), ExpectedError);
+}
+
+// Ensure step 6 |ToIndex(byteOffset)| is executed before step 9 |IsDetachedBuffer(buffer)|.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = ValueThrowing();
+
+ detach();
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, 0), ExpectedError);
+}
+
+// Ensure step 6 |ToIndex(byteOffset)| is executed before step 9 |IsDetachedBuffer(buffer)|.
+// - Variant: Detach buffer dynamically.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = ValueThrowing(detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, 0), ExpectedError);
+}
+
+// Ensure step 6 |ToIndex(byteOffset)| is executed before step 8.a |ToIndex(length)|.
+for (let {buffer} of createBuffers()) {
+ let byteOffset = ValueThrowing();
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, poisonedValue), ExpectedError);
+}
+
+// Ensure step 7 |offset modulo elementSize ≠ 0| is executed before step 9 |IsDetachedBuffer(buffer)|.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 1;
+
+ detach();
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, 0), RangeError);
+}
+
+// Ensure step 7 |offset modulo elementSize ≠ 0| is executed before step 9 |IsDetachedBuffer(buffer)|.
+// - Variant: Detach buffer dynamically.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = ValueReturning(1, detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, 0), RangeError);
+}
+
+// Ensure step 7 |offset modulo elementSize ≠ 0| is executed before step 8.a |ToIndex(length)|.
+for (let {buffer} of createBuffers()) {
+ assertThrowsInstanceOf(() => new Int32Array(buffer, 1, poisonedValue), RangeError);
+}
+
+// Ensure step 8.a |ToIndex(length)| is executed before step 9 |IsDetachedBuffer(buffer)|.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 0;
+ let length = ValueThrowing();
+
+ detach();
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), ExpectedError);
+}
+
+// Ensure step 8.a |ToIndex(length)| is executed before step 9 |IsDetachedBuffer(buffer)|.
+// - Variant: Detach buffer dynamically (1).
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = ValueReturning(0, detach);
+ let length = ValueThrowing();
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), ExpectedError);
+}
+
+// Ensure step 8.a |ToIndex(length)| is executed before step 9 |IsDetachedBuffer(buffer)|.
+// - Variant: Detach buffer dynamically (2).
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 0;
+ let length = ValueThrowing(detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), ExpectedError);
+}
+
+// Ensure step 9 |IsDetachedBuffer(buffer)| is executed before step 11.a |bufferByteLength modulo elementSize ≠ 0|.
+for (let {buffer, detach} of createBuffers([1, 9])) {
+ let byteOffset = 0;
+
+ detach();
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset), TypeError);
+}
+
+// Ensure step 9 |IsDetachedBuffer(buffer)| is executed before step 11.a |bufferByteLength modulo elementSize ≠ 0|.
+// - Variant: Detach buffer dynamically.
+for (let {buffer, detach} of createBuffers([1, 9])) {
+ let byteOffset = ValueReturning(0, detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset), TypeError);
+}
+
+// Ensure step 9 |IsDetachedBuffer(buffer)| is executed before step 11.c |newByteLength < 0|.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 64;
+
+ detach();
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset), TypeError);
+}
+
+// Ensure step 9 |IsDetachedBuffer(buffer)| is executed before step 11.c |newByteLength < 0|.
+// - Variant: Detach buffer dynamically.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = ValueReturning(64, detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset), TypeError);
+}
+
+// Ensure step 9 |IsDetachedBuffer(buffer)| is executed before step 12.b |offset+newByteLength > bufferByteLength|.
+// - Case A: The given byteOffset is too large.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 64;
+ let length = ValueReturning(0, detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), TypeError);
+}
+
+// Ensure step 9 |IsDetachedBuffer(buffer)| is executed before step 12.b |offset+newByteLength > bufferByteLength|.
+// - Case B: The given length is too large.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 0;
+ let length = ValueReturning(64, detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), TypeError);
+}
+
+// Ensure we handle the case when ToIndex(byteOffset) detaches the array buffer.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = ValueReturning(0, detach);
+ let length = 0;
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), TypeError);
+}
+
+// Ensure we handle the case when ToIndex(length) detaches the array buffer.
+for (let {buffer, detach} of createBuffers()) {
+ let byteOffset = 0;
+ let length = ValueReturning(0, detach);
+
+ assertThrowsInstanceOf(() => new Int32Array(buffer, byteOffset, length), TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);