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 525012 6c08bfd19a365a958118d2a44ff4d36773e9f3c0
parent 525011 6149ddaa39a6436f6d212da737be23bfa1bbf914
child 525013 e5b9c443c421e5c77177584bfd60099b9b7212b5
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [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);