| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 e.type = type; | 125 e.type = type; |
| 126 e.arguments = args; | 126 e.arguments = args; |
| 127 return e; | 127 return e; |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 /** | 131 /** |
| 132 * Setup the Script function and constructor. | 132 * Setup the Script function and constructor. |
| 133 */ | 133 */ |
| 134 %FunctionSetInstanceClassName(Script, 'Script'); | 134 %FunctionSetInstanceClassName(Script, 'Script'); |
| 135 %SetProperty(Script.prototype, 'constructor', Script, DONT_ENUM); | 135 %SetProperty(Script.prototype, 'constructor', Script, |
| 136 DONT_ENUM | DONT_DELETE | READ_ONLY); |
| 136 %SetCode(Script, function(x) { | 137 %SetCode(Script, function(x) { |
| 137 // Script objects can only be created by the VM. | 138 // Script objects can only be created by the VM. |
| 138 throw new $Error("Not supported"); | 139 throw new $Error("Not supported"); |
| 139 }); | 140 }); |
| 140 | 141 |
| 141 | 142 |
| 142 // Helper functions; called from the runtime system. | 143 // Helper functions; called from the runtime system. |
| 143 function FormatMessage(message) { | 144 function FormatMessage(message) { |
| 144 if (kMessages === 0) { | 145 if (kMessages === 0) { |
| 145 kMessages = { | 146 kMessages = { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 strict_reserved_word: ["Use of future reserved word in strict mode
"], | 245 strict_reserved_word: ["Use of future reserved word in strict mode
"], |
| 245 strict_delete: ["Delete of an unqualified identifier in str
ict mode."], | 246 strict_delete: ["Delete of an unqualified identifier in str
ict mode."], |
| 246 strict_delete_property: ["Cannot delete property '", "%0", "' of ",
"%1"], | 247 strict_delete_property: ["Cannot delete property '", "%0", "' of ",
"%1"], |
| 247 strict_const: ["Use of const in strict mode."], | 248 strict_const: ["Use of const in strict mode."], |
| 248 strict_function: ["In strict mode code, functions can only be
declared at top level or immediately within another function." ], | 249 strict_function: ["In strict mode code, functions can only be
declared at top level or immediately within another function." ], |
| 249 strict_read_only_property: ["Cannot assign to read only property '", "%
0", "' of ", "%1"], | 250 strict_read_only_property: ["Cannot assign to read only property '", "%
0", "' of ", "%1"], |
| 250 strict_cannot_assign: ["Cannot assign to read only '", "%0", "' in
strict mode"], | 251 strict_cannot_assign: ["Cannot assign to read only '", "%0", "' in
strict mode"], |
| 251 strict_poison_pill: ["'caller', 'callee', and 'arguments' proper
ties may not be accessed on strict mode functions or the arguments objects for c
alls to them"], | 252 strict_poison_pill: ["'caller', 'callee', and 'arguments' proper
ties may not be accessed on strict mode functions or the arguments objects for c
alls to them"], |
| 252 strict_caller: ["Illegal access to a strict mode caller fun
ction."], | 253 strict_caller: ["Illegal access to a strict mode caller fun
ction."], |
| 253 unprotected_let: ["Illegal let declaration in unprotected sta
tement context."], | 254 unprotected_let: ["Illegal let declaration in unprotected sta
tement context."], |
| 255 __proto__: null |
| 254 }; | 256 }; |
| 255 } | 257 } |
| 256 var message_type = %MessageGetType(message); | 258 var message_type = %MessageGetType(message); |
| 257 var format = kMessages[message_type]; | 259 var format = kMessages[message_type]; |
| 258 if (!format) return "<unknown message " + message_type + ">"; | 260 if (!format) return "<unknown message " + message_type + ">"; |
| 259 return FormatString(format, message); | 261 return FormatString(format, message); |
| 260 } | 262 } |
| 261 | 263 |
| 262 | 264 |
| 263 function GetLineNumber(message) { | 265 function GetLineNumber(message) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 function MakeError(type, args) { | 312 function MakeError(type, args) { |
| 311 return MakeGenericError($Error, type, args); | 313 return MakeGenericError($Error, type, args); |
| 312 } | 314 } |
| 313 | 315 |
| 314 /** | 316 /** |
| 315 * Find a line number given a specific source position. | 317 * Find a line number given a specific source position. |
| 316 * @param {number} position The source position. | 318 * @param {number} position The source position. |
| 317 * @return {number} 0 if input too small, -1 if input too large, | 319 * @return {number} 0 if input too small, -1 if input too large, |
| 318 else the line number. | 320 else the line number. |
| 319 */ | 321 */ |
| 320 Script.prototype.lineFromPosition = function(position) { | 322 function ScriptLineFromPosition(position) { |
| 321 var lower = 0; | 323 var lower = 0; |
| 322 var upper = this.lineCount() - 1; | 324 var upper = this.lineCount() - 1; |
| 323 var line_ends = this.line_ends; | 325 var line_ends = this.line_ends; |
| 324 | 326 |
| 325 // We'll never find invalid positions so bail right away. | 327 // We'll never find invalid positions so bail right away. |
| 326 if (position > line_ends[upper]) { | 328 if (position > line_ends[upper]) { |
| 327 return -1; | 329 return -1; |
| 328 } | 330 } |
| 329 | 331 |
| 330 // This means we don't have to safe-guard indexing line_ends[i - 1]. | 332 // This means we don't have to safe-guard indexing line_ends[i - 1]. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 349 } | 351 } |
| 350 | 352 |
| 351 /** | 353 /** |
| 352 * Get information on a specific source position. | 354 * Get information on a specific source position. |
| 353 * @param {number} position The source position | 355 * @param {number} position The source position |
| 354 * @param {boolean} include_resource_offset Set to true to have the resource | 356 * @param {boolean} include_resource_offset Set to true to have the resource |
| 355 * offset added to the location | 357 * offset added to the location |
| 356 * @return {SourceLocation} | 358 * @return {SourceLocation} |
| 357 * If line is negative or not in the source null is returned. | 359 * If line is negative or not in the source null is returned. |
| 358 */ | 360 */ |
| 359 Script.prototype.locationFromPosition = function (position, | 361 function ScriptLocationFromPosition(position, |
| 360 include_resource_offset) { | 362 include_resource_offset) { |
| 361 var line = this.lineFromPosition(position); | 363 var line = this.lineFromPosition(position); |
| 362 if (line == -1) return null; | 364 if (line == -1) return null; |
| 363 | 365 |
| 364 // Determine start, end and column. | 366 // Determine start, end and column. |
| 365 var line_ends = this.line_ends; | 367 var line_ends = this.line_ends; |
| 366 var start = line == 0 ? 0 : line_ends[line - 1] + 1; | 368 var start = line == 0 ? 0 : line_ends[line - 1] + 1; |
| 367 var end = line_ends[line]; | 369 var end = line_ends[line]; |
| 368 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') end
--; | 370 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') { |
| 371 end--; |
| 372 } |
| 369 var column = position - start; | 373 var column = position - start; |
| 370 | 374 |
| 371 // Adjust according to the offset within the resource. | 375 // Adjust according to the offset within the resource. |
| 372 if (include_resource_offset) { | 376 if (include_resource_offset) { |
| 373 line += this.line_offset; | 377 line += this.line_offset; |
| 374 if (line == this.line_offset) { | 378 if (line == this.line_offset) { |
| 375 column += this.column_offset; | 379 column += this.column_offset; |
| 376 } | 380 } |
| 377 } | 381 } |
| 378 | 382 |
| 379 return new SourceLocation(this, position, line, column, start, end); | 383 return new SourceLocation(this, position, line, column, start, end); |
| 380 }; | 384 }; |
| 381 | 385 |
| 382 | 386 |
| 383 /** | 387 /** |
| 384 * Get information on a specific source line and column possibly offset by a | 388 * Get information on a specific source line and column possibly offset by a |
| 385 * fixed source position. This function is used to find a source position from | 389 * fixed source position. This function is used to find a source position from |
| 386 * a line and column position. The fixed source position offset is typically | 390 * a line and column position. The fixed source position offset is typically |
| 387 * used to find a source position in a function based on a line and column in | 391 * used to find a source position in a function based on a line and column in |
| 388 * the source for the function alone. The offset passed will then be the | 392 * the source for the function alone. The offset passed will then be the |
| 389 * start position of the source for the function within the full script source. | 393 * start position of the source for the function within the full script source. |
| 390 * @param {number} opt_line The line within the source. Default value is 0 | 394 * @param {number} opt_line The line within the source. Default value is 0 |
| 391 * @param {number} opt_column The column in within the line. Default value is 0 | 395 * @param {number} opt_column The column in within the line. Default value is 0 |
| 392 * @param {number} opt_offset_position The offset from the begining of the | 396 * @param {number} opt_offset_position The offset from the begining of the |
| 393 * source from where the line and column calculation starts. Default value i
s 0 | 397 * source from where the line and column calculation starts. |
| 398 * Default value is 0 |
| 394 * @return {SourceLocation} | 399 * @return {SourceLocation} |
| 395 * If line is negative or not in the source null is returned. | 400 * If line is negative or not in the source null is returned. |
| 396 */ | 401 */ |
| 397 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p
osition) { | 402 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) { |
| 398 // Default is the first line in the script. Lines in the script is relative | 403 // Default is the first line in the script. Lines in the script is relative |
| 399 // to the offset within the resource. | 404 // to the offset within the resource. |
| 400 var line = 0; | 405 var line = 0; |
| 401 if (!IS_UNDEFINED(opt_line)) { | 406 if (!IS_UNDEFINED(opt_line)) { |
| 402 line = opt_line - this.line_offset; | 407 line = opt_line - this.line_offset; |
| 403 } | 408 } |
| 404 | 409 |
| 405 // Default is first column. If on the first line add the offset within the | 410 // Default is first column. If on the first line add the offset within the |
| 406 // resource. | 411 // resource. |
| 407 var column = opt_column || 0; | 412 var column = opt_column || 0; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 429 /** | 434 /** |
| 430 * Get a slice of source code from the script. The boundaries for the slice is | 435 * Get a slice of source code from the script. The boundaries for the slice is |
| 431 * specified in lines. | 436 * specified in lines. |
| 432 * @param {number} opt_from_line The first line (zero bound) in the slice. | 437 * @param {number} opt_from_line The first line (zero bound) in the slice. |
| 433 * Default is 0 | 438 * Default is 0 |
| 434 * @param {number} opt_to_column The last line (zero bound) in the slice (non | 439 * @param {number} opt_to_column The last line (zero bound) in the slice (non |
| 435 * inclusive). Default is the number of lines in the script | 440 * inclusive). Default is the number of lines in the script |
| 436 * @return {SourceSlice} The source slice or null of the parameters where | 441 * @return {SourceSlice} The source slice or null of the parameters where |
| 437 * invalid | 442 * invalid |
| 438 */ | 443 */ |
| 439 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) { | 444 function ScriptSourceSlice(opt_from_line, opt_to_line) { |
| 440 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line
; | 445 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line
; |
| 441 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
: opt_to_line | 446 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
: opt_to_line |
| 442 | 447 |
| 443 // Adjust according to the offset within the resource. | 448 // Adjust according to the offset within the resource. |
| 444 from_line -= this.line_offset; | 449 from_line -= this.line_offset; |
| 445 to_line -= this.line_offset; | 450 to_line -= this.line_offset; |
| 446 if (from_line < 0) from_line = 0; | 451 if (from_line < 0) from_line = 0; |
| 447 if (to_line > this.lineCount()) to_line = this.lineCount(); | 452 if (to_line > this.lineCount()) to_line = this.lineCount(); |
| 448 | 453 |
| 449 // Check parameters. | 454 // Check parameters. |
| 450 if (from_line >= this.lineCount() || | 455 if (from_line >= this.lineCount() || |
| 451 to_line < 0 || | 456 to_line < 0 || |
| 452 from_line > to_line) { | 457 from_line > to_line) { |
| 453 return null; | 458 return null; |
| 454 } | 459 } |
| 455 | 460 |
| 456 var line_ends = this.line_ends; | 461 var line_ends = this.line_ends; |
| 457 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1; | 462 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1; |
| 458 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1; | 463 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1; |
| 459 | 464 |
| 460 // Return a source slice with line numbers re-adjusted to the resource. | 465 // Return a source slice with line numbers re-adjusted to the resource. |
| 461 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line
_offset, | 466 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line
_offset, |
| 462 from_position, to_position); | 467 from_position, to_position); |
| 463 } | 468 } |
| 464 | 469 |
| 465 | 470 |
| 466 Script.prototype.sourceLine = function (opt_line) { | 471 function ScriptSourceLine(opt_line) { |
| 467 // Default is the first line in the script. Lines in the script are relative | 472 // Default is the first line in the script. Lines in the script are relative |
| 468 // to the offset within the resource. | 473 // to the offset within the resource. |
| 469 var line = 0; | 474 var line = 0; |
| 470 if (!IS_UNDEFINED(opt_line)) { | 475 if (!IS_UNDEFINED(opt_line)) { |
| 471 line = opt_line - this.line_offset; | 476 line = opt_line - this.line_offset; |
| 472 } | 477 } |
| 473 | 478 |
| 474 // Check parameter. | 479 // Check parameter. |
| 475 if (line < 0 || this.lineCount() <= line) { | 480 if (line < 0 || this.lineCount() <= line) { |
| 476 return null; | 481 return null; |
| 477 } | 482 } |
| 478 | 483 |
| 479 // Return the source line. | 484 // Return the source line. |
| 480 var line_ends = this.line_ends; | 485 var line_ends = this.line_ends; |
| 481 var start = line == 0 ? 0 : line_ends[line - 1] + 1; | 486 var start = line == 0 ? 0 : line_ends[line - 1] + 1; |
| 482 var end = line_ends[line]; | 487 var end = line_ends[line]; |
| 483 return %_CallFunction(this.source, start, end, StringSubstring); | 488 return %_CallFunction(this.source, start, end, StringSubstring); |
| 484 } | 489 } |
| 485 | 490 |
| 486 | 491 |
| 487 /** | 492 /** |
| 488 * Returns the number of source lines. | 493 * Returns the number of source lines. |
| 489 * @return {number} | 494 * @return {number} |
| 490 * Number of source lines. | 495 * Number of source lines. |
| 491 */ | 496 */ |
| 492 Script.prototype.lineCount = function() { | 497 function ScriptLineCount() { |
| 493 // Return number of source lines. | 498 // Return number of source lines. |
| 494 return this.line_ends.length; | 499 return this.line_ends.length; |
| 495 }; | 500 }; |
| 496 | 501 |
| 497 | 502 |
| 498 /** | 503 /** |
| 499 * Returns the name of script if available, contents of sourceURL comment | 504 * Returns the name of script if available, contents of sourceURL comment |
| 500 * otherwise. See | 505 * otherwise. See |
| 501 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt | 506 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt |
| 502 * for details on using //@ sourceURL comment to identify scritps that don't | 507 * for details on using //@ sourceURL comment to identify scritps that don't |
| 503 * have name. | 508 * have name. |
| 504 * | 509 * |
| 505 * @return {?string} script name if present, value for //@ sourceURL comment | 510 * @return {?string} script name if present, value for //@ sourceURL comment |
| 506 * otherwise. | 511 * otherwise. |
| 507 */ | 512 */ |
| 508 Script.prototype.nameOrSourceURL = function() { | 513 function ScriptNameOrSourceURL() { |
| 509 if (this.name) | 514 if (this.name) { |
| 510 return this.name; | 515 return this.name; |
| 516 } |
| 511 // TODO(608): the spaces in a regexp below had to be escaped as \040 | 517 // TODO(608): the spaces in a regexp below had to be escaped as \040 |
| 512 // because this file is being processed by js2c whose handling of spaces | 518 // because this file is being processed by js2c whose handling of spaces |
| 513 // in regexps is broken. Also, ['"] are excluded from allowed URLs to | 519 // in regexps is broken. Also, ['"] are excluded from allowed URLs to |
| 514 // avoid matches against sources that invoke evals with sourceURL. | 520 // avoid matches against sources that invoke evals with sourceURL. |
| 515 // A better solution would be to detect these special comments in | 521 // A better solution would be to detect these special comments in |
| 516 // the scanner/parser. | 522 // the scanner/parser. |
| 517 var source = ToString(this.source); | 523 var source = ToString(this.source); |
| 518 var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0); | 524 var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0); |
| 519 if (sourceUrlPos > 4) { | 525 if (sourceUrlPos > 4) { |
| 520 var sourceUrlPattern = | 526 var sourceUrlPattern = |
| 521 /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm; | 527 /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm; |
| 522 // Don't reuse lastMatchInfo here, so we create a new array with room | 528 // Don't reuse lastMatchInfo here, so we create a new array with room |
| 523 // for four captures (array with length one longer than the index | 529 // for four captures (array with length one longer than the index |
| 524 // of the fourth capture, where the numbering is zero-based). | 530 // of the fourth capture, where the numbering is zero-based). |
| 525 var matchInfo = new InternalArray(CAPTURE(3) + 1); | 531 var matchInfo = new InternalArray(CAPTURE(3) + 1); |
| 526 var match = | 532 var match = |
| 527 %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo); | 533 %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo); |
| 528 if (match) { | 534 if (match) { |
| 529 return SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]); | 535 return SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]); |
| 530 } | 536 } |
| 531 } | 537 } |
| 532 return this.name; | 538 return this.name; |
| 533 } | 539 } |
| 534 | 540 |
| 535 | 541 |
| 542 SetupLockedPrototype(Script, |
| 543 $Array("source", "name", "line_ends", "line_offset", "column_offset"), |
| 544 $Array( |
| 545 "lineFromPosition", ScriptLineFromPosition, |
| 546 "locationFromPosition", ScriptLocationFromPosition, |
| 547 "locationFromLine", ScriptLocationFromLine, |
| 548 "sourceSlice", ScriptSourceSlice, |
| 549 "sourceLine", ScriptSourceLine, |
| 550 "lineCount", ScriptLineCount, |
| 551 "nameOrSourceURL", ScriptNameOrSourceURL |
| 552 ) |
| 553 ); |
| 554 |
| 555 |
| 536 /** | 556 /** |
| 537 * Class for source location. A source location is a position within some | 557 * Class for source location. A source location is a position within some |
| 538 * source with the following properties: | 558 * source with the following properties: |
| 539 * script : script object for the source | 559 * script : script object for the source |
| 540 * line : source line number | 560 * line : source line number |
| 541 * column : source column within the line | 561 * column : source column within the line |
| 542 * position : position within the source | 562 * position : position within the source |
| 543 * start : position of start of source context (inclusive) | 563 * start : position of start of source context (inclusive) |
| 544 * end : position of end of source context (not inclusive) | 564 * end : position of end of source context (not inclusive) |
| 545 * Source text for the source context is the character interval [start, end[. In | 565 * Source text for the source context is the character interval [start, end[. In |
| (...skipping 10 matching lines...) Expand all Loading... |
| 556 */ | 576 */ |
| 557 function SourceLocation(script, position, line, column, start, end) { | 577 function SourceLocation(script, position, line, column, start, end) { |
| 558 this.script = script; | 578 this.script = script; |
| 559 this.position = position; | 579 this.position = position; |
| 560 this.line = line; | 580 this.line = line; |
| 561 this.column = column; | 581 this.column = column; |
| 562 this.start = start; | 582 this.start = start; |
| 563 this.end = end; | 583 this.end = end; |
| 564 } | 584 } |
| 565 | 585 |
| 566 SourceLocation.prototype.__proto__ = null; | |
| 567 | |
| 568 const kLineLengthLimit = 78; | 586 const kLineLengthLimit = 78; |
| 569 | 587 |
| 570 /** | 588 /** |
| 571 * Restrict source location start and end positions to make the source slice | 589 * Restrict source location start and end positions to make the source slice |
| 572 * no more that a certain number of characters wide. | 590 * no more that a certain number of characters wide. |
| 573 * @param {number} opt_limit The with limit of the source text with a default | 591 * @param {number} opt_limit The with limit of the source text with a default |
| 574 * of 78 | 592 * of 78 |
| 575 * @param {number} opt_before The number of characters to prefer before the | 593 * @param {number} opt_before The number of characters to prefer before the |
| 576 * position with a default value of 10 less that the limit | 594 * position with a default value of 10 less that the limit |
| 577 */ | 595 */ |
| 578 SourceLocation.prototype.restrict = function (opt_limit, opt_before) { | 596 function SourceLocationRestrict(opt_limit, opt_before) { |
| 579 // Find the actual limit to use. | 597 // Find the actual limit to use. |
| 580 var limit; | 598 var limit; |
| 581 var before; | 599 var before; |
| 582 if (!IS_UNDEFINED(opt_limit)) { | 600 if (!IS_UNDEFINED(opt_limit)) { |
| 583 limit = opt_limit; | 601 limit = opt_limit; |
| 584 } else { | 602 } else { |
| 585 limit = kLineLengthLimit; | 603 limit = kLineLengthLimit; |
| 586 } | 604 } |
| 587 if (!IS_UNDEFINED(opt_before)) { | 605 if (!IS_UNDEFINED(opt_before)) { |
| 588 before = opt_before; | 606 before = opt_before; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 615 } | 633 } |
| 616 } | 634 } |
| 617 }; | 635 }; |
| 618 | 636 |
| 619 | 637 |
| 620 /** | 638 /** |
| 621 * Get the source text for a SourceLocation | 639 * Get the source text for a SourceLocation |
| 622 * @return {String} | 640 * @return {String} |
| 623 * Source text for this location. | 641 * Source text for this location. |
| 624 */ | 642 */ |
| 625 SourceLocation.prototype.sourceText = function () { | 643 function SourceLocationSourceText() { |
| 626 return %_CallFunction(this.script.source, this.start, this.end, StringSubstrin
g); | 644 return %_CallFunction(this.script.source, this.start, this.end, StringSubstrin
g); |
| 627 }; | 645 }; |
| 628 | 646 |
| 629 | 647 |
| 648 SetupLockedPrototype(SourceLocation, |
| 649 $Array("script", "position", "line", "column", "start", "end"), |
| 650 $Array( |
| 651 "restrict", SourceLocationRestrict, |
| 652 "sourceText", SourceLocationSourceText |
| 653 ) |
| 654 ); |
| 655 |
| 656 |
| 630 /** | 657 /** |
| 631 * Class for a source slice. A source slice is a part of a script source with | 658 * Class for a source slice. A source slice is a part of a script source with |
| 632 * the following properties: | 659 * the following properties: |
| 633 * script : script object for the source | 660 * script : script object for the source |
| 634 * from_line : line number for the first line in the slice | 661 * from_line : line number for the first line in the slice |
| 635 * to_line : source line number for the last line in the slice | 662 * to_line : source line number for the last line in the slice |
| 636 * from_position : position of the first character in the slice | 663 * from_position : position of the first character in the slice |
| 637 * to_position : position of the last character in the slice | 664 * to_position : position of the last character in the slice |
| 638 * The to_line and to_position are not included in the slice, that is the lines | 665 * The to_line and to_position are not included in the slice, that is the lines |
| 639 * in the slice are [from_line, to_line[. Likewise the characters in the slice | 666 * in the slice are [from_line, to_line[. Likewise the characters in the slice |
| 640 * are [from_position, to_position[. | 667 * are [from_position, to_position[. |
| 641 * @param {Script} script The Script object for the source slice | 668 * @param {Script} script The Script object for the source slice |
| 642 * @param {number} from_line | 669 * @param {number} from_line |
| 643 * @param {number} to_line | 670 * @param {number} to_line |
| 644 * @param {number} from_position | 671 * @param {number} from_position |
| 645 * @param {number} to_position | 672 * @param {number} to_position |
| 646 * @constructor | 673 * @constructor |
| 647 */ | 674 */ |
| 648 function SourceSlice(script, from_line, to_line, from_position, to_position) { | 675 function SourceSlice(script, from_line, to_line, from_position, to_position) { |
| 649 this.script = script; | 676 this.script = script; |
| 650 this.from_line = from_line; | 677 this.from_line = from_line; |
| 651 this.to_line = to_line; | 678 this.to_line = to_line; |
| 652 this.from_position = from_position; | 679 this.from_position = from_position; |
| 653 this.to_position = to_position; | 680 this.to_position = to_position; |
| 654 } | 681 } |
| 655 | 682 |
| 656 SourceSlice.prototype.__proto__ = null; | |
| 657 | |
| 658 /** | 683 /** |
| 659 * Get the source text for a SourceSlice | 684 * Get the source text for a SourceSlice |
| 660 * @return {String} Source text for this slice. The last line will include | 685 * @return {String} Source text for this slice. The last line will include |
| 661 * the line terminating characters (if any) | 686 * the line terminating characters (if any) |
| 662 */ | 687 */ |
| 663 SourceSlice.prototype.sourceText = function () { | 688 function SourceSliceSourceText() { |
| 664 return %_CallFunction(this.script.source, | 689 return %_CallFunction(this.script.source, |
| 665 this.from_position, | 690 this.from_position, |
| 666 this.to_position, | 691 this.to_position, |
| 667 StringSubstring); | 692 StringSubstring); |
| 668 }; | 693 }; |
| 669 | 694 |
| 695 SetupLockedPrototype(SourceSlice, |
| 696 $Array("script", "from_line", "to_line", "from_position", "to_position"), |
| 697 $Array("sourceText", SourceSliceSourceText) |
| 698 ); |
| 699 |
| 670 | 700 |
| 671 // Returns the offset of the given position within the containing | 701 // Returns the offset of the given position within the containing |
| 672 // line. | 702 // line. |
| 673 function GetPositionInLine(message) { | 703 function GetPositionInLine(message) { |
| 674 var script = %MessageGetScript(message); | 704 var script = %MessageGetScript(message); |
| 675 var start_position = %MessageGetStartPosition(message); | 705 var start_position = %MessageGetStartPosition(message); |
| 676 var location = script.locationFromPosition(start_position, false); | 706 var location = script.locationFromPosition(start_position, false); |
| 677 if (location == null) return -1; | 707 if (location == null) return -1; |
| 678 location.restrict(); | 708 location.restrict(); |
| 679 return start_position - location.start; | 709 return start_position - location.start; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 desc = ToPropertyDescriptor(desc); | 744 desc = ToPropertyDescriptor(desc); |
| 715 DefineOwnProperty(obj, name, desc, true); | 745 DefineOwnProperty(obj, name, desc, true); |
| 716 } | 746 } |
| 717 | 747 |
| 718 function CallSite(receiver, fun, pos) { | 748 function CallSite(receiver, fun, pos) { |
| 719 this.receiver = receiver; | 749 this.receiver = receiver; |
| 720 this.fun = fun; | 750 this.fun = fun; |
| 721 this.pos = pos; | 751 this.pos = pos; |
| 722 } | 752 } |
| 723 | 753 |
| 724 CallSite.prototype.__proto__ = null; | 754 function CallSiteGetThis() { |
| 725 | |
| 726 CallSite.prototype.getThis = function () { | |
| 727 return this.receiver; | 755 return this.receiver; |
| 728 }; | 756 }; |
| 729 | 757 |
| 730 CallSite.prototype.getTypeName = function () { | 758 function CallSiteGetTypeName() { |
| 731 var constructor = this.receiver.constructor; | 759 var constructor = this.receiver.constructor; |
| 732 if (!constructor) { | 760 if (!constructor) { |
| 733 return %_CallFunction(this.receiver, ObjectToString); | 761 return %_CallFunction(this.receiver, ObjectToString); |
| 734 } | 762 } |
| 735 var constructorName = constructor.name; | 763 var constructorName = constructor.name; |
| 736 if (!constructorName) { | 764 if (!constructorName) { |
| 737 return %_CallFunction(this.receiver, ObjectToString); | 765 return %_CallFunction(this.receiver, ObjectToString); |
| 738 } | 766 } |
| 739 return constructorName; | 767 return constructorName; |
| 740 }; | 768 }; |
| 741 | 769 |
| 742 CallSite.prototype.isToplevel = function () { | 770 function CallSiteIsToplevel() { |
| 743 if (this.receiver == null) { | 771 if (this.receiver == null) { |
| 744 return true; | 772 return true; |
| 745 } | 773 } |
| 746 return IS_GLOBAL(this.receiver); | 774 return IS_GLOBAL(this.receiver); |
| 747 }; | 775 }; |
| 748 | 776 |
| 749 CallSite.prototype.isEval = function () { | 777 function CallSiteIsEval() { |
| 750 var script = %FunctionGetScript(this.fun); | 778 var script = %FunctionGetScript(this.fun); |
| 751 return script && script.compilation_type == COMPILATION_TYPE_EVAL; | 779 return script && script.compilation_type == COMPILATION_TYPE_EVAL; |
| 752 }; | 780 }; |
| 753 | 781 |
| 754 CallSite.prototype.getEvalOrigin = function () { | 782 function CallSiteGetEvalOrigin() { |
| 755 var script = %FunctionGetScript(this.fun); | 783 var script = %FunctionGetScript(this.fun); |
| 756 return FormatEvalOrigin(script); | 784 return FormatEvalOrigin(script); |
| 757 }; | 785 }; |
| 758 | 786 |
| 759 CallSite.prototype.getScriptNameOrSourceURL = function () { | 787 function CallSiteGetScriptNameOrSourceURL() { |
| 760 var script = %FunctionGetScript(this.fun); | 788 var script = %FunctionGetScript(this.fun); |
| 761 return script ? script.nameOrSourceURL() : null; | 789 return script ? script.nameOrSourceURL() : null; |
| 762 }; | 790 }; |
| 763 | 791 |
| 764 CallSite.prototype.getFunction = function () { | 792 function CallSiteGetFunction() { |
| 765 return this.fun; | 793 return this.fun; |
| 766 }; | 794 }; |
| 767 | 795 |
| 768 CallSite.prototype.getFunctionName = function () { | 796 function CallSiteGetFunctionName() { |
| 769 // See if the function knows its own name | 797 // See if the function knows its own name |
| 770 var name = this.fun.name; | 798 var name = this.fun.name; |
| 771 if (name) { | 799 if (name) { |
| 772 return name; | 800 return name; |
| 773 } else { | 801 } else { |
| 774 return %FunctionGetInferredName(this.fun); | 802 return %FunctionGetInferredName(this.fun); |
| 775 } | 803 } |
| 776 // Maybe this is an evaluation? | 804 // Maybe this is an evaluation? |
| 777 var script = %FunctionGetScript(this.fun); | 805 var script = %FunctionGetScript(this.fun); |
| 778 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { | 806 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { |
| 779 return "eval"; | 807 return "eval"; |
| 780 } | 808 } |
| 781 return null; | 809 return null; |
| 782 }; | 810 }; |
| 783 | 811 |
| 784 CallSite.prototype.getMethodName = function () { | 812 function CallSiteGetMethodName() { |
| 785 // See if we can find a unique property on the receiver that holds | 813 // See if we can find a unique property on the receiver that holds |
| 786 // this function. | 814 // this function. |
| 787 var ownName = this.fun.name; | 815 var ownName = this.fun.name; |
| 788 if (ownName && this.receiver && | 816 if (ownName && this.receiver && |
| 789 (%_CallFunction(this.receiver, ownName, ObjectLookupGetter) === this.fun |
| | 817 (%_CallFunction(this.receiver, ownName, ObjectLookupGetter) === this.fun |
| |
| 790 %_CallFunction(this.receiver, ownName, ObjectLookupSetter) === this.fun |
| | 818 %_CallFunction(this.receiver, ownName, ObjectLookupSetter) === this.fun |
| |
| 791 this.receiver[ownName] === this.fun)) { | 819 this.receiver[ownName] === this.fun)) { |
| 792 // To handle DontEnum properties we guess that the method has | 820 // To handle DontEnum properties we guess that the method has |
| 793 // the same name as the function. | 821 // the same name as the function. |
| 794 return ownName; | 822 return ownName; |
| 795 } | 823 } |
| 796 var name = null; | 824 var name = null; |
| 797 for (var prop in this.receiver) { | 825 for (var prop in this.receiver) { |
| 798 if (this.receiver.__lookupGetter__(prop) === this.fun || | 826 if (this.receiver.__lookupGetter__(prop) === this.fun || |
| 799 this.receiver.__lookupSetter__(prop) === this.fun || | 827 this.receiver.__lookupSetter__(prop) === this.fun || |
| 800 (!this.receiver.__lookupGetter__(prop) && this.receiver[prop] === this.f
un)) { | 828 (!this.receiver.__lookupGetter__(prop) && this.receiver[prop] === this.f
un)) { |
| 801 // If we find more than one match bail out to avoid confusion. | 829 // If we find more than one match bail out to avoid confusion. |
| 802 if (name) { | 830 if (name) { |
| 803 return null; | 831 return null; |
| 804 } | 832 } |
| 805 name = prop; | 833 name = prop; |
| 806 } | 834 } |
| 807 } | 835 } |
| 808 if (name) { | 836 if (name) { |
| 809 return name; | 837 return name; |
| 810 } | 838 } |
| 811 return null; | 839 return null; |
| 812 }; | 840 }; |
| 813 | 841 |
| 814 CallSite.prototype.getFileName = function () { | 842 function CallSiteGetFileName() { |
| 815 var script = %FunctionGetScript(this.fun); | 843 var script = %FunctionGetScript(this.fun); |
| 816 return script ? script.name : null; | 844 return script ? script.name : null; |
| 817 }; | 845 }; |
| 818 | 846 |
| 819 CallSite.prototype.getLineNumber = function () { | 847 function CallSiteGetLineNumber() { |
| 820 if (this.pos == -1) { | 848 if (this.pos == -1) { |
| 821 return null; | 849 return null; |
| 822 } | 850 } |
| 823 var script = %FunctionGetScript(this.fun); | 851 var script = %FunctionGetScript(this.fun); |
| 824 var location = null; | 852 var location = null; |
| 825 if (script) { | 853 if (script) { |
| 826 location = script.locationFromPosition(this.pos, true); | 854 location = script.locationFromPosition(this.pos, true); |
| 827 } | 855 } |
| 828 return location ? location.line + 1 : null; | 856 return location ? location.line + 1 : null; |
| 829 }; | 857 }; |
| 830 | 858 |
| 831 CallSite.prototype.getColumnNumber = function () { | 859 function CallSiteGetColumnNumber() { |
| 832 if (this.pos == -1) { | 860 if (this.pos == -1) { |
| 833 return null; | 861 return null; |
| 834 } | 862 } |
| 835 var script = %FunctionGetScript(this.fun); | 863 var script = %FunctionGetScript(this.fun); |
| 836 var location = null; | 864 var location = null; |
| 837 if (script) { | 865 if (script) { |
| 838 location = script.locationFromPosition(this.pos, true); | 866 location = script.locationFromPosition(this.pos, true); |
| 839 } | 867 } |
| 840 return location ? location.column + 1: null; | 868 return location ? location.column + 1: null; |
| 841 }; | 869 }; |
| 842 | 870 |
| 843 CallSite.prototype.isNative = function () { | 871 function CallSiteIsNative() { |
| 844 var script = %FunctionGetScript(this.fun); | 872 var script = %FunctionGetScript(this.fun); |
| 845 return script ? (script.type == TYPE_NATIVE) : false; | 873 return script ? (script.type == TYPE_NATIVE) : false; |
| 846 }; | 874 }; |
| 847 | 875 |
| 848 CallSite.prototype.getPosition = function () { | 876 function CallSiteGetPosition() { |
| 849 return this.pos; | 877 return this.pos; |
| 850 }; | 878 }; |
| 851 | 879 |
| 852 CallSite.prototype.isConstructor = function () { | 880 function CallSiteIsConstructor() { |
| 853 var constructor = this.receiver ? this.receiver.constructor : null; | 881 var constructor = this.receiver ? this.receiver.constructor : null; |
| 854 if (!constructor) { | 882 if (!constructor) { |
| 855 return false; | 883 return false; |
| 856 } | 884 } |
| 857 return this.fun === constructor; | 885 return this.fun === constructor; |
| 858 }; | 886 }; |
| 859 | 887 |
| 888 SetupLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array( |
| 889 "getThis", CallSiteGetThis, |
| 890 "getTypeName", CallSiteGetTypeName, |
| 891 "isToplevel", CallSiteIsToplevel, |
| 892 "isEval", CallSiteIsEval, |
| 893 "getEvalOrigin", CallSiteGetEvalOrigin, |
| 894 "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL, |
| 895 "getFunction", CallSiteGetFunction, |
| 896 "getFunctionName", CallSiteGetFunctionName, |
| 897 "getMethodName", CallSiteGetMethodName, |
| 898 "getFileName", CallSiteGetFileName, |
| 899 "getLineNumber", CallSiteGetLineNumber, |
| 900 "getColumnNumber", CallSiteGetColumnNumber, |
| 901 "isNative", CallSiteIsNative, |
| 902 "getPosition", CallSiteGetPosition, |
| 903 "isConstructor", CallSiteIsConstructor |
| 904 )); |
| 905 |
| 906 |
| 860 function FormatEvalOrigin(script) { | 907 function FormatEvalOrigin(script) { |
| 861 var sourceURL = script.nameOrSourceURL(); | 908 var sourceURL = script.nameOrSourceURL(); |
| 862 if (sourceURL) { | 909 if (sourceURL) { |
| 863 return sourceURL; | 910 return sourceURL; |
| 864 } | 911 } |
| 865 | 912 |
| 866 var eval_origin = "eval at "; | 913 var eval_origin = "eval at "; |
| 867 if (script.eval_from_function_name) { | 914 if (script.eval_from_function_name) { |
| 868 eval_origin += script.eval_from_function_name; | 915 eval_origin += script.eval_from_function_name; |
| 869 } else { | 916 } else { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 frames.push(new CallSite(recv, fun, pos)); | 1039 frames.push(new CallSite(recv, fun, pos)); |
| 993 } | 1040 } |
| 994 if (IS_FUNCTION($Error.prepareStackTrace)) { | 1041 if (IS_FUNCTION($Error.prepareStackTrace)) { |
| 995 return $Error.prepareStackTrace(error, frames); | 1042 return $Error.prepareStackTrace(error, frames); |
| 996 } else { | 1043 } else { |
| 997 return FormatStackTrace(error, frames); | 1044 return FormatStackTrace(error, frames); |
| 998 } | 1045 } |
| 999 } | 1046 } |
| 1000 | 1047 |
| 1001 function DefineError(f) { | 1048 function DefineError(f) { |
| 1049 %AssertIsBootstrapping(); |
| 1002 // Store the error function in both the global object | 1050 // Store the error function in both the global object |
| 1003 // and the runtime object. The function is fetched | 1051 // and the runtime object. The function is fetched |
| 1004 // from the runtime object when throwing errors from | 1052 // from the runtime object when throwing errors from |
| 1005 // within the runtime system to avoid strange side | 1053 // within the runtime system to avoid strange side |
| 1006 // effects when overwriting the error functions from | 1054 // effects when overwriting the error functions from |
| 1007 // user code. | 1055 // user code. |
| 1008 var name = f.name; | 1056 var name = f.name; |
| 1009 %SetProperty(global, name, f, DONT_ENUM); | 1057 %SetProperty(global, name, f, DONT_ENUM); |
| 1010 this['$' + name] = f; | 1058 this['$' + name] = f; |
| 1011 // Configure the error function. | 1059 // Configure the error function. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 this.DefineError(function RangeError() { }); | 1127 this.DefineError(function RangeError() { }); |
| 1080 this.DefineError(function SyntaxError() { }); | 1128 this.DefineError(function SyntaxError() { }); |
| 1081 this.DefineError(function ReferenceError() { }); | 1129 this.DefineError(function ReferenceError() { }); |
| 1082 this.DefineError(function EvalError() { }); | 1130 this.DefineError(function EvalError() { }); |
| 1083 this.DefineError(function URIError() { }); | 1131 this.DefineError(function URIError() { }); |
| 1084 | 1132 |
| 1085 $Error.captureStackTrace = captureStackTrace; | 1133 $Error.captureStackTrace = captureStackTrace; |
| 1086 | 1134 |
| 1087 // Setup extra properties of the Error.prototype object. | 1135 // Setup extra properties of the Error.prototype object. |
| 1088 function setErrorMessage() { | 1136 function setErrorMessage() { |
| 1137 %AssertIsBootstrapping(); |
| 1089 var desc = {value: '', | 1138 var desc = {value: '', |
| 1090 enumerable: false, | 1139 enumerable: false, |
| 1091 configurable: true, | 1140 configurable: true, |
| 1092 writable: true }; | 1141 writable: true }; |
| 1093 DefineOwnProperty($Error.prototype, | 1142 DefineOwnProperty($Error.prototype, |
| 1094 'message', | 1143 'message', |
| 1095 ToPropertyDescriptor(desc), | 1144 ToPropertyDescriptor(desc), |
| 1096 true); | 1145 true); |
| 1097 | 1146 |
| 1098 } | 1147 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 throw e; | 1190 throw e; |
| 1142 } | 1191 } |
| 1143 } | 1192 } |
| 1144 | 1193 |
| 1145 | 1194 |
| 1146 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', errorToString]); | 1195 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', errorToString]); |
| 1147 | 1196 |
| 1148 // Boilerplate for exceptions for stack overflows. Used from | 1197 // Boilerplate for exceptions for stack overflows. Used from |
| 1149 // Isolate::StackOverflow(). | 1198 // Isolate::StackOverflow(). |
| 1150 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); | 1199 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); |
| OLD | NEW |