Author: [EMAIL PROTECTED]
Date: Tue Sep  9 05:16:57 2008
New Revision: 232

Added:
    changes/[EMAIL PROTECTED]/try-catch-src-info/
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/
       - copied from r230, /branches/bleeding_edge/
Modified:
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/include/v8.h
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/api.cc
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/debug.cc
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.cc
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.h
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.js
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/top.cc
     
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/top.h
     
changes/[EMAIL 
PROTECTED]/try-catch-src-info/bleeding_edge/test/cctest/test-api.cc

Log:
Added source info to TryCatches.  Reorganized exception messaging
somewhat and folded stack traces into message.  Use of this in the
shell will follow in a separate changelist.



Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/include/v8.h
==============================================================================
--- /branches/bleeding_edge/include/v8.h        (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/include/v8.h  
Tue Sep  9 05:16:57 2008
@@ -553,7 +553,7 @@
  class EXPORT Message {
   public:
    Local<String> Get();
-  Local<Value> GetSourceLine();
+  Local<String> GetSourceLine();

    // TODO(1241256): Rewrite (or remove) this method.  We don't want to
    // deal with ownership of the returned string and we want to use
@@ -566,8 +566,41 @@
    // bindings.
    Handle<Value> GetSourceData();

+  /**
+   * Returns the number, 1-based, of the line where the error occurred.
+   */
    int GetLineNumber();

+  /**
+   * Returns the index within the script of the first character where
+   * the error occurred.
+   */
+  int GetStartPosition();
+
+  /**
+   * Returns the index within the script of the last character where
+   * the error occurred.
+   */
+  int GetEndPosition();
+
+  /**
+   * Returns the index within the line of the first character where
+   * the error occurred.
+   */
+  int GetStartColumn();
+
+  /**
+   * Returns the index within the line of the last character where
+   * the error occurred.
+   */
+  int GetEndColumn();
+
+  /**
+   * Returns a string stack trace if trace_exceptions is enabled and
+   * one is available.
+   */
+  Local<String> GetStackTrace();
+
    // TODO(1245381): Print to a string instead of on a FILE.
    static void PrintCurrentStackTrace(FILE* out);
  };
@@ -1912,6 +1945,15 @@
    Local<Value> Exception();

    /**
+   * Returns the message associated with this exception.  If there is
+   * no message associated an empty handle is returned.
+   *
+   * The returned handle is valid until this TryCatch block has been
+   * destroyed.
+   */
+  Local<v8::Message> Message();
+
+  /**
     * Clears any exceptions that may have been caught by this try/catch  
block.
     * After this method has been called, HasCaught() will return false.
     *
@@ -1935,6 +1977,7 @@
   public:
    TryCatch* next_;
    void* exception_;
+  void* message_;
    bool is_verbose_;
  };


Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/api.cc
==============================================================================
--- /branches/bleeding_edge/src/api.cc  (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/api.cc    
Tue Sep  9 05:16:57 2008
@@ -1081,6 +1081,7 @@
  v8::TryCatch::TryCatch()
      : next_(i::Top::try_catch_handler()),
        exception_(i::Heap::the_hole_value()),
+      message_(i::Smi::FromInt(0)),
        is_verbose_(false) {
    i::Top::RegisterTryCatchHandler(this);
  }
@@ -1107,8 +1108,19 @@
  }


+v8::Local<v8::Message> v8::TryCatch::Message() {
+  if (HasCaught() && message_ != i::Smi::FromInt(0)) {
+    i::Object* message = reinterpret_cast<i::Object*>(message_);
+    return v8::Utils::MessageToLocal(i::Handle<i::Object>(message));
+  } else {
+    return v8::Local<v8::Message>();
+  }
+}
+
+
  void v8::TryCatch::Reset() {
    exception_ = i::Heap::the_hole_value();
+  message_ = i::Smi::FromInt(0);
  }


@@ -1196,15 +1208,80 @@
  }


-Local<Value> Message::GetSourceLine() {
-  ON_BAILOUT("v8::Message::GetSourceLine()", return Local<Value>());
+int Message::GetStartPosition() {
+  if (IsDeadCheck("v8::Message::GetStartPosition()")) return 0;
+  HandleScope scope;
+
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  return static_cast<int>(GetProperty(data_obj, "startPos")->Number());
+}
+
+
+int Message::GetEndPosition() {
+  if (IsDeadCheck("v8::Message::GetEndPosition()")) return 0;
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  return static_cast<int>(GetProperty(data_obj, "endPos")->Number());
+}
+
+
+int Message::GetStartColumn() {
+  if (IsDeadCheck("v8::Message::GetStartColumn()")) return 0;
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
+      "GetPositionInLine",
+      data_obj,
+      &has_pending_exception);
+  EXCEPTION_BAILOUT_CHECK(0);
+  return static_cast<int>(start_col_obj->Number());
+}
+
+
+int Message::GetEndColumn() {
+  if (IsDeadCheck("v8::Message::GetEndColumn()")) return 0;
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
+      "GetPositionInLine",
+      data_obj,
+      &has_pending_exception);
+  EXCEPTION_BAILOUT_CHECK(0);
+  int start =  
static_cast<int>(GetProperty(data_obj, "startPos")->Number());
+  int end = static_cast<int>(GetProperty(data_obj, "endPos")->Number());
+  return static_cast<int>(start_col_obj->Number()) + (end - start);
+}
+
+
+v8::Local<v8::String> Message::GetStackTrace() {
+  if (IsDeadCheck("v8::Message::GetStackTrace()"))
+    return v8::Local<v8::String>();
+  HandleScope scope;
+  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
+  i::Handle<i::Object> trace = GetProperty(data_obj, "stackTrace");
+  if (trace->IsString()) {
+    return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(trace)));
+  } else {
+    return Local<String>();
+  }
+}
+
+
+Local<String> Message::GetSourceLine() {
+  ON_BAILOUT("v8::Message::GetSourceLine()", return Local<String>());
    HandleScope scope;
    EXCEPTION_PREAMBLE();
    i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
                                                     Utils::OpenHandle(this),
                                                     &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::Value>());
-  return scope.Close(Utils::ToLocal(result));
+  EXCEPTION_BAILOUT_CHECK(Local<v8::String>());
+  if (result->IsString()) {
+    return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
+  } else {
+    return Local<String>();
+  }
  }



Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/debug.cc
==============================================================================
--- /branches/bleeding_edge/src/debug.cc        (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/debug.cc  
Tue Sep  9 05:16:57 2008
@@ -537,8 +537,10 @@

    // Check for caught exceptions.
    if (caught_exception) {
-    MessageHandler::ReportMessage("error_loading_debugger", NULL,
-                                  HandleVector<Object>(&result, 1));
+    Handle<Object> message = MessageHandler::MakeMessageObject(
+        "error_loading_debugger", NULL, HandleVector<Object>(&result, 1),
+        Handle<String>());
+    MessageHandler::ReportMessage(NULL, message);
      return false;
    }


Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.cc
==============================================================================
--- /branches/bleeding_edge/src/messages.cc     (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.cc      
 
Tue Sep  9 05:16:57 2008
@@ -60,8 +60,11 @@
  }


-void MessageHandler::ReportMessage(const char* type, MessageLocation* loc,
-                                   Vector< Handle<Object> > args) {
+Handle<Object> MessageHandler::MakeMessageObject(
+    const char* type,
+    MessageLocation* loc,
+    Vector< Handle<Object> > args,
+    Handle<String> stack_trace) {
    // Build error message object
    HandleScope scope;
    Handle<Object> type_str = Factory::LookupAsciiSymbol(type);
@@ -82,12 +85,16 @@
    }
    Handle<Object> start_handle(Smi::FromInt(start));
    Handle<Object> end_handle(Smi::FromInt(end));
-  const int argc = 5;
+  Handle<Object> stack_trace_val = stack_trace.is_null()
+    ? Factory::undefined_value()
+    : Handle<Object>::cast(stack_trace);
+  const int argc = 6;
    Object** argv[argc] = { type_str.location(),
                            array.location(),
                            start_handle.location(),
                            end_handle.location(),
-                          script.location() };
+                          script.location(),
+                          stack_trace_val.location() };

    bool caught_exception = false;
    Handle<Object> message =
@@ -97,8 +104,13 @@
    // skip doing the callback. This usually only happens in case of
    // stack overflow exceptions being thrown by the parser when the
    // stack is almost full.
-  if (caught_exception) return;
+  if (caught_exception) return Handle<Object>();
+  return message.EscapeFrom(&scope);
+}

+
+void MessageHandler::ReportMessage(MessageLocation* loc,
+                                   Handle<Object> message) {
    v8::Local<v8::Message> api_message_obj =  
v8::Utils::MessageToLocal(message);

    v8::NeanderArray global_listeners(Factory::message_listeners());

Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.h
==============================================================================
--- /branches/bleeding_edge/src/messages.h      (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.h       
 
Tue Sep  9 05:16:57 2008
@@ -70,6 +70,7 @@
        : script_(script),
          start_pos_(start_pos),
          end_pos_(end_pos) { }
+  MessageLocation() : start_pos_(-1), end_pos_(-1) { }

    Handle<Script> script() const { return script_; }
    int start_pos() const { return start_pos_; }
@@ -89,10 +90,14 @@
    // 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<Object> MakeMessageObject(const char* type,
+                                          MessageLocation* loc,
+                                          Vector< Handle<Object> > args,
+                                          Handle<String> stack_trace);
+
    // Report a formatted message (needs JS allocation).
-  static void ReportMessage(const char* type,
-                            MessageLocation* loc,
-                            Vector< Handle<Object> > args);
+  static void ReportMessage(MessageLocation* loc, Handle<Object> message);

    static void DefaultMessageReport(const MessageLocation* loc,
                                     Handle<Object> message_obj);

Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.js
==============================================================================
--- /branches/bleeding_edge/src/messages.js     (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/messages.js      
 
Tue Sep  9 05:16:57 2008
@@ -555,17 +555,18 @@
  };


-function ErrorMessage(type, args, startPos, endPos, script) {
+function ErrorMessage(type, args, startPos, endPos, script, stackTrace) {
    this.startPos = startPos;
    this.endPos = endPos;
    this.type = type;
    this.args = args;
    this.script = script;
+  this.stackTrace = stackTrace;
  };


-function MakeMessage(type, args, startPos, endPos, script) {
-  return new ErrorMessage(type, args, startPos, endPos, script);
+function MakeMessage(type, args, startPos, endPos, script, stackTrace) {
+  return new ErrorMessage(type, args, startPos, endPos, script,  
stackTrace);
  };



Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/top.cc
==============================================================================
--- /branches/bleeding_edge/src/top.cc  (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/top.cc    
Tue Sep  9 05:16:57 2008
@@ -79,6 +79,7 @@
         block != NULL;
         block = block->next_) {
      VISIT(reinterpret_cast<Object*&>(block->exception_));
+    VISIT(reinterpret_cast<Object*&>(block->message_));
    }

    // Iterate over pointers on native execution stack.
@@ -671,39 +672,34 @@
  }


+void Top::ComputeLocation(MessageLocation* target) {
+  *target = MessageLocation(empty_script(), -1, -1);
+  StackTraceFrameIterator it;
+  if (!it.done()) {
+    JavaScriptFrame* frame = it.frame();
+    JSFunction* fun = JSFunction::cast(frame->function());
+    Object* script = fun->shared()->script();
+    if (script->IsScript() &&
+        !(Script::cast(script)->source()->IsUndefined())) {
+      int pos = frame->FindCode()->SourcePosition(frame->pc());
+      // Compute the location from the function and the reloc info.
+      Handle<Script> casted_script(Script::cast(script));
+      *target = MessageLocation(casted_script, pos, pos + 1);
+    }
+  }
+}
+
+
  void Top::ReportUncaughtException(Handle<Object> exception,
                                    MessageLocation* location,
                                    Handle<String> stack_trace) {
-  MessageLocation computed_location(empty_script(), -1, -1);
-  if (location == NULL) {
-    location = &computed_location;
-
-    StackTraceFrameIterator it;
-    if (!it.done()) {
-      JavaScriptFrame* frame = it.frame();
-      JSFunction* fun = JSFunction::cast(frame->function());
-      Object* script = fun->shared()->script();
-      if (script->IsScript() &&
-          !(Script::cast(script)->source()->IsUndefined())) {
-        int pos = frame->FindCode()->SourcePosition(frame->pc());
-        // Compute the location from the function and the reloc info.
-        Handle<Script> casted_script(Script::cast(script));
-        computed_location = MessageLocation(casted_script, pos, pos + 1);
-      }
-    }
-  }
+  Handle<Object> message = MessageHandler::MakeMessageObject(
+      "uncaught_exception", location, HandleVector<Object>(&exception, 1),
+      stack_trace);
+

    // Report the uncaught exception.
-  MessageHandler::ReportMessage("uncaught_exception",
-                                location,
-                                HandleVector<Object>(&exception, 1));
-
-  // Optionally, report the stack trace separately.
-  if (!stack_trace.is_null()) {
-    MessageHandler::ReportMessage("stack_trace",
-                                  location,
-                                  HandleVector<String>(&stack_trace, 1));
-  }
+  MessageHandler::ReportMessage(location, message);
  }


@@ -771,12 +767,30 @@
      ShouldReportException(&is_caught_externally);
    if (is_rethrow) report_exception = false;

+  Handle<Object> message_obj;
+  MessageLocation potential_computed_location;
+  if (is_caught_externally || report_exception) {
+    if (location == NULL) {
+      // If no location was specified we use a computed one instead
+      ComputeLocation(&potential_computed_location);
+      location = &potential_computed_location;
+    }
+    Handle<String> stack_trace;
+    if (FLAG_trace_exception) stack_trace = StackTrace();
+    message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
+        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.
    if (is_caught_externally) {
      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.
@@ -786,9 +800,7 @@
      if (message != NULL) {
        MessageHandler::ReportMessage(message);
      } else {
-      Handle<String> stack_trace;
-      if (FLAG_trace_exception) stack_trace = StackTrace();
-      ReportUncaughtException(exception_handle, location, stack_trace);
+      MessageHandler::ReportMessage(location, message_obj);
      }
    }
    thread_local_.external_caught_exception_ = is_caught_externally;

Modified:  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/top.h
==============================================================================
--- /branches/bleeding_edge/src/top.h   (original)
+++  
changes/[EMAIL PROTECTED]/try-catch-src-info/bleeding_edge/src/top.h     
Tue Sep  9 05:16:57 2008
@@ -226,6 +226,10 @@
                                        MessageLocation* location,
                                        Handle<String> stack_trace);

+  // Attempts to compute the current source location, storing the
+  // result in the target out parameter.
+  static void ComputeLocation(MessageLocation* target);
+
    // Override command line flag.
    static void TraceException(bool flag);


Modified:  
changes/[EMAIL 
PROTECTED]/try-catch-src-info/bleeding_edge/test/cctest/test-api.cc
==============================================================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     (original)
+++  
changes/[EMAIL 
PROTECTED]/try-catch-src-info/bleeding_edge/test/cctest/test-api.cc       
Tue Sep  9 05:16:57 2008
@@ -4843,3 +4843,40 @@
    v8::Handle<v8::Object> result = templ->NewInstance();
    CHECK_EQ(1, result->InternalFieldCount());
  }
+
+
+THREADED_TEST(TryCatchSourceInfo) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::Handle<v8::String> source = v8::String::New(
+      "function Foo() {\n"
+      "  return Bar();\n"
+      "}\n"
+      "\n"
+      "function Bar() {\n"
+      "  return Baz();\n"
+      "}\n"
+      "\n"
+      "function Baz() {\n"
+      "  throw 'nirk';\n"
+      "}\n"
+      "\n"
+      "Foo();\n");
+  v8::Handle<v8::Script> script = v8::Script::Compile(source,
+      v8::String::New("test.js"));
+  v8::TryCatch try_catch;
+  v8::Handle<v8::Value> result = script->Run();
+  CHECK(result.IsEmpty());
+  CHECK(try_catch.HasCaught());
+  v8::Handle<v8::Message> message = try_catch.Message();
+  CHECK(!message.IsEmpty());
+  CHECK_EQ(10, message->GetLineNumber());
+  CHECK_EQ(91, message->GetStartPosition());
+  CHECK_EQ(92, message->GetEndPosition());
+  CHECK_EQ(2, message->GetStartColumn());
+  CHECK_EQ(3, message->GetEndColumn());
+  v8::String::AsciiValue line(message->GetSourceLine());
+  CHECK_EQ("  throw 'nirk';", *line);
+  v8::String::AsciiValue name(message->GetScriptResourceName());
+  CHECK_EQ("test.js", *name);
+}

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

Reply via email to