| 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 |