summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/stream
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/stream')
-rw-r--r--js/src/jit-test/tests/stream/bug-1387503-1.js38
-rw-r--r--js/src/jit-test/tests/stream/bug-1387503-2.js40
-rw-r--r--js/src/jit-test/tests/stream/bug-1503399-1.js19
-rw-r--r--js/src/jit-test/tests/stream/bug-1503399-2.js12
-rw-r--r--js/src/jit-test/tests/stream/bug-1503406.js14
-rw-r--r--js/src/jit-test/tests/stream/bug-1512008.js9
-rw-r--r--js/src/jit-test/tests/stream/bug-1513266.js16
-rw-r--r--js/src/jit-test/tests/stream/bug-1515816.js17
-rw-r--r--js/src/jit-test/tests/stream/proper-realm-cancel.js8
-rw-r--r--js/src/jit-test/tests/stream/proper-realm-pull.js7
-rw-r--r--js/src/jit-test/tests/stream/reader-closedPromise-handled-2.js34
-rw-r--r--js/src/jit-test/tests/stream/reader-closedPromise-handled.js24
12 files changed, 238 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/stream/bug-1387503-1.js b/js/src/jit-test/tests/stream/bug-1387503-1.js
new file mode 100644
index 0000000000..a12dc2ad1d
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1387503-1.js
@@ -0,0 +1,38 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+// Test uncatchable error when a stream source's pull() method is called.
+
+// Make `debugger;` raise an uncatchable error.
+let g = newGlobal({newCompartment: true});
+g.parent = this;
+g.hit = false;
+g.eval(`
+ new Debugger(parent).onDebuggerStatement = _frame => (hit = true, null);
+`);
+
+// Create a stream whose pull() method raises an uncatchable error,
+// and try reading from it.
+let readerCreated = false;
+let fnFinished = false;
+async function fn() {
+ try {
+ let stream = new ReadableStream({
+ start(controller) {},
+ pull(controller) {
+ debugger;
+ }
+ });
+
+ let reader = stream.getReader();
+ let p = reader.read();
+ readerCreated = true;
+ await p;
+ } finally {
+ fnFinished = true;
+ }
+}
+
+fn();
+drainJobQueue();
+assertEq(readerCreated, true);
+assertEq(g.hit, true);
+assertEq(fnFinished, false);
diff --git a/js/src/jit-test/tests/stream/bug-1387503-2.js b/js/src/jit-test/tests/stream/bug-1387503-2.js
new file mode 100644
index 0000000000..d6885f325a
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1387503-2.js
@@ -0,0 +1,40 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+// Test uncatchable error when a stream's queuing strategy's size() method is called.
+
+// Make `debugger;` raise an uncatchable exception.
+let g = newGlobal({newCompartment: true});
+g.parent = this;
+g.hit = false;
+g.eval(`
+ var dbg = new Debugger(parent);
+ dbg.onDebuggerStatement = (_frame, exc) => (hit = true, null);
+`);
+
+let fnFinished = false;
+async function fn() {
+ // Await once to postpone the uncatchable error until we're running inside
+ // a reaction job. We don't want the rest of the test to be terminated.
+ // (`drainJobQueue` catches uncatchable errors!)
+ await 1;
+
+ try {
+ // Create a stream with a strategy whose .size() method raises an
+ // uncatchable exception, and have it call that method.
+ new ReadableStream({
+ start(controller) {
+ controller.enqueue("FIRST POST"); // this calls .size()
+ }
+ }, {
+ size() {
+ debugger;
+ }
+ });
+ } finally {
+ fnFinished = true;
+ }
+}
+
+fn();
+drainJobQueue();
+assertEq(g.hit, true);
+assertEq(fnFinished, false);
diff --git a/js/src/jit-test/tests/stream/bug-1503399-1.js b/js/src/jit-test/tests/stream/bug-1503399-1.js
new file mode 100644
index 0000000000..a5f7443279
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1503399-1.js
@@ -0,0 +1,19 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+// Don't assert if the wrapper that's the value of stream.[[reader]] gets nuked.
+
+load(libdir + "asserts.js");
+
+ignoreUnhandledRejections();
+
+let g = newGlobal({newCompartment: true});
+let stream = new ReadableStream({
+ start(controller) {
+ controller.enqueue("ponies");
+ controller.close();
+ }
+});
+g.stream = stream;
+g.eval("var reader = ReadableStream.prototype.getReader.call(stream);");
+nukeCCW(g.reader);
+assertErrorMessage(() => g.eval("reader.read()"), g.TypeError, "can't access dead object");
+g.eval("reader.releaseLock();");
diff --git a/js/src/jit-test/tests/stream/bug-1503399-2.js b/js/src/jit-test/tests/stream/bug-1503399-2.js
new file mode 100644
index 0000000000..fe7de74e7c
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1503399-2.js
@@ -0,0 +1,12 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+// Don't assert if the wrapper that's the value of reader.[[stream]] gets nuked.
+
+load(libdir + "asserts.js");
+
+let g = newGlobal({newCompartment: true});
+let stream = new g.ReadableStream({});
+let reader = ReadableStream.prototype.getReader.call(stream);
+nukeCCW(stream);
+
+assertErrorMessage(() => reader.read(), TypeError, "can't access dead object");
+assertErrorMessage(() => reader.releaseLock(), TypeError, "can't access dead object");
diff --git a/js/src/jit-test/tests/stream/bug-1503406.js b/js/src/jit-test/tests/stream/bug-1503406.js
new file mode 100644
index 0000000000..c325b5ea01
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1503406.js
@@ -0,0 +1,14 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+let g = newGlobal();
+let reader = g.eval(`
+ let stream = new ReadableStream({
+ start(controller) {
+ controller.enqueue([]);
+ },
+ });
+ let [b1, b2] = stream.tee();
+ b1.getReader();
+`);
+let read = new ReadableStream({}).getReader().read;
+drainJobQueue(); // let the stream be started before reading
+read.call(reader);
diff --git a/js/src/jit-test/tests/stream/bug-1512008.js b/js/src/jit-test/tests/stream/bug-1512008.js
new file mode 100644
index 0000000000..32dc847256
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1512008.js
@@ -0,0 +1,9 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+ignoreUnhandledRejections();
+
+Object.defineProperty(Promise, Symbol.species, {
+ value: function(g) {
+ g(function() {}, function() {})
+ }
+});
+new ReadableStream().tee();
diff --git a/js/src/jit-test/tests/stream/bug-1513266.js b/js/src/jit-test/tests/stream/bug-1513266.js
new file mode 100644
index 0000000000..3db1e2d941
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1513266.js
@@ -0,0 +1,16 @@
+// |jit-test| --no-ion; --no-baseline; skip-if: !('oomTest' in this && this.hasOwnProperty("ReadableStream"))
+
+ignoreUnhandledRejections();
+
+function test() {
+ let controller;
+ let stream = new ReadableStream({
+ start(c) { }
+ });
+ stream.getReader();
+ drainJobQueue();
+}
+
+// Force lazy parsing to happen before oomTest starts (see `help(oomTest)`).
+test();
+oomTest(test, { verbose: true, keepFailing: false });
diff --git a/js/src/jit-test/tests/stream/bug-1515816.js b/js/src/jit-test/tests/stream/bug-1515816.js
new file mode 100644
index 0000000000..44329b056d
--- /dev/null
+++ b/js/src/jit-test/tests/stream/bug-1515816.js
@@ -0,0 +1,17 @@
+// |jit-test| --no-ion; --no-baseline; --no-blinterp; skip-if: !('oomAfterAllocations' in this && this.hasOwnProperty("ReadableStream"))
+// Don't crash on OOM in ReadableStreamDefaultReader.prototype.read().
+
+for (let n = 1; n < 1000; n++) {
+ let stream = new ReadableStream({
+ start(controller) {
+ controller.enqueue(7);
+ }
+ });
+ let reader = stream.getReader();
+ oomAfterAllocations(n);
+ try {
+ reader.read();
+ n = 1000;
+ } catch { }
+ resetOOMFailure();
+}
diff --git a/js/src/jit-test/tests/stream/proper-realm-cancel.js b/js/src/jit-test/tests/stream/proper-realm-cancel.js
new file mode 100644
index 0000000000..b1098c3698
--- /dev/null
+++ b/js/src/jit-test/tests/stream/proper-realm-cancel.js
@@ -0,0 +1,8 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+
+ignoreUnhandledRejections();
+
+var g = newGlobal({ newCompartment: true });
+var ccwCancelMethod = new g.Function("return 17;");
+
+new ReadableStream({ cancel: ccwCancelMethod }).cancel("bye");
diff --git a/js/src/jit-test/tests/stream/proper-realm-pull.js b/js/src/jit-test/tests/stream/proper-realm-pull.js
new file mode 100644
index 0000000000..60ef7f5d82
--- /dev/null
+++ b/js/src/jit-test/tests/stream/proper-realm-pull.js
@@ -0,0 +1,7 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+ignoreUnhandledRejections();
+
+var g = newGlobal({ newCompartment: true });
+var ccwPullMethod = new g.Function("return 17;");
+
+new ReadableStream({ pull: ccwPullMethod });
diff --git a/js/src/jit-test/tests/stream/reader-closedPromise-handled-2.js b/js/src/jit-test/tests/stream/reader-closedPromise-handled-2.js
new file mode 100644
index 0000000000..0525ff91ee
--- /dev/null
+++ b/js/src/jit-test/tests/stream/reader-closedPromise-handled-2.js
@@ -0,0 +1,34 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+// Releasing a reader should not result in a promise being tracked as
+// unhandled.
+
+function test(readable) {
+ // Create an errored stream.
+ let controller;
+ let stream = new ReadableStream({
+ start(c) {
+ controller = c;
+ }
+ });
+ drainJobQueue();
+
+ // Track promises.
+ let status = new Map;
+ setPromiseRejectionTrackerCallback((p, x) => { status.set(p, x); });
+
+ // Per Streams spec 3.7.5 step 5, this creates a rejected promise
+ // (reader.closed) but marks it as handled.
+ let reader = stream.getReader();
+ if (!readable) {
+ controller.close();
+ }
+ reader.releaseLock();
+
+ // Check that the promise's status is not 0 (unhandled);
+ // it may be either 1 (handled) or undefined (never tracked).
+ let result = status.get(reader.closed);
+ assertEq(result === 1 || result === undefined, true);
+}
+
+test(true);
+test(false);
diff --git a/js/src/jit-test/tests/stream/reader-closedPromise-handled.js b/js/src/jit-test/tests/stream/reader-closedPromise-handled.js
new file mode 100644
index 0000000000..b17a8dda4d
--- /dev/null
+++ b/js/src/jit-test/tests/stream/reader-closedPromise-handled.js
@@ -0,0 +1,24 @@
+// |jit-test| skip-if: !this.hasOwnProperty("ReadableStream")
+// Creating a reader from an errored stream should not result in a promise
+// being tracked as unhandled.
+
+// Create an errored stream.
+let stream = new ReadableStream({
+ start(controller) {
+ controller.error(new Error("splines insufficiently reticulated"));
+ }
+});
+drainJobQueue();
+
+// Track promises.
+let status = new Map;
+setPromiseRejectionTrackerCallback((p, x) => { status.set(p, x); });
+
+// Per Streams spec 3.7.4 step 5.c, this creates a rejected promise
+// (reader.closed) but marks it as handled.
+let reader = stream.getReader();
+
+// Check that the promise's status is not 0 (unhandled);
+// it may be either 1 (handled) or undefined (never tracked).
+let result = status.get(reader.closed);
+assertEq(result === 1 || result === undefined, true);