Bug 1475678 - Part 2: Skip RejectMaybeWrappedPromise when the promise is definitely not wrapped. r=arai
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 13 Jul 2018 13:57:34 -0700
changeset 427580 e1ca4196b3256a52ceb773a55f21dcce311f4c9a
parent 427579 f8d04aa5f853750145c9e821eb0f150fb95a721d
child 427581 ef8a735fbc88b3f1ff534025c1515784eb3c7142
push id34307
push usercsabou@mozilla.com
push dateFri, 20 Jul 2018 21:42:49 +0000
treeherdermozilla-central@6eec814dea78 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1475678
milestone63.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 1475678 - Part 2: Skip RejectMaybeWrappedPromise when the promise is definitely not wrapped. r=arai
js/src/builtin/Promise.cpp
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -596,18 +596,23 @@ IsSettledMaybeWrappedPromise(JSObject* p
         // Caller needs to handle dead wrappers.
         if (JS_IsDeadWrapper(promise))
             return false;
     }
 
     return promise->as<PromiseObject>().state() != JS::PromiseState::Pending;
 }
 
-static MOZ_MUST_USE bool RejectMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj,
-                                                   HandleValue reason);
+// ES2016, 25.4.1.7.
+static MOZ_MUST_USE bool
+RejectMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj, HandleValue reason);
+
+// ES2016, 25.4.1.7.
+static MOZ_MUST_USE bool
+RejectPromiseInternal(JSContext* cx, Handle<PromiseObject*> promise, HandleValue reason);
 
 // ES2016, 25.4.1.3.1.
 static bool
 RejectPromiseFunction(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     RootedFunction reject(cx, &args.callee().as<JSFunction>());
@@ -950,16 +955,23 @@ ResolvePromise(JSContext* cx, Handle<Pro
     // Step 7 of FulfillPromise.
     // Step 8 of RejectPromise.
     if (reactionsVal.isObject())
         return TriggerPromiseReactions(cx, reactionsVal, state, valueOrReason);
 
     return true;
 }
 
+// ES2016, 25.4.1.7.
+static MOZ_MUST_USE bool
+RejectPromiseInternal(JSContext* cx, Handle<PromiseObject*> promise, HandleValue reason)
+{
+    return ResolvePromise(cx, promise, reason, JS::PromiseState::Rejected);
+}
+
 // ES2016, 25.4.1.4.
 static MOZ_MUST_USE bool
 FulfillMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj, HandleValue value_)
 {
     Rooted<PromiseObject*> promise(cx);
     RootedValue value(cx, value_);
 
     mozilla::Maybe<AutoRealm> ar;
@@ -1236,17 +1248,17 @@ DefaultResolvingPromiseReactionJob(JSCon
     if (promiseToResolve->state() == JS::PromiseState::Pending) {
         RootedValue argument(cx, reaction->handlerArg());
 
         // Step 6.
         bool ok;
         if (reaction->targetState() == JS::PromiseState::Fulfilled)
             ok = ResolvePromiseInternal(cx, promiseToResolve, argument);
         else
-            ok = RejectMaybeWrappedPromise(cx, promiseToResolve, argument);
+            ok = RejectPromiseInternal(cx, promiseToResolve, argument);
 
         if (!ok) {
             resolutionMode = RejectMode;
             if (!MaybeGetAndClearException(cx, &handlerResult))
                 return false;
         }
     }
 
@@ -1553,17 +1565,17 @@ PromiseResolveBuiltinThenableJob(JSConte
     // Testing functions allow to directly settle a promise without going
     // through the resolving functions. In that case the normal bookkeeping to
     // ensure only pending promises can be resolved doesn't apply and we need
     // to manually check for already settled promises. The exception is simply
     // dropped when this case happens.
     if (promise->as<PromiseObject>().state() != JS::PromiseState::Pending)
         return true;
 
-    return RejectMaybeWrappedPromise(cx, promise, exception);
+    return RejectPromiseInternal(cx, promise.as<PromiseObject>(), exception);
 }
 
 /**
  * Tells the embedding to enqueue a Promise resolve thenable job, based on
  * three parameters:
  * promiseToResolve_ - The promise to resolve, obviously.
  * thenable_ - The thenable to resolve the Promise with.
  * thenVal - The `then` function to invoke with the `thenable` as the receiver.
@@ -2185,27 +2197,27 @@ RunResolutionFunction(JSContext *cx, Han
         FixedInvokeArgs<1> resolveArgs(cx);
         resolveArgs[0].set(result);
         return Call(cx, calleeOrRval, UndefinedHandleValue, resolveArgs, &calleeOrRval);
     }
 
     if (!promiseObj)
         return true;
 
-    Rooted<PromiseObject*> promise(cx, &promiseObj->as<PromiseObject>());
+    Handle<PromiseObject*> promise = promiseObj.as<PromiseObject>();
     if (promise->state() != JS::PromiseState::Pending)
         return true;
 
     if (!PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS))
         return true;
 
     if (mode == ResolveMode)
         return ResolvePromiseInternal(cx, promise, result);
 
-    return RejectMaybeWrappedPromise(cx, promiseObj, result);
+    return RejectPromiseInternal(cx, promise, result);
 }
 
 // ES2016, 25.4.4.1.1.
 static MOZ_MUST_USE bool
 PerformPromiseAll(JSContext *cx, JS::ForOfIterator& iterator, HandleObject C,
                   HandleObject promiseObj, HandleObject resolve, HandleObject reject,
                   bool* done)
 {
@@ -2871,17 +2883,17 @@ js::IsPromiseForAsync(JSObject* promise)
 MOZ_MUST_USE bool
 js::AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise)
 {
     // Step 3.f.
     RootedValue exc(cx);
     if (!MaybeGetAndClearException(cx, &exc))
         return false;
 
-    if (!RejectMaybeWrappedPromise(cx, resultPromise, exc))
+    if (!RejectPromiseInternal(cx, resultPromise, exc))
         return false;
 
     // Step 3.g.
     return true;
 }
 
 // ES 2018 draft 25.5.5.2 steps 3.d-e, 3.g.
 MOZ_MUST_USE bool
@@ -2982,17 +2994,17 @@ js::AsyncFromSyncIteratorMethod(JSContex
         // code.
 
         // Step 3.a.
         RootedValue badGeneratorError(cx);
         if (!GetTypeError(cx, JSMSG_NOT_AN_ASYNC_ITERATOR, &badGeneratorError))
             return false;
 
         // Step 3.b.
-        if (!RejectMaybeWrappedPromise(cx, resultPromise, badGeneratorError))
+        if (!RejectPromiseInternal(cx, resultPromise, badGeneratorError))
             return false;
 
         // Step 3.c.
         args.rval().setObject(*resultPromise);
         return true;
     }
 
     Rooted<AsyncFromSyncIteratorObject*> asyncIter(
@@ -3032,17 +3044,17 @@ js::AsyncFromSyncIteratorMethod(JSContex
         // 11.1.3.2.3 steps 5-6.
         MOZ_ASSERT(completionKind == CompletionKind::Throw);
         if (!GetProperty(cx, iter, iter, cx->names().throw_, &func))
             return AbruptRejectPromise(cx, args, resultPromise, nullptr);
 
         // Step 7.
         if (func.isNullOrUndefined()) {
             // Step 7.a.
-            if (!RejectMaybeWrappedPromise(cx, resultPromise, args.get(0)))
+            if (!RejectPromiseInternal(cx, resultPromise, args.get(0)))
                 return AbruptRejectPromise(cx, args, resultPromise, nullptr);
 
             // Step 7.b.
             args.rval().setObject(*resultPromise);
             return true;
         }
     }
 
@@ -3161,17 +3173,17 @@ AsyncGeneratorResumeNext(JSContext* cx, 
                 return false;
 
             // Step 5.
             Rooted<PromiseObject*> resultPromise(cx, request->promise());
 
             asyncGenObj->cacheRequest(request);
 
             // Step 6.
-            if (!RejectMaybeWrappedPromise(cx, resultPromise, exception))
+            if (!RejectPromiseInternal(cx, resultPromise, exception))
                 return false;
 
             // Steps 7-8.
             break;
           }
           case ResumeNextKind::Resolve: {
             // 11.4.3.3 AsyncGeneratorResolve ( generator, value, done )
             HandleValue value = valueOrException;
@@ -3328,17 +3340,17 @@ js::AsyncGeneratorEnqueue(JSContext* cx,
     // Step 3.
     if (!asyncGenVal.isObject() || !asyncGenVal.toObject().is<AsyncGeneratorObject>()) {
         // Step 3.a.
         RootedValue badGeneratorError(cx);
         if (!GetTypeError(cx, JSMSG_NOT_AN_ASYNC_GENERATOR, &badGeneratorError))
             return false;
 
         // Step 3.b.
-        if (!RejectMaybeWrappedPromise(cx, resultPromise, badGeneratorError))
+        if (!RejectPromiseInternal(cx, resultPromise, badGeneratorError))
             return false;
 
         // Step 3.c.
         result.setObject(*resultPromise);
         return true;
     }
 
     Rooted<AsyncGeneratorObject*> asyncGenObj(