Bug 1418106 - Throw error when resolving or rejecting promise returned by async function with testing function. r=till
authorTooru Fujisawa <arai_a@mac.com>
Sun, 19 Nov 2017 23:32:26 +0900
changeset 392609 ba1f15d69399
parent 392608 6c90e8fb37c3
child 392610 ef82504a2782
push id97483
push userarai_a@mac.com
push date2017-11-19 14:34 +0000
treeherdermozilla-inbound@ba1f15d69399 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1418106
milestone59.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 1418106 - Throw error when resolving or rejecting promise returned by async function with testing function. r=till
js/src/builtin/Promise.cpp
js/src/builtin/Promise.h
js/src/builtin/TestingFunctions.cpp
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -2507,16 +2507,23 @@ js::CreatePromiseObjectForAsync(JSContex
     if (!promise)
         return nullptr;
 
     AddPromiseFlags(*promise, PROMISE_FLAG_ASYNC);
     promise->setFixedSlot(PromiseSlot_AwaitGenerator, generatorVal);
     return promise;
 }
 
+bool
+js::IsPromiseForAsync(JSObject* promise)
+{
+    return promise->is<PromiseObject>() &&
+           PromiseHasAnyFlag(promise->as<PromiseObject>(), PROMISE_FLAG_ASYNC);
+}
+
 // ES 2018 draft 25.5.5.2 steps 3.f, 3.g.
 MOZ_MUST_USE bool
 js::AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise)
 {
     // Step 3.f.
     RootedValue exc(cx);
     if (!MaybeGetAndClearException(cx, &exc))
         return false;
--- a/js/src/builtin/Promise.h
+++ b/js/src/builtin/Promise.h
@@ -133,16 +133,19 @@ OriginalPromiseThen(JSContext* cx, Handl
 MOZ_MUST_USE JSObject*
 PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
 
 
 MOZ_MUST_USE PromiseObject*
 CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
 
 MOZ_MUST_USE bool
+IsPromiseForAsync(JSObject* promise);
+
+MOZ_MUST_USE bool
 AsyncFunctionReturned(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
 
 MOZ_MUST_USE bool
 AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise);
 
 MOZ_MUST_USE bool
 AsyncFunctionAwait(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
 
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -2049,16 +2049,21 @@ ResolvePromise(JSContext* cx, unsigned a
     mozilla::Maybe<AutoCompartment> ac;
     if (IsWrapper(promise)) {
         promise = UncheckedUnwrap(promise);
         ac.emplace(cx, promise);
         if (!cx->compartment()->wrap(cx, &resolution))
             return false;
     }
 
+    if (IsPromiseForAsync(promise)) {
+        JS_ReportErrorASCII(cx, "async function's promise shouldn't be manually resolved");
+        return false;
+    }
+
     bool result = JS::ResolvePromise(cx, promise, resolution);
     if (result)
         args.rval().setUndefined();
     return result;
 }
 
 static bool
 RejectPromise(JSContext* cx, unsigned argc, Value* vp)
@@ -2076,16 +2081,21 @@ RejectPromise(JSContext* cx, unsigned ar
     mozilla::Maybe<AutoCompartment> ac;
     if (IsWrapper(promise)) {
         promise = UncheckedUnwrap(promise);
         ac.emplace(cx, promise);
         if (!cx->compartment()->wrap(cx, &reason))
             return false;
     }
 
+    if (IsPromiseForAsync(promise)) {
+        JS_ReportErrorASCII(cx, "async function's promise shouldn't be manually rejected");
+        return false;
+    }
+
     bool result = JS::RejectPromise(cx, promise, reason);
     if (result)
         args.rval().setUndefined();
     return result;
 }
 
 static bool
 StreamsAreEnabled(JSContext* cx, unsigned argc, Value* vp)