Index: src/top.cc |
=================================================================== |
--- src/top.cc (revision 1639) |
+++ src/top.cc (working copy) |
@@ -285,6 +285,7 @@ |
void Top::UnregisterTryCatchHandler(v8::TryCatch* that) { |
ASSERT(thread_local_.try_catch_handler_ == that); |
thread_local_.try_catch_handler_ = that->next_; |
+ thread_local_.catcher_ = NULL; |
} |
@@ -724,10 +725,9 @@ |
// Determine reporting and whether the exception is caught externally. |
bool is_caught_externally = false; |
bool is_out_of_memory = exception == Failure::OutOfMemoryException(); |
- bool should_return_exception = ShouldReportException(&is_caught_externally); |
+ bool should_return_exception = ShouldReportException(&is_caught_externally); |
bool report_exception = !is_out_of_memory && should_return_exception; |
- |
// Notify debugger of exception. |
Debugger::OnException(exception_handle, report_exception); |
@@ -823,16 +823,36 @@ |
bool Top::optional_reschedule_exception(bool is_bottom_call) { |
- if (!is_out_of_memory() && |
- (thread_local_.external_caught_exception_ || is_bottom_call)) { |
- thread_local_.external_caught_exception_ = false; |
- clear_pending_exception(); |
- return false; |
- } else { |
- thread_local_.scheduled_exception_ = pending_exception(); |
- clear_pending_exception(); |
- return true; |
+ // Allways reschedule out of memory exceptions. |
+ if (!is_out_of_memory()) { |
+ // Never reschedule the exception if this is the bottom call. |
+ bool clear_exception = is_bottom_call; |
+ |
+ // If the exception is externally caught, clear it if there are no |
+ // JavaScript frames on the way to the C++ frame that has the |
+ // external handler. |
+ if (thread_local_.external_caught_exception_) { |
+ ASSERT(thread_local_.try_catch_handler_ != NULL); |
+ Address external_handler_address = |
+ reinterpret_cast<Address>(thread_local_.try_catch_handler_); |
+ JavaScriptFrameIterator it; |
+ if (it.done() || (it.frame()->sp() > external_handler_address)) { |
+ clear_exception = true; |
+ } |
+ } |
+ |
+ // Clear the exception if needed. |
+ if (clear_exception) { |
+ thread_local_.external_caught_exception_ = false; |
+ clear_pending_exception(); |
+ return false; |
+ } |
} |
+ |
+ // Reschedule the exception. |
+ thread_local_.scheduled_exception_ = pending_exception(); |
+ clear_pending_exception(); |
+ return true; |
} |