| 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 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 return constructorName; | 1081 return constructorName; |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 | 1084 |
| 1085 function captureStackTrace(obj, cons_opt) { | 1085 function captureStackTrace(obj, cons_opt) { |
| 1086 var stackTraceLimit = $Error.stackTraceLimit; | 1086 var stackTraceLimit = $Error.stackTraceLimit; |
| 1087 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; | 1087 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; |
| 1088 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { | 1088 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { |
| 1089 stackTraceLimit = 10000; | 1089 stackTraceLimit = 10000; |
| 1090 } | 1090 } |
| 1091 var raw_stack = %CollectStackTrace(obj, | 1091 var stack = %CollectStackTrace(obj, |
| 1092 cons_opt ? cons_opt : captureStackTrace, | 1092 cons_opt ? cons_opt : captureStackTrace, |
| 1093 stackTraceLimit); | 1093 stackTraceLimit); |
| 1094 | 1094 |
| 1095 // Don't be lazy if the error stack formatting is custom (observable). | 1095 // Don't be lazy if the error stack formatting is custom (observable). |
| 1096 if (IS_FUNCTION($Error.prepareStackTrace)) { | 1096 if (IS_FUNCTION($Error.prepareStackTrace)) { |
| 1097 var custom_stacktrace_fun = $Error.prepareStackTrace; | 1097 var custom_stacktrace_fun = $Error.prepareStackTrace; |
| 1098 // Use default error formatting for the case that custom formatting throws. | 1098 // Use default error formatting for the case that custom formatting throws. |
| 1099 $Error.prepareStackTrace = null; | 1099 $Error.prepareStackTrace = null; |
| 1100 var array = []; | 1100 var array = []; |
| 1101 %MoveArrayContents(GetStackFrames(raw_stack), array); | 1101 %MoveArrayContents(GetStackFrames(stack), array); |
| 1102 obj.stack = custom_stacktrace_fun(obj, array); | 1102 obj.stack = custom_stacktrace_fun(obj, array); |
| 1103 $Error.prepareStackTrace = custom_stacktrace_fun; | 1103 $Error.prepareStackTrace = custom_stacktrace_fun; |
| 1104 return; | 1104 return; |
| 1105 } | 1105 } |
| 1106 | 1106 |
| 1107 var error_string = FormatErrorString(obj); | 1107 var error_string = FormatErrorString(obj); |
| 1108 // Note that 'obj' and 'this' maybe different when called on objects that | 1108 // Note that 'obj' and 'this' maybe different when called on objects that |
| 1109 // have the error object on its prototype chain. The getter replaces itself | 1109 // have the error object on its prototype chain. The getter replaces itself |
| 1110 // with a data property as soon as the stack trace has been formatted. | 1110 // with a data property as soon as the stack trace has been formatted. |
| 1111 // The getter must not change the object layout as it may be called after GC. |
| 1111 var getter = function() { | 1112 var getter = function() { |
| 1112 var value = FormatStackTrace(error_string, GetStackFrames(raw_stack)); | 1113 if (IS_STRING(stack)) return stack; |
| 1113 %DefineOrRedefineDataProperty(obj, 'stack', value, NONE); | 1114 // Stack is still a raw array awaiting to be formatted. |
| 1114 return value; | 1115 stack = FormatStackTrace(error_string, GetStackFrames(stack)); |
| 1116 // Release context value. |
| 1117 error_string = void 0; |
| 1118 return stack; |
| 1115 }; | 1119 }; |
| 1116 %MarkOneShotGetter(getter); | 1120 %MarkOneShotGetter(getter); |
| 1117 | 1121 |
| 1118 // The 'stack' property of the receiver is set as data property. If | 1122 // The 'stack' property of the receiver is set as data property. If |
| 1119 // the receiver is the same as holder, this accessor pair is replaced. | 1123 // the receiver is the same as holder, this accessor pair is replaced. |
| 1120 var setter = function(v) { | 1124 var setter = function(v) { |
| 1121 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1125 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
| 1122 }; | 1126 }; |
| 1123 | 1127 |
| 1124 %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM); | 1128 %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 function SetUpStackOverflowBoilerplate() { | 1260 function SetUpStackOverflowBoilerplate() { |
| 1257 var boilerplate = MakeRangeError('stack_overflow', []); | 1261 var boilerplate = MakeRangeError('stack_overflow', []); |
| 1258 | 1262 |
| 1259 // The raw stack trace is stored as hidden property of the copy of this | 1263 // The raw stack trace is stored as hidden property of the copy of this |
| 1260 // boilerplate error object. Note that the receiver 'this' may not be that | 1264 // boilerplate error object. Note that the receiver 'this' may not be that |
| 1261 // error object copy, but can be found on the prototype chain of 'this'. | 1265 // error object copy, but can be found on the prototype chain of 'this'. |
| 1262 // When the stack trace is formatted, this accessor property is replaced by | 1266 // When the stack trace is formatted, this accessor property is replaced by |
| 1263 // a data property. | 1267 // a data property. |
| 1264 var error_string = boilerplate.name + ": " + boilerplate.message; | 1268 var error_string = boilerplate.name + ": " + boilerplate.message; |
| 1265 | 1269 |
| 1270 // The getter must not change the object layout as it may be called after GC. |
| 1266 function getter() { | 1271 function getter() { |
| 1267 var holder = this; | 1272 var holder = this; |
| 1268 while (!IS_ERROR(holder)) { | 1273 while (!IS_ERROR(holder)) { |
| 1269 holder = %GetPrototype(holder); | 1274 holder = %GetPrototype(holder); |
| 1270 if (holder == null) return MakeSyntaxError('illegal_access', []); | 1275 if (holder == null) return MakeSyntaxError('illegal_access', []); |
| 1271 } | 1276 } |
| 1272 var raw_stack = %GetOverflowedRawStackTrace(holder); | 1277 var stack = %GetOverflowedStackTrace(holder); |
| 1273 var result = IS_ARRAY(raw_stack) | 1278 if (IS_STRING(stack)) return stack; |
| 1274 ? FormatStackTrace(error_string, GetStackFrames(raw_stack)) | 1279 if (IS_ARRAY(stack)) { |
| 1275 : void 0; | 1280 var result = FormatStackTrace(error_string, GetStackFrames(stack)); |
| 1276 %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); | 1281 %SetOverflowedStackTrace(holder, result); |
| 1277 return result; | 1282 return result; |
| 1283 } |
| 1284 return void 0; |
| 1278 } | 1285 } |
| 1279 %MarkOneShotGetter(getter); | 1286 %MarkOneShotGetter(getter); |
| 1280 | 1287 |
| 1281 // The 'stack' property of the receiver is set as data property. If | 1288 // The 'stack' property of the receiver is set as data property. If |
| 1282 // the receiver is the same as holder, this accessor pair is replaced. | 1289 // the receiver is the same as holder, this accessor pair is replaced. |
| 1283 function setter(v) { | 1290 function setter(v) { |
| 1284 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1291 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
| 1292 // Release the stack trace that is stored as hidden property, if exists. |
| 1293 %SetOverflowedStackTrace(this, void 0); |
| 1285 } | 1294 } |
| 1286 | 1295 |
| 1287 %DefineOrRedefineAccessorProperty( | 1296 %DefineOrRedefineAccessorProperty( |
| 1288 boilerplate, 'stack', getter, setter, DONT_ENUM); | 1297 boilerplate, 'stack', getter, setter, DONT_ENUM); |
| 1289 | 1298 |
| 1290 return boilerplate; | 1299 return boilerplate; |
| 1291 } | 1300 } |
| 1292 | 1301 |
| 1293 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); | 1302 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |
| OLD | NEW |