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 {
void* message_;
bool is_verbose_;
bool capture_message_;
void* js_handler_;
};
......
......@@ -1081,7 +1081,8 @@ v8::TryCatch::TryCatch()
exception_(i::Heap::the_hole_value()),
message_(i::Smi::FromInt(0)),
is_verbose_(false),
capture_message_(true) {
capture_message_(true),
js_handler_(NULL) {
i::Top::RegisterTryCatchHandler(this);
}
......
......@@ -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) {
that->js_handler_ = thread_local_.handler_; // casted to void*
thread_local_.try_catch_handler_ = that;
}
......@@ -719,8 +742,7 @@ bool Top::ShouldReportException(bool* is_caught_externally) {
// address of the external handler so we can compare the address to
// determine which one is closer to the top of the stack.
bool has_external_handler = (thread_local_.try_catch_handler_ != NULL);
Address external_handler_address =
reinterpret_cast<Address>(thread_local_.try_catch_handler_);
v8::TryCatch* try_catch = thread_local_.try_catch_handler_;
// NOTE: The stack is assumed to grown towards lower addresses. If
// the handler is at a higher address than the external address it
......@@ -732,10 +754,12 @@ bool Top::ShouldReportException(bool* is_caught_externally) {
}
// The exception has been externally caught if and only if there is
// an external handler which is above any JavaScript try-catch but NOT
// try-finally handlers.
// an external handler which is on top of the top-most try-catch
// handler.
//
// See comments in RegisterTryCatchHandler for details.
*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
// JavaScript code.
......@@ -745,7 +769,7 @@ bool Top::ShouldReportException(bool* is_caught_externally) {
// exception if it isn't caught by JavaScript code.
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.
return thread_local_.try_catch_handler_->is_verbose_;
} 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