| 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_;
|
| }
|
| }
|
|
|
|
|