OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 } | 727 } |
728 | 728 |
729 | 729 |
730 function GetStackTraceLine(recv, fun, pos, isGlobal) { | 730 function GetStackTraceLine(recv, fun, pos, isGlobal) { |
731 return new CallSite(recv, fun, pos).toString(); | 731 return new CallSite(recv, fun, pos).toString(); |
732 } | 732 } |
733 | 733 |
734 // ---------------------------------------------------------------------------- | 734 // ---------------------------------------------------------------------------- |
735 // Error implementation | 735 // Error implementation |
736 | 736 |
737 // Defines accessors for a property that is calculated the first time | |
738 // the property is read. | |
739 function DefineOneShotAccessor(obj, name, fun) { | |
740 // Note that the accessors consistently operate on 'obj', not 'this'. | |
741 // Since the object may occur in someone else's prototype chain we | |
742 // can't rely on 'this' being the same as 'obj'. | |
743 var value; | |
744 var value_factory = fun; | |
745 var getter = function() { | |
746 if (value_factory == null) { | |
747 return value; | |
748 } | |
749 value = value_factory(obj); | |
750 value_factory = null; | |
751 return value; | |
752 }; | |
753 var setter = function(v) { | |
754 value_factory = null; | |
755 value = v; | |
756 }; | |
757 %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM); | |
758 } | |
759 | |
760 function CallSite(receiver, fun, pos) { | 737 function CallSite(receiver, fun, pos) { |
761 this.receiver = receiver; | 738 this.receiver = receiver; |
762 this.fun = fun; | 739 this.fun = fun; |
763 this.pos = pos; | 740 this.pos = pos; |
764 } | 741 } |
765 | 742 |
766 function CallSiteGetThis() { | 743 function CallSiteGetThis() { |
767 return this.receiver; | 744 return this.receiver; |
768 } | 745 } |
769 | 746 |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 | 1061 |
1085 function captureStackTrace(obj, cons_opt) { | 1062 function captureStackTrace(obj, cons_opt) { |
1086 var stackTraceLimit = $Error.stackTraceLimit; | 1063 var stackTraceLimit = $Error.stackTraceLimit; |
1087 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; | 1064 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; |
1088 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { | 1065 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { |
1089 stackTraceLimit = 10000; | 1066 stackTraceLimit = 10000; |
1090 } | 1067 } |
1091 var raw_stack = %CollectStackTrace(obj, | 1068 var raw_stack = %CollectStackTrace(obj, |
1092 cons_opt ? cons_opt : captureStackTrace, | 1069 cons_opt ? cons_opt : captureStackTrace, |
1093 stackTraceLimit); | 1070 stackTraceLimit); |
1094 DefineOneShotAccessor(obj, 'stack', function (obj) { | 1071 // Note that 'obj' and 'this' maybe different when called on objects that |
1095 return FormatRawStackTrace(obj, raw_stack); | 1072 // have the error object on its prototype chain. The getter replaces itself |
1096 }); | 1073 // with a data property as soon as the stack trace has been formatted. |
| 1074 var getter = function() { |
| 1075 var value = FormatRawStackTrace(obj, raw_stack); |
| 1076 %DefineOrRedefineDataProperty(obj, 'stack', value, NONE); |
| 1077 return value; |
| 1078 }; |
| 1079 // The 'stack' property of the receiver is set as data property. If |
| 1080 // the receiver is the same as holder, this accessor pair is replaced. |
| 1081 var setter = function(v) { |
| 1082 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
| 1083 }; |
| 1084 |
| 1085 %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM); |
1097 } | 1086 } |
1098 | 1087 |
1099 | 1088 |
1100 function SetUpError() { | 1089 function SetUpError() { |
1101 // Define special error type constructors. | 1090 // Define special error type constructors. |
1102 | 1091 |
1103 var DefineError = function(f) { | 1092 var DefineError = function(f) { |
1104 // Store the error function in both the global object | 1093 // Store the error function in both the global object |
1105 // and the runtime object. The function is fetched | 1094 // and the runtime object. The function is fetched |
1106 // from the runtime object when throwing errors from | 1095 // from the runtime object when throwing errors from |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 } | 1210 } |
1222 throw e; | 1211 throw e; |
1223 } | 1212 } |
1224 } | 1213 } |
1225 | 1214 |
1226 | 1215 |
1227 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]); | 1216 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]); |
1228 | 1217 |
1229 // Boilerplate for exceptions for stack overflows. Used from | 1218 // Boilerplate for exceptions for stack overflows. Used from |
1230 // Isolate::StackOverflow(). | 1219 // Isolate::StackOverflow(). |
1231 var kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); | 1220 function SetUpStackOverflowBoilerplate() { |
| 1221 var boilerplate = MakeRangeError('stack_overflow', []); |
| 1222 |
| 1223 // The raw stack trace is stored as hidden property of the copy of this |
| 1224 // boilerplate error object. Note that the receiver 'this' may not be that |
| 1225 // error object copy, but can be found on the prototype chain of 'this'. |
| 1226 // When the stack trace is formatted, this accessor property is replaced by |
| 1227 // a data property. |
| 1228 function getter() { |
| 1229 var holder = this; |
| 1230 while (!IS_ERROR(holder)) { |
| 1231 holder = %GetPrototype(holder); |
| 1232 if (holder == null) return MakeSyntaxError('illegal_access', []); |
| 1233 } |
| 1234 var raw_stack = %GetOverflowedRawStackTrace(holder); |
| 1235 var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack) |
| 1236 : void 0; |
| 1237 %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); |
| 1238 return result; |
| 1239 } |
| 1240 |
| 1241 // The 'stack' property of the receiver is set as data property. If |
| 1242 // the receiver is the same as holder, this accessor pair is replaced. |
| 1243 function setter(v) { |
| 1244 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
| 1245 } |
| 1246 |
| 1247 %DefineOrRedefineAccessorProperty( |
| 1248 boilerplate, 'stack', getter, setter, DONT_ENUM); |
| 1249 |
| 1250 return boilerplate; |
| 1251 } |
| 1252 |
| 1253 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |
OLD | NEW |