Show file name/line number in stack trace
authorpeter.rybin@gmail.com <peter.rybin@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 18 Mar 2010 22:15:54 +0000 (22:15 +0000)
committerpeter.rybin@gmail.com <peter.rybin@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 18 Mar 2010 22:15:54 +0000 (22:15 +0000)
Review URL: http://codereview.chromium.org/1002010

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

src/frames.cc
src/handles.cc
src/handles.h

index 3bf4c93e39893bba2031a58dd984e9ba450603c1..227fa67d54b2ba854a2682c890a8ae6bc4efe9a5 100644 (file)
@@ -520,6 +520,31 @@ void JavaScriptFrame::Print(StringStream* accumulator,
   Code* code = NULL;
   if (IsConstructor()) accumulator->Add("new ");
   accumulator->PrintFunction(function, receiver, &code);
+
+  if (function->IsJSFunction()) {
+    Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared());
+    Object* script_obj = shared->script();
+    if (script_obj->IsScript()) {
+      Handle<Script> script(Script::cast(script_obj));
+      accumulator->Add(" [");
+      accumulator->PrintName(script->name());
+
+      Address pc = this->pc();
+      if (code != NULL && code->kind() == Code::FUNCTION &&
+          pc >= code->instruction_start() && pc < code->relocation_start()) {
+        int source_pos = code->SourcePosition(pc);
+        int line = GetScriptLineNumberSafe(script, source_pos) + 1;
+        accumulator->Add(":%d", line);
+      } else {
+        int function_start_pos = shared->start_position();
+        int line = GetScriptLineNumberSafe(script, function_start_pos) + 1;
+        accumulator->Add(":~%d", line);
+      }
+
+      accumulator->Add("] ");
+    }
+  }
+
   accumulator->Add("(this=%o", receiver);
 
   // Get scope information for nicer output, if possible. If code is
index 53c16a49999996f8b5c572cf29bb3dcfd3dc942a..4ebeaa79c0639cc90ffc3318872b45aa064301a8 100644 (file)
@@ -514,6 +514,30 @@ int GetScriptLineNumber(Handle<Script> script, int code_pos) {
 }
 
 
+int GetScriptLineNumberSafe(Handle<Script> script, int code_pos) {
+  AssertNoAllocation no_allocation;
+  if (!script->line_ends()->IsUndefined()) {
+    return GetScriptLineNumber(script, code_pos);
+  }
+  // Slow mode: we do not have line_ends. We have to iterate through source.
+  if (!script->source()->IsString()) {
+    return -1;
+  }
+  String* source = String::cast(script->source());
+  int line = 0;
+  int len = source->length();
+  for (int pos = 0; pos < len; pos++) {
+    if (pos == code_pos) {
+      break;
+    }
+    if (source->Get(pos) == '\n') {
+      line++;
+    }
+  }
+  return line;
+}
+
+
 void CustomArguments::IterateInstance(ObjectVisitor* v) {
   v->VisitPointers(values_, values_ + 4);
 }
index 0c137a4ce7caa64a8bb4870a69376e58328e4a5a..f241da203675ab728d44559d6ce6fa2b52eb0d41 100644 (file)
@@ -267,6 +267,8 @@ Handle<JSValue> GetScriptWrapper(Handle<Script> script);
 // Script line number computations.
 void InitScriptLineEnds(Handle<Script> script);
 int GetScriptLineNumber(Handle<Script> script, int code_position);
+// The safe version does not make heap allocations but may work much slower.
+int GetScriptLineNumberSafe(Handle<Script> script, int code_position);
 
 // Computes the enumerable keys from interceptors. Used for debug mirrors and
 // by GetKeysInFixedArrayFor below.