Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 35b935fbc3571ac613aec806c3254db98d61715c..62dad8df706c2b265eab7e43f24e72c07c22c1c0 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -1143,7 +1143,7 @@ void Isolate::ScheduleThrow(Object* exception) { |
// When scheduling a throw we first throw the exception to get the |
// error reporting if it is uncaught before rescheduling it. |
Throw(exception); |
- PropagatePendingExceptionToExternalTryCatch(); |
+ ReportPendingMessages(); |
if (has_pending_exception()) { |
thread_local_top()->scheduled_exception_ = pending_exception(); |
thread_local_top()->external_caught_exception_ = false; |
@@ -1410,32 +1410,50 @@ bool Isolate::IsExternalHandlerOnTop(Object* exception) { |
void Isolate::ReportPendingMessages() { |
Object* exception = pending_exception(); |
- // Try to propagate the exception to an external v8::TryCatch handler. If |
- // propagation was unsuccessful, then we will get another chance at reporting |
- // the pending message if the exception is re-thrown. |
- bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch(); |
- if (!has_been_propagated) return; |
- |
- // Clear the pending message object early to avoid endless recursion. |
- Object* message_obj = thread_local_top_.pending_message_obj_; |
- clear_pending_message(); |
- |
- // For uncatchable exceptions we do nothing. If needed, the exception and the |
- // message have already been propagated to v8::TryCatch. |
- if (!is_catchable_by_javascript(exception)) return; |
+ // Propagation is unsuccessful because there still is a JavaScript handler on |
+ // top that might catch the exception and hence prevent message reporting. |
+ if (IsJavaScriptHandlerOnTop(exception)) { |
+ thread_local_top_.external_caught_exception_ = false; |
+ return; |
+ } |
// Determine whether the message needs to be reported to all message handlers |
- // depending on whether and external v8::TryCatch or an internal JavaScript |
- // handler is on top. |
+ // depending on whether an external v8::TryCatch handler is on top. |
bool should_report_exception; |
+ Object* message_obj = thread_local_top_.pending_message_obj_; |
+ DCHECK(message_obj->IsJSMessageObject() || message_obj->IsTheHole()); |
if (IsExternalHandlerOnTop(exception)) { |
+ // Propagate the exception to an external v8::TryCatch handler. |
+ if (!is_catchable_by_javascript(exception)) { |
+ try_catch_handler()->can_continue_ = false; |
+ try_catch_handler()->has_terminated_ = true; |
+ try_catch_handler()->exception_ = heap()->null_value(); |
+ } else { |
+ try_catch_handler()->can_continue_ = true; |
+ try_catch_handler()->has_terminated_ = false; |
+ try_catch_handler()->exception_ = exception; |
+ // Propagate to the external try-catch only if we got an actual message. |
+ if (!message_obj->IsTheHole()) { |
+ try_catch_handler()->message_obj_ = message_obj; |
+ } |
+ } |
+ |
// Only report the exception if the external handler is verbose. |
+ thread_local_top_.external_caught_exception_ = true; |
should_report_exception = try_catch_handler()->is_verbose_; |
} else { |
- // Report the exception if it isn't caught by JavaScript code. |
- should_report_exception = !IsJavaScriptHandlerOnTop(exception); |
+ // Report the exception because it cannot be caught by JavaScript code. |
+ thread_local_top_.external_caught_exception_ = false; |
+ should_report_exception = true; |
} |
+ // Clear the pending message object early to avoid endless recursion. |
+ clear_pending_message(); |
+ |
+ // For uncatchable exceptions we do nothing. If needed, the exception and the |
+ // message have already been propagated to v8::TryCatch. |
+ if (!is_catchable_by_javascript(exception)) return; |
+ |
// Actually report the pending message to all message handlers. |
if (!message_obj->IsTheHole() && should_report_exception) { |
HandleScope scope(this); |
@@ -1470,7 +1488,7 @@ MessageLocation Isolate::GetMessageLocation() { |
bool Isolate::OptionalRescheduleException(bool is_bottom_call) { |
DCHECK(has_pending_exception()); |
- PropagatePendingExceptionToExternalTryCatch(); |
+ ReportPendingMessages(); |
bool is_termination_exception = |
pending_exception() == heap_.termination_exception(); |
@@ -1950,40 +1968,6 @@ void Isolate::InitializeThreadLocal() { |
} |
-bool Isolate::PropagatePendingExceptionToExternalTryCatch() { |
- Object* exception = pending_exception(); |
- |
- if (IsJavaScriptHandlerOnTop(exception)) { |
- thread_local_top_.external_caught_exception_ = false; |
- return false; |
- } |
- |
- if (!IsExternalHandlerOnTop(exception)) { |
- thread_local_top_.external_caught_exception_ = false; |
- return true; |
- } |
- |
- thread_local_top_.external_caught_exception_ = true; |
- if (!is_catchable_by_javascript(exception)) { |
- try_catch_handler()->can_continue_ = false; |
- try_catch_handler()->has_terminated_ = true; |
- try_catch_handler()->exception_ = heap()->null_value(); |
- } else { |
- v8::TryCatch* handler = try_catch_handler(); |
- DCHECK(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
- thread_local_top_.pending_message_obj_->IsTheHole()); |
- handler->can_continue_ = true; |
- handler->has_terminated_ = false; |
- handler->exception_ = pending_exception(); |
- // Propagate to the external try-catch only if we got an actual message. |
- if (thread_local_top_.pending_message_obj_->IsTheHole()) return true; |
- |
- handler->message_obj_ = thread_local_top_.pending_message_obj_; |
- } |
- return true; |
-} |
- |
- |
void Isolate::InitializeLoggingAndCounters() { |
if (logger_ == NULL) { |
logger_ = new Logger(this); |