Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/messages.js

Issue 1137683003: Only record one in n line endings to save space. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix false detection of exotic newlines Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/macros.py ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ------------------------------------------------------------------- 5 // -------------------------------------------------------------------
6 6
7 var $errorToString; 7 var $errorToString;
8 var $getStackTraceLine; 8 var $getStackTraceLine;
9 var $messageGetPositionInLine; 9 var $messageGetPositionInLine;
10 var $messageGetLineNumber; 10 var $messageGetLineNumber;
(...skipping 22 matching lines...) Expand all
33 %CheckIsBootstrapping(); 33 %CheckIsBootstrapping();
34 34
35 // ------------------------------------------------------------------- 35 // -------------------------------------------------------------------
36 // Imports 36 // Imports
37 37
38 var GlobalObject = global.Object; 38 var GlobalObject = global.Object;
39 var InternalArray = utils.InternalArray; 39 var InternalArray = utils.InternalArray;
40 var ObjectDefineProperty = utils.ObjectDefineProperty; 40 var ObjectDefineProperty = utils.ObjectDefineProperty;
41 41
42 var ArrayJoin; 42 var ArrayJoin;
43 var MathFloor;
43 var ObjectToString; 44 var ObjectToString;
44 var StringCharAt; 45 var StringCharAt;
45 var StringIndexOf; 46 var StringIndexOf;
46 var StringSubstring; 47 var StringSubstring;
47 48
48 utils.Import(function(from) { 49 utils.Import(function(from) {
49 ArrayJoin = from.ArrayJoin; 50 ArrayJoin = from.ArrayJoin;
51 MathFloor = from.MathFloor;
50 ObjectToString = from.ObjectToString; 52 ObjectToString = from.ObjectToString;
51 StringCharAt = from.StringCharAt; 53 StringCharAt = from.StringCharAt;
52 StringIndexOf = from.StringIndexOf; 54 StringIndexOf = from.StringIndexOf;
53 StringSubstring = from.StringSubstring; 55 StringSubstring = from.StringSubstring;
54 }); 56 });
55 57
56 // ------------------------------------------------------------------- 58 // -------------------------------------------------------------------
57 59
58 var GlobalError; 60 var GlobalError;
59 var GlobalTypeError; 61 var GlobalTypeError;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 // Returns the source code line containing the given source 198 // Returns the source code line containing the given source
197 // position, or the empty string if the position is invalid. 199 // position, or the empty string if the position is invalid.
198 function GetSourceLine(message) { 200 function GetSourceLine(message) {
199 var script = %MessageGetScript(message); 201 var script = %MessageGetScript(message);
200 var start_position = %MessageGetStartPosition(message); 202 var start_position = %MessageGetStartPosition(message);
201 var location = script.locationFromPosition(start_position, true); 203 var location = script.locationFromPosition(start_position, true);
202 if (location == null) return ""; 204 if (location == null) return "";
203 return location.sourceText(); 205 return location.sourceText();
204 } 206 }
205 207
208
209 function Newlines(source, from, to, reduction) {
210 var newLines = new InternalArray();
211 if (!IS_STRING(source)) return newLines;
212
213 var length = source.length;
214 for (; from < to && from < length && newLines.length < reduction - 1
215 ; ++from) {
216 var c = %_StringCharCodeAt(source, from);
217 if (c == ASCII_CR) {
218 if (from < length - 1) {
219 var c2 = %_StringCharCodeAt(source, from + 1);
220 if (c2 == ASCII_NL) {
221 from++; // CR-LF counts as one newline.
222 }
223 }
224 newLines.push(from);
225 } else if (c == ASCII_NL) {
226 newLines.push(from);
227 }
228 }
229 // End-of-file virtual end-of-line.
230 if (to >= length) {
231 var last = length != 0 ? %_StringCharCodeAt(source, length - 1) : 0;
232 if (last != ASCII_NL && last != ASCII_CR) newLines.push(source.length - 1);
233 }
234 return newLines;
235 }
236
237
238 function ScriptLineEnd(line) {
239 if (line < 0) return -1;
240 var source = this.source;
241 if (!IS_STRING(source)) return -1;
242 var line_ends = this.line_ends;
243 var reduction = line_ends[REDUCTION_INDEX];
244 var index = MathFloor(line / reduction) + FIRST_LINE_END_INDEX;
245 if (index >= line_ends.length) return -1;
246 var position = line_ends[index];
247 if (line % reduction == 0) return position;
248 var lines = Newlines(source, position + 1, source.length, reduction);
249 return lines[line % reduction - 1];
250 }
251
252
206 /** 253 /**
207 * Find a line number given a specific source position. 254 * Find a line number given a specific source position.
208 * @param {number} position The source position. 255 * @param {number} position The source position.
209 * @return {number} 0 if input too small, -1 if input too large, 256 * @return {number} -1 if position too large, else the 0-based line number.
210 else the line number.
211 */ 257 */
212 function ScriptLineFromPosition(position) { 258 function ScriptLineFromPosition(position) {
213 var lower = 0; 259 var source = this.source;
214 var upper = this.lineCount() - 1; 260 if (!IS_STRING(source)) return -1;
261
215 var line_ends = this.line_ends; 262 var line_ends = this.line_ends;
263 var lower = FIRST_LINE_END_INDEX;
264 var upper = line_ends.length - 1;
216 265
217 // We'll never find invalid positions so bail right away. 266 var reduction = line_ends[REDUCTION_INDEX];
267 // This '>' would normally be a '>=', but due to {}-less 'with' statements in
268 // top-level code we sometimes encounter code positions that are one character
269 // after the end of the source. See comment in Rewriter::Rewrite.
270 if (position > source.length) return -1;
271
272 var index = 0;
273
274 // Binary search to find line # from position range.
218 if (position > line_ends[upper]) { 275 if (position > line_ends[upper]) {
219 return -1; 276 index = upper;
277 } else {
278 // Invariant: position > line_ends[lower]
279 // Invariant: position <= line_ends[upper]
280 while (lower + 1 < upper) {
281 // Since they differ by at least 2, i must be different from both
282 // upper or lower.
283 var i = (lower + upper) >> 1;
284 if (position > line_ends[i]) {
285 lower = i;
286 } else {
287 upper = i;
288 }
289 }
290 index = lower;
220 } 291 }
221 292
222 // This means we don't have to safe-guard indexing line_ends[i - 1]. 293 var line = (index - FIRST_LINE_END_INDEX) * reduction;
223 if (position <= line_ends[0]) { 294 return line +
224 return 0; 295 Newlines(source, line_ends[index] + 1, position, reduction).length;
225 }
226
227 // Binary search to find line # from position range.
228 while (upper >= 1) {
229 var i = (lower + upper) >> 1;
230
231 if (position > line_ends[i]) {
232 lower = i + 1;
233 } else if (position <= line_ends[i - 1]) {
234 upper = i - 1;
235 } else {
236 return i;
237 }
238 }
239
240 return -1;
241 } 296 }
242 297
243 /** 298 /**
244 * Get information on a specific source position. 299 * Get information on a specific source position.
245 * @param {number} position The source position 300 * @param {number} position The source position
246 * @param {boolean} include_resource_offset Set to true to have the resource 301 * @param {boolean} include_resource_offset Set to true to have the resource
247 * offset added to the location 302 * offset added to the location
248 * @return {SourceLocation} 303 * @return {SourceLocation}
249 * If line is negative or not in the source null is returned. 304 * If line is negative or not in the source null is returned.
250 */ 305 */
251 function ScriptLocationFromPosition(position, 306 function ScriptLocationFromPosition(position,
252 include_resource_offset) { 307 include_resource_offset) {
308 // Get zero-based line number.
253 var line = this.lineFromPosition(position); 309 var line = this.lineFromPosition(position);
254 if (line == -1) return null; 310 if (line == -1) return null;
255 311
256 // Determine start, end and column. 312 // Determine start, end and column.
257 var line_ends = this.line_ends; 313 var start = this.lineEnd(line) + 1;
258 var start = line == 0 ? 0 : line_ends[line - 1] + 1; 314 // End will be used for substr, so make it non-inclusive.
259 var end = line_ends[line]; 315 var end = this.lineEnd(line + 1) + 1;
260 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') { 316 if (end > this.source.length) end = this.source.length;
317 // But trim the newline if there is one (there might not be at EOF).
318 while (end > start) {
319 var trim_char = %_CallFunction(this.source, end - 1, StringCharAt);
320 if (trim_char != '\n' && trim_char != '\r') break;
261 end--; 321 end--;
262 } 322 }
263 var column = position - start; 323 var column = position - start;
264 324
265 // Adjust according to the offset within the resource. 325 // Adjust according to the offset within the resource.
266 if (include_resource_offset) { 326 if (include_resource_offset) {
267 line += this.line_offset; 327 line += this.line_offset;
268 if (line == this.line_offset) { 328 if (line == this.line_offset) {
269 column += this.column_offset; 329 column += this.column_offset;
270 } 330 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 return this.locationFromPosition(offset_position + column, false); 370 return this.locationFromPosition(offset_position + column, false);
311 } else { 371 } else {
312 // Find the line where the offset position is located. 372 // Find the line where the offset position is located.
313 var offset_line = this.lineFromPosition(offset_position); 373 var offset_line = this.lineFromPosition(offset_position);
314 374
315 if (offset_line == -1 || offset_line + line >= this.lineCount()) { 375 if (offset_line == -1 || offset_line + line >= this.lineCount()) {
316 return null; 376 return null;
317 } 377 }
318 378
319 return this.locationFromPosition( 379 return this.locationFromPosition(
320 this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here. 380 this.lineEnd(offset_line + line) + 1 + column); // line > 0 here.
321 } 381 }
322 } 382 }
323 383
324 384
325 /** 385 /**
326 * Get a slice of source code from the script. The boundaries for the slice is 386 * Get a slice of source code from the script. The boundaries for the slice is
327 * specified in lines. 387 * specified in lines.
328 * @param {number} opt_from_line The first line (zero bound) in the slice. 388 * @param {number} opt_from_line The first line (zero bound) in the slice.
329 * Default is 0 389 * Default is 0
330 * @param {number} opt_to_column The last line (zero bound) in the slice (non 390 * @param {number} opt_to_column The last line (zero bound) in the slice (non
(...skipping 13 matching lines...) Expand all
344 if (from_line < 0) from_line = 0; 404 if (from_line < 0) from_line = 0;
345 if (to_line > this.lineCount()) to_line = this.lineCount(); 405 if (to_line > this.lineCount()) to_line = this.lineCount();
346 406
347 // Check parameters. 407 // Check parameters.
348 if (from_line >= this.lineCount() || 408 if (from_line >= this.lineCount() ||
349 to_line < 0 || 409 to_line < 0 ||
350 from_line > to_line) { 410 from_line > to_line) {
351 return null; 411 return null;
352 } 412 }
353 413
354 var line_ends = this.line_ends; 414 var from_position = this.lineEnd(from_line) + 1;
355 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1; 415 var to_position = this.lineEnd(to_line) + 1;
356 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
357 416
358 // Return a source slice with line numbers re-adjusted to the resource. 417 // Return a source slice with line numbers re-adjusted to the resource.
359 return new SourceSlice(this, 418 return new SourceSlice(this,
360 from_line + this.line_offset, 419 from_line + this.line_offset,
361 to_line + this.line_offset, 420 to_line + this.line_offset,
362 from_position, to_position); 421 from_position, to_position);
363 } 422 }
364 423
365 424
366 function ScriptSourceLine(opt_line) { 425 function ScriptSourceLine(opt_line) {
367 // Default is the first line in the script. Lines in the script are relative 426 // Default is the first line in the script. Lines in the script are relative
368 // to the offset within the resource. 427 // to the offset within the resource.
369 var line = 0; 428 var line = 0;
370 if (!IS_UNDEFINED(opt_line)) { 429 if (!IS_UNDEFINED(opt_line)) {
371 line = opt_line - this.line_offset; 430 line = opt_line - this.line_offset;
372 } 431 }
373 432
374 // Check parameter. 433 // Check parameter.
375 if (line < 0 || this.lineCount() <= line) { 434 if (line < 0 || this.lineCount() <= line) {
376 return null; 435 return null;
377 } 436 }
378 437
379 // Return the source line. 438 // Return the source line.
380 var line_ends = this.line_ends; 439 var start = this.lineEnd(line) + 1;
381 var start = line == 0 ? 0 : line_ends[line - 1] + 1; 440 var end = this.lineEnd(line + 1);
382 var end = line_ends[line];
383 return %_CallFunction(this.source, start, end, StringSubstring); 441 return %_CallFunction(this.source, start, end, StringSubstring);
384 } 442 }
385 443
386 444
387 /** 445 /**
388 * Returns the number of source lines. 446 * Returns the number of source lines.
389 * @return {number} 447 * @return {number}
390 * Number of source lines. 448 * Number of source lines.
391 */ 449 */
392 function ScriptLineCount() { 450 function ScriptLineCount() {
393 // Return number of source lines. 451 // Return number of source lines.
394 return this.line_ends.length; 452 return this.line_ends[NUMBER_OF_LINES_INDEX];
395 } 453 }
396 454
397 455
398 /** 456 /**
399 * If sourceURL comment is available returns sourceURL comment contents. 457 * If sourceURL comment is available returns sourceURL comment contents.
400 * Otherwise, script name is returned. See 458 * Otherwise, script name is returned. See
401 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt 459 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
402 * and Source Map Revision 3 proposal for details on using //# sourceURL and 460 * and Source Map Revision 3 proposal for details on using //# sourceURL and
403 * deprecated //@ sourceURL comment to identify scripts that don't have name. 461 * deprecated //@ sourceURL comment to identify scripts that don't have name.
404 * 462 *
(...skipping 14 matching lines...) Expand all
419 "line_ends", 477 "line_ends",
420 "line_offset", 478 "line_offset",
421 "column_offset" 479 "column_offset"
422 ], [ 480 ], [
423 "lineFromPosition", ScriptLineFromPosition, 481 "lineFromPosition", ScriptLineFromPosition,
424 "locationFromPosition", ScriptLocationFromPosition, 482 "locationFromPosition", ScriptLocationFromPosition,
425 "locationFromLine", ScriptLocationFromLine, 483 "locationFromLine", ScriptLocationFromLine,
426 "sourceSlice", ScriptSourceSlice, 484 "sourceSlice", ScriptSourceSlice,
427 "sourceLine", ScriptSourceLine, 485 "sourceLine", ScriptSourceLine,
428 "lineCount", ScriptLineCount, 486 "lineCount", ScriptLineCount,
429 "nameOrSourceURL", ScriptNameOrSourceURL 487 "nameOrSourceURL", ScriptNameOrSourceURL,
488 "lineEnd", ScriptLineEnd
430 ] 489 ]
431 ); 490 );
432 491
433 492
434 /** 493 /**
435 * Class for source location. A source location is a position within some 494 * Class for source location. A source location is a position within some
436 * source with the following properties: 495 * source with the following properties:
437 * script : script object for the source 496 * script : script object for the source
438 * line : source line number 497 * line : source line number
439 * column : source column within the line 498 * column : source column within the line
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 // Define accessors first, as this may fail and throw. 1141 // Define accessors first, as this may fail and throw.
1083 ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter, 1142 ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
1084 set: StackTraceSetter, 1143 set: StackTraceSetter,
1085 configurable: true }); 1144 configurable: true });
1086 %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace); 1145 %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
1087 }; 1146 };
1088 1147
1089 GlobalError.captureStackTrace = captureStackTrace; 1148 GlobalError.captureStackTrace = captureStackTrace;
1090 1149
1091 }); 1150 });
OLDNEW
« no previous file with comments | « src/macros.py ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698