summaryrefslogtreecommitdiffstats
path: root/js/src/tests/shell
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/shell')
-rw-r--r--js/src/tests/shell/README1
-rw-r--r--js/src/tests/shell/futex-apis.js113
-rw-r--r--js/src/tests/shell/futex.js160
-rw-r--r--js/src/tests/shell/gcstats.js60
-rw-r--r--js/src/tests/shell/os.js39
-rw-r--r--js/src/tests/shell/shell.js4
-rw-r--r--js/src/tests/shell/warning.js34
7 files changed, 411 insertions, 0 deletions
diff --git a/js/src/tests/shell/README b/js/src/tests/shell/README
new file mode 100644
index 000000000..0c7a3d149
--- /dev/null
+++ b/js/src/tests/shell/README
@@ -0,0 +1 @@
+Tests for JS shell-only functions
diff --git a/js/src/tests/shell/futex-apis.js b/js/src/tests/shell/futex-apis.js
new file mode 100644
index 000000000..b3e0acd55
--- /dev/null
+++ b/js/src/tests/shell/futex-apis.js
@@ -0,0 +1,113 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if (!(this.SharedArrayBuffer && this.Atomics)) {
+ reportCompare(true,true);
+ quit(0);
+}
+
+// Checks for parameter validation of wait/wake API. All of these test
+// cases should throw exceptions during parameter validation, before
+// we check whether any waiting should be done.
+
+let ab = new ArrayBuffer(16);
+let sab = new SharedArrayBuffer(16);
+
+//////////////////////////////////////////////////////////////////////
+//
+// The view must be an Int32Array on a SharedArrayBuffer.
+
+// Check against non-TypedArray cases.
+
+{
+ let values = [null,
+ undefined,
+ true,
+ false,
+ new Boolean(true),
+ 10,
+ 3.14,
+ new Number(4),
+ "Hi there",
+ new Date,
+ /a*utomaton/g,
+ { password: "qumquat" },
+ new DataView(new ArrayBuffer(10)),
+ new ArrayBuffer(128),
+ new SharedArrayBuffer(128),
+ new Error("Ouch"),
+ [1,1,2,3,5,8],
+ ((x) => -x),
+ new Map(),
+ new Set(),
+ new WeakMap(),
+ new WeakSet(),
+ this.Promise ? new Promise(() => "done") : null,
+ Symbol("halleluja"),
+ // TODO: Proxy?
+ Object,
+ Int32Array,
+ Date,
+ Math,
+ Atomics ];
+
+ for ( let i=0 ; i < values.length ; i++ ) {
+ let view = values[i];
+ assertThrowsInstanceOf(() => Atomics.wait(view, 0, 0), TypeError);
+ assertThrowsInstanceOf(() => Atomics.wake(view, 0), TypeError);
+ }
+}
+
+// Check against TypedArray on non-shared memory cases.
+
+{
+ let views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
+
+ for ( let View of views ) {
+ let view = new View(ab);
+
+ assertThrowsInstanceOf(() => Atomics.wait(view, 0, 0), TypeError);
+ assertThrowsInstanceOf(() => Atomics.wake(view, 0), TypeError);
+ }
+}
+
+// Check against TypedArray on shared memory, but wrong view type
+
+{
+ let views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Uint32Array,
+ Uint8ClampedArray, Float32Array, Float64Array];
+
+ for ( let View of views ) {
+ let view = new View(sab);
+
+ assertThrowsInstanceOf(() => Atomics.wait(view, 0, 0), TypeError);
+ assertThrowsInstanceOf(() => Atomics.wake(view, 0), TypeError);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+//
+// The indices must be in the range of the array
+
+{
+ let view = new Int32Array(sab);
+
+ let indices = [ (view) => -1,
+ (view) => view.length,
+ (view) => view.length*2,
+ (view) => undefined,
+ (view) => '3.5',
+ (view) => { password: "qumquat" } ];
+
+ for ( let iidx=0 ; iidx < indices.length ; iidx++ ) {
+ let Idx = indices[iidx](view);
+ assertThrowsInstanceOf(() => Atomics.wait(view, Idx, 10), RangeError);
+ assertThrowsInstanceOf(() => Atomics.wake(view, Idx), RangeError);
+ }
+}
+
+reportCompare(true,true);
diff --git a/js/src/tests/shell/futex.js b/js/src/tests/shell/futex.js
new file mode 100644
index 000000000..b0951f12e
--- /dev/null
+++ b/js/src/tests/shell/futex.js
@@ -0,0 +1,160 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+if (!(this.SharedArrayBuffer && this.getSharedArrayBuffer && this.setSharedArrayBuffer)) {
+ reportCompare(true,true);
+ quit(0);
+}
+
+var DEBUG = false;
+
+function dprint(s) {
+ if (DEBUG) print(s);
+}
+
+// Tests the SharedArrayBuffer mailbox in the shell.
+// Tests the wait/wake functionality in the shell.
+
+var sab = new SharedArrayBuffer(12);
+var mem = new Int32Array(sab);
+
+// SharedArrayBuffer mailbox tests
+
+assertEq(getSharedArrayBuffer(), null); // Mbx starts empty
+
+assertEq(setSharedArrayBuffer(mem.buffer), undefined); // Setter returns undefined
+assertEq(getSharedArrayBuffer() == null, false); // And then the mbx is not empty
+
+var v = getSharedArrayBuffer();
+assertEq(v.byteLength, mem.buffer.byteLength); // Looks like what we put in?
+var w = new Int32Array(v);
+mem[0] = 314159;
+assertEq(w[0], 314159); // Shares memory (locally) with what we put in?
+mem[0] = 0;
+
+setSharedArrayBuffer(null); // Setting to null clears to null
+assertEq(getSharedArrayBuffer(), null);
+
+setSharedArrayBuffer(mem.buffer);
+setSharedArrayBuffer(undefined); // Setting to undefined clears to null
+assertEq(getSharedArrayBuffer(), null);
+
+setSharedArrayBuffer(mem.buffer);
+setSharedArrayBuffer(); // Setting without arguments clears to null
+assertEq(getSharedArrayBuffer(), null);
+
+// Only SharedArrayBuffer can be stored in the mbx
+
+assertThrowsInstanceOf(() => setSharedArrayBuffer({x:10, y:20}), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer([1,2]), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer(new ArrayBuffer(10)), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer(new Int32Array(10)), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer(false), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer(3.14), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer(mem), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer("abracadabra"), Error);
+assertThrowsInstanceOf(() => setSharedArrayBuffer(() => 37), Error);
+
+// Futex test
+
+if (helperThreadCount() === 0) {
+ // Abort if there is no helper thread.
+ reportCompare(true,true);
+ quit();
+}
+
+////////////////////////////////////////////////////////////
+
+// wait() returns "not-equal" if the value is not the expected one.
+
+mem[0] = 42;
+
+assertEq(Atomics.wait(mem, 0, 33), "not-equal");
+
+// wait() returns "timed-out" if it times out
+
+assertEq(Atomics.wait(mem, 0, 42, 100), "timed-out");
+
+////////////////////////////////////////////////////////////
+
+// Main is sharing the buffer with the worker; the worker is clearing
+// the buffer.
+
+mem[0] = 42;
+mem[1] = 37;
+mem[2] = DEBUG;
+
+setSharedArrayBuffer(mem.buffer);
+
+evalInWorker(`
+var mem = new Int32Array(getSharedArrayBuffer());
+function dprint(s) {
+ if (mem[2]) print(s);
+}
+assertEq(mem[0], 42); // what was written in the main thread
+assertEq(mem[1], 37); // is read in the worker
+mem[1] = 1337;
+dprint("Sleeping for 2 seconds");
+sleep(2);
+dprint("Waking the main thread now");
+setSharedArrayBuffer(null);
+assertEq(Atomics.wake(mem, 0, 1), 1); // Can fail spuriously but very unlikely
+`);
+
+var then = Date.now();
+assertEq(Atomics.wait(mem, 0, 42), "ok");
+dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
+assertEq(mem[1], 1337); // what was written in the worker is read in the main thread
+assertEq(getSharedArrayBuffer(), null); // The worker's clearing of the mbx is visible
+
+////////////////////////////////////////////////////////////
+
+// Test the default argument to atomics.wake()
+
+setSharedArrayBuffer(mem.buffer);
+
+evalInWorker(`
+var mem = new Int32Array(getSharedArrayBuffer());
+sleep(2); // Probably long enough to avoid a spurious error next
+assertEq(Atomics.wake(mem, 0), 1); // Last argument to wake should default to +Infinity
+`);
+
+var then = Date.now();
+dprint("Main thread waiting on wakeup (2s)");
+assertEq(Atomics.wait(mem, 0, 42), "ok");
+dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
+
+////////////////////////////////////////////////////////////
+
+// A tricky case: while in the wait there will be an interrupt, and in
+// the interrupt handler we will execute a wait. This is
+// explicitly prohibited (for now), so there should be a catchable exception.
+
+var exn = false;
+timeout(2, function () {
+ dprint("In the interrupt, starting inner wait with timeout 2s");
+ try {
+ Atomics.wait(mem, 0, 42); // Should throw
+ } catch (e) {
+ dprint("Got the interrupt exception!");
+ exn = true;
+ }
+ return true;
+});
+try {
+ dprint("Starting outer wait");
+ assertEq(Atomics.wait(mem, 0, 42, 5000), "timed-out");
+}
+finally {
+ timeout(-1);
+}
+assertEq(exn, true);
+
+////////////////////////////////////////////////////////////
+
+dprint("Done");
+reportCompare(true,true);
diff --git a/js/src/tests/shell/gcstats.js b/js/src/tests/shell/gcstats.js
new file mode 100644
index 000000000..6343b56bb
--- /dev/null
+++ b/js/src/tests/shell/gcstats.js
@@ -0,0 +1,60 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+function garbage() {
+ var x;
+ for (var i = 0; i < 100000; i++)
+ x = { 'i': i };
+}
+
+setGCCallback({
+ action: "majorGC",
+ depth: 1,
+ phases: "both"
+});
+
+gc();
+garbage();
+
+setGCCallback({
+ action: "majorGC",
+ depth: 2,
+ phases: "both"
+});
+
+gc();
+garbage();
+
+setGCCallback({
+ action: "majorGC",
+ depth: 10,
+ phases: "begin"
+});
+
+gc();
+garbage();
+
+setGCCallback({
+ action: "minorGC",
+ phases: "both"
+});
+
+gc();
+garbage();
+
+var caught = false;
+try {
+ setGCCallback({
+ action: "majorGC",
+ depth: 10000,
+ phases: "begin"
+ });
+} catch (e) {
+ caught = ((""+e).indexOf("Nesting depth too large") >= 0);
+}
+
+reportCompare(caught, true);
diff --git a/js/src/tests/shell/os.js b/js/src/tests/shell/os.js
new file mode 100644
index 000000000..06e08f683
--- /dev/null
+++ b/js/src/tests/shell/os.js
@@ -0,0 +1,39 @@
+// |reftest| skip-if(!xulRuntime.shell||xulRuntime.OS=="WINNT")
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var pid = os.getpid();
+assertEq(pid > 0, true);
+
+var PATH = os.getenv("PATH");
+assertEq(PATH.indexOf("bin") > 0, true);
+assertEq(os.getenv("SQUAMMISH_HILLBILLY_GOAT_SQUEEZERS"), undefined);
+
+assertEq(os.system("true"), 0, "/bin/true should exit 0");
+assertEq(os.system("false") != 0, true, "/bin/false should exit nonzero");
+
+var kidpid = os.spawn("sleep 60");
+assertEq(kidpid > 0, true, "spawning sleep");
+var info = os.waitpid(kidpid, true);
+assertEq(info.hasOwnProperty("pid"), false);
+assertEq(info.hasOwnProperty("exitStatus"), false);
+
+os.kill(kidpid);
+
+info = os.waitpid(kidpid);
+assertEq(info.hasOwnProperty("pid"), true, "waiting on dead process should return pid");
+assertEq(info.pid, kidpid);
+assertEq(info.hasOwnProperty("exitStatus"), false, "killed process should not have exitStatus");
+
+kidpid = os.spawn("false");
+assertEq(kidpid > 0, true, "spawning /bin/false");
+info = os.waitpid(kidpid);
+assertEq(info.hasOwnProperty("pid"), true, "waiting on dead process should return pid");
+assertEq(info.pid, kidpid);
+assertEq(info.hasOwnProperty("exitStatus"), true, "process should have exitStatus");
+assertEq(info.exitStatus, 1, "/bin/false should exit 1");
+
+reportCompare(true, true);
diff --git a/js/src/tests/shell/shell.js b/js/src/tests/shell/shell.js
new file mode 100644
index 000000000..7584133da
--- /dev/null
+++ b/js/src/tests/shell/shell.js
@@ -0,0 +1,4 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
diff --git a/js/src/tests/shell/warning.js b/js/src/tests/shell/warning.js
new file mode 100644
index 000000000..550c10bc5
--- /dev/null
+++ b/js/src/tests/shell/warning.js
@@ -0,0 +1,34 @@
+// |reftest| skip-if(!xulRuntime.shell)
+
+var BUGNUMBER = 1170716;
+var summary = 'Add js shell functions to get last warning';
+
+print(BUGNUMBER + ": " + summary);
+
+// Warning with JSEXN_SYNTAXERR.
+
+enableLastWarning();
+options("strict");
+eval(`var a; if (a=0) {}`);
+
+warning = getLastWarning();
+assertEq(warning !== null, true);
+assertEq(warning.name, "SyntaxError");
+assertEq(warning.message.includes("equality"), true);
+assertEq(warning.lineNumber, 1);
+assertEq(warning.columnNumber, 14);
+
+// Disabled.
+
+disableLastWarning();
+
+eval(`var a; if (a=0) {}`);
+
+enableLastWarning();
+warning = getLastWarning();
+assertEq(warning, null);
+
+disableLastWarning();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);