| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 apply_non_function: "Function.prototype.apply was called on %0, whic
h is a %1 and not a function", | 95 apply_non_function: "Function.prototype.apply was called on %0, whic
h is a %1 and not a function", |
| 96 apply_wrong_args: "Function.prototype.apply: Arguments list has wr
ong type", | 96 apply_wrong_args: "Function.prototype.apply: Arguments list has wr
ong type", |
| 97 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0' in
%1", | 97 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0' in
%1", |
| 98 instanceof_function_expected: "Expecting a function in instanceof check, but g
ot %0", | 98 instanceof_function_expected: "Expecting a function in instanceof check, but g
ot %0", |
| 99 instanceof_nonobject_proto: "Function has non-object prototype '%0' in insta
nceof check", | 99 instanceof_nonobject_proto: "Function has non-object prototype '%0' in insta
nceof check", |
| 100 null_to_object: "Cannot convert null to object", | 100 null_to_object: "Cannot convert null to object", |
| 101 // RangeError | 101 // RangeError |
| 102 invalid_array_length: "Invalid array length", | 102 invalid_array_length: "Invalid array length", |
| 103 invalid_array_apply_length: "Function.prototype.apply supports only up to 10
24 arguments", | 103 invalid_array_apply_length: "Function.prototype.apply supports only up to 10
24 arguments", |
| 104 stack_overflow: "Maximum call stack size exceeded", | 104 stack_overflow: "Maximum call stack size exceeded", |
| 105 apply_overflow: "Function.prototype.apply cannot support %0 argu
ments", | 105 apply_overflow: "Function.prototype.apply cannot support %0 argu
ments", |
| 106 // SyntaxError | 106 // SyntaxError |
| 107 unable_to_parse: "Parse error", | 107 unable_to_parse: "Parse error", |
| 108 duplicate_regexp_flag: "Duplicate RegExp flag %0", | 108 duplicate_regexp_flag: "Duplicate RegExp flag %0", |
| 109 unrecognized_regexp_flag: "Unrecognized RegExp flag %0", | 109 unrecognized_regexp_flag: "Unrecognized RegExp flag %0", |
| 110 invalid_regexp: "Invalid RegExp pattern /%0/", | 110 invalid_regexp: "Invalid RegExp pattern /%0/", |
| 111 illegal_break: "Illegal break statement", | 111 illegal_break: "Illegal break statement", |
| 112 illegal_continue: "Illegal continue statement", | 112 illegal_continue: "Illegal continue statement", |
| 113 illegal_return: "Illegal return statement", | 113 illegal_return: "Illegal return statement", |
| 114 error_loading_debugger: "Error loading debugger %0", | 114 error_loading_debugger: "Error loading debugger %0", |
| 115 no_input_to_regexp: "No input to %0", | 115 no_input_to_regexp: "No input to %0", |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 return MakeGenericError($EvalError, type, args); | 221 return MakeGenericError($EvalError, type, args); |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 function MakeError(type, args) { | 225 function MakeError(type, args) { |
| 226 return MakeGenericError($Error, type, args); | 226 return MakeGenericError($Error, type, args); |
| 227 } | 227 } |
| 228 | 228 |
| 229 | 229 |
| 230 /** | 230 /** |
| 231 * Initialize the cached source information in a script. Currently all line | |
| 232 * end positions are cached. | |
| 233 */ | |
| 234 Script.prototype.initSourceInfo_ = function () { | |
| 235 // Just return if initialized. | |
| 236 if (this.lineEnds_) return; | |
| 237 | |
| 238 // Collect all line endings. | |
| 239 this.lineEnds_ = []; | |
| 240 for (var i = 0; i < this.source.length; i++) { | |
| 241 var current = this.source.charAt(i); | |
| 242 if (current == '\n') { | |
| 243 this.lineEnds_.push(i); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 // If the script does not end with a line ending add the final end position | |
| 248 // as just past the last line ending. | |
| 249 if (this.lineEnds_[this.lineEnds_.length - 1] != this.source.length - 1) { | |
| 250 this.lineEnds_.push(this.source.length); | |
| 251 } | |
| 252 }; | |
| 253 | |
| 254 | |
| 255 /** | |
| 256 * Get information on a specific source position. | 231 * Get information on a specific source position. |
| 257 * @param {number} position The source position | 232 * @param {number} position The source position |
| 258 * @return {SourceLocation} | 233 * @return {SourceLocation} |
| 259 * If line is negative or not in the source null is returned. | 234 * If line is negative or not in the source null is returned. |
| 260 */ | 235 */ |
| 261 Script.prototype.locationFromPosition = function (position) { | 236 Script.prototype.locationFromPosition = function (position) { |
| 262 // Make sure source info has been initialized. | |
| 263 this.initSourceInfo_(); | |
| 264 | |
| 265 var lineCount = this.lineCount(); | 237 var lineCount = this.lineCount(); |
| 266 var line = -1; | 238 var line = -1; |
| 267 if (position <= this.lineEnds_[0]) { | 239 if (position <= this.line_ends[0]) { |
| 268 line = 0; | 240 line = 0; |
| 269 } else { | 241 } else { |
| 270 for (var i = 1; i < lineCount; i++) { | 242 for (var i = 1; i < lineCount; i++) { |
| 271 if (this.lineEnds_[i - 1] < position && position <= this.lineEnds_[i]) { | 243 if (this.line_ends[i - 1] < position && position <= this.line_ends[i]) { |
| 272 line = i; | 244 line = i; |
| 273 break; | 245 break; |
| 274 } | 246 } |
| 275 } | 247 } |
| 276 } | 248 } |
| 277 | 249 |
| 278 if (line == -1) return null; | 250 if (line == -1) return null; |
| 279 | 251 |
| 280 // Determine start, end and column. | 252 // Determine start, end and column. |
| 281 var start = line == 0 ? 0 : this.lineEnds_[line - 1] + 1; | 253 var start = line == 0 ? 0 : this.line_ends[line - 1] + 1; |
| 282 var end = this.lineEnds_[line]; | 254 var end = this.line_ends[line]; |
| 283 if (end > 0 && this.source.charAt(end - 1) == '\r') end--; | 255 if (end > 0 && this.source.charAt(end - 1) == '\r') end--; |
| 284 var column = position - start; | 256 var column = position - start; |
| 285 | 257 |
| 286 // Adjust according to the offset within the resource. | 258 // Adjust according to the offset within the resource. |
| 287 line += this.line_offset; | 259 line += this.line_offset; |
| 288 if (line == this.line_offset) { | 260 if (line == this.line_offset) { |
| 289 column += this.column_offset; | 261 column += this.column_offset; |
| 290 } | 262 } |
| 291 | 263 |
| 292 return new SourceLocation(this, position, line, column, start, end); | 264 return new SourceLocation(this, position, line, column, start, end); |
| 293 }; | 265 }; |
| 294 | 266 |
| 295 | 267 |
| 296 /** | 268 /** |
| 297 * Get information on a specific source line and column possibly offset by a | 269 * Get information on a specific source line and column possibly offset by a |
| 298 * fixed source position. This function is used to find a source position from | 270 * fixed source position. This function is used to find a source position from |
| 299 * a line and column position. The fixed source position offset is typically | 271 * a line and column position. The fixed source position offset is typically |
| 300 * used to find a source position in a function based on a line and column in | 272 * used to find a source position in a function based on a line and column in |
| 301 * the source for the function alone. The offset passed will then be the | 273 * the source for the function alone. The offset passed will then be the |
| 302 * start position of the source for the function within the full script source. | 274 * start position of the source for the function within the full script source. |
| 303 * @param {number} opt_line The line within the source. Default value is 0 | 275 * @param {number} opt_line The line within the source. Default value is 0 |
| 304 * @param {number} opt_column The column in within the line. Default value is 0 | 276 * @param {number} opt_column The column in within the line. Default value is 0 |
| 305 * @param {number} opt_offset_position The offset from the begining of the | 277 * @param {number} opt_offset_position The offset from the begining of the |
| 306 * source from where the line and column calculation starts. Default value i
s 0 | 278 * source from where the line and column calculation starts. Default value i
s 0 |
| 307 * @return {SourceLocation} | 279 * @return {SourceLocation} |
| 308 * If line is negative or not in the source null is returned. | 280 * If line is negative or not in the source null is returned. |
| 309 */ | 281 */ |
| 310 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p
osition) { | 282 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p
osition) { |
| 311 // Make soure source info has been initialized. | |
| 312 this.initSourceInfo_(); | |
| 313 | |
| 314 // Default is the first line in the script. Lines in the script is relative | 283 // Default is the first line in the script. Lines in the script is relative |
| 315 // to the offset within the resource. | 284 // to the offset within the resource. |
| 316 var line = 0; | 285 var line = 0; |
| 317 if (!IS_UNDEFINED(opt_line)) { | 286 if (!IS_UNDEFINED(opt_line)) { |
| 318 line = opt_line - this.line_offset; | 287 line = opt_line - this.line_offset; |
| 319 } | 288 } |
| 320 | 289 |
| 321 // Default is first column. If on the first line add the offset within the | 290 // Default is first column. If on the first line add the offset within the |
| 322 // resource. | 291 // resource. |
| 323 var column = opt_column || 0; | 292 var column = opt_column || 0; |
| 324 if (line == 0) { | 293 if (line == 0) { |
| 325 column -= this.column_offset | 294 column -= this.column_offset |
| 326 } | 295 } |
| 327 | 296 |
| 328 var offset_position = opt_offset_position || 0; | 297 var offset_position = opt_offset_position || 0; |
| 329 if (line < 0 || column < 0 || offset_position < 0) return null; | 298 if (line < 0 || column < 0 || offset_position < 0) return null; |
| 330 if (line == 0) { | 299 if (line == 0) { |
| 331 return this.locationFromPosition(offset_position + column); | 300 return this.locationFromPosition(offset_position + column); |
| 332 } else { | 301 } else { |
| 333 // Find the line where the offset position is located | 302 // Find the line where the offset position is located |
| 334 var lineCount = this.lineCount(); | 303 var lineCount = this.lineCount(); |
| 335 var offset_line; | 304 var offset_line; |
| 336 for (var i = 0; i < lineCount; i++) { | 305 for (var i = 0; i < lineCount; i++) { |
| 337 if (offset_position <= this.lineEnds_[i]) { | 306 if (offset_position <= this.line_ends[i]) { |
| 338 offset_line = i; | 307 offset_line = i; |
| 339 break; | 308 break; |
| 340 } | 309 } |
| 341 } | 310 } |
| 342 if (offset_line + line >= lineCount) return null; | 311 if (offset_line + line >= lineCount) return null; |
| 343 return this.locationFromPosition(this.lineEnds_[offset_line + line - 1] + 1
+ column); // line > 0 here. | 312 return this.locationFromPosition(this.line_ends[offset_line + line - 1] + 1
+ column); // line > 0 here. |
| 344 } | 313 } |
| 345 } | 314 } |
| 346 | 315 |
| 347 | 316 |
| 348 /** | 317 /** |
| 349 * Get a slice of source code from the script. The boundaries for the slice is | 318 * Get a slice of source code from the script. The boundaries for the slice is |
| 350 * specified in lines. | 319 * specified in lines. |
| 351 * @param {number} opt_from_line The first line (zero bound) in the slice. | 320 * @param {number} opt_from_line The first line (zero bound) in the slice. |
| 352 * Default is 0 | 321 * Default is 0 |
| 353 * @param {number} opt_to_column The last line (zero bound) in the slice (non | 322 * @param {number} opt_to_column The last line (zero bound) in the slice (non |
| 354 * inclusive). Default is the number of lines in the script | 323 * inclusive). Default is the number of lines in the script |
| 355 * @return {SourceSlice} The source slice or null of the parameters where | 324 * @return {SourceSlice} The source slice or null of the parameters where |
| 356 * invalid | 325 * invalid |
| 357 */ | 326 */ |
| 358 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) { | 327 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) { |
| 359 // Make soure source info has been initialized. | |
| 360 this.initSourceInfo_(); | |
| 361 | |
| 362 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line
; | 328 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line
; |
| 363 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
: opt_to_line | 329 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
: opt_to_line |
| 364 | 330 |
| 365 // Adjust according to the offset within the resource. | 331 // Adjust according to the offset within the resource. |
| 366 from_line -= this.line_offset; | 332 from_line -= this.line_offset; |
| 367 to_line -= this.line_offset; | 333 to_line -= this.line_offset; |
| 368 if (from_line < 0) from_line = 0; | 334 if (from_line < 0) from_line = 0; |
| 369 if (to_line > this.lineCount()) to_line = this.lineCount(); | 335 if (to_line > this.lineCount()) to_line = this.lineCount(); |
| 370 | 336 |
| 371 // Check parameters. | 337 // Check parameters. |
| 372 if (from_line >= this.lineCount() || | 338 if (from_line >= this.lineCount() || |
| 373 to_line < 0 || | 339 to_line < 0 || |
| 374 from_line > to_line) { | 340 from_line > to_line) { |
| 375 return null; | 341 return null; |
| 376 } | 342 } |
| 377 | 343 |
| 378 var from_position = from_line == 0 ? 0 : this.lineEnds_[from_line - 1] + 1; | 344 var from_position = from_line == 0 ? 0 : this.line_ends[from_line - 1] + 1; |
| 379 var to_position = to_line == 0 ? 0 : this.lineEnds_[to_line - 1] + 1; | 345 var to_position = to_line == 0 ? 0 : this.line_ends[to_line - 1] + 1; |
| 380 | 346 |
| 381 // Return a source slice with line numbers re-adjusted to the resource. | 347 // Return a source slice with line numbers re-adjusted to the resource. |
| 382 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line
_offset, | 348 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line
_offset, |
| 383 from_position, to_position); | 349 from_position, to_position); |
| 384 } | 350 } |
| 385 | 351 |
| 386 | 352 |
| 387 Script.prototype.sourceLine = function (opt_line) { | 353 Script.prototype.sourceLine = function (opt_line) { |
| 388 // Default is the first line in the script. Lines in the script are relative | 354 // Default is the first line in the script. Lines in the script are relative |
| 389 // to the offset within the resource. | 355 // to the offset within the resource. |
| 390 var line = 0; | 356 var line = 0; |
| 391 if (!IS_UNDEFINED(opt_line)) { | 357 if (!IS_UNDEFINED(opt_line)) { |
| 392 line = opt_line - this.line_offset; | 358 line = opt_line - this.line_offset; |
| 393 } | 359 } |
| 394 | 360 |
| 395 // Check parameter. | 361 // Check parameter. |
| 396 if (line < 0 || this.lineCount() <= line) { | 362 if (line < 0 || this.lineCount() <= line) { |
| 397 return null; | 363 return null; |
| 398 } | 364 } |
| 399 | 365 |
| 400 // Return the source line. | 366 // Return the source line. |
| 401 var start = line == 0 ? 0 : this.lineEnds_[line - 1] + 1; | 367 var start = line == 0 ? 0 : this.line_ends[line - 1] + 1; |
| 402 var end = this.lineEnds_[line]; | 368 var end = this.line_ends[line]; |
| 403 return this.source.substring(start, end); | 369 return this.source.substring(start, end); |
| 404 } | 370 } |
| 405 | 371 |
| 406 | 372 |
| 407 /** | 373 /** |
| 408 * Returns the number of source lines. | 374 * Returns the number of source lines. |
| 409 * @return {number} | 375 * @return {number} |
| 410 * Number of source lines. | 376 * Number of source lines. |
| 411 */ | 377 */ |
| 412 Script.prototype.lineCount = function() { | 378 Script.prototype.lineCount = function() { |
| 413 // Make soure source info has been initialized. | 379 // Return number of source lines. |
| 414 this.initSourceInfo_(); | 380 return this.line_ends.length; |
| 415 | |
| 416 // Return number of source lines. | |
| 417 return this.lineEnds_.length; | |
| 418 }; | 381 }; |
| 419 | 382 |
| 420 | 383 |
| 421 /** | 384 /** |
| 422 * Class for source location. A source location is a position within some | 385 * Class for source location. A source location is a position within some |
| 423 * source with the following properties: | 386 * source with the following properties: |
| 424 * script : script object for the source | 387 * script : script object for the source |
| 425 * line : source line number | 388 * line : source line number |
| 426 * column : source column within the line | 389 * column : source column within the line |
| 427 * position : position within the source | 390 * position : position within the source |
| 428 * start : position of start of source context (inclusive) | 391 * start : position of start of source context (inclusive) |
| 429 * end : position of end of source context (not inclusive) | 392 * end : position of end of source context (not inclusive) |
| 430 * Source text for the source context is the character interval [start, end[. In | 393 * Source text for the source context is the character interval [start, end[. In |
| 431 * most cases end will point to a newline character. It might point just past | 394 * most cases end will point to a newline character. It might point just past |
| 432 * the final position of the source if the last source line does not end with a | 395 * the final position of the source if the last source line does not end with a |
| 433 * newline character. | 396 * newline character. |
| 434 * @param {Script} script The Script object for which this is a location | 397 * @param {Script} script The Script object for which this is a location |
| 435 * @param {number} position Source position for the location | 398 * @param {number} position Source position for the location |
| 436 * @param {number} line The line number for the location | 399 * @param {number} line The line number for the location |
| 437 * @param {number} column The column within the line for the location | 400 * @param {number} column The column within the line for the location |
| 438 * @param {number} start Source position for start of source context | 401 * @param {number} start Source position for start of source context |
| 439 * @param {number} end Source position for end of source context | 402 * @param {number} end Source position for end of source context |
| 440 * @constructor | 403 * @constructor |
| 441 */ | 404 */ |
| 442 function SourceLocation(script, position, line, column, start, end) { | 405 function SourceLocation(script, position, line, column, start, end) { |
| 443 this.script = script; | 406 this.script = script; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); | 633 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); |
| 671 } | 634 } |
| 672 var message = this.message; | 635 var message = this.message; |
| 673 return this.name + (message ? (": " + message) : ""); | 636 return this.name + (message ? (": " + message) : ""); |
| 674 }, DONT_ENUM); | 637 }, DONT_ENUM); |
| 675 | 638 |
| 676 | 639 |
| 677 // Boilerplate for exceptions for stack overflows. Used from | 640 // Boilerplate for exceptions for stack overflows. Used from |
| 678 // Top::StackOverflow(). | 641 // Top::StackOverflow(). |
| 679 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); | 642 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); |
| OLD | NEW |