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 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 thread_local_top()->pending_handler_code_ = code; | 1289 thread_local_top()->pending_handler_code_ = code; |
1290 thread_local_top()->pending_handler_offset_ = offset; | 1290 thread_local_top()->pending_handler_offset_ = offset; |
1291 thread_local_top()->pending_handler_fp_ = handler_fp; | 1291 thread_local_top()->pending_handler_fp_ = handler_fp; |
1292 thread_local_top()->pending_handler_sp_ = handler_sp; | 1292 thread_local_top()->pending_handler_sp_ = handler_sp; |
1293 | 1293 |
1294 // Return and clear pending exception. | 1294 // Return and clear pending exception. |
1295 clear_pending_exception(); | 1295 clear_pending_exception(); |
1296 return exception; | 1296 return exception; |
1297 } | 1297 } |
1298 | 1298 |
| 1299 namespace { |
| 1300 HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) { |
| 1301 HandlerTable::CatchPrediction prediction; |
| 1302 if (frame->is_optimized()) { |
| 1303 if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) { |
| 1304 // This optimized frame will catch. It's handler table does not include |
| 1305 // exception prediction, and we need to use the corresponding handler |
| 1306 // tables on the unoptimized code objects. |
| 1307 List<FrameSummary> summaries; |
| 1308 frame->Summarize(&summaries); |
| 1309 for (const FrameSummary& summary : summaries) { |
| 1310 int code_offset = summary.code_offset(); |
| 1311 int index = summary.abstract_code()->LookupRangeInHandlerTable( |
| 1312 code_offset, nullptr, &prediction); |
| 1313 if (index <= 0) continue; |
| 1314 if (prediction == HandlerTable::UNCAUGHT) continue; |
| 1315 return prediction; |
| 1316 } |
| 1317 } |
| 1318 } else if (frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) { |
| 1319 return prediction; |
| 1320 } |
| 1321 return HandlerTable::UNCAUGHT; |
| 1322 } |
| 1323 } // anonymous namespace |
1299 | 1324 |
1300 Isolate::CatchType Isolate::PredictExceptionCatcher() { | 1325 Isolate::CatchType Isolate::PredictExceptionCatcher() { |
1301 Address external_handler = thread_local_top()->try_catch_handler_address(); | 1326 Address external_handler = thread_local_top()->try_catch_handler_address(); |
1302 Address entry_handler = Isolate::handler(thread_local_top()); | 1327 Address entry_handler = Isolate::handler(thread_local_top()); |
1303 if (IsExternalHandlerOnTop(nullptr)) return CAUGHT_BY_EXTERNAL; | 1328 if (IsExternalHandlerOnTop(nullptr)) return CAUGHT_BY_EXTERNAL; |
1304 | 1329 |
1305 // Search for an exception handler by performing a full walk over the stack. | 1330 // Search for an exception handler by performing a full walk over the stack. |
1306 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { | 1331 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { |
1307 StackFrame* frame = iter.frame(); | 1332 StackFrame* frame = iter.frame(); |
1308 | 1333 |
1309 // For JSEntryStub frames we update the JS_ENTRY handler. | 1334 // For JSEntryStub frames we update the JS_ENTRY handler. |
1310 if (frame->is_entry() || frame->is_entry_construct()) { | 1335 if (frame->is_entry() || frame->is_entry_construct()) { |
1311 entry_handler = frame->top_handler()->next()->address(); | 1336 entry_handler = frame->top_handler()->next()->address(); |
1312 } | 1337 } |
1313 | 1338 |
1314 // For JavaScript frames we perform a lookup in the handler table. | 1339 // For JavaScript frames we perform a lookup in the handler table. |
1315 if (frame->is_java_script()) { | 1340 if (frame->is_java_script()) { |
1316 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); | 1341 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame); |
1317 HandlerTable::CatchPrediction prediction; | 1342 if (PredictException(js_frame) != HandlerTable::UNCAUGHT) { |
1318 if (js_frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) { | 1343 return CAUGHT_BY_JAVASCRIPT; |
1319 // We are conservative with our prediction: try-finally is considered | |
1320 // to always rethrow, to meet the expectation of the debugger. | |
1321 if (prediction != HandlerTable::UNCAUGHT) return CAUGHT_BY_JAVASCRIPT; | |
1322 } | 1344 } |
1323 } | 1345 } |
1324 | 1346 |
1325 // The exception has been externally caught if and only if there is an | 1347 // 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. | 1348 // external handler which is on top of the top-most JS_ENTRY handler. |
1327 if (external_handler != nullptr && !try_catch_handler()->is_verbose_) { | 1349 if (external_handler != nullptr && !try_catch_handler()->is_verbose_) { |
1328 if (entry_handler == nullptr || entry_handler > external_handler) { | 1350 if (entry_handler == nullptr || entry_handler > external_handler) { |
1329 return CAUGHT_BY_EXTERNAL; | 1351 return CAUGHT_BY_EXTERNAL; |
1330 } | 1352 } |
1331 } | 1353 } |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 } | 1745 } |
1724 | 1746 |
1725 | 1747 |
1726 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { | 1748 Handle<Object> Isolate::GetPromiseOnStackOnThrow() { |
1727 Handle<Object> undefined = factory()->undefined_value(); | 1749 Handle<Object> undefined = factory()->undefined_value(); |
1728 ThreadLocalTop* tltop = thread_local_top(); | 1750 ThreadLocalTop* tltop = thread_local_top(); |
1729 if (tltop->promise_on_stack_ == NULL) return undefined; | 1751 if (tltop->promise_on_stack_ == NULL) return undefined; |
1730 // Find the top-most try-catch or try-finally handler. | 1752 // Find the top-most try-catch or try-finally handler. |
1731 if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined; | 1753 if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined; |
1732 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { | 1754 for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) { |
1733 JavaScriptFrame* frame = it.frame(); | 1755 switch (PredictException(it.frame())) { |
1734 HandlerTable::CatchPrediction prediction; | 1756 case HandlerTable::UNCAUGHT: |
1735 if (frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) { | 1757 break; |
1736 // Throwing inside a Promise only leads to a reject if not caught by an | 1758 case HandlerTable::CAUGHT: |
1737 // inner try-catch or try-finally. | 1759 return undefined; |
1738 if (prediction == HandlerTable::PROMISE) { | 1760 case HandlerTable::PROMISE: |
1739 return tltop->promise_on_stack_->promise(); | 1761 return tltop->promise_on_stack_->promise(); |
1740 } | |
1741 return undefined; | |
1742 } | 1762 } |
1743 } | 1763 } |
1744 return undefined; | 1764 return undefined; |
1745 } | 1765 } |
1746 | 1766 |
1747 | 1767 |
1748 void Isolate::SetCaptureStackTraceForUncaughtExceptions( | 1768 void Isolate::SetCaptureStackTraceForUncaughtExceptions( |
1749 bool capture, | 1769 bool capture, |
1750 int frame_limit, | 1770 int frame_limit, |
1751 StackTrace::StackTraceOptions options) { | 1771 StackTrace::StackTraceOptions options) { |
(...skipping 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3179 // Then check whether this scope intercepts. | 3199 // Then check whether this scope intercepts. |
3180 if ((flag & intercept_mask_)) { | 3200 if ((flag & intercept_mask_)) { |
3181 intercepted_flags_ |= flag; | 3201 intercepted_flags_ |= flag; |
3182 return true; | 3202 return true; |
3183 } | 3203 } |
3184 return false; | 3204 return false; |
3185 } | 3205 } |
3186 | 3206 |
3187 } // namespace internal | 3207 } // namespace internal |
3188 } // namespace v8 | 3208 } // namespace v8 |
OLD | NEW |