Author: olehougaard
Date: Fri Dec  5 00:35:52 2008
New Revision: 919

Added:
     
branches/bleeding_edge/test/message/try-catch-finally-return-in-finally.js
       - copied unchanged from r917,  
/branches/bleeding_edge/test/message/try-catch-finally-return-in-finally.js
     
branches/bleeding_edge/test/message/try-catch-finally-return-in-finally.out
       - copied unchanged from r917,  
/branches/bleeding_edge/test/message/try-catch-finally-return-in-finally.out
    branches/bleeding_edge/test/message/try-finally-return-in-finally.js
       - copied unchanged from r917,  
/branches/bleeding_edge/test/message/try-finally-return-in-finally.js
    branches/bleeding_edge/test/message/try-finally-return-in-finally.out
       - copied unchanged from r917,  
/branches/bleeding_edge/test/message/try-finally-return-in-finally.out
Modified:
    branches/bleeding_edge/src/compiler.cc
    branches/bleeding_edge/src/execution.cc
    branches/bleeding_edge/src/top.cc
    branches/bleeding_edge/src/top.h
    branches/bleeding_edge/test/cctest/test-api.cc

Log:
Added reporting compilation errors.
Review URL: http://codereview.chromium.org/13125

Modified: branches/bleeding_edge/src/compiler.cc
==============================================================================
--- branches/bleeding_edge/src/compiler.cc      (original)
+++ branches/bleeding_edge/src/compiler.cc      Fri Dec  5 00:35:52 2008
@@ -74,6 +74,11 @@

    // Generate code and return it.
    Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
+  // Check for stack-overflow exception.
+  if (result.is_null()) {
+    Top::StackOverflow();
+    Top::ReportPendingMessages();
+  }
    return result;
  }

@@ -101,6 +106,7 @@
    // Check for parse errors.
    if (lit == NULL) {
      ASSERT(Top::has_pending_exception());
+    Top::ReportPendingMessages();
      return Handle<JSFunction>::null();
    }

@@ -117,7 +123,6 @@

    // Check for stack-overflow exceptions.
    if (code.is_null()) {
-    Top::StackOverflow();
      return Handle<JSFunction>::null();
    }

@@ -206,6 +211,8 @@
      }
    }

+  if (result.is_null()) Top::ReportPendingMessages();
+
    return result;
  }

@@ -235,6 +242,9 @@
        CompilationCache::PutFunction(source, entry, result);
      }
    }
+
+  if (result.is_null()) Top::ReportPendingMessages();
+
    return result;
  }

@@ -269,6 +279,7 @@
    // Check for parse errors.
    if (lit == NULL) {
      ASSERT(Top::has_pending_exception());
+    Top::ReportPendingMessages();
      return false;
    }

@@ -283,9 +294,7 @@
    // Compile the code.
    Handle<Code> code = MakeCode(lit, script, false);

-  // Check for stack-overflow exception.
    if (code.is_null()) {
-    Top::StackOverflow();
      return false;
    }


Modified: branches/bleeding_edge/src/execution.cc
==============================================================================
--- branches/bleeding_edge/src/execution.cc     (original)
+++ branches/bleeding_edge/src/execution.cc     Fri Dec  5 00:35:52 2008
@@ -95,15 +95,10 @@
    *has_pending_exception = value->IsException();
    ASSERT(*has_pending_exception == Top::has_pending_exception());
    if (*has_pending_exception) {
-    Top::setup_external_caught();
-    // If the pending exception is OutOfMemoryException set out_of_memory  
in
-    // the global context.  Note: We have to mark the global context here
-    // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
-    // set it.
-    if (Top::pending_exception() == Failure::OutOfMemoryException()) {
-      Top::context()->mark_out_of_memory();
-    }
+    Top::ReportPendingMessages();
      return Handle<Object>();
+  } else {
+    Top::clear_pending_message();
    }

    return Handle<Object>(value);

Modified: branches/bleeding_edge/src/top.cc
==============================================================================
--- branches/bleeding_edge/src/top.cc   (original)
+++ branches/bleeding_edge/src/top.cc   Fri Dec  5 00:35:52 2008
@@ -66,6 +66,9 @@

  void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
    v->VisitPointer(&(thread->pending_exception_));
+  v->VisitPointer(&(thread->pending_message_obj_));
+  v->VisitPointer(
+      bit_cast<Object**, Script**>(&(thread->pending_message_script_)));
    v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_)));
    v->VisitPointer(&(thread->scheduled_exception_));

@@ -99,6 +102,7 @@
    thread_local_.external_caught_exception_ = false;
    thread_local_.failed_access_check_callback_ = NULL;
    clear_pending_exception();
+  clear_pending_message();
    clear_scheduled_exception();
    thread_local_.save_context_ = NULL;
    thread_local_.catcher_ = NULL;
@@ -791,8 +795,13 @@

    // Determine reporting and whether the exception is caught externally.
    bool is_caught_externally = false;
-  bool report_exception = (exception != Failure::OutOfMemoryException()) &&
-      ShouldReportException(&is_caught_externally);
+  bool is_out_of_memory = exception == Failure::OutOfMemoryException();
+  bool should_return_exception =   
ShouldReportException(&is_caught_externally);
+  bool report_exception = !is_out_of_memory && should_return_exception;
+
+
+  // Notify debugger of exception.
+  Debugger::OnException(exception_handle, report_exception);

    // Generate the message.
    Handle<Object> message_obj;
@@ -812,35 +821,63 @@
          location, HandleVector<Object>(&exception_handle, 1), stack_trace);
    }

-  // If the exception is caught externally, we store it in the
-  // try/catch handler. The C code can find it later and process it if
-  // necessary.
-  thread_local_.catcher_ = NULL;
+  // Save the message for reporting if the the exception remains uncaught.
+  thread_local_.pending_message_ = message;
+  if (!message_obj.is_null()) {
+    thread_local_.pending_message_obj_ = *message_obj;
+    if (location != NULL) {
+      thread_local_.pending_message_script_ = *location->script();
+      thread_local_.pending_message_start_pos_ = location->start_pos();
+      thread_local_.pending_message_end_pos_ = location->end_pos();
+    }
+  }
+
    if (is_caught_externally) {
      thread_local_.catcher_ = thread_local_.try_catch_handler_;
-    thread_local_.try_catch_handler_->exception_ =
-      reinterpret_cast<void*>(*exception_handle);
-    if (!message_obj.is_null()) {
-      thread_local_.try_catch_handler_->message_ =
-        reinterpret_cast<void*>(*message_obj);
-    }
    }

-  // Notify debugger of exception.
-  Debugger::OnException(exception_handle, report_exception);
+  // NOTE: Notifying the debugger or generating the message
+  // may have caused new exceptions. For now, we just ignore
+  // that and set the pending exception to the original one.
+  set_pending_exception(*exception_handle);
+}
+

-  if (report_exception) {
-    if (message != NULL) {
-      MessageHandler::ReportMessage(message);
-    } else if (!message_obj.is_null()) {
-      MessageHandler::ReportMessage(location, message_obj);
+void Top::ReportPendingMessages() {
+  ASSERT(has_pending_exception());
+  setup_external_caught();
+  // If the pending exception is OutOfMemoryException set out_of_memory in
+  // the global context.  Note: We have to mark the global context here
+  // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
+  // set it.
+  HandleScope scope;
+  if (thread_local_.pending_exception_ == Failure::OutOfMemoryException())  
{
+    context()->mark_out_of_memory();
+  } else {
+    Handle<Object> exception(pending_exception());
+    if (thread_local_.external_caught_exception_) {
+      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);
+      }
      }
+    set_pending_exception(*exception);
    }
-
-  // NOTE: Notifying the debugger or reporting the exception may have  
caused
-  // new exceptions. For now, we just ignore that and set the pending  
exception
-  // to the original one.
-  set_pending_exception(*exception_handle);
+  clear_pending_message();
  }



Modified: branches/bleeding_edge/src/top.h
==============================================================================
--- branches/bleeding_edge/src/top.h    (original)
+++ branches/bleeding_edge/src/top.h    Fri Dec  5 00:35:52 2008
@@ -46,6 +46,11 @@
    // lookups.
    Context* context_;
    Object* pending_exception_;
+  const char* pending_message_;
+  Object* pending_message_obj_;
+  Script* pending_message_script_;
+  int pending_message_start_pos_;
+  int pending_message_end_pos_;
    // Use a separate value for scheduled exceptions to preserve the
    // invariants that hold about pending_exception.  We may want to
    // unify them later.
@@ -120,6 +125,12 @@
    static bool has_pending_exception() {
      return !thread_local_.pending_exception_->IsTheHole();
    }
+  static void clear_pending_message() {
+    thread_local_.catcher_ = NULL;
+    thread_local_.pending_message_ = NULL;
+    thread_local_.pending_message_obj_ = Heap::the_hole_value();
+    thread_local_.pending_message_script_ = NULL;
+  }
    static v8::TryCatch* try_catch_handler() {
      return thread_local_.try_catch_handler_;
    }
@@ -146,6 +157,7 @@

    static void setup_external_caught() {
      thread_local_.external_caught_exception_ =
+        (!thread_local_.pending_exception_->IsTheHole()) &&
          (thread_local_.catcher_ != NULL) &&
          (Top::thread_local_.try_catch_handler_ ==  
Top::thread_local_.catcher_);
    }
@@ -207,6 +219,7 @@
    // originally.
    static Failure* ReThrow(Object* exception, MessageLocation* location =  
NULL);
    static void ScheduleThrow(Object* exception);
+  static void ReportPendingMessages();

    // Promote a scheduled exception to pending. Asserts  
has_scheduled_exception.
    static Object* PromoteScheduledException();

Modified: branches/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-api.cc      (original)
+++ branches/bleeding_edge/test/cctest/test-api.cc      Fri Dec  5 00:35:52 2008
@@ -2960,6 +2960,7 @@
  // Counts uncaught exceptions, but other tests running in parallel
  // also have uncaught exceptions.
  TEST(ApiUncaughtException) {
+  report_count = 0;
    v8::HandleScope scope;
    LocalContext env;
    v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener);
@@ -2983,6 +2984,37 @@
    CHECK(trouble_caller->IsFunction());
    Function::Cast(*trouble_caller)->Call(global, 0, NULL);
    CHECK_EQ(1, report_count);
+  v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener);
+}
+
+
+TEST(CompilationErrorUsingTryCatchHandler) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::TryCatch try_catch;
+  Script::Compile(v8_str("This doesn't &*&@#$&*^ compile."));
+  CHECK_NE(NULL, *try_catch.Exception());
+  CHECK(try_catch.HasCaught());
+}
+
+
+TEST(TryCatchFinallyUsingTryCatchHandler) {
+  v8::HandleScope scope;
+  LocalContext env;
+  v8::TryCatch try_catch;
+  Script::Compile(v8_str("try { throw ''; } catch (e) {}"))->Run();
+  CHECK(!try_catch.HasCaught());
+  Script::Compile(v8_str("try { throw ''; } finally {}"))->Run();
+  CHECK(try_catch.HasCaught());
+  try_catch.Reset();
+  Script::Compile(v8_str("(function() {"
+                         "try { throw ''; } finally { return; }"
+                         "})()"))->Run();
+  CHECK(!try_catch.HasCaught());
+  Script::Compile(v8_str("(function()"
+                         "  { try { throw ''; } finally { throw 0; }"
+                         "})()"))->Run();
+  CHECK(try_catch.HasCaught());
  }



--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to