Index: src/messages.js |
diff --git a/src/messages.js b/src/messages.js |
index 3ff69fb61d2377db7760f2ff5076dd2740badaad..8d79dac43225931eb1800bde5f2b54feead2f92b 100644 |
--- a/src/messages.js |
+++ b/src/messages.js |
@@ -40,7 +40,6 @@ |
var ObjectDefineProperty = utils.ObjectDefineProperty; |
var ArrayJoin; |
-var MathFloor; |
var ObjectToString; |
var StringCharAt; |
var StringIndexOf; |
@@ -48,7 +47,6 @@ |
utils.Import(function(from) { |
ArrayJoin = from.ArrayJoin; |
- MathFloor = from.MathFloor; |
ObjectToString = from.ObjectToString; |
StringCharAt = from.StringCharAt; |
StringIndexOf = from.StringIndexOf; |
@@ -205,94 +203,41 @@ |
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; |
- |
- var index = 0; |
+ |
+ // We'll never find invalid positions so bail right away. |
+ if (position > line_ends[upper]) { |
+ return -1; |
+ } |
+ |
+ // 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; |
- } |
- } |
- index = lower; |
- } |
- |
- var line = (index - FIRST_LINE_END_INDEX) * reduction; |
- return line + |
- Newlines(source, line_ends[index] + 1, position, reduction).length; |
+ 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; |
+ } |
+ } |
+ |
+ return -1; |
} |
/** |
@@ -305,19 +250,14 @@ |
*/ |
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 @@ |
} |
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 @@ |
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 @@ |
} |
// 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 ScriptLineCount() { |
// Return number of source lines. |
- return this.line_ends[NUMBER_OF_LINES_INDEX]; |
+ return this.line_ends.length; |
} |
@@ -484,8 +426,7 @@ |
"sourceSlice", ScriptSourceSlice, |
"sourceLine", ScriptSourceLine, |
"lineCount", ScriptLineCount, |
- "nameOrSourceURL", ScriptNameOrSourceURL, |
- "lineEnd", ScriptLineEnd |
+ "nameOrSourceURL", ScriptNameOrSourceURL |
] |
); |