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