Allow recursive messages reporting as it is already used.
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 11 Apr 2011 16:16:52 +0000 (16:16 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 11 Apr 2011 16:16:52 +0000 (16:16 +0000)
Instead discard unhandled exceptions thown while running
message listeners.

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

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

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

index dd0a1fe..c291314 100644 (file)
@@ -188,9 +188,6 @@ class ThreadLocalTop BASE_EMBEDDED {
   // unify them later.
   MaybeObject* scheduled_exception_;
   bool external_caught_exception_;
-  // True if unhandled message is being currently reported by
-  // MessageHandler::ReportMessage.
-  bool in_exception_reporting_;
   SaveContext* save_context_;
   v8::TryCatch* catcher_;
 
@@ -526,12 +523,6 @@ class Isolate {
   bool* external_caught_exception_address() {
     return &thread_local_top_.external_caught_exception_;
   }
-  bool in_exception_reporting() {
-    return thread_local_top_.in_exception_reporting_;
-  }
-  void set_in_exception_reporting(bool value) {
-    thread_local_top_.in_exception_reporting_ = value;
-  }
   v8::TryCatch* catcher() {
     return thread_local_top_.catcher_;
   }
index 0cc8251..abc2537 100644 (file)
@@ -104,15 +104,6 @@ Handle<JSMessageObject> MessageHandler::MakeMessageObject(
 void MessageHandler::ReportMessage(Isolate* isolate,
                                    MessageLocation* loc,
                                    Handle<Object> message) {
-  // If we are in process of message reporting, just ignore all other requests
-  // to report a message as they are due to unhandled exceptions thrown in
-  // message callbacks.
-  if (isolate->in_exception_reporting()) {
-    PrintF("uncaught exception thrown while reporting\n");
-    return;
-  }
-  isolate->set_in_exception_reporting(true);
-
   // We are calling into embedder's code which can throw exceptions.
   // Thus we need to save current exception state, reset it to the clean one
   // and ignore scheduled exceptions callbacks can throw.
@@ -138,14 +129,16 @@ void MessageHandler::ReportMessage(Isolate* isolate,
       v8::MessageCallback callback =
           FUNCTION_CAST<v8::MessageCallback>(callback_obj->proxy());
       Handle<Object> callback_data(listener.get(1));
-      callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+      {
+        // Do not allow exceptions to propagate.
+        v8::TryCatch tryCatch;
+        callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+      }
       if (isolate->has_scheduled_exception()) {
         isolate->clear_scheduled_exception();
       }
     }
   }
-
-  isolate->set_in_exception_reporting(false);
 }
 
 
index 8611a31..6771f38 100644 (file)
@@ -72,7 +72,6 @@ void ThreadLocalTop::Initialize() {
   int id = Isolate::Current()->thread_manager()->CurrentId();
   thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id;
   external_caught_exception_ = false;
-  in_exception_reporting_ = false;
   failed_access_check_callback_ = NULL;
   save_context_ = NULL;
   catcher_ = NULL;
index 715dbdb..d7621d1 100644 (file)
@@ -8671,18 +8671,21 @@ static Handle<Value> ThrowingCallbackWithTryCatch(const Arguments& args) {
 }
 
 
+static int call_depth;
+
+
 static void WithTryCatch(Handle<Message> message, Handle<Value> data) {
   TryCatch try_catch;
 }
 
 
 static void ThrowFromJS(Handle<Message> message, Handle<Value> data) {
-  CompileRun("throw 'ThrowInJS';");
+  if (--call_depth) CompileRun("throw 'ThrowInJS';");
 }
 
 
 static void ThrowViaApi(Handle<Message> message, Handle<Value> data) {
-  ThrowException(v8_str("ThrowViaApi"));
+  if (--call_depth) ThrowException(v8_str("ThrowViaApi"));
 }
 
 
@@ -8708,6 +8711,7 @@ THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) {
     if (callback != NULL) {
       V8::AddMessageListener(callback);
     }
+    call_depth = 5;
     ExpectFalse(
         "var thrown = false;\n"
         "try { func(); } catch(e) { thrown = true; }\n"