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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/isolate.h" 5 #include "src/isolate.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <fstream> // NOLINT(readability/streams) 9 #include <fstream> // NOLINT(readability/streams)
10 #include <sstream> 10 #include <sstream>
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 void Isolate::PopPromise() { 1696 void Isolate::PopPromise() {
1697 ThreadLocalTop* tltop = thread_local_top(); 1697 ThreadLocalTop* tltop = thread_local_top();
1698 if (tltop->promise_on_stack_ == NULL) return; 1698 if (tltop->promise_on_stack_ == NULL) return;
1699 PromiseOnStack* prev = tltop->promise_on_stack_->prev(); 1699 PromiseOnStack* prev = tltop->promise_on_stack_->prev();
1700 Handle<Object> global_promise = tltop->promise_on_stack_->promise(); 1700 Handle<Object> global_promise = tltop->promise_on_stack_->promise();
1701 delete tltop->promise_on_stack_; 1701 delete tltop->promise_on_stack_;
1702 tltop->promise_on_stack_ = prev; 1702 tltop->promise_on_stack_ = prev;
1703 global_handles()->Destroy(global_promise.location()); 1703 global_handles()->Destroy(global_promise.location());
1704 } 1704 }
1705 1705
1706 bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<JSObject> promise) {
1707 Handle<JSFunction> fun = promise_has_user_defined_reject_handler();
1708 Handle<Object> has_reject_handler;
1709 ASSIGN_RETURN_ON_EXCEPTION_VALUE(this, has_reject_handler,
1710 Execution::Call(this, fun, promise, 0, NULL),
1711 false);
1712 return has_reject_handler->IsTrue(this);
1713 }
1706 1714
1707 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { 1715 Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
1708 Handle<Object> undefined = factory()->undefined_value(); 1716 Handle<Object> undefined = factory()->undefined_value();
1709 ThreadLocalTop* tltop = thread_local_top(); 1717 ThreadLocalTop* tltop = thread_local_top();
1710 if (tltop->promise_on_stack_ == NULL) return undefined; 1718 if (tltop->promise_on_stack_ == NULL) return undefined;
1711 // Find the top-most try-catch or try-finally handler. 1719 // Find the top-most try-catch or try-finally handler.
1712 CatchType prediction = PredictExceptionCatcher(); 1720 CatchType prediction = PredictExceptionCatcher();
1713 if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) { 1721 if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) {
1714 return undefined; 1722 return undefined;
1715 } 1723 }
1716 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { 1724 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
1717 switch (PredictException(it.frame())) { 1725 switch (PredictException(it.frame())) {
1718 case HandlerTable::UNCAUGHT: 1726 case HandlerTable::UNCAUGHT:
1719 break; 1727 break;
1720 case HandlerTable::CAUGHT: 1728 case HandlerTable::CAUGHT:
1721 case HandlerTable::DESUGARING: 1729 case HandlerTable::DESUGARING:
1722 return undefined; 1730 return undefined;
1723 case HandlerTable::PROMISE: 1731 case HandlerTable::PROMISE:
1724 case HandlerTable::ASYNC_AWAIT:
1725 return tltop->promise_on_stack_->promise(); 1732 return tltop->promise_on_stack_->promise();
1733 case HandlerTable::ASYNC_AWAIT: {
1734 // If in an async/await, pop up successive async/await stack frames
1735 // until an asynchronous one with dependents is found, or a non-async
1736 // stack frame is encountered, in order to handle the synchronous
1737 // async/await catch prediction case: assume that async function calls
1738 // are awaited.
1739 PromiseOnStack* promise_on_stack = tltop->promise_on_stack_;
1740 for (it.Advance(); !it.done(); it.Advance()) {
1741 if (PromiseHasUserDefinedRejectHandler(promise_on_stack->promise())) {
1742 break;
1743 }
1744 JavaScriptFrame* frame = it.frame();
1745 if (!frame->function()->shared()->is_async()) {
1746 // Keep searching up the stack until an async function stack frame
1747 // is found, heuristically assuming that that will ultimately await
1748 // whatever is going on here.
1749 continue;
1750 }
1751 PromiseOnStack* next_promise_on_stack = promise_on_stack->prev();
1752 if (next_promise_on_stack == nullptr) break;
1753 switch (PredictException(it.frame())) {
1754 case HandlerTable::CAUGHT:
1755 case HandlerTable::DESUGARING: {
1756 // Mark the inner promise as caught in the "synchronous case" so
1757 // that Debug::OnException will see.
1758 Handle<Symbol> key = factory()->promise_handled_hint_symbol();
1759 JSObject::SetProperty(promise_on_stack->promise(), key, key,
1760 STRICT)
1761 .Assert();
1762 return promise_on_stack->promise();
1763 }
1764 case HandlerTable::ASYNC_AWAIT:
1765 promise_on_stack = next_promise_on_stack;
1766 continue;
1767 case HandlerTable::PROMISE:
1768 case HandlerTable::UNCAUGHT:
1769 UNREACHABLE();
1770 }
1771 }
1772 return promise_on_stack->promise();
1773 }
1726 } 1774 }
1727 } 1775 }
1728 return undefined; 1776 return undefined;
1729 } 1777 }
1730 1778
1731 1779
1732 void Isolate::SetCaptureStackTraceForUncaughtExceptions( 1780 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
1733 bool capture, 1781 bool capture,
1734 int frame_limit, 1782 int frame_limit,
1735 StackTrace::StackTraceOptions options) { 1783 StackTrace::StackTraceOptions options) {
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after
3166 // Then check whether this scope intercepts. 3214 // Then check whether this scope intercepts.
3167 if ((flag & intercept_mask_)) { 3215 if ((flag & intercept_mask_)) {
3168 intercepted_flags_ |= flag; 3216 intercepted_flags_ |= flag;
3169 return true; 3217 return true;
3170 } 3218 }
3171 return false; 3219 return false;
3172 } 3220 }
3173 3221
3174 } // namespace internal 3222 } // namespace internal
3175 } // namespace v8 3223 } // namespace v8
OLDNEW
« 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