Index: src/top.cc |
=================================================================== |
--- src/top.cc (revision 1483) |
+++ src/top.cc (working copy) |
@@ -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; |
} |