Report stack overflow exceptions to V8 message listeners
authoryurys@chromium.org <yurys@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Apr 2011 09:39:45 +0000 (09:39 +0000)
committeryurys@chromium.org <yurys@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Apr 2011 09:39:45 +0000 (09:39 +0000)
Stack overflow exceptions like other JavaScript exceptions should be reported to listeners added via V8::AddMessageListener
Review URL: http://codereview.chromium.org/6816021

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

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

index cf720f5..dd0a1fe 100644 (file)
@@ -179,7 +179,6 @@ class ThreadLocalTop BASE_EMBEDDED {
   int thread_id_;
   MaybeObject* pending_exception_;
   bool has_pending_message_;
-  const char* pending_message_;
   Object* pending_message_obj_;
   Script* pending_message_script_;
   int pending_message_start_pos_;
@@ -515,7 +514,6 @@ class Isolate {
   }
   void clear_pending_message() {
     thread_local_top_.has_pending_message_ = false;
-    thread_local_top_.pending_message_ = NULL;
     thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
     thread_local_top_.pending_message_script_ = NULL;
   }
@@ -675,9 +673,7 @@ class Isolate {
 
   // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
   Failure* PromoteScheduledException();
-  void DoThrow(MaybeObject* exception,
-               MessageLocation* location,
-               const char* message);
+  void DoThrow(MaybeObject* exception, MessageLocation* location);
   // Checks if exception should be reported and finds out if it's
   // caught externally.
   bool ShouldReportException(bool* can_be_caught_externally,
index 5e15b93..0cc8251 100644 (file)
@@ -56,11 +56,6 @@ void MessageHandler::DefaultMessageReport(const MessageLocation* loc,
 }
 
 
-void MessageHandler::ReportMessage(const char* msg) {
-  PrintF("%s\n", msg);
-}
-
-
 Handle<JSMessageObject> MessageHandler::MakeMessageObject(
     const char* type,
     MessageLocation* loc,
@@ -113,7 +108,7 @@ void MessageHandler::ReportMessage(Isolate* isolate,
   // to report a message as they are due to unhandled exceptions thrown in
   // message callbacks.
   if (isolate->in_exception_reporting()) {
-    ReportMessage("uncaught exception thrown while reporting");
+    PrintF("uncaught exception thrown while reporting\n");
     return;
   }
   isolate->set_in_exception_reporting(true);
index 0d5f9f7..fc2162d 100644 (file)
@@ -89,9 +89,6 @@ class MessageLocation {
 // of message listeners registered in an environment
 class MessageHandler {
  public:
-  // Report a message (w/o JS heap allocation).
-  static void ReportMessage(const char* msg);
-
   // Returns a message object for the API to use.
   static Handle<JSMessageObject> MakeMessageObject(
       const char* type,
index 7a1ce1b..8a38323 100644 (file)
@@ -534,19 +534,19 @@ Failure* Isolate::StackOverflow() {
   // the message for stack overflow exceptions which is very likely to
   // double fault with another stack overflow exception, we use a
   // precomputed message.
 DoThrow(*exception, NULL, kStackOverflowMessage);
DoThrow(*exception, NULL);
   return Failure::Exception();
 }
 
 
 Failure* Isolate::TerminateExecution() {
-  DoThrow(heap_.termination_exception(), NULL, NULL);
+  DoThrow(heap_.termination_exception(), NULL);
   return Failure::Exception();
 }
 
 
 Failure* Isolate::Throw(Object* exception, MessageLocation* location) {
-  DoThrow(exception, location, NULL);
+  DoThrow(exception, location);
   return Failure::Exception();
 }
 
@@ -664,9 +664,7 @@ bool Isolate::ShouldReportException(bool* can_be_caught_externally,
 }
 
 
-void Isolate::DoThrow(MaybeObject* exception,
-                      MessageLocation* location,
-                      const char* message) {
+void Isolate::DoThrow(MaybeObject* exception, MessageLocation* location) {
   ASSERT(!has_pending_exception());
 
   HandleScope scope;
@@ -723,7 +721,6 @@ void Isolate::DoThrow(MaybeObject* exception,
 
   // Save the message for reporting if the the exception remains uncaught.
   thread_local_top()->has_pending_message_ = report_exception;
-  thread_local_top()->pending_message_ = message;
   if (!message_obj.is_null()) {
     thread_local_top()->pending_message_obj_ = *message_obj;
     if (location != NULL) {
@@ -811,9 +808,7 @@ void Isolate::ReportPendingMessages() {
   } else {
     if (thread_local_top_.has_pending_message_) {
       thread_local_top_.has_pending_message_ = false;
-      if (thread_local_top_.pending_message_ != NULL) {
-        MessageHandler::ReportMessage(thread_local_top_.pending_message_);
-      } else if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
+      if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
         HandleScope scope;
         Handle<Object> message_obj(thread_local_top_.pending_message_obj_);
         if (thread_local_top_.pending_message_script_ != NULL) {
index cf982af..a9051c2 100644 (file)
@@ -2663,6 +2663,21 @@ TEST(APIThrowMessageAndVerboseTryCatch) {
 }
 
 
+TEST(APIStackOverflowAndVerboseTryCatch) {
+  message_received = false;
+  v8::HandleScope scope;
+  v8::V8::AddMessageListener(receive_message);
+  LocalContext context;
+  v8::TryCatch try_catch;
+  try_catch.SetVerbose(true);
+  Local<Value> result = CompileRun("function foo() { foo(); } foo();");
+  CHECK(try_catch.HasCaught());
+  CHECK(result.IsEmpty());
+  CHECK(message_received);
+  v8::V8::RemoveMessageListeners(receive_message);
+}
+
+
 THREADED_TEST(ExternalScriptException) {
   v8::HandleScope scope;
   Local<ObjectTemplate> templ = ObjectTemplate::New();