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