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 |