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

Unified Diff: src/isolate.cc

Issue 2276243002: Mark await expressions as caught or uncaught (Closed)
Patch Set: Format 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 110f614e1b7f80afe660e910b48be74c488b59ae..7203c55d5a301ca2c2a139b3d6380fcd6d249172 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1311,6 +1311,8 @@ 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::PROMISE) return CAUGHT_BY_PROMISE;
if (prediction != HandlerTable::UNCAUGHT) return CAUGHT_BY_JAVASCRIPT;
}
@@ -1701,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();
@@ -1720,6 +1730,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;

Powered by Google App Engine
This is Rietveld 408576698