Chromium Code Reviews| Index: src/top.cc |
| =================================================================== |
| --- src/top.cc (revision 904) |
| +++ src/top.cc (working copy) |
| @@ -66,6 +66,8 @@ |
| void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { |
| v->VisitPointer(&(thread->pending_exception_)); |
| + v->VisitPointer(&(thread->pending_message_obj_)); |
| + v->VisitPointer(bit_cast<Object**, Script**>(&(thread->pending_message_script_))); |
| v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); |
| v->VisitPointer(&(thread->scheduled_exception_)); |
| @@ -99,6 +101,7 @@ |
| thread_local_.external_caught_exception_ = false; |
| thread_local_.failed_access_check_callback_ = NULL; |
| clear_pending_exception(); |
| + clear_pending_message(); |
| clear_scheduled_exception(); |
| thread_local_.save_context_ = NULL; |
| thread_local_.catcher_ = NULL; |
| @@ -736,7 +739,7 @@ |
| } |
| -bool Top::ShouldReportException(bool* is_caught_externally) { |
| +bool Top::IsUncaughtException(bool* is_caught_externally) { |
|
Søren Thygesen Gjesse
2008/12/04 07:53:53
This function does not only check whether the exce
olehougaard
2008/12/04 08:44:35
Reverting to the original name.
|
| StackHandler* handler = |
| StackHandler::FromAddress(Top::handler(Top::GetCurrentThread())); |
| @@ -791,9 +794,14 @@ |
| // Determine reporting and whether the exception is caught externally. |
| bool is_caught_externally = false; |
| - bool report_exception = (exception != Failure::OutOfMemoryException()) && |
| - ShouldReportException(&is_caught_externally); |
| + bool is_out_of_memory = exception == Failure::OutOfMemoryException(); |
| + bool is_uncaught_exception = IsUncaughtException(&is_caught_externally); |
| + bool report_exception = !is_out_of_memory && is_uncaught_exception; |
| + |
| + // Notify debugger of exception. |
| + Debugger::OnException(exception_handle, report_exception); |
| + |
| // Generate the message. |
| Handle<Object> message_obj; |
| MessageLocation potential_computed_location; |
| @@ -812,38 +820,66 @@ |
| location, HandleVector<Object>(&exception_handle, 1), stack_trace); |
| } |
| - // If the exception is caught externally, we store it in the |
| - // try/catch handler. The C code can find it later and process it if |
| - // necessary. |
| - thread_local_.catcher_ = NULL; |
| - if (is_caught_externally) { |
| - thread_local_.catcher_ = thread_local_.try_catch_handler_; |
| - thread_local_.try_catch_handler_->exception_ = |
| - reinterpret_cast<void*>(*exception_handle); |
| - if (!message_obj.is_null()) { |
| - thread_local_.try_catch_handler_->message_ = |
| - reinterpret_cast<void*>(*message_obj); |
| + // Save the message for reporting if the the exception remains uncaught. |
| + thread_local_.pending_message_ = message; |
| + if (!message_obj.is_null()) { |
| + thread_local_.pending_message_obj_ = *message_obj; |
| + if (location != NULL) { |
| + thread_local_.pending_message_script_ = *location->script(); |
| + thread_local_.pending_message_start_pos_ = location->start_pos(); |
| + thread_local_.pending_message_end_pos_ = location->end_pos(); |
| } |
| } |
| - // Notify debugger of exception. |
| - Debugger::OnException(exception_handle, report_exception); |
| - |
| - if (report_exception) { |
| - if (message != NULL) { |
| - MessageHandler::ReportMessage(message); |
| - } else if (!message_obj.is_null()) { |
| - MessageHandler::ReportMessage(location, message_obj); |
| - } |
| + if (is_caught_externally) { |
| + thread_local_.catcher_ = thread_local_.try_catch_handler_; |
| } |
| - // NOTE: Notifying the debugger or reporting the exception may have caused |
| - // new exceptions. For now, we just ignore that and set the pending exception |
| + // NOTE: Notifying the debugger may have caused new exceptions. |
|
Søren Thygesen Gjesse
2008/12/04 07:53:53
Generating the message without reporting it can al
olehougaard
2008/12/04 08:44:35
Updated the comment.
|
| + // For now, we just ignore that and set the pending exception |
| // to the original one. |
| set_pending_exception(*exception_handle); |
| } |
| +void Top::ReportPendingMessages() { |
| + ASSERT(has_pending_exception()); |
| + setup_external_caught(); |
| + // If the pending exception is OutOfMemoryException set out_of_memory in |
| + // the global context. Note: We have to mark the global context here |
| + // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to |
| + // set it. |
| + HandleScope scope; |
| + if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { |
| + context()->mark_out_of_memory(); |
| + } else { |
| + Handle<Object> exception(pending_exception()); |
| + if (thread_local_.external_caught_exception_) { |
| + thread_local_.try_catch_handler_->exception_ |
| + = thread_local_.pending_exception_; |
|
Mads Ager (chromium)
2008/12/03 15:44:48
We normally have the '=' on the previous line.
olehougaard
2008/12/04 08:44:35
Fixed.
|
| + if (!thread_local_.pending_message_obj_->IsTheHole()) { |
| + try_catch_handler()->message_ = thread_local_.pending_message_obj_; |
| + } |
| + } else if (thread_local_.pending_message_ != NULL) { |
| + MessageHandler::ReportMessage(thread_local_.pending_message_); |
| + } else if (!thread_local_.pending_message_obj_->IsTheHole()) { |
| + Handle<Object> message_obj(thread_local_.pending_message_obj_); |
| + if (thread_local_.pending_message_script_ != NULL) { |
| + Handle<Script> script(thread_local_.pending_message_script_); |
| + int start_pos = thread_local_.pending_message_start_pos_; |
| + int end_pos = thread_local_.pending_message_end_pos_; |
| + MessageLocation location(script, start_pos, end_pos); |
| + MessageHandler::ReportMessage(&location, message_obj); |
| + } else { |
| + MessageHandler::ReportMessage(NULL, message_obj); |
| + } |
| + } |
| + set_pending_exception(*exception); |
| + } |
| + clear_pending_message(); |
| +} |
| + |
| + |
| void Top::TraceException(bool flag) { |
| FLAG_trace_exception = flag; |
| } |