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

Unified Diff: src/isolate.cc

Issue 2325813002: Async/await catch prediction for "the synchronous case" (Closed)
Patch Set: 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
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 70f75b2d8658be4ff658049e22d61011e5f9c352..9b384ebd42367c1bc10010a5b58aeb9a9d7a4728 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1703,6 +1703,14 @@ void Isolate::PopPromise() {
global_handles()->Destroy(global_promise.location());
}
+bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<JSObject> promise) {
+ Handle<JSFunction> fun = promise_has_user_defined_reject_handler();
+ Handle<Object> has_reject_handler;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(this, has_reject_handler,
+ Execution::Call(this, fun, promise, 0, NULL),
+ false);
+ return has_reject_handler->IsTrue(this);
+}
Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
Handle<Object> undefined = factory()->undefined_value();
@@ -1721,8 +1729,48 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
case HandlerTable::DESUGARING:
return undefined;
case HandlerTable::PROMISE:
- case HandlerTable::ASYNC_AWAIT:
return tltop->promise_on_stack_->promise();
+ case HandlerTable::ASYNC_AWAIT: {
+ // If in an async/await, 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.
+ PromiseOnStack* promise_on_stack = tltop->promise_on_stack_;
+ for (it.Advance(); !it.done(); it.Advance()) {
+ if (PromiseHasUserDefinedRejectHandler(promise_on_stack->promise())) {
+ break;
+ }
+ JavaScriptFrame* frame = it.frame();
+ if (!frame->function()->shared()->is_async()) {
+ // Keep searching up the stack until an async function stack frame
+ // is found, heuristically assuming that that will ultimately await
+ // whatever is going on here.
+ continue;
+ }
+ PromiseOnStack* next_promise_on_stack = promise_on_stack->prev();
+ if (next_promise_on_stack == nullptr) break;
+ switch (PredictException(it.frame())) {
+ case HandlerTable::CAUGHT:
+ case HandlerTable::DESUGARING: {
+ // Mark the inner promise as caught in the "synchronous case" so
+ // that Debug::OnException will see.
+ Handle<Symbol> key = factory()->promise_handled_hint_symbol();
+ JSObject::SetProperty(promise_on_stack->promise(), key, key,
+ STRICT)
+ .Assert();
+ return promise_on_stack->promise();
+ }
+ case HandlerTable::ASYNC_AWAIT:
+ promise_on_stack = next_promise_on_stack;
+ continue;
+ case HandlerTable::PROMISE:
+ case HandlerTable::UNCAUGHT:
+ UNREACHABLE();
+ }
+ }
+ return promise_on_stack->promise();
+ }
}
}
return undefined;
« no previous file with comments | « src/isolate.h ('k') | src/runtime/runtime-internal.cc » ('j') | src/runtime/runtime-internal.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698