summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/extensions/sharedtypedarray.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/extensions/sharedtypedarray.js273
1 files changed, 273 insertions, 0 deletions
diff --git a/js/src/tests/non262/extensions/sharedtypedarray.js b/js/src/tests/non262/extensions/sharedtypedarray.js
new file mode 100644
index 0000000000..56187d29f5
--- /dev/null
+++ b/js/src/tests/non262/extensions/sharedtypedarray.js
@@ -0,0 +1,273 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/* -*- Mode: js2; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Minimal test cases. Note that on 64-bit a SharedArrayBuffer is
+// very expensive under these rules - a 4GB area is reserved for it.
+// So don't go allocating a ton of them.
+//
+// These tests cannot test that sharing works across workers. There
+// are or will be tests, in dom/workers, that do that.
+
+var b;
+
+function testSharedArrayBuffer() {
+ b = new SharedArrayBuffer("4096"); // Test string conversion, too
+ assertEq(b instanceof SharedArrayBuffer, true);
+ assertEq(b.byteLength, 4096);
+
+ b.fnord = "Hi there";
+ assertEq(b.fnord, "Hi there");
+
+ SharedArrayBuffer.prototype.abracadabra = "no wishing for wishes!";
+ assertEq(b.abracadabra, "no wishing for wishes!");
+
+ // SharedArrayBuffer is not a conversion operator, not even for instances of itself
+ assertThrowsInstanceOf(() => SharedArrayBuffer(b), TypeError);
+
+ // can't convert any other object either
+ assertThrowsInstanceOf(() => SharedArrayBuffer({}), TypeError);
+
+ // byteLength can be invoked as per normal, indirectly
+ assertEq(Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype,"byteLength").get.call(b), 4096);
+
+ // however byteLength is not generic
+ assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype,"byteLength").get.call({}), TypeError);
+
+}
+
+function testSharedTypedArray() {
+ var x1 = new Int8Array(b);
+ var x2 = new Int32Array(b);
+
+ assertEq(ArrayBuffer.isView(x1), true); // ArrayBuffer.isView() works even if the buffer is a SharedArrayBuffer
+ assertEq(ArrayBuffer.isView(x2), true);
+ assertEq(ArrayBuffer.isView({}), false);
+
+ assertEq(x1.buffer, b);
+ assertEq(x2.buffer, b);
+
+ assertEq(x1.byteLength, b.byteLength);
+ assertEq(x2.byteLength, b.byteLength);
+
+ assertEq(x1.byteOffset, 0);
+ assertEq(x2.byteOffset, 0);
+
+ assertEq(x1.length, b.byteLength);
+ assertEq(x2.length, b.byteLength / 4);
+
+ var x3 = new Int8Array(b, 20);
+ assertEq(x3.length, b.byteLength - 20);
+ assertEq(x3.byteOffset, 20);
+
+ var x3 = new Int32Array(b, 20, 10);
+ assertEq(x3.length, 10);
+ assertEq(x3.byteOffset, 20);
+
+ // Mismatched type
+ assertThrowsInstanceOf(() => Int8Array(x2), TypeError);
+
+ // Unconvertable object
+ assertThrowsInstanceOf(() => Int8Array({}), TypeError);
+
+ // negative start
+ assertThrowsInstanceOf(() => new Int8Array(b, -7), RangeError);
+
+ // not congruent mod element size
+ assertThrowsInstanceOf(() => new Int32Array(b, 3), RangeError);
+
+ // start out of range
+ assertThrowsInstanceOf(() => new Int32Array(b, 4104), RangeError);
+
+ // end out of range
+ assertThrowsInstanceOf(() => new Int32Array(b, 4092, 2), RangeError);
+
+ // Views alias the storage
+ x2[0] = -1;
+ assertEq(x1[0], -1);
+ x1[0] = 1;
+ x1[1] = 1;
+ x1[2] = 1;
+ x1[3] = 1;
+ assertEq(x2[0], 0x01010101);
+
+ assertEq(x2[5], 0);
+ x3[0] = -1;
+ assertEq(x2[5], -1);
+
+ // Out-of-range accesses yield undefined
+ assertEq(x2[1023], 0);
+ assertEq(x2[1024], undefined);
+ assertEq(x2[2047], undefined);
+}
+
+function testSharedTypedArrayMethods() {
+ var v = new Int32Array(b);
+ for ( var i=0 ; i < v.length ; i++ )
+ v[i] = i;
+
+ // Rudimentary tests - they don't test any boundary conditions
+
+ // subarray
+ var w = v.subarray(10, 20);
+ assertEq(w.length, 10);
+ for ( var i=0 ; i < w.length ; i++ )
+ assertEq(w[i], v[i+10]);
+ for ( var i=0 ; i < w.length ; i++ )
+ w[i] = -w[i];
+ for ( var i=0 ; i < w.length ; i++ )
+ assertEq(w[i], v[i+10]);
+
+ // copyWithin
+ for ( var i=0 ; i < v.length ; i++ )
+ v[i] = i;
+ v.copyWithin(10, 20, 30);
+ for ( var i=0 ; i < 10 ; i++ )
+ assertEq(v[i], i);
+ for ( var i=10 ; i < 20 ; i++ )
+ assertEq(v[i], v[i+10]);
+
+ // set
+ for ( var i=0 ; i < v.length ; i++ )
+ v[i] = i;
+ v.set([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10], 5);
+ for ( var i=5 ; i < 15 ; i++ )
+ assertEq(v[i], -i+4);
+
+ // In the following two cases the two arrays will reference the same buffer,
+ // so there will be an overlapping copy.
+ //
+ // Case 1: Read from lower indices than are written
+ v.set(v.subarray(0, 7), 1);
+ assertEq(v[0], 0);
+ assertEq(v[1], 0);
+ assertEq(v[2], 1);
+ assertEq(v[3], 2);
+ assertEq(v[4], 3);
+ assertEq(v[5], 4);
+ assertEq(v[6], -1);
+ assertEq(v[7], -2);
+ assertEq(v[8], -4);
+ assertEq(v[9], -5);
+
+ // Case 2: Read from higher indices than are written
+ v.set(v.subarray(1, 5), 0);
+ assertEq(v[0], 0);
+ assertEq(v[1], 1);
+ assertEq(v[2], 2);
+ assertEq(v[3], 3);
+ assertEq(v[4], 3);
+ assertEq(v[5], 4);
+ assertEq(v[6], -1);
+ assertEq(v[7], -2);
+ assertEq(v[8], -4);
+ assertEq(v[9], -5);
+}
+
+function testClone1() {
+ var sab1 = b;
+ var blob = serialize(sab1, [], {SharedArrayBuffer: 'allow'});
+ var sab2 = deserialize(blob, {SharedArrayBuffer: 'allow'});
+ if (typeof sharedAddress != "undefined")
+ assertEq(sharedAddress(sab1), sharedAddress(sab2));
+}
+
+function testClone2() {
+ var sab = b;
+ var ia1 = new Int32Array(sab);
+ var blob = serialize(ia1, [], {SharedArrayBuffer: 'allow'});
+ var ia2 = deserialize(blob, {SharedArrayBuffer: 'allow'});
+ assertEq(ia1.length, ia2.length);
+ assertEq(ia1.buffer instanceof SharedArrayBuffer, true);
+ if (typeof sharedAddress != "undefined")
+ assertEq(sharedAddress(ia1.buffer), sharedAddress(ia2.buffer));
+ ia1[10] = 37;
+ assertEq(ia2[10], 37);
+}
+
+// Serializing a SharedArrayBuffer should fail if we've set its flag to 'deny' or if
+// the flag is bogus or if the flag is not set to 'allow' explicitly
+
+function testNoClone() {
+ // This just tests the API in serialize()
+ assertThrowsInstanceOf(() => serialize(b, [], {SharedArrayBuffer: false}), Error);
+
+ // This tests the actual cloning functionality - should fail
+ assertThrowsInstanceOf(() => serialize(b, [], {SharedArrayBuffer: 'deny'}), TypeError);
+
+ // This tests that cloning a SharedArrayBuffer is not allowed by default
+ assertThrowsInstanceOf(() => serialize(b), TypeError);
+
+ // Ditto - should succeed
+ assertEq(typeof serialize(b, [], {SharedArrayBuffer: 'allow'}), "object");
+
+ let blob = serialize(b, [], {SharedArrayBuffer: 'allow'});
+ // This just tests the API in deserialize()
+ assertThrowsInstanceOf(() => deserialize(blob, {SharedArrayBuffer: false}), Error);
+
+ // This tests the actual cloning functionality - should fail
+ assertThrowsInstanceOf(() => deserialize(blob, {SharedArrayBuffer: 'deny'}), TypeError);
+
+ // This tests that cloning a SharedArrayBuffer is not allowed by default
+ assertThrowsInstanceOf(() => deserialize(blob), TypeError);
+
+ // Ditto - should succeed
+ assertEq(typeof deserialize(blob, {SharedArrayBuffer: 'allow'}), "object");
+}
+
+function testRedundantTransfer() {
+ // Throws TypeError in the shell, DataCloneError in the browser.
+ assertThrowsInstanceOf(() => {
+ var sab1 = b;
+ var blob = serialize(sab1, [sab1], {SharedArrayBuffer: 'allow'});
+ }, TypeError);
+}
+
+function testApplicable() {
+ var sab = b;
+ var x;
+
+ // Just make sure we can create all the view types on shared memory.
+
+ x = new Int32Array(sab);
+ assertEq(x.length, sab.byteLength / Int32Array.BYTES_PER_ELEMENT);
+ x = new Uint32Array(sab);
+ assertEq(x.length, sab.byteLength / Uint32Array.BYTES_PER_ELEMENT);
+
+ x = new Int16Array(sab);
+ assertEq(x.length, sab.byteLength / Int16Array.BYTES_PER_ELEMENT);
+ x = new Uint16Array(sab);
+ assertEq(x.length, sab.byteLength / Uint16Array.BYTES_PER_ELEMENT);
+
+ x = new Int8Array(sab);
+ assertEq(x.length, sab.byteLength / Int8Array.BYTES_PER_ELEMENT);
+ x = new Uint8Array(sab);
+ assertEq(x.length, sab.byteLength / Uint8Array.BYTES_PER_ELEMENT);
+
+ // Though the atomic operations are illegal on Uint8ClampedArray and the
+ // float arrays, they can still be used to create views on shared memory.
+
+ x = new Uint8ClampedArray(sab);
+ assertEq(x.length, sab.byteLength / Uint8ClampedArray.BYTES_PER_ELEMENT);
+
+ x = new Float32Array(sab);
+ assertEq(x.length, sab.byteLength / Float32Array.BYTES_PER_ELEMENT);
+ x = new Float64Array(sab);
+ assertEq(x.length, sab.byteLength / Float64Array.BYTES_PER_ELEMENT);
+}
+
+if (this.SharedArrayBuffer) {
+ testSharedArrayBuffer();
+ testSharedTypedArray();
+ testSharedTypedArrayMethods();
+ testClone1();
+ testClone2();
+ testNoClone();
+ testRedundantTransfer();
+ testApplicable();
+}
+
+reportCompare(0, 0, 'ok');