Bug 1561911 - Part 3: Set closedPromise.[[PromiseIsHandled]] to true in ReadableStreamError. r=jwalden
authorTooru Fujisawa <arai_a@mac.com>
Wed, 04 Dec 2019 09:47:07 +0000
changeset 505292 4c5f5aad4fd76c7c4040f24d88f7b7695332c540
parent 505291 fc547f512ed850b4b618d69890b4fd0885257cac
child 505293 8fc8a1f595788306652351e0971ecaf13880a1fe
push id36881
push userdvarga@mozilla.com
push dateWed, 04 Dec 2019 16:22:31 +0000
treeherdermozilla-central@13fb375eaf14 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1561911
milestone73.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1561911 - Part 3: Set closedPromise.[[PromiseIsHandled]] to true in ReadableStreamError. r=jwalden Implemented 3.5.6. ReadableStreamError step 10. Differential Revision: https://phabricator.services.mozilla.com/D55615
js/src/builtin/streams/ReadableStreamInternals.cpp
js/src/tests/non262/ReadableStream/closed-is-handled.js
testing/web-platform/meta/streams/readable-streams/default-reader.any.js.ini
testing/web-platform/meta/streams/readable-streams/tee.any.js.ini
--- a/js/src/builtin/streams/ReadableStreamInternals.cpp
+++ b/js/src/builtin/streams/ReadableStreamInternals.cpp
@@ -28,17 +28,17 @@
 #include "js/Value.h"  // JS::Value, JS::{Boolean,Object}Value, JS::UndefinedHandleValue
 #include "vm/JSContext.h"     // JSContext
 #include "vm/JSFunction.h"    // JSFunction, js::NewNativeFunction
 #include "vm/NativeObject.h"  // js::NativeObject
 #include "vm/ObjectGroup.h"   // js::GenericObject
 #include "vm/Realm.h"         // JS::Realm
 #include "vm/StringType.h"    // js::PropertyName
 
-#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::{Reject,Resolve}UnwrappedPromiseWithUndefined
+#include "builtin/streams/MiscellaneousOperations-inl.h"  // js::{Reject,Resolve}UnwrappedPromiseWithUndefined, js::SetPromiseIsHandled
 #include "builtin/streams/ReadableStreamReader-inl.h"  // js::js::UnwrapReaderFromStream{,NoThrow}
 #include "vm/Compartment-inl.h"                        // JS::Compartment::wrap
 #include "vm/JSContext-inl.h"                          // JSContext::check
 #include "vm/List-inl.h"  // js::ListObject, js::AppendToListInFixedSlot, js::StoreNewListInFixedSlot
 #include "vm/Realm-inl.h"  // JS::Realm
 
 using js::ReadableStream;
 
@@ -340,16 +340,26 @@ MOZ_MUST_USE bool js::ReadableStreamErro
   }
 
   // Step 9: Reject reader.[[closedPromise]] with e.
   if (!RejectUnwrappedPromiseWithError(cx, unwrappedReader->closedPromise(),
                                        e)) {
     return false;
   }
 
+  // Step 10: Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
+  //
+  // `closedPromise` can return a CCW, but that case is filtered out by step 6,
+  // given the only place that can set [[closedPromise]] to a CCW is
+  // 3.8.5 ReadableStreamReaderGenericRelease step 4, and
+  // 3.8.5 ReadableStreamReaderGenericRelease step 6 sets
+  // stream.[[reader]] to undefined.
+  Rooted<JSObject*> closedPromise(cx, unwrappedReader->closedPromise());
+  SetPromiseIsHandled(cx, closedPromise.as<PromiseObject>());
+
   if (unwrappedStream->mode() == JS::ReadableStreamMode::ExternalSource) {
     // Make sure we're in the stream's compartment.
     AutoRealm ar(cx, unwrappedStream);
     JS::ReadableStreamUnderlyingSource* source =
         unwrappedStream->controller()->externalSource();
 
     // Ensure that the embedding doesn't have to deal with
     // mixed-compartment arguments to the callback.
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/ReadableStream/closed-is-handled.js
@@ -0,0 +1,27 @@
+// |reftest| skip-if(!this.ReadableStream||!this.drainJobQueue)
+
+// 3.5.6. ReadableStreamError ( stream, e ) nothrow
+//
+// 9. Reject reader.[[closedPromise]] with e.
+// 10. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
+//
+// Rejection for [[closedPromise]] shouldn't be reported as unhandled.
+
+const rs = new ReadableStream({
+  start() {
+    return Promise.reject(new Error("test"));
+  }
+});
+
+let rejected = false;
+rs.getReader().read().then(() => {}, () => { rejected = true; });
+
+drainJobQueue();
+
+assertEq(rejected, true);
+
+if (typeof reportCompare === 'function') {
+  reportCompare(0, 0);
+}
+
+// Shell itself reports unhandled rejection if there's any.
deleted file mode 100644
--- a/testing/web-platform/meta/streams/readable-streams/default-reader.any.js.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[default-reader.any.html]
-  expected: ERROR
-
-[default-reader.any.serviceworker.html]
-  expected: ERROR
-
-[default-reader.any.sharedworker.html]
-  expected: OK
--- a/testing/web-platform/meta/streams/readable-streams/tee.any.js.ini
+++ b/testing/web-platform/meta/streams/readable-streams/tee.any.js.ini
@@ -1,55 +1,51 @@
 [tee.any.sharedworker.html]
-  expected: ERROR
   [ReadableStreamTee should not pull more chunks than can fit in the branch queue]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 1 is reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while both branches are reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 2 is reading]
     expected: FAIL
 
 
 [tee.any.worker.html]
-  expected: ERROR
   [ReadableStreamTee should not pull more chunks than can fit in the branch queue]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 1 is reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while both branches are reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 2 is reading]
     expected: FAIL
 
 
 [tee.any.serviceworker.html]
-  expected: ERROR
   [ReadableStreamTee should not pull more chunks than can fit in the branch queue]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 1 is reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while both branches are reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 2 is reading]
     expected: FAIL
 
 
 [tee.any.html]
-  expected: ERROR
   [ReadableStreamTee should not pull more chunks than can fit in the branch queue]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while branch 1 is reading]
     expected: FAIL
 
   [ReadableStreamTee stops pulling when original stream errors while both branches are reading]
     expected: FAIL