Fixing exception reporting so that a verbose TryCatch handler works again.
authorolehougaard <olehougaard@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 5 Dec 2008 13:30:55 +0000 (13:30 +0000)
committerolehougaard <olehougaard@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 5 Dec 2008 13:30:55 +0000 (13:30 +0000)
Review URL: http://codereview.chromium.org/13173

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@924 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/top.cc
src/top.h
test/cctest/test-api.cc

index d5226d8a842ae383af7dab4c15fcd1f8119c3736..6c096daf8ecc2eb11b461528975063a1d5ee277a 100644 (file)
@@ -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();
index 8afaf90d9418f967aa6087088b497a73f759540d..7fe735cd0a348b8cd535489492f616da86244b9c 100644 (file)
--- a/src/top.h
+++ b/src/top.h
@@ -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;
index c40869242441152e16caeaa5cae24c6ac73dcd43..b69debc127f269f0d857193c4fcbc5fee7f617e2 100644 (file)
@@ -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();