OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 | 554 |
555 // ---------------------------------------------------------------------------- | 555 // ---------------------------------------------------------------------------- |
556 // Error implementation | 556 // Error implementation |
557 | 557 |
558 // If this object gets passed to an error constructor the error will | 558 // If this object gets passed to an error constructor the error will |
559 // get an accessor for .message that constructs a descriptive error | 559 // get an accessor for .message that constructs a descriptive error |
560 // message on access. | 560 // message on access. |
561 var kAddMessageAccessorsMarker = { }; | 561 var kAddMessageAccessorsMarker = { }; |
562 | 562 |
563 // Defines accessors for a property that is calculated the first time | 563 // Defines accessors for a property that is calculated the first time |
564 // the property is read and then replaces the accessor with the value. | 564 // the property is read. |
565 // Also, setting the property causes the accessors to be deleted. | |
566 function DefineOneShotAccessor(obj, name, fun) { | 565 function DefineOneShotAccessor(obj, name, fun) { |
567 // Note that the accessors consistently operate on 'obj', not 'this'. | 566 // Note that the accessors consistently operate on 'obj', not 'this'. |
568 // Since the object may occur in someone else's prototype chain we | 567 // Since the object may occur in someone else's prototype chain we |
569 // can't rely on 'this' being the same as 'obj'. | 568 // can't rely on 'this' being the same as 'obj'. |
| 569 var hasBeenSet = false; |
| 570 var value; |
570 obj.__defineGetter__(name, function () { | 571 obj.__defineGetter__(name, function () { |
571 var value = fun(obj); | 572 if (hasBeenSet) { |
572 obj[name] = value; | 573 return value; |
| 574 } |
| 575 hasBeenSet = true; |
| 576 value = fun(obj); |
573 return value; | 577 return value; |
574 }); | 578 }); |
575 obj.__defineSetter__(name, function (v) { | 579 obj.__defineSetter__(name, function (v) { |
576 delete obj[name]; | 580 hasBeenSet = true; |
577 obj[name] = v; | 581 value = v; |
578 }); | 582 }); |
579 } | 583 } |
580 | 584 |
581 function CallSite(receiver, fun, pos) { | 585 function CallSite(receiver, fun, pos) { |
582 this.receiver = receiver; | 586 this.receiver = receiver; |
583 this.fun = fun; | 587 this.fun = fun; |
584 this.pos = pos; | 588 this.pos = pos; |
585 } | 589 } |
586 | 590 |
587 CallSite.prototype.getThis = function () { | 591 CallSite.prototype.getThis = function () { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 f.prototype.name = name; | 830 f.prototype.name = name; |
827 %SetCode(f, function(m) { | 831 %SetCode(f, function(m) { |
828 if (%_IsConstructCall()) { | 832 if (%_IsConstructCall()) { |
829 if (m === kAddMessageAccessorsMarker) { | 833 if (m === kAddMessageAccessorsMarker) { |
830 DefineOneShotAccessor(this, 'message', function (obj) { | 834 DefineOneShotAccessor(this, 'message', function (obj) { |
831 return FormatMessage({type: obj.type, args: obj.arguments}); | 835 return FormatMessage({type: obj.type, args: obj.arguments}); |
832 }); | 836 }); |
833 } else if (!IS_UNDEFINED(m)) { | 837 } else if (!IS_UNDEFINED(m)) { |
834 this.message = ToString(m); | 838 this.message = ToString(m); |
835 } | 839 } |
836 var stackTraceLimit = $Error.stackTraceLimit; | 840 captureStackTrace(this, f); |
837 if (stackTraceLimit) { | |
838 // Cap the limit to avoid extremely big traces | |
839 if (stackTraceLimit < 0 || stackTraceLimit > 10000) | |
840 stackTraceLimit = 10000; | |
841 var raw_stack = %CollectStackTrace(f, stackTraceLimit); | |
842 DefineOneShotAccessor(this, 'stack', function (obj) { | |
843 return FormatRawStackTrace(obj, raw_stack); | |
844 }); | |
845 } | |
846 } else { | 841 } else { |
847 return new f(m); | 842 return new f(m); |
848 } | 843 } |
849 }); | 844 }); |
850 } | 845 } |
851 | 846 |
| 847 function captureStackTrace(obj, cons_opt) { |
| 848 var stackTraceLimit = $Error.stackTraceLimit; |
| 849 if (!stackTraceLimit) return; |
| 850 if (stackTraceLimit < 0 || stackTraceLimit > 10000) |
| 851 stackTraceLimit = 10000; |
| 852 var raw_stack = %CollectStackTrace(cons_opt ? cons_opt : captureStackTrace, |
| 853 stackTraceLimit); |
| 854 DefineOneShotAccessor(obj, 'stack', function (obj) { |
| 855 return FormatRawStackTrace(obj, raw_stack); |
| 856 }); |
| 857 }; |
| 858 |
852 $Math.__proto__ = global.Object.prototype; | 859 $Math.__proto__ = global.Object.prototype; |
853 | 860 |
854 DefineError(function Error() { }); | 861 DefineError(function Error() { }); |
855 DefineError(function TypeError() { }); | 862 DefineError(function TypeError() { }); |
856 DefineError(function RangeError() { }); | 863 DefineError(function RangeError() { }); |
857 DefineError(function SyntaxError() { }); | 864 DefineError(function SyntaxError() { }); |
858 DefineError(function ReferenceError() { }); | 865 DefineError(function ReferenceError() { }); |
859 DefineError(function EvalError() { }); | 866 DefineError(function EvalError() { }); |
860 DefineError(function URIError() { }); | 867 DefineError(function URIError() { }); |
861 | 868 |
| 869 $Error.captureStackTrace = captureStackTrace; |
| 870 |
862 // Setup extra properties of the Error.prototype object. | 871 // Setup extra properties of the Error.prototype object. |
863 $Error.prototype.message = ''; | 872 $Error.prototype.message = ''; |
864 | 873 |
865 %SetProperty($Error.prototype, 'toString', function toString() { | 874 %SetProperty($Error.prototype, 'toString', function toString() { |
866 var type = this.type; | 875 var type = this.type; |
867 if (type && !this.hasOwnProperty("message")) { | 876 if (type && !this.hasOwnProperty("message")) { |
868 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); | 877 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); |
869 } | 878 } |
870 var message = this.message; | 879 var message = this.message; |
871 return this.name + (message ? (": " + message) : ""); | 880 return this.name + (message ? (": " + message) : ""); |
872 }, DONT_ENUM); | 881 }, DONT_ENUM); |
873 | 882 |
874 | 883 |
875 // Boilerplate for exceptions for stack overflows. Used from | 884 // Boilerplate for exceptions for stack overflows. Used from |
876 // Top::StackOverflow(). | 885 // Top::StackOverflow(). |
877 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); | 886 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); |
OLD | NEW |