Fixing exception reporting so that a verbose TryCatch handler works again.
Review URL: http://codereview.chromium.org/13173 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@924 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
07e14578c0
commit
89855a08d9
34
src/top.cc
34
src/top.cc
@ -822,6 +822,7 @@ void Top::DoThrow(Object* exception,
|
||||
}
|
||||
|
||||
// Save the message for reporting if the the exception remains uncaught.
|
||||
thread_local_.has_pending_message_ = report_exception;
|
||||
thread_local_.pending_message_ = message;
|
||||
if (!message_obj.is_null()) {
|
||||
thread_local_.pending_message_obj_ = *message_obj;
|
||||
@ -855,26 +856,33 @@ void Top::ReportPendingMessages() {
|
||||
context()->mark_out_of_memory();
|
||||
} else {
|
||||
Handle<Object> exception(pending_exception());
|
||||
if (thread_local_.external_caught_exception_) {
|
||||
bool external_caught = thread_local_.external_caught_exception_;
|
||||
thread_local_.external_caught_exception_ = false;
|
||||
if (external_caught) {
|
||||
thread_local_.try_catch_handler_->exception_ =
|
||||
thread_local_.pending_exception_;
|
||||
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);
|
||||
}
|
||||
if (thread_local_.has_pending_message_) {
|
||||
thread_local_.has_pending_message_ = false;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
thread_local_.external_caught_exception_ = external_caught;
|
||||
set_pending_exception(*exception);
|
||||
}
|
||||
clear_pending_message();
|
||||
|
@ -46,6 +46,7 @@ class ThreadLocalTop BASE_EMBEDDED {
|
||||
// lookups.
|
||||
Context* context_;
|
||||
Object* pending_exception_;
|
||||
bool has_pending_message_;
|
||||
const char* pending_message_;
|
||||
Object* pending_message_obj_;
|
||||
Script* pending_message_script_;
|
||||
@ -127,6 +128,7 @@ class Top {
|
||||
}
|
||||
static void clear_pending_message() {
|
||||
thread_local_.catcher_ = NULL;
|
||||
thread_local_.has_pending_message_ = false;
|
||||
thread_local_.pending_message_ = NULL;
|
||||
thread_local_.pending_message_obj_ = Heap::the_hole_value();
|
||||
thread_local_.pending_message_script_ = NULL;
|
||||
|
@ -1666,6 +1666,55 @@ THREADED_TEST(APICatch) {
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(APIThrowTryCatch) {
|
||||
v8::HandleScope scope;
|
||||
Local<ObjectTemplate> templ = ObjectTemplate::New();
|
||||
templ->Set(v8_str("ThrowFromC"),
|
||||
v8::FunctionTemplate::New(ThrowFromC));
|
||||
LocalContext context(0, templ);
|
||||
v8::TryCatch try_catch;
|
||||
CompileRun("ThrowFromC();");
|
||||
CHECK(try_catch.HasCaught());
|
||||
}
|
||||
|
||||
|
||||
static void receive_message(v8::Handle<v8::Message> message,
|
||||
v8::Handle<v8::Value> data) {
|
||||
message_received = true;
|
||||
}
|
||||
|
||||
|
||||
TEST(APIThrowMessage) {
|
||||
message_received = false;
|
||||
v8::HandleScope scope;
|
||||
v8::V8::AddMessageListener(receive_message);
|
||||
Local<ObjectTemplate> templ = ObjectTemplate::New();
|
||||
templ->Set(v8_str("ThrowFromC"),
|
||||
v8::FunctionTemplate::New(ThrowFromC));
|
||||
LocalContext context(0, templ);
|
||||
CompileRun("ThrowFromC();");
|
||||
CHECK(message_received);
|
||||
v8::V8::RemoveMessageListeners(check_message);
|
||||
}
|
||||
|
||||
|
||||
TEST(APIThrowMessageAndVerboseTryCatch) {
|
||||
message_received = false;
|
||||
v8::HandleScope scope;
|
||||
v8::V8::AddMessageListener(receive_message);
|
||||
Local<ObjectTemplate> templ = ObjectTemplate::New();
|
||||
templ->Set(v8_str("ThrowFromC"),
|
||||
v8::FunctionTemplate::New(ThrowFromC));
|
||||
LocalContext context(0, templ);
|
||||
v8::TryCatch try_catch;
|
||||
try_catch.SetVerbose(true);
|
||||
CompileRun("ThrowFromC();");
|
||||
CHECK(try_catch.HasCaught());
|
||||
CHECK(message_received);
|
||||
v8::V8::RemoveMessageListeners(check_message);
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(ExternalScriptException) {
|
||||
v8::HandleScope scope;
|
||||
Local<ObjectTemplate> templ = ObjectTemplate::New();
|
||||
|
Loading…
Reference in New Issue
Block a user