From 86235036c5c6b07514c2668a82ff5637b671cdff Mon Sep 17 00:00:00 2001 From: Maya Lekova Date: Wed, 12 Feb 2020 17:59:15 +0100 Subject: [PATCH] [promises] Fix undefined case in promise macros Handle the undefined promiseOrCapability case in RejectPromiseReactionJob and FulfillPromiseReactionJob. Fixed: chromium:1046213 Change-Id: If6f51c28189a27476969c7b5b456741b5be829be Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2050399 Commit-Queue: Maya Lekova Reviewed-by: Tobias Tebbi Cr-Commit-Position: refs/heads/master@{#66248} --- src/builtins/promise-reaction-job.tq | 50 +++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/builtins/promise-reaction-job.tq b/src/builtins/promise-reaction-job.tq index 1db33f4a7a..1d20d22efb 100644 --- a/src/builtins/promise-reaction-job.tq +++ b/src/builtins/promise-reaction-job.tq @@ -17,27 +17,28 @@ namespace promise { promiseOrCapability: JSPromise|PromiseCapability|Undefined, reason: JSAny, reactionType: constexpr PromiseReactionType): JSAny { if constexpr (reactionType == kPromiseReactionReject) { - if (IsJSPromise(promiseOrCapability)) { - // For fast native promises we can skip the indirection via the - // promiseCapability.[[Reject]] function and run the resolve logic - // directly from here. - return RejectPromise( - UnsafeCast(promiseOrCapability), reason, False); - } else - deferred { - assert(IsPromiseCapability(promiseOrCapability)); + typeswitch (promiseOrCapability) { + case (promise: JSPromise): { + // For fast native promises we can skip the indirection via the + // promiseCapability.[[Reject]] function and run the resolve logic + // directly from here. + return RejectPromise(promise, reason, False); + } + case (Undefined): { + return Undefined; + } + case (capability: PromiseCapability): { // In the general case we need to call the (user provided) // promiseCapability.[[Reject]] function. try { - const promiseCapability = - UnsafeCast(promiseOrCapability); - const reject = UnsafeCast(promiseCapability.reject); + const reject = UnsafeCast(capability.reject); return Call(context, reject, Undefined, reason); } catch (e) { // Swallow the exception here. return runtime::ReportMessage(e); } } + } } else { StaticAssert(reactionType == kPromiseReactionFulfill); // We have to call out to the dedicated PromiseRejectReactionJob @@ -53,20 +54,20 @@ namespace promise { context: Context, promiseOrCapability: JSPromise|PromiseCapability|Undefined, result: JSAny, reactionType: constexpr PromiseReactionType): JSAny { - if (IsJSPromise(promiseOrCapability)) { - // For fast native promises we can skip the indirection via the - // promiseCapability.[[Resolve]] function and run the resolve logic - // directly from here. - return ResolvePromise( - context, UnsafeCast(promiseOrCapability), result); - } else - deferred { - assert(IsPromiseCapability(promiseOrCapability)); + typeswitch (promiseOrCapability) { + case (promise: JSPromise): { + // For fast native promises we can skip the indirection via the + // promiseCapability.[[Resolve]] function and run the resolve logic + // directly from here. + return ResolvePromise(context, promise, result); + } + case (Undefined): { + return Undefined; + } + case (capability: PromiseCapability): { // In the general case we need to call the (user provided) // promiseCapability.[[Resolve]] function. - const promiseCapability = - UnsafeCast(promiseOrCapability); - const resolve = UnsafeCast(promiseCapability.resolve); + const resolve = UnsafeCast(capability.resolve); try { return Call(context, resolve, Undefined, result); } catch (e) { @@ -74,6 +75,7 @@ namespace promise { context, promiseOrCapability, e, reactionType); } } + } } // https://tc39.es/ecma262/#sec-promisereactionjob