| 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); | 
|  |