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

Unified Diff: src/isolate.cc

Issue 2286753002: Synchronous path changes
Patch Set: Created 4 years, 4 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/objects.h » ('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 5876af004fc56d7be5cccb9e1d9b360e43c71f20..cb5eb1616bc23f58d082f6929786815dd194dfdd 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1319,6 +1319,7 @@ Isolate::CatchType Isolate::PredictExceptionCatcher() {
JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame);
HandlerTable::CatchPrediction prediction = PredictException(js_frame);
if (prediction == HandlerTable::DESUGARING) return CAUGHT_BY_DESUGARING;
+ if (prediction == HandlerTable::ASYNC_AWAIT) return CAUGHT_BY_ASYNC_AWAIT;
if (prediction != HandlerTable::UNCAUGHT) return CAUGHT_BY_JAVASCRIPT;
}
@@ -1725,6 +1726,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();
@@ -1744,6 +1753,47 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
return undefined;
case HandlerTable::PROMISE:
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/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698