Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: src/isolate.cc

Issue 2325813002: Async/await catch prediction for "the synchronous case" (Closed)
Patch Set: TryCall Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/isolate.h ('k') | src/runtime/runtime-internal.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 1b96583cb093cd44eb2022945e59b2a6bc185322..d6b41ec2b125182ad2d00ee4014306eca1574dd8 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1703,6 +1703,19 @@ void Isolate::PopPromise() {
global_handles()->Destroy(global_promise.location());
}
+bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) {
+ Handle<JSFunction> fun = promise_has_user_defined_reject_handler();
+ Handle<Object> has_reject_handler;
+ if (Execution::TryCall(this, fun, promise, 0, NULL)
+ .ToHandle(&has_reject_handler)) {
+ return has_reject_handler->IsTrue(this);
+ }
+ // If an exception is thrown in the course of execution of this built-in
+ // function, it indicates either a bug, or a synthetic uncatchable
+ // exception in the shutdown path. In either case, it's OK to predict either
+ // way in DevTools.
+ return false;
+}
Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
Handle<Object> undefined = factory()->undefined_value();
@@ -1713,19 +1726,46 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) {
return undefined;
}
+ Handle<Object> retval = undefined;
+ PromiseOnStack* promise_on_stack = tltop->promise_on_stack_;
for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
switch (PredictException(it.frame())) {
case HandlerTable::UNCAUGHT:
- case HandlerTable::ASYNC_AWAIT:
- break;
+ continue;
case HandlerTable::CAUGHT:
case HandlerTable::DESUGARING:
- return undefined;
+ if (retval->IsJSObject()) {
+ // Caught the result of an inner async/await invocation.
+ // Mark the inner promise as caught in the "synchronous case" so
+ // that Debug::OnException will see. In the synchronous case,
+ // namely in the code in an async function before the first
+ // await, the function which has this exception event has not yet
+ // returned, so the generated Promise has not yet been marked
+ // by AsyncFunctionAwaitCaught with promiseHandledHintSymbol.
+ Handle<Symbol> key = factory()->promise_handled_hint_symbol();
+ JSObject::SetProperty(Handle<JSObject>::cast(retval), key,
+ factory()->true_value(), STRICT)
+ .Assert();
+ }
+ return retval;
case HandlerTable::PROMISE:
- return tltop->promise_on_stack_->promise();
+ return promise_on_stack->promise();
+ case HandlerTable::ASYNC_AWAIT: {
+ // If in the initial portion of async/await, continue the loop to pop up
+ // successive async/await stack frames until an asynchronous one with
+ // dependents is found, or a non-async stack frame is encountered, in
+ // order to handle the synchronous async/await catch prediction case:
+ // assume that async function calls are awaited.
+ retval = promise_on_stack->promise();
+ if (PromiseHasUserDefinedRejectHandler(retval)) {
+ return retval;
+ }
+ promise_on_stack = promise_on_stack->prev();
+ continue;
+ }
}
}
- return undefined;
+ return retval;
}
« no previous file with comments | « src/isolate.h ('k') | src/runtime/runtime-internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698