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