Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 564fd7b64638694ba978725aa5776995a678f61a..2cb8116070cbf81c0cf51af086ca57f0e46d2c9d 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -107,6 +107,7 @@ void ThreadLocalTop::InitializeInternal() { |
// is complete. |
pending_exception_ = NULL; |
has_pending_message_ = false; |
+ rethrowing_message_ = false; |
pending_message_obj_ = NULL; |
pending_message_script_ = NULL; |
scheduled_exception_ = NULL; |
@@ -486,7 +487,8 @@ void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { |
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. |
@@ -1162,6 +1164,22 @@ void Isolate::ScheduleThrow(Object* exception) { |
} |
+void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) { |
+ ASSERT(handler == try_catch_handler()); |
+ ASSERT(handler->HasCaught()); |
+ ASSERT(handler->rethrow_); |
+ ASSERT(handler->capture_message_); |
+ Object* message = reinterpret_cast<Object*>(handler->message_obj_); |
+ Object* script = reinterpret_cast<Object*>(handler->message_script_); |
+ ASSERT(message->IsJSMessageObject() || message->IsTheHole()); |
+ ASSERT(script->IsScript() || script->IsTheHole()); |
+ thread_local_top()->pending_message_obj_ = message; |
+ thread_local_top()->pending_message_script_ = script; |
+ thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_; |
+ thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_; |
+} |
+ |
+ |
Failure* Isolate::PromoteScheduledException() { |
MaybeObject* thrown = scheduled_exception(); |
clear_scheduled_exception(); |
@@ -1280,9 +1298,12 @@ void Isolate::DoThrow(Object* exception, MessageLocation* location) { |
ShouldReportException(&can_be_caught_externally, catchable_by_javascript); |
bool report_exception = catchable_by_javascript && should_report_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()->rethrowing_message_; |
bool bootstrapping = bootstrapper()->IsActive(); |
+ thread_local_top()->rethrowing_message_ = false; |
+ |
#ifdef ENABLE_DEBUGGER_SUPPORT |
// Notify debugger of exception. |
if (catchable_by_javascript) { |
@@ -1464,8 +1485,9 @@ void Isolate::ReportPendingMessages() { |
HandleScope scope(this); |
Handle<Object> message_obj(thread_local_top_.pending_message_obj_, |
this); |
- if (thread_local_top_.pending_message_script_ != NULL) { |
- Handle<Script> script(thread_local_top_.pending_message_script_); |
+ if (!thread_local_top_.pending_message_script_->IsTheHole()) { |
+ Handle<Script> script( |
+ Script::cast(thread_local_top_.pending_message_script_)); |
int start_pos = thread_local_top_.pending_message_start_pos_; |
int end_pos = thread_local_top_.pending_message_end_pos_; |
MessageLocation location(script, start_pos, end_pos); |
@@ -1487,8 +1509,9 @@ MessageLocation Isolate::GetMessageLocation() { |
thread_local_top_.pending_exception_ != heap()->termination_exception() && |
thread_local_top_.has_pending_message_ && |
!thread_local_top_.pending_message_obj_->IsTheHole() && |
- thread_local_top_.pending_message_script_ != NULL) { |
- Handle<Script> script(thread_local_top_.pending_message_script_); |
+ !thread_local_top_.pending_message_obj_->IsTheHole()) { |
+ Handle<Script> script( |
+ Script::cast(thread_local_top_.pending_message_script_)); |
int start_pos = thread_local_top_.pending_message_start_pos_; |
int end_pos = thread_local_top_.pending_message_end_pos_; |
return MessageLocation(script, start_pos, end_pos); |
@@ -2041,15 +2064,24 @@ void Isolate::PropagatePendingExceptionToExternalTryCatch() { |
try_catch_handler()->has_terminated_ = true; |
try_catch_handler()->exception_ = heap()->null_value(); |
} else { |
+ v8::TryCatch* handler = try_catch_handler(); |
// At this point all non-object (failure) exceptions have |
// been dealt with so this shouldn't fail. |
ASSERT(!pending_exception()->IsFailure()); |
- try_catch_handler()->can_continue_ = true; |
- 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_; |
- } |
+ ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() || |
+ thread_local_top_.pending_message_obj_->IsTheHole()); |
+ ASSERT(thread_local_top_.pending_message_script_->IsScript() || |
+ thread_local_top_.pending_message_script_->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; |
+ |
+ handler->message_obj_ = thread_local_top_.pending_message_obj_; |
+ handler->message_script_ = thread_local_top_.pending_message_script_; |
+ handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_; |
+ handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_; |
} |
} |