OLD | NEW |
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 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 // For JSEntryStub frames we update the JS_ENTRY handler. | 1312 // For JSEntryStub frames we update the JS_ENTRY handler. |
1313 if (frame->is_entry() || frame->is_entry_construct()) { | 1313 if (frame->is_entry() || frame->is_entry_construct()) { |
1314 entry_handler = frame->top_handler()->next()->address(); | 1314 entry_handler = frame->top_handler()->next()->address(); |
1315 } | 1315 } |
1316 | 1316 |
1317 // For JavaScript frames we perform a lookup in the handler table. | 1317 // For JavaScript frames we perform a lookup in the handler table. |
1318 if (frame->is_java_script()) { | 1318 if (frame->is_java_script()) { |
1319 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); | 1319 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); |
1320 HandlerTable::CatchPrediction prediction = PredictException(js_frame); | 1320 HandlerTable::CatchPrediction prediction = PredictException(js_frame); |
1321 if (prediction == HandlerTable::DESUGARING) return CAUGHT_BY_DESUGARING; | 1321 if (prediction == HandlerTable::DESUGARING) return CAUGHT_BY_DESUGARING; |
| 1322 if (prediction == HandlerTable::ASYNC_AWAIT) return CAUGHT_BY_ASYNC_AWAIT; |
1322 if (prediction != HandlerTable::UNCAUGHT) return CAUGHT_BY_JAVASCRIPT; | 1323 if (prediction != HandlerTable::UNCAUGHT) return CAUGHT_BY_JAVASCRIPT; |
1323 } | 1324 } |
1324 | 1325 |
1325 // The exception has been externally caught if and only if there is an | 1326 // The exception has been externally caught if and only if there is an |
1326 // external handler which is on top of the top-most JS_ENTRY handler. | 1327 // external handler which is on top of the top-most JS_ENTRY handler. |
1327 if (external_handler != nullptr && !try_catch_handler()->is_verbose_) { | 1328 if (external_handler != nullptr && !try_catch_handler()->is_verbose_) { |
1328 if (entry_handler == nullptr || entry_handler > external_handler) { | 1329 if (entry_handler == nullptr || entry_handler > external_handler) { |
1329 return CAUGHT_BY_EXTERNAL; | 1330 return CAUGHT_BY_EXTERNAL; |
1330 } | 1331 } |
1331 } | 1332 } |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 void Isolate::PopPromise() { | 1719 void Isolate::PopPromise() { |
1719 ThreadLocalTop* tltop = thread_local_top(); | 1720 ThreadLocalTop* tltop = thread_local_top(); |
1720 if (tltop->promise_on_stack_ == NULL) return; | 1721 if (tltop->promise_on_stack_ == NULL) return; |
1721 PromiseOnStack* prev = tltop->promise_on_stack_->prev(); | 1722 PromiseOnStack* prev = tltop->promise_on_stack_->prev(); |
1722 Handle<Object> global_promise = tltop->promise_on_stack_->promise(); | 1723 Handle<Object> global_promise = tltop->promise_on_stack_->promise(); |
1723 delete tltop->promise_on_stack_; | 1724 delete tltop->promise_on_stack_; |
1724 tltop->promise_on_stack_ = prev; | 1725 tltop->promise_on_stack_ = prev; |
1725 global_handles()->Destroy(global_promise.location()); | 1726 global_handles()->Destroy(global_promise.location()); |
1726 } | 1727 } |
1727 | 1728 |
| 1729 bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<JSObject> promise) { |
| 1730 Handle<JSFunction> fun = promise_has_user_defined_reject_handler(); |
| 1731 Handle<Object> has_reject_handler; |
| 1732 ASSIGN_RETURN_ON_EXCEPTION_VALUE(this, has_reject_handler, |
| 1733 Execution::Call(this, fun, promise, 0, NULL), |
| 1734 false); |
| 1735 return has_reject_handler->IsTrue(this); |
| 1736 } |
1728 | 1737 |
1729 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { | 1738 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { |
1730 Handle<Object> undefined = factory()->undefined_value(); | 1739 Handle<Object> undefined = factory()->undefined_value(); |
1731 ThreadLocalTop* tltop = thread_local_top(); | 1740 ThreadLocalTop* tltop = thread_local_top(); |
1732 if (tltop->promise_on_stack_ == NULL) return undefined; | 1741 if (tltop->promise_on_stack_ == NULL) return undefined; |
1733 // Find the top-most try-catch or try-finally handler. | 1742 // Find the top-most try-catch or try-finally handler. |
1734 CatchType prediction = PredictExceptionCatcher(); | 1743 CatchType prediction = PredictExceptionCatcher(); |
1735 if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) { | 1744 if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) { |
1736 return undefined; | 1745 return undefined; |
1737 } | 1746 } |
1738 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { | 1747 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { |
1739 switch (PredictException(it.frame())) { | 1748 switch (PredictException(it.frame())) { |
1740 case HandlerTable::UNCAUGHT: | 1749 case HandlerTable::UNCAUGHT: |
1741 break; | 1750 break; |
1742 case HandlerTable::CAUGHT: | 1751 case HandlerTable::CAUGHT: |
1743 case HandlerTable::DESUGARING: | 1752 case HandlerTable::DESUGARING: |
1744 return undefined; | 1753 return undefined; |
1745 case HandlerTable::PROMISE: | 1754 case HandlerTable::PROMISE: |
1746 return tltop->promise_on_stack_->promise(); | 1755 return tltop->promise_on_stack_->promise(); |
| 1756 case HandlerTable::ASYNC_AWAIT: { |
| 1757 // If in an async/await, pop up successive async/await stack frames |
| 1758 // until an asynchronous one with dependents is found, or a non-async |
| 1759 // stack frame is encountered, in order to handle the synchronous |
| 1760 // async/await catch prediction case: assume that async function calls |
| 1761 // are awaited. |
| 1762 PromiseOnStack* promise_on_stack = tltop->promise_on_stack_; |
| 1763 for (it.Advance(); !it.done(); it.Advance()) { |
| 1764 if (PromiseHasUserDefinedRejectHandler(promise_on_stack->promise())) { |
| 1765 break; |
| 1766 } |
| 1767 JavaScriptFrame* frame = it.frame(); |
| 1768 if (!frame->function()->shared()->is_async()) { |
| 1769 // Keep searching up the stack until an async function stack frame |
| 1770 // is found, heuristically assuming that that will ultimately await |
| 1771 // whatever is going on here. |
| 1772 continue; |
| 1773 } |
| 1774 PromiseOnStack* next_promise_on_stack = promise_on_stack->prev(); |
| 1775 if (next_promise_on_stack == nullptr) break; |
| 1776 switch (PredictException(it.frame())) { |
| 1777 case HandlerTable::CAUGHT: |
| 1778 case HandlerTable::DESUGARING: { |
| 1779 // Mark the inner promise as caught in the "synchronous case" so |
| 1780 // that Debug::OnException will see. |
| 1781 Handle<Symbol> key = factory()->promise_handled_hint_symbol(); |
| 1782 JSObject::SetProperty(promise_on_stack->promise(), key, key, |
| 1783 STRICT) |
| 1784 .Assert(); |
| 1785 return promise_on_stack->promise(); |
| 1786 } |
| 1787 case HandlerTable::ASYNC_AWAIT: |
| 1788 promise_on_stack = next_promise_on_stack; |
| 1789 continue; |
| 1790 case HandlerTable::PROMISE: |
| 1791 case HandlerTable::UNCAUGHT: |
| 1792 UNREACHABLE(); |
| 1793 } |
| 1794 } |
| 1795 return promise_on_stack->promise(); |
| 1796 } |
1747 } | 1797 } |
1748 } | 1798 } |
1749 return undefined; | 1799 return undefined; |
1750 } | 1800 } |
1751 | 1801 |
1752 | 1802 |
1753 void Isolate::SetCaptureStackTraceForUncaughtExceptions( | 1803 void Isolate::SetCaptureStackTraceForUncaughtExceptions( |
1754 bool capture, | 1804 bool capture, |
1755 int frame_limit, | 1805 int frame_limit, |
1756 StackTrace::StackTraceOptions options) { | 1806 StackTrace::StackTraceOptions options) { |
(...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3179 // Then check whether this scope intercepts. | 3229 // Then check whether this scope intercepts. |
3180 if ((flag & intercept_mask_)) { | 3230 if ((flag & intercept_mask_)) { |
3181 intercepted_flags_ |= flag; | 3231 intercepted_flags_ |= flag; |
3182 return true; | 3232 return true; |
3183 } | 3233 } |
3184 return false; | 3234 return false; |
3185 } | 3235 } |
3186 | 3236 |
3187 } // namespace internal | 3237 } // namespace internal |
3188 } // namespace v8 | 3238 } // namespace v8 |
OLD | NEW |