Commit 98525aab authored by feng@chromium.org's avatar feng@chromium.org

Fix the exception order by remember JS handler in an external handler.

Review URL: http://codereview.chromium.org/10625

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@744 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 47c71e84
...@@ -2052,6 +2052,7 @@ class EXPORT TryCatch { ...@@ -2052,6 +2052,7 @@ class EXPORT TryCatch {
void* message_; void* message_;
bool is_verbose_; bool is_verbose_;
bool capture_message_; bool capture_message_;
void* js_handler_;
}; };
......
...@@ -1081,7 +1081,8 @@ v8::TryCatch::TryCatch() ...@@ -1081,7 +1081,8 @@ v8::TryCatch::TryCatch()
exception_(i::Heap::the_hole_value()), exception_(i::Heap::the_hole_value()),
message_(i::Smi::FromInt(0)), message_(i::Smi::FromInt(0)),
is_verbose_(false), is_verbose_(false),
capture_message_(true) { capture_message_(true),
js_handler_(NULL) {
i::Top::RegisterTryCatchHandler(this); i::Top::RegisterTryCatchHandler(this);
} }
......
...@@ -253,7 +253,30 @@ void Top::TearDown() { ...@@ -253,7 +253,30 @@ void Top::TearDown() {
} }
// There are cases where the C stack is separated from JS stack (ARM simulator).
// To figure out the order of top-most JS try-catch handler and the top-most C
// try-catch handler, the C try-catch handler keeps a reference to the top-most
// JS try_catch handler when it was created.
//
// Here is a picture to explain the idea:
// Top::thread_local_.handler_ Top::thread_local_.try_catch_handler_
//
// | |
// v v
//
// | JS handler | | C try_catch handler |
// | next |--+ +-------- | js_handler_ |
// | | | next_ |--+
// | | |
// | JS handler |--+ <---------+ |
// | next |
//
// If the top-most JS try-catch handler is not equal to
// Top::thread_local_.try_catch_handler_.js_handler_, it means the JS handler
// is on the top. Otherwise, it means the C try-catch handler is on the top.
//
void Top::RegisterTryCatchHandler(v8::TryCatch* that) { void Top::RegisterTryCatchHandler(v8::TryCatch* that) {
that->js_handler_ = thread_local_.handler_; // casted to void*
thread_local_.try_catch_handler_ = that; thread_local_.try_catch_handler_ = that;
} }
...@@ -719,8 +742,7 @@ bool Top::ShouldReportException(bool* is_caught_externally) { ...@@ -719,8 +742,7 @@ bool Top::ShouldReportException(bool* is_caught_externally) {
// address of the external handler so we can compare the address to // address of the external handler so we can compare the address to
// determine which one is closer to the top of the stack. // determine which one is closer to the top of the stack.
bool has_external_handler = (thread_local_.try_catch_handler_ != NULL); bool has_external_handler = (thread_local_.try_catch_handler_ != NULL);
Address external_handler_address = v8::TryCatch* try_catch = thread_local_.try_catch_handler_;
reinterpret_cast<Address>(thread_local_.try_catch_handler_);
// NOTE: The stack is assumed to grown towards lower addresses. If // NOTE: The stack is assumed to grown towards lower addresses. If
// the handler is at a higher address than the external address it // the handler is at a higher address than the external address it
...@@ -732,10 +754,12 @@ bool Top::ShouldReportException(bool* is_caught_externally) { ...@@ -732,10 +754,12 @@ bool Top::ShouldReportException(bool* is_caught_externally) {
} }
// The exception has been externally caught if and only if there is // The exception has been externally caught if and only if there is
// an external handler which is above any JavaScript try-catch but NOT // an external handler which is on top of the top-most try-catch
// try-finally handlers. // handler.
//
// See comments in RegisterTryCatchHandler for details.
*is_caught_externally = has_external_handler && *is_caught_externally = has_external_handler &&
(handler == NULL || handler->address() > external_handler_address); (handler == NULL || handler == try_catch->js_handler_);
// If we have a try-catch handler then the exception is caught in // If we have a try-catch handler then the exception is caught in
// JavaScript code. // JavaScript code.
...@@ -745,7 +769,7 @@ bool Top::ShouldReportException(bool* is_caught_externally) { ...@@ -745,7 +769,7 @@ bool Top::ShouldReportException(bool* is_caught_externally) {
// exception if it isn't caught by JavaScript code. // exception if it isn't caught by JavaScript code.
if (!has_external_handler) return is_uncaught_by_js; if (!has_external_handler) return is_uncaught_by_js;
if (is_uncaught_by_js || handler->address() > external_handler_address) { if (is_uncaught_by_js || handler == try_catch->js_handler_) {
// Only report the exception if the external handler is verbose. // Only report the exception if the external handler is verbose.
return thread_local_.try_catch_handler_->is_verbose_; return thread_local_.try_catch_handler_->is_verbose_;
} else { } else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment