Chromium Code Reviews| Index: src/top.cc |
| diff --git a/src/top.cc b/src/top.cc |
| index e32eb6bc8b2677b64db262582b9c48c112d4033b..6b85af268c8cf5e07a78b17bbf365e15b29af726 100644 |
| --- a/src/top.cc |
| +++ b/src/top.cc |
| @@ -924,38 +924,62 @@ void Top::DoThrow(MaybeObject* exception, |
| } |
| +void Top::PropagatePendingExceptionToExteranlTryCatch() { |
| + ASSERT(has_pending_exception()); |
| + |
| + if (!thread_local_.external_caught_exception_) return; |
| + |
| + if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { |
| + // Do not propagate OOM exception: we should kill VM asap. |
| + } else if (thread_local_.pending_exception_ == |
| + Heap::termination_exception()) { |
| + thread_local_.TryCatchHandler()->can_continue_ = false; |
|
Vitaly Repeshko
2011/01/28 14:03:33
try_catch_handler() is a nicer alias for thread_lo
antonm
2011/01/28 14:43:18
Done.
|
| + thread_local_.TryCatchHandler()->exception_ = Heap::null_value(); |
| + } else { |
| + // At this point all non-object (failure) exceptions have |
| + // been dealt with so this shouldn't fail. |
| + Object* pending_exception_object = pending_exception()->ToObjectUnchecked(); |
| + Handle<Object> exception(pending_exception_object); |
|
Vitaly Repeshko
2011/01/28 14:03:33
Unused? If it is intended to be used, shouldn't we
antonm
2011/01/28 14:43:18
Thanks a lot, indeed unused.
|
| + thread_local_.TryCatchHandler()->can_continue_ = true; |
| + thread_local_.TryCatchHandler()->exception_ = |
| + thread_local_.pending_exception_; |
| + if (!thread_local_.pending_message_obj_->IsTheHole()) { |
| + try_catch_handler()->message_ = thread_local_.pending_message_obj_; |
| + } |
| + } |
| +} |
| + |
| + |
| void Top::ReportPendingMessages() { |
|
Vitaly Repeshko
2011/01/28 14:03:33
It reports only a single message, doesn't it? Drop
antonm
2011/01/28 14:43:18
I don't know. Let's investigate it later.
|
| ASSERT(has_pending_exception()); |
| setup_external_caught(); |
|
Vitaly Repeshko
2011/01/28 14:03:33
This looks slightly backwards: one function sets a
antonm
2011/01/28 14:43:18
I don't want to rework the things too much. I agr
|
| + PropagatePendingExceptionToExteranlTryCatch(); |
| + |
| + bool external_caught = thread_local_.external_caught_exception_; |
| // 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. |
| - bool external_caught = thread_local_.external_caught_exception_; |
| - HandleScope scope; |
| if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) { |
| context()->mark_out_of_memory(); |
| } else if (thread_local_.pending_exception_ == |
| Heap::termination_exception()) { |
| - if (external_caught) { |
| - thread_local_.TryCatchHandler()->can_continue_ = false; |
| - thread_local_.TryCatchHandler()->exception_ = Heap::null_value(); |
| - } |
| + // Do nothing: if needed, the exception has been already propagated to |
| + // v8::TryCatch. |
| } else { |
| - // At this point all non-object (failure) exceptions have |
| - // been dealt with so this shouldn't fail. |
| - Object* pending_exception_object = pending_exception()->ToObjectUnchecked(); |
| - Handle<Object> exception(pending_exception_object); |
| - thread_local_.external_caught_exception_ = false; |
| - if (external_caught) { |
| - thread_local_.TryCatchHandler()->can_continue_ = true; |
| - thread_local_.TryCatchHandler()->exception_ = |
| - thread_local_.pending_exception_; |
| - if (!thread_local_.pending_message_obj_->IsTheHole()) { |
| - try_catch_handler()->message_ = thread_local_.pending_message_obj_; |
| - } |
| - } |
| if (thread_local_.has_pending_message_) { |
|
Vitaly Repeshko
2011/01/28 14:03:33
Join with "else" above?
antonm
2011/01/28 14:43:18
I'd like to keep identical structure of failure an
|
| + HandleScope scope; |
| + |
| + // At this point all non-object (failure) exceptions have |
| + // been dealt with so this shouldn't fail. |
| + Object* pending_exception_obj = pending_exception()->ToObjectUnchecked(); |
| + // Message reporting executes arbitrary embedder's code and hence |
| + // we need to save this state. |
| + // TODO(antonm): consider saving the whole thread_local_. |
|
Vitaly Repeshko
2011/01/28 14:03:33
I don't think we should save the whole thread loca
antonm
2011/01/28 14:43:18
Yep, that's why I left it as todo (there is this f
|
| + Handle<Object> exception(pending_exception_obj); |
| + thread_local_.external_caught_exception_ = false; |
| + v8::TryCatch* former_catcher = thread_local_.catcher_; |
| + |
|
Mads Ager (chromium)
2011/01/28 11:39:18
Clear pending exception here instead of in ReportM
antonm
2011/01/28 13:37:25
See above.
Vitaly Repeshko
2011/01/28 14:03:33
I agree. This logic should be all moved here.
antonm
2011/01/28 14:43:18
See patch 2.
|
| thread_local_.has_pending_message_ = false; |
| if (thread_local_.pending_message_ != NULL) { |
| MessageHandler::ReportMessage(thread_local_.pending_message_); |
| @@ -971,9 +995,12 @@ void Top::ReportPendingMessages() { |
| MessageHandler::ReportMessage(NULL, message_obj); |
| } |
| } |
| + |
| + // Restore previously saved state. |
| + thread_local_.catcher_ = former_catcher; |
| + thread_local_.external_caught_exception_ = external_caught; |
| + set_pending_exception(*exception); |
| } |
| - thread_local_.external_caught_exception_ = external_caught; |
| - set_pending_exception(*exception); |
| } |
| clear_pending_message(); |
| } |
| @@ -985,6 +1012,9 @@ void Top::TraceException(bool flag) { |
| bool Top::OptionalRescheduleException(bool is_bottom_call) { |
| + setup_external_caught(); |
| + PropagatePendingExceptionToExteranlTryCatch(); |
| + |
| // Allways reschedule out of memory exceptions. |
| if (!is_out_of_memory()) { |
| bool is_termination_exception = |