Index: src/isolate.cc |
=================================================================== |
--- src/isolate.cc (revision 14909) |
+++ src/isolate.cc (working copy) |
@@ -107,6 +107,7 @@ |
// is complete. |
pending_exception_ = NULL; |
has_pending_message_ = false; |
+ restoring_message_ = false; |
pending_message_obj_ = NULL; |
pending_message_script_ = NULL; |
scheduled_exception_ = NULL; |
@@ -480,7 +481,8 @@ |
block != NULL; |
block = TRY_CATCH_FROM_ADDRESS(block->next_)) { |
v->VisitPointer(BitCast<Object**>(&(block->exception_))); |
- v->VisitPointer(BitCast<Object**>(&(block->message_))); |
+ v->VisitPointer(BitCast<Object**>(&(block->message_obj_))); |
+ v->VisitPointer(BitCast<Object**>(&(block->message_script_))); |
} |
// Iterate over pointers on native execution stack. |
@@ -1156,6 +1158,19 @@ |
} |
+void Isolate::RestoreMessage(Object* message, Script* script, |
+ int start_pos, int end_pos) { |
+ // Flag is checked in DoThrow(), which immediately follows. |
+ thread_local_top()->restoring_message_ = true; |
+ thread_local_top()->pending_message_obj_ = message; |
+ if (script) { |
+ thread_local_top()->pending_message_script_ = script; |
+ } |
+ thread_local_top()->pending_message_start_pos_ = start_pos; |
+ thread_local_top()->pending_message_end_pos_ = end_pos; |
+} |
+ |
+ |
Failure* Isolate::PromoteScheduledException() { |
MaybeObject* thrown = scheduled_exception(); |
clear_scheduled_exception(); |
@@ -1273,10 +1288,18 @@ |
bool should_report_exception = |
ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
bool report_exception = catchable_by_javascript && should_report_exception; |
+ // When determining if a message needs to be generated, make sure to check |
+ // restoring_message_. If an external TryCatch re-threw an exception, it |
+ // will have already called RestoreMessage() to put the original message, |
+ // script, and location back in place. In that case, this code must not |
+ // clobber the values computed from the original exception. |
bool try_catch_needs_message = |
- can_be_caught_externally && try_catch_handler()->capture_message_; |
+ can_be_caught_externally && try_catch_handler()->capture_message_ && |
+ !thread_local_top_.restoring_message_; |
bool bootstrapping = bootstrapper()->IsActive(); |
+ thread_local_top_.restoring_message_ = false; |
+ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
// Notify debugger of exception. |
if (catchable_by_javascript) { |
@@ -2041,7 +2064,16 @@ |
try_catch_handler()->has_terminated_ = false; |
try_catch_handler()->exception_ = pending_exception(); |
if (!thread_local_top_.pending_message_obj_->IsTheHole()) { |
- try_catch_handler()->message_ = thread_local_top_.pending_message_obj_; |
+ try_catch_handler()->message_obj_ = |
+ thread_local_top_.pending_message_obj_; |
+ if (!thread_local_top_.pending_message_script_->IsTheHole()) { |
+ try_catch_handler()->message_script_ = |
+ thread_local_top_.pending_message_script_; |
+ } |
+ try_catch_handler()->message_start_pos_ = |
+ thread_local_top_.pending_message_start_pos_; |
+ try_catch_handler()->message_end_pos_ = |
+ thread_local_top_.pending_message_end_pos_; |
} |
} |
} |