summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/TypedArray/test-integrity-level-detached.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/TypedArray/test-integrity-level-detached.js104
1 files changed, 104 insertions, 0 deletions
diff --git a/js/src/tests/non262/TypedArray/test-integrity-level-detached.js b/js/src/tests/non262/TypedArray/test-integrity-level-detached.js
new file mode 100644
index 0000000000..68f772de61
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/test-integrity-level-detached.js
@@ -0,0 +1,104 @@
+const EMPTY = 0;
+const INLINE_STORAGE = 10;
+const NON_INLINE_STORAGE = 1024;
+
+class DetachedInt32Array extends Int32Array {
+ constructor(...args) {
+ super(...args);
+ detachArrayBuffer(this.buffer);
+ }
+}
+
+function throwsTypeError(fn) {
+ try {
+ fn();
+ } catch (e) {
+ assertEq(e instanceof TypeError, true);
+ return true;
+ }
+ return false;
+}
+
+// Non-standard: Accessing elements of detached array buffers should throw, but
+// this is currently not implemented.
+const ACCESS_ON_DETACHED_ARRAY_BUFFER_THROWS = (() => {
+ let ta = new DetachedInt32Array(10);
+ let throws = throwsTypeError(() => ta[0]);
+ // Ensure [[Get]] and [[GetOwnProperty]] return consistent results.
+ assertEq(throwsTypeError(() => Object.getOwnPropertyDescriptor(ta, 0)), throws);
+ return throws;
+})();
+
+function maybeThrowOnDetached(fn, returnValue) {
+ if (ACCESS_ON_DETACHED_ARRAY_BUFFER_THROWS) {
+ assertThrowsInstanceOf(fn, TypeError);
+ return returnValue;
+ }
+ return fn();
+}
+
+// Empty typed arrays can be sealed.
+{
+ let ta = new DetachedInt32Array(EMPTY);
+ Object.seal(ta);
+
+ assertEq(Object.isExtensible(ta), false);
+ assertEq(Object.isSealed(ta), true);
+ assertEq(Object.isFrozen(ta), true);
+}
+
+// Non-empty typed arrays can be sealed, but calling TestIntegrityLevel will
+// throw on detached typed arrays.
+for (let length of [INLINE_STORAGE, NON_INLINE_STORAGE]) {
+ let ta = new DetachedInt32Array(length);
+ Object.seal(ta);
+
+ assertEq(Object.isExtensible(ta), false);
+ assertEq(maybeThrowOnDetached(() => Object.isSealed(ta), true), true);
+ assertEq(maybeThrowOnDetached(() => Object.isFrozen(ta), true), true);
+}
+
+// Empty typed arrays can be frozen.
+{
+ let ta = new DetachedInt32Array(EMPTY);
+ Object.freeze(ta);
+
+ assertEq(Object.isExtensible(ta), false);
+ assertEq(Object.isSealed(ta), true);
+ assertEq(Object.isFrozen(ta), true);
+}
+
+// Non-empty typed arrays cannot be frozen.
+for (let length of [INLINE_STORAGE, NON_INLINE_STORAGE]) {
+ let ta = new DetachedInt32Array(length);
+ maybeThrowOnDetached(() => Object.freeze(ta));
+
+ assertEq(Object.isExtensible(ta), false);
+ assertEq(maybeThrowOnDetached(() => Object.isSealed(ta), true), true);
+ assertEq(maybeThrowOnDetached(() => Object.isFrozen(ta), true), true);
+}
+
+// Non-extensible empty typed arrays are sealed and frozen.
+{
+ let ta = new DetachedInt32Array(EMPTY);
+ Object.preventExtensions(ta);
+
+ assertEq(Object.isExtensible(ta), false);
+ assertEq(Object.isSealed(ta), true);
+ assertEq(Object.isFrozen(ta), true);
+}
+
+// Calling TestIntegrityLevel will throw on detached typed arrays with non-zero
+// length.
+for (let length of [INLINE_STORAGE, NON_INLINE_STORAGE]) {
+ let ta = new DetachedInt32Array(length);
+ Object.preventExtensions(ta);
+
+ assertEq(Object.isExtensible(ta), false);
+ assertEq(maybeThrowOnDetached(() => Object.isSealed(ta), true), true);
+ assertEq(maybeThrowOnDetached(() => Object.isFrozen(ta), true), true);
+}
+
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);