summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/TypedArray/sort-negative-nan.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/TypedArray/sort-negative-nan.js106
1 files changed, 106 insertions, 0 deletions
diff --git a/js/src/tests/non262/TypedArray/sort-negative-nan.js b/js/src/tests/non262/TypedArray/sort-negative-nan.js
new file mode 100644
index 0000000000..cf9a67714b
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/sort-negative-nan.js
@@ -0,0 +1,106 @@
+// Test with all floating point typed arrays.
+const floatConstructors = anyTypedArrayConstructors.filter(isFloatConstructor);
+
+// Also test with cross-compartment wrapped typed arrays.
+if (typeof newGlobal === "function") {
+ const otherGlobal = newGlobal();
+ floatConstructors.push(otherGlobal.Float32Array);
+ floatConstructors.push(otherGlobal.Float64Array);
+}
+
+function* prod(xs, ys) {
+ for (let x of xs) {
+ for (let y of ys) {
+ yield [x, y];
+ }
+ }
+}
+
+const isLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] !== 0;
+
+function seti32(i32, i, v) {
+ i32[i] = v;
+}
+
+function seti64(i32, i, [hi, lo]) {
+ i32[i * 2 + isLittleEndian] = hi;
+ i32[i * 2 + !isLittleEndian] = lo;
+}
+
+const setInt = {
+ Float32: seti32,
+ Float64: seti64,
+};
+
+const NaNs = {
+ Float32: [
+ 0x7F800001|0, // smallest SNaN
+ 0x7FBFFFFF|0, // largest SNaN
+ 0x7FC00000|0, // smallest QNaN
+ 0x7FFFFFFF|0, // largest QNaN
+ 0xFF800001|0, // smallest SNaN, sign-bit set
+ 0xFFBFFFFF|0, // largest SNaN, sign-bit set
+ 0xFFC00000|0, // smallest QNaN, sign-bit set
+ 0xFFFFFFFF|0, // largest QNaN, sign-bit set
+ ],
+ Float64: [
+ [0x7FF00000|0, 0x00000001|0], // smallest SNaN
+ [0x7FF7FFFF|0, 0xFFFFFFFF|0], // largest SNaN
+ [0x7FF80000|0, 0x00000000|0], // smallest QNaN
+ [0x7FFFFFFF|0, 0xFFFFFFFF|0], // largest QNaN
+ [0xFFF00000|0, 0x00000001|0], // smallest SNaN, sign-bit set
+ [0xFFF7FFFF|0, 0xFFFFFFFF|0], // largest SNaN, sign-bit set
+ [0xFFF80000|0, 0x00000000|0], // smallest QNaN, sign-bit set
+ [0xFFFFFFFF|0, 0xFFFFFFFF|0], // largest QNaN, sign-bit set
+ ],
+};
+
+// %TypedArray%.prototype.sort
+const TypedArraySort = Int32Array.prototype.sort;
+
+// Test with small and large typed arrays.
+const typedArrayLengths = [16, 4096];
+
+for (const [TA, taLength] of prod(floatConstructors, typedArrayLengths)) {
+ let type = TA.name.slice(0, -"Array".length);
+ let nansLength = NaNs[type].length;
+ let fta = new TA(taLength);
+ let i32 = new Int32Array(fta.buffer);
+
+ // Add NaNs in various representations at the start of the typed array.
+ for (let i = 0; i < nansLength; ++i) {
+ setInt[type](i32, i, NaNs[type][i]);
+ }
+
+ // Also add two non-NaN values for testing.
+ fta[nansLength] = 123;
+ fta[nansLength + 1] = -456;
+
+ // Sort the array and validate sort() sorted all elements correctly.
+ TypedArraySort.call(fta);
+
+ // |-456| should be sorted to the start.
+ assertEq(fta[0], -456);
+
+ // Followed by a bunch of zeros,
+ const zeroOffset = 1;
+ const zeroCount = taLength - nansLength - 2;
+ for (let i = 0; i < zeroCount; ++i) {
+ assertEq(fta[zeroOffset + i], 0, `At offset: ${zeroOffset + i}`);
+ }
+
+ // and then |123|.
+ assertEq(fta[zeroOffset + zeroCount], 123);
+
+ // And finally the NaNs.
+ const nanOffset = zeroCount + 2;
+ for (let i = 0; i < nansLength; ++i) {
+ // We don't assert a specific NaN value is present, because this is
+ // not required by the spec and we don't provide any guarantees NaN
+ // values are either unchanged or canonicalized in sort().
+ assertEq(fta[nanOffset + i], NaN, `At offset: ${nanOffset + i}`);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);