Bug 1532602 - Throw error when settlePromiseNow is called on already-resolved promise. r=jorendorff
authorTooru Fujisawa <arai_a@mac.com>
Thu, 14 Mar 2019 19:54:26 +0000
changeset 522014 6c08bfd19a365a958118d2a44ff4d36773e9f3c0
parent 522013 6149ddaa39a6436f6d212da737be23bfa1bbf914
child 522015 e5b9c443c421e5c77177584bfd60099b9b7212b5
push id10870
push usernbeleuzu@mozilla.com
push dateFri, 15 Mar 2019 20:00:07 +0000
treeherdermozilla-beta@c594aee5b7a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1532602
milestone67.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 1532602 - Throw error when settlePromiseNow is called on already-resolved promise. r=jorendorff Differential Revision: https://phabricator.services.mozilla.com/D23349
js/src/builtin/TestingFunctions.cpp
js/src/jit-test/tests/promise/settle-now-already-resolved.js
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -2168,16 +2168,21 @@ static bool SettlePromiseNow(JSContext* 
 
   Rooted<PromiseObject*> promise(cx, &args[0].toObject().as<PromiseObject>());
   if (IsPromiseForAsync(promise)) {
     JS_ReportErrorASCII(
         cx, "async function's promise shouldn't be manually settled");
     return false;
   }
 
+  if (promise->state() != JS::PromiseState::Pending) {
+    JS_ReportErrorASCII(cx, "cannot settle an already-resolved promise");
+    return false;
+  }
+
   int32_t flags = promise->flags();
   promise->setFixedSlot(
       PromiseSlot_Flags,
       Int32Value(flags | PROMISE_FLAG_RESOLVED | PROMISE_FLAG_FULFILLED));
   promise->setFixedSlot(PromiseSlot_ReactionsOrResult, UndefinedValue());
 
   Debugger::onPromiseSettled(cx, promise);
   return true;
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/promise/settle-now-already-resolved.js
@@ -0,0 +1,28 @@
+// |jit-test| error:Unhandled rejection
+
+load(libdir + "asserts.js");
+
+// Calling settlePromiseNow on already-resolved promise should throw, and
+// unhandled rejection tracking should work.
+
+assertThrowsInstanceOf(() => {
+  var promise = new Promise(resolve => {
+    resolve(10);
+  });
+  settlePromiseNow(promise);
+}, Error);
+
+
+assertThrowsInstanceOf(() => {
+  var promise = new Promise((_, reject) => {
+    reject(10);
+  });
+  settlePromiseNow(promise);
+}, Error);
+
+assertThrowsInstanceOf(() => {
+  var promise = new Promise(() => {
+    throw 10;
+  });
+  settlePromiseNow(promise);
+}, Error);