Revert of Only record one in n line endings to save space. (patchset #4 id:60001...
authorerikcorry <erikcorry@chromium.org>
Mon, 8 Jun 2015 14:24:25 +0000 (07:24 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 8 Jun 2015 14:24:42 +0000 (14:24 +0000)
Reason for revert:
Test failures https://storage.googleapis.com/chromium-layout-test-archives/V8-Blink_Win/345/layout-test-results/results.html

Original issue's description:
> Only record one in n line endings to save space.
>
> R=yangguo@chromium.org
> BUG=
>
> Committed: https://crrev.com/b3d4bce593559276e68d3d7d9168f4351e4e5090
> Cr-Commit-Position: refs/heads/master@{#28837}

TBR=yangguo@chromium.org,erik.corry@gmail.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=

Review URL: https://codereview.chromium.org/1155683010

Cr-Commit-Position: refs/heads/master@{#28841}

src/debug.cc
src/isolate.cc
src/macros.py
src/messages.js
src/objects.cc
src/objects.h
src/rewriter.cc
test/cctest/test-api.cc
test/mjsunit/debug-sourceinfo.js

index 13fac5f..342aa50 100644 (file)
@@ -2552,7 +2552,8 @@ void Debug::OnCompileError(Handle<Script> script) {
 }
 
 
-void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) {
+void Debug::OnDebugBreak(Handle<Object> break_points_hit,
+                            bool auto_continue) {
   // The caller provided for DebugScope.
   AssertDebugContext();
   // Bail out if there is no listener for this event
index ee6778e..43e875b 100644 (file)
@@ -511,9 +511,18 @@ class CaptureStackTraceHelper {
       // line_number is already shifted by the script_line_offset.
       int relative_line_number = line_number - script_line_offset;
       if (!column_key_.is_null() && relative_line_number >= 0) {
-        int column = Script::GetColumnNumber(script, position);
+        Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
+        int start = (relative_line_number == 0) ? 0 :
+            Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
+        int column_offset = position - start;
+        if (relative_line_number == 0) {
+          // For the case where the code is on the same line as the script
+          // tag.
+          column_offset += script->column_offset()->value();
+        }
         JSObject::AddProperty(stack_frame, column_key_,
-                              handle(Smi::FromInt(column + 1), isolate_), NONE);
+                              handle(Smi::FromInt(column_offset + 1), isolate_),
+                              NONE);
       }
       JSObject::AddProperty(stack_frame, line_key_,
                             handle(Smi::FromInt(line_number + 1), isolate_),
index 9e07d42..94f94c3 100644 (file)
@@ -305,13 +305,6 @@ macro ORDERED_HASH_MAP_CHAIN_AT(table, entry, numBuckets) = (FIXED_ARRAY_GET(tab
 # Must match OrderedHashTable::kNotFound.
 define NOT_FOUND = -1;
 
-# Line ends array constants - see v8::internal::Script
-define REDUCTION_INDEX = 0;
-define NUMBER_OF_LINES_INDEX = 1;
-define FIRST_LINE_END_INDEX = 2;
-define ASCII_NL = 10;
-define ASCII_CR = 13;
-
 # Check whether debug is active.
 define DEBUG_IS_ACTIVE = (%_DebugIsActive() != 0);
 macro DEBUG_IS_STEPPING(function) = (%_DebugIsActive() != 0 && %DebugCallbackSupportsStepping(function));
index 3d84f72..727efc4 100644 (file)
@@ -40,7 +40,6 @@ var InternalArray = utils.InternalArray;
 var ObjectDefineProperty = utils.ObjectDefineProperty;
 
 var ArrayJoin;
-var MathFloor;
 var ObjectToString;
 var StringCharAt;
 var StringIndexOf;
@@ -48,7 +47,6 @@ var StringSubstring;
 
 utils.Import(function(from) {
   ArrayJoin = from.ArrayJoin;
-  MathFloor = from.MathFloor;
   ObjectToString = from.ObjectToString;
   StringCharAt = from.StringCharAt;
   StringIndexOf = from.StringIndexOf;
@@ -205,94 +203,41 @@ function GetSourceLine(message) {
   return location.sourceText();
 }
 
-
-function Newlines(source, from, to, reduction) {
-  var newLines = new InternalArray();
-  if (!IS_STRING(source)) return newLines;
-
-  var length = source.length;
-  for (; from < to && from < length && newLines.length < reduction - 1
-       ; ++from) {
-    var c = %_StringCharCodeAt(source, from);
-    if (c == ASCII_CR) {
-      if (from < length - 1) {
-        var c2 = %_StringCharCodeAt(source, from + 1);
-        if (c2 == ASCII_NL) {
-          from++;  // CR-LF counts as one newline.
-        }
-      }
-      newLines.push(from);
-    } else if (c == ASCII_NL) {
-      newLines.push(from);
-    }
-  }
-  // End-of-file virtual end-of-line.
-  if (to >= length) {
-    var last = length != 0 ? %_StringCharCodeAt(source, length - 1) : 0;
-    if (last != ASCII_NL && last != ASCII_CR) newLines.push(source.length - 1);
-  }
-  return newLines;
-}
-
-
-function ScriptLineEnd(line) {
-  if (line < 0) return -1;
-  var source = this.source;
-  if (!IS_STRING(source)) return -1;
-  var line_ends = this.line_ends;
-  var reduction = line_ends[REDUCTION_INDEX];
-  var index = MathFloor(line / reduction) + FIRST_LINE_END_INDEX;
-  if (index >= line_ends.length) return -1;
-  var position = line_ends[index];
-  if (line % reduction == 0) return position;
-  var lines = Newlines(source, position + 1, source.length, reduction);
-  return lines[line % reduction - 1];
-}
-
-
 /**
  * Find a line number given a specific source position.
  * @param {number} position The source position.
- * @return {number} -1 if position too large, else the 0-based line number.
+ * @return {number} 0 if input too small, -1 if input too large,
+       else the line number.
  */
 function ScriptLineFromPosition(position) {
-  var source = this.source;
-  if (!IS_STRING(source)) return -1;
-
+  var lower = 0;
+  var upper = this.lineCount() - 1;
   var line_ends = this.line_ends;
-  var lower = FIRST_LINE_END_INDEX;
-  var upper = line_ends.length - 1;
 
-  var reduction = line_ends[REDUCTION_INDEX];
-  // This '>' would normally be a '>=', but due to {}-less 'with' statements in
-  // top-level code we sometimes encounter code positions that are one character
-  // after the end of the source. See comment in Rewriter::Rewrite.
-  if (position > source.length) return -1;
+  // We'll never find invalid positions so bail right away.
+  if (position > line_ends[upper]) {
+    return -1;
+  }
 
-  var index = 0;
+  // This means we don't have to safe-guard indexing line_ends[i - 1].
+  if (position <= line_ends[0]) {
+    return 0;
+  }
 
   // Binary search to find line # from position range.
-  if (position > line_ends[upper]) {
-    index = upper;
-  } else {
-    // Invariant: position > line_ends[lower]
-    // Invariant: position <= line_ends[upper]
-    while (lower + 1 < upper) {
-      // Since they differ by at least 2, i must be different from both
-      // upper or lower.
-      var i = (lower + upper) >> 1;
-      if (position > line_ends[i]) {
-        lower = i;
-      } else {
-        upper = i;
-      }
+  while (upper >= 1) {
+    var i = (lower + upper) >> 1;
+
+    if (position > line_ends[i]) {
+      lower = i + 1;
+    } else if (position <= line_ends[i - 1]) {
+      upper = i - 1;
+    } else {
+      return i;
     }
-    index = lower;
   }
 
-  var line = (index - FIRST_LINE_END_INDEX) * reduction;
-  return line +
-      Newlines(source, line_ends[index] + 1, position, reduction).length;
+  return -1;
 }
 
 /**
@@ -305,19 +250,14 @@ function ScriptLineFromPosition(position) {
  */
 function ScriptLocationFromPosition(position,
                                     include_resource_offset) {
-  // Get zero-based line number.
   var line = this.lineFromPosition(position);
   if (line == -1) return null;
 
   // Determine start, end and column.
-  var start = this.lineEnd(line) + 1;
-  // End will be used for substr, so make it non-inclusive.
-  var end = this.lineEnd(line + 1) + 1;
-  if (end > this.source.length) end = this.source.length;
-  // But trim the newline if there is one (there might not be at EOF).
-  while (end > start) {
-    var trim_char = %_CallFunction(this.source, end - 1, StringCharAt);
-    if (trim_char != '\n' && trim_char != '\r') break;
+  var line_ends = this.line_ends;
+  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
+  var end = line_ends[line];
+  if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
     end--;
   }
   var column = position - start;
@@ -377,7 +317,7 @@ function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
     }
 
     return this.locationFromPosition(
-        this.lineEnd(offset_line + line) + 1 + column);  // line > 0 here.
+        this.line_ends[offset_line + line - 1] + 1 + column);  // line > 0 here.
   }
 }
 
@@ -411,14 +351,15 @@ function ScriptSourceSlice(opt_from_line, opt_to_line) {
     return null;
   }
 
-  var from_position = this.lineEnd(from_line) + 1;
-  var to_position = this.lineEnd(to_line) + 1;
+  var line_ends = this.line_ends;
+  var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
+  var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
 
   // Return a source slice with line numbers re-adjusted to the resource.
   return new SourceSlice(this,
                          from_line + this.line_offset,
                          to_line + this.line_offset,
-                         from_position, to_position);
+                          from_position, to_position);
 }
 
 
@@ -436,8 +377,9 @@ function ScriptSourceLine(opt_line) {
   }
 
   // Return the source line.
-  var start = this.lineEnd(line) + 1;
-  var end = this.lineEnd(line + 1);
+  var line_ends = this.line_ends;
+  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
+  var end = line_ends[line];
   return %_CallFunction(this.source, start, end, StringSubstring);
 }
 
@@ -449,7 +391,7 @@ function ScriptSourceLine(opt_line) {
  */
 function ScriptLineCount() {
   // Return number of source lines.
-  return this.line_ends[NUMBER_OF_LINES_INDEX];
+  return this.line_ends.length;
 }
 
 
@@ -484,8 +426,7 @@ utils.SetUpLockedPrototype(Script, [
     "sourceSlice", ScriptSourceSlice,
     "sourceLine", ScriptSourceLine,
     "lineCount", ScriptLineCount,
-    "nameOrSourceURL", ScriptNameOrSourceURL,
-    "lineEnd", ScriptLineEnd
+    "nameOrSourceURL", ScriptNameOrSourceURL
   ]
 );
 
index fe1a433..249597b 100644 (file)
@@ -8901,62 +8901,18 @@ static void CalculateLineEndsImpl(Isolate* isolate,
                                   Vector<const SourceChar> src,
                                   bool include_ending_line) {
   const int src_len = src.length();
-  bool exotic_newlines = false;
-  if (include_ending_line) {
-    // Initally assume reduction is 1, ie all line endings are in the array.
-    DCHECK_EQ(line_ends->length(), Script::kReductionIndex);
-    line_ends->Add(1);
-    // Write a placeholder for the number-of-lines indicator.
-    DCHECK_EQ(line_ends->length(), Script::kNumberOfLinesIndex);
-    line_ends->Add(0);
-    DCHECK_EQ(line_ends->length(), Script::kFirstLineEndIndex);
-    // There's a fictional newline just before the first character.  This
-    // simplifies a lot of things.
-    line_ends->Add(-1);
-  }
   UnicodeCache* cache = isolate->unicode_cache();
   for (int i = 0; i < src_len - 1; i++) {
     SourceChar current = src[i];
     SourceChar next = src[i + 1];
-    if (cache->IsLineTerminatorSequence(current, next)) {
-      if (current != '\n' && current != '\r') exotic_newlines = true;
-      line_ends->Add(i);
-    }
+    if (cache->IsLineTerminatorSequence(current, next)) line_ends->Add(i);
   }
 
-  int last_posn = src_len - 1;
-  if (last_posn >= 0 && cache->IsLineTerminatorSequence(src[last_posn], 0)) {
-    if (src[last_posn] != '\n' && src[last_posn] != '\r')
-      exotic_newlines = true;
-    line_ends->Add(last_posn);
+  if (src_len > 0 && cache->IsLineTerminatorSequence(src[src_len - 1], 0)) {
+    line_ends->Add(src_len - 1);
   } else if (include_ending_line) {
-    // Even if the last line misses a line end, it is counted. Because we
-    // sometimes use character positions that are one beyond the end of the
-    // source (see Rewriter::Rewrite) we set the newline one beyond that.
-    // This is used for substr calculations, which trims to string length,
-    // so it's harmless.
-    line_ends->Add(last_posn + 1);
-  }
-  if (include_ending_line) {
-    // Update number of lines in script.
-    int lines = line_ends->length() - (Script::kFirstLineEndIndex + 1);
-    line_ends->Set(Script::kNumberOfLinesIndex, lines);
-    // Abuse some flags. The bots will run with a good variety of these flags,
-    // giving better coverage for the reduction code.
-    bool always_reduce = FLAG_always_opt;
-    bool never_reduce = !FLAG_crankshaft;
-    if (!never_reduce && !exotic_newlines &&
-        (always_reduce ||
-         (line_ends->length() > 5 && line_ends->length() * 8 > src_len / 12))) {
-      // If the line-ends array (8 bytes per entry) is larger than about 8%
-      // of the source length, then we reduce it to save memory. This won't
-      // trigger if lines are > 100 characters on average. If it triggers, then
-      // the goal is for it to take only 3% of the source size.
-      int reduction =
-          always_reduce ? 2 : (line_ends->length() * 8 * 33 / src_len);
-      DCHECK(reduction > 1);
-      line_ends->Set(Script::kReductionIndex, reduction);
-    }
+    // Even if the last line misses a line end, it is counted.
+    line_ends->Add(src_len);
   }
 }
 
@@ -8985,30 +8941,12 @@ Handle<FixedArray> String::CalculateLineEnds(Handle<String> src,
                             include_ending_line);
     }
   }
-  if (include_ending_line) {
-    const int kReductionIndex = Script::kReductionIndex;
-    const int kFirstLineEndIndex = Script::kFirstLineEndIndex;
-    int line_count = line_ends.length() - kFirstLineEndIndex;
-    int reduction = line_ends[kReductionIndex];
-    int reduced_lines = (line_count + reduction - 1) / reduction;
-    Handle<FixedArray> array =
-        isolate->factory()->NewFixedArray(kFirstLineEndIndex + reduced_lines);
-    for (int i = 0; i < kFirstLineEndIndex; i++) {
-      array->set(i, Smi::FromInt(line_ends[i]));
-    }
-    int j = kFirstLineEndIndex;
-    for (int i = 0; i < line_count; i += reduction, ++j) {
-      array->set(j, Smi::FromInt(line_ends[i + kFirstLineEndIndex]));
-    }
-    return array;
-  } else {
-    Handle<FixedArray> array =
-        isolate->factory()->NewFixedArray(line_ends.length());
-    for (int i = 0; i < line_ends.length(); i++) {
-      array->set(i, Smi::FromInt(line_ends[i]));
-    }
-    return array;
+  int line_count = line_ends.length();
+  Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
+  for (int i = 0; i < line_count; i++) {
+    array->set(i, Smi::FromInt(line_ends[i]));
   }
+  return array;
 }
 
 
@@ -10366,113 +10304,41 @@ void Script::InitLineEnds(Handle<Script> script) {
 }
 
 
-static int CountForwardNNewlines(Handle<Script> script, int block_position,
-                                 int n) {
-  int position = block_position;
-  Handle<Object> source_object(script->source(), script->GetIsolate());
-  if (!source_object->IsString() || n == 0) return position;
-  Handle<String> source(Handle<String>::cast(source_object));
-  int length = source->length();
-  for (int i = position; i < length; i++) {
-    uc16 current = source->Get(i);
-    if (current == '\r') {
-      n--;
-      if (i + 1 < length && source->Get(i + 1) == '\n') i++;
-    } else if (current == '\n') {
-      n--;
-    }
-    if (n == 0) return i + 1;
-  }
-  if (n == 1 && length > 0) {
-    uc16 last = source->Get(length - 1);
-    if (last != '\n' && last != '\r') return length;
-  }
-  return -1;
-}
-
-
 int Script::GetColumnNumber(Handle<Script> script, int code_pos) {
-  // Get zero-based line number.
   int line_number = GetLineNumber(script, code_pos);
   if (line_number == -1) return -1;
 
   DisallowHeapAllocation no_allocation;
   FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
   line_number = line_number - script->line_offset()->value();
-  int reduction = Smi::cast(line_ends_array->get(kReductionIndex))->value();
-
-  int line_block_position =
-      Smi::cast(line_ends_array->get(line_number / reduction +
-                                     kFirstLineEndIndex))->value() +
-      1;
-
-  int line_position = CountForwardNNewlines(script, line_block_position,
-                                            line_number % reduction);
-  if (line_number == 0) line_position = -script->column_offset()->value();
-  return code_pos - line_position;
+  if (line_number == 0) return code_pos + script->column_offset()->value();
+  int prev_line_end_pos =
+      Smi::cast(line_ends_array->get(line_number - 1))->value();
+  return code_pos - (prev_line_end_pos + 1);
 }
 
 
-// Zero-based line number, calculated from UTF16 character position.
 int Script::GetLineNumberWithArray(int code_pos) {
   DisallowHeapAllocation no_allocation;
   DCHECK(line_ends()->IsFixedArray());
   FixedArray* line_ends_array = FixedArray::cast(line_ends());
   int line_ends_len = line_ends_array->length();
-  if (line_ends_len == 0) return -1;  // This happens if there is no source.
-  // There's always at least one line ending: A fictional newline just before
-  // the start.
-  DCHECK_GE(line_ends_len, kFirstLineEndIndex + 1);
-  int lower = kFirstLineEndIndex;
-  int upper = line_ends_len - 1;
-
-  if (code_pos < 0) return -1;
-  int index = 0;
+  if (line_ends_len == 0) return -1;
 
-  if (code_pos > Smi::cast(line_ends_array->get(upper))->value()) {
-    index = upper;
-  } else {
-    while (lower + 1 < upper) {
-      DCHECK_LE(Smi::cast(line_ends_array->get(lower))->value(), code_pos);
-      DCHECK_LE(code_pos, Smi::cast(line_ends_array->get(upper))->value());
-      int i = (lower + upper) >> 1;
-      DCHECK(lower != i && upper != i);
-      if ((Smi::cast(line_ends_array->get(i)))->value() >= code_pos) {
-        upper = i;
-      } else {
-        lower = i;
-      }
-    }
-    index = lower;
+  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
+    return line_offset()->value();
   }
 
-  int reduction = Smi::cast(line_ends_array->get(kReductionIndex))->value();
-  int line_number = (index - kFirstLineEndIndex) * reduction;
-
-  // We only saved an nth of the line ends in the array, because there were so
-  // many.
-  int start_of_earlier_line =
-      Smi::cast(line_ends_array->get(index))->value() + 1;
-
-  if (reduction == 1 || !source()->IsString()) {
-    return line_number + line_offset()->value();
-  }
-  String* src = String::cast(source());
-  // This '>' would normally be a '>=', but due to {}-less 'with' statements in
-  // top-level code we sometimes encounter code positions that are one character
-  // after the end of the source. See comment in Rewriter::Rewrite.
-  if (code_pos > src->length()) return -1;
-  for (int i = start_of_earlier_line; i < src->length() && i < code_pos; i++) {
-    uc16 current = src->Get(i);
-    if (current == '\r') {
-      if (i < code_pos - 1 && i < src->length() - 1 && src->Get(i + 1) == '\n')
-        i++;
-      line_number++;
-    } else if (current == '\n') {
-      line_number++;
+  int left = 0;
+  int right = line_ends_len;
+  while (int half = (right - left) / 2) {
+    if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
+      right -= half;
+    } else {
+      left += half;
     }
   }
-  return line_number + line_offset()->value();
+  return right + line_offset()->value();
 }
 
 
index 19e92df..582038c 100644 (file)
@@ -6540,11 +6540,6 @@ class Script: public Struct {
   static const int kSourceMappingUrlOffset = kSourceUrlOffset + kPointerSize;
   static const int kSize = kSourceMappingUrlOffset + kPointerSize;
 
-  // Sync with constants in macros.py.
-  static const int kReductionIndex = 0;
-  static const int kNumberOfLinesIndex = 1;
-  static const int kFirstLineEndIndex = 2;
-
  private:
   int GetLineNumberWithArray(int code_pos);
 
index bcfb814..ee08d88 100644 (file)
@@ -235,9 +235,6 @@ bool Rewriter::Rewrite(ParseInfo* info) {
       //   eval('with ({x:1}) x = 1');
       // the end position of the function generated for executing the eval code
       // coincides with the end of the with scope which is the position of '1'.
-      // Note that this may mean the position is outside the source code
-      // completely if there is no terminal newline, curly brace, or semicolon,
-      // often the case for 'eval'.
       int pos = function->end_position();
       VariableProxy* result_proxy =
           processor.factory()->NewVariableProxy(result, pos);
index e00b772..acefcf5 100644 (file)
@@ -14301,32 +14301,6 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) {
 }
 
 
-void ChangeNewlines(int kind, char* dest, size_t dest_len, const char* source) {
-  if (kind == 0) {
-    for (size_t i = 0; i <= strlen(source); i++) {
-      dest[i] = source[i];
-    }
-  } else {
-    for (size_t i = 0; i <= strlen(source); i++) {
-      char c = source[i];
-      if (c == '\n') {
-        if (kind == 1) {
-          *dest++ = '\r';
-          *dest++ = '\n';
-        } else {
-          // UTF-8 version of 0x2028 newline.
-          *dest++ = '\xe2';
-          *dest++ = '\x80';
-          *dest++ = '\xa8';
-        }
-      } else {
-        *dest++ = c;
-      }
-    }
-  }
-}
-
-
 // Tests the C++ StackTrace API.
 // TODO(3074796): Reenable this as a THREADED_TEST once it passes.
 // THREADED_TEST(CaptureStackTrace) {
@@ -14340,61 +14314,50 @@ TEST(CaptureStackTrace) {
              v8::FunctionTemplate::New(isolate, AnalyzeStackInNativeCode));
   LocalContext context(0, templ);
 
-  for (int i = 0; i < 3; i++) {
-    // Test getting OVERVIEW information. Should ignore information that is not
-    // script name, function name, line number, and column offset.
-    const char* overview_source =
-        "function bar() {\n"
-        "  var y; AnalyzeStackInNativeCode(1);\n"
-        "}\n"
-        "function foo() {\n"
-        "\n"
-        "  bar();\n"
-        "}\n"
-        "var x;eval('new foo();');";
-    size_t munged_length = strlen(overview_source) * 3 + 1;
-    char* overview_munged_source = new char[munged_length];
-    ChangeNewlines(i, overview_munged_source, munged_length, overview_source);
-
-    v8::Handle<v8::String> overview_src =
-        v8::String::NewFromUtf8(isolate, overview_munged_source);
-    delete[] overview_munged_source;
-    v8::ScriptCompiler::Source script_source(overview_src,
-                                             v8::ScriptOrigin(origin));
-    v8::Handle<Value> overview_result(
-        v8::ScriptCompiler::CompileUnbound(isolate, &script_source)
-            ->BindToCurrentContext()
-            ->Run());
-    CHECK(!overview_result.IsEmpty());
-    CHECK(overview_result->IsObject());
-
-    // Test getting DETAILED information.
-    const char* detailed_source =
-        "function bat() {AnalyzeStackInNativeCode(2);\n"
-        "}\n"
-        "\n"
-        "function baz() {\n"
-        "  bat();\n"
-        "}\n"
-        "eval('new baz();');";
-    munged_length = strlen(detailed_source) * 3 + 1;
-    char* detailed_munged_source = new char[munged_length];
-    ChangeNewlines(i, detailed_munged_source, munged_length, detailed_source);
-    v8::Handle<v8::String> detailed_src =
-        v8::String::NewFromUtf8(isolate, detailed_munged_source);
-    delete[] detailed_munged_source;
-    // Make the script using a non-zero line and column offset.
-    v8::Handle<v8::Integer> line_offset = v8::Integer::New(isolate, 3);
-    v8::Handle<v8::Integer> column_offset = v8::Integer::New(isolate, 5);
-    v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset);
-    v8::ScriptCompiler::Source script_source2(detailed_src, detailed_origin);
-    v8::Handle<v8::UnboundScript> detailed_script(
-        v8::ScriptCompiler::CompileUnbound(isolate, &script_source2));
-    v8::Handle<Value> detailed_result(
-        detailed_script->BindToCurrentContext()->Run());
-    CHECK(!detailed_result.IsEmpty());
-    CHECK(detailed_result->IsObject());
-  }
+  // Test getting OVERVIEW information. Should ignore information that is not
+  // script name, function name, line number, and column offset.
+  const char *overview_source =
+    "function bar() {\n"
+    "  var y; AnalyzeStackInNativeCode(1);\n"
+    "}\n"
+    "function foo() {\n"
+    "\n"
+    "  bar();\n"
+    "}\n"
+    "var x;eval('new foo();');";
+  v8::Handle<v8::String> overview_src =
+      v8::String::NewFromUtf8(isolate, overview_source);
+  v8::ScriptCompiler::Source script_source(overview_src,
+                                           v8::ScriptOrigin(origin));
+  v8::Handle<Value> overview_result(
+      v8::ScriptCompiler::CompileUnbound(isolate, &script_source)
+          ->BindToCurrentContext()
+          ->Run());
+  CHECK(!overview_result.IsEmpty());
+  CHECK(overview_result->IsObject());
+
+  // Test getting DETAILED information.
+  const char *detailed_source =
+    "function bat() {AnalyzeStackInNativeCode(2);\n"
+    "}\n"
+    "\n"
+    "function baz() {\n"
+    "  bat();\n"
+    "}\n"
+    "eval('new baz();');";
+  v8::Handle<v8::String> detailed_src =
+      v8::String::NewFromUtf8(isolate, detailed_source);
+  // Make the script using a non-zero line and column offset.
+  v8::Handle<v8::Integer> line_offset = v8::Integer::New(isolate, 3);
+  v8::Handle<v8::Integer> column_offset = v8::Integer::New(isolate, 5);
+  v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset);
+  v8::ScriptCompiler::Source script_source2(detailed_src, detailed_origin);
+  v8::Handle<v8::UnboundScript> detailed_script(
+      v8::ScriptCompiler::CompileUnbound(isolate, &script_source2));
+  v8::Handle<Value> detailed_result(
+      detailed_script->BindToCurrentContext()->Run());
+  CHECK(!detailed_result.IsEmpty());
+  CHECK(detailed_result->IsObject());
 }
 
 
index 9c03449..1dbe1b7 100644 (file)
@@ -63,11 +63,11 @@ var comment_lines = 28;
 
 // This is the last position in the entire file (note: this equals
 // file size of <debug-sourceinfo.js> - 1, since starting at 0).
-var last_position = 11591;
+var last_position = 11337;
 // This is the last line of entire file (note: starting at 0).
-var last_line = 268;
-// This is the column of the last character (note: starting at 0) due to
-// final line having a trailing newline that is conceptually part of that line.
+var last_line = 265;
+// This is the last column of last line (note: starting at 0 and +1, due
+// to trailing <LF>).
 var last_column = 1;
 
 // This magic number is the length or the first line comment (actually number
@@ -250,10 +250,7 @@ assertEquals(158 + start_d, Debug.findFunctionSourceLocation(d, 17, 0).position)
 
 // Make sure invalid inputs work properly.
 assertEquals(0, script.locationFromPosition(-1).line);
-// We might expect last_position + 1 to be the first illegal position, but we
-// sometimes generate character positions that are one past the last character.
-// See Rewriter::Rewrite for details.
-assertEquals(null, script.locationFromPosition(last_position + 2));
+assertEquals(null, script.locationFromPosition(last_position + 1));
 
 // Test last position.
 assertEquals(last_position, script.locationFromPosition(last_position).position);