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 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 var code = raw_stack[i + 2]; | 1071 var code = raw_stack[i + 2]; |
1072 var pc = raw_stack[i + 3]; | 1072 var pc = raw_stack[i + 3]; |
1073 var pos = %FunctionGetPositionForOffset(code, pc); | 1073 var pos = %FunctionGetPositionForOffset(code, pc); |
1074 non_strict_frames--; | 1074 non_strict_frames--; |
1075 frames.push(new CallSite(recv, fun, pos, (non_strict_frames < 0))); | 1075 frames.push(new CallSite(recv, fun, pos, (non_strict_frames < 0))); |
1076 } | 1076 } |
1077 return frames; | 1077 return frames; |
1078 } | 1078 } |
1079 | 1079 |
1080 | 1080 |
1081 function FormatStackTrace(error_string, frames) { | 1081 // Flag to prevent recursive call of Error.prepareStackTrace. |
| 1082 var formatting_custom_stack_trace = false; |
| 1083 |
| 1084 |
| 1085 function FormatStackTrace(obj, error_string, frames) { |
| 1086 if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) { |
| 1087 var array = []; |
| 1088 %MoveArrayContents(frames, array); |
| 1089 formatting_custom_stack_trace = true; |
| 1090 var stack_trace = void 0; |
| 1091 try { |
| 1092 stack_trace = $Error.prepareStackTrace(obj, array); |
| 1093 } catch (e) { |
| 1094 throw e; // The custom formatting function threw. Rethrow. |
| 1095 } finally { |
| 1096 formatting_custom_stack_trace = false; |
| 1097 } |
| 1098 return stack_trace; |
| 1099 } |
| 1100 |
1082 var lines = new InternalArray(); | 1101 var lines = new InternalArray(); |
1083 lines.push(error_string); | 1102 lines.push(error_string); |
1084 for (var i = 0; i < frames.length; i++) { | 1103 for (var i = 0; i < frames.length; i++) { |
1085 var frame = frames[i]; | 1104 var frame = frames[i]; |
1086 var line; | 1105 var line; |
1087 try { | 1106 try { |
1088 line = frame.toString(); | 1107 line = frame.toString(); |
1089 } catch (e) { | 1108 } catch (e) { |
1090 try { | 1109 try { |
1091 line = "<error: " + e + ">"; | 1110 line = "<error: " + e + ">"; |
(...skipping 16 matching lines...) Expand all Loading... |
1108 } | 1127 } |
1109 var constructorName = constructor.name; | 1128 var constructorName = constructor.name; |
1110 if (!constructorName) { | 1129 if (!constructorName) { |
1111 return requireConstructor ? null : | 1130 return requireConstructor ? null : |
1112 %_CallFunction(receiver, ObjectToString); | 1131 %_CallFunction(receiver, ObjectToString); |
1113 } | 1132 } |
1114 return constructorName; | 1133 return constructorName; |
1115 } | 1134 } |
1116 | 1135 |
1117 | 1136 |
1118 // Flag to prevent recursive call of Error.prepareStackTrace. | |
1119 var formatting_custom_stack_trace = false; | |
1120 | |
1121 | |
1122 function captureStackTrace(obj, cons_opt) { | 1137 function captureStackTrace(obj, cons_opt) { |
1123 var stackTraceLimit = $Error.stackTraceLimit; | 1138 var stackTraceLimit = $Error.stackTraceLimit; |
1124 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; | 1139 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; |
1125 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { | 1140 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { |
1126 stackTraceLimit = 10000; | 1141 stackTraceLimit = 10000; |
1127 } | 1142 } |
1128 var stack = %CollectStackTrace(obj, | 1143 var stack = %CollectStackTrace(obj, |
1129 cons_opt ? cons_opt : captureStackTrace, | 1144 cons_opt ? cons_opt : captureStackTrace, |
1130 stackTraceLimit); | 1145 stackTraceLimit); |
1131 | 1146 |
1132 // Don't be lazy if the error stack formatting is custom (observable). | |
1133 if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) { | |
1134 var array = []; | |
1135 %MoveArrayContents(GetStackFrames(stack), array); | |
1136 formatting_custom_stack_trace = true; | |
1137 try { | |
1138 obj.stack = $Error.prepareStackTrace(obj, array); | |
1139 } catch (e) { | |
1140 throw e; // The custom formatting function threw. Rethrow. | |
1141 } finally { | |
1142 formatting_custom_stack_trace = false; | |
1143 } | |
1144 return; | |
1145 } | |
1146 | |
1147 var error_string = FormatErrorString(obj); | 1147 var error_string = FormatErrorString(obj); |
1148 // The holder of this getter ('obj') may not be the receiver ('this'). | 1148 // The holder of this getter ('obj') may not be the receiver ('this'). |
1149 // When this getter is called the first time, we use the context values to | 1149 // When this getter is called the first time, we use the context values to |
1150 // format a stack trace string and turn this accessor pair into a data | 1150 // format a stack trace string and turn this accessor pair into a data |
1151 // property (on the holder). | 1151 // property (on the holder). |
1152 var getter = function() { | 1152 var getter = function() { |
1153 // Stack is still a raw array awaiting to be formatted. | 1153 // Stack is still a raw array awaiting to be formatted. |
1154 var result = FormatStackTrace(error_string, GetStackFrames(stack)); | 1154 var result = FormatStackTrace(obj, error_string, GetStackFrames(stack)); |
1155 // Turn this accessor into a data property. | 1155 // Turn this accessor into a data property. |
1156 %DefineOrRedefineDataProperty(obj, 'stack', result, NONE); | 1156 %DefineOrRedefineDataProperty(obj, 'stack', result, NONE); |
1157 // Release context values. | 1157 // Release context values. |
1158 stack = error_string = void 0; | 1158 stack = error_string = void 0; |
1159 return result; | 1159 return result; |
1160 }; | 1160 }; |
1161 | 1161 |
1162 // Set the 'stack' property on the receiver. If the receiver is the same as | 1162 // Set the 'stack' property on the receiver. If the receiver is the same as |
1163 // holder of this setter, the accessor pair is turned into a data property. | 1163 // holder of this setter, the accessor pair is turned into a data property. |
1164 var setter = function(v) { | 1164 var setter = function(v) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 var getter = function() { | 1314 var getter = function() { |
1315 var holder = this; | 1315 var holder = this; |
1316 while (!IS_ERROR(holder)) { | 1316 while (!IS_ERROR(holder)) { |
1317 holder = %GetPrototype(holder); | 1317 holder = %GetPrototype(holder); |
1318 if (IS_NULL(holder)) return MakeSyntaxError('illegal_access', []); | 1318 if (IS_NULL(holder)) return MakeSyntaxError('illegal_access', []); |
1319 } | 1319 } |
1320 var stack = %GetAndClearOverflowedStackTrace(holder); | 1320 var stack = %GetAndClearOverflowedStackTrace(holder); |
1321 // We may not have captured any stack trace. | 1321 // We may not have captured any stack trace. |
1322 if (IS_UNDEFINED(stack)) return stack; | 1322 if (IS_UNDEFINED(stack)) return stack; |
1323 | 1323 |
1324 var result = FormatStackTrace(error_string, GetStackFrames(stack)); | 1324 var result = FormatStackTrace(holder, error_string, GetStackFrames(stack)); |
1325 // Replace this accessor with a data property. | 1325 // Replace this accessor with a data property. |
1326 %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); | 1326 %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); |
1327 return result; | 1327 return result; |
1328 }; | 1328 }; |
1329 | 1329 |
1330 // Set the 'stack' property on the receiver. If the receiver is the same as | 1330 // Set the 'stack' property on the receiver. If the receiver is the same as |
1331 // holder of this setter, the accessor pair is turned into a data property. | 1331 // holder of this setter, the accessor pair is turned into a data property. |
1332 var setter = function(v) { | 1332 var setter = function(v) { |
1333 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1333 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
1334 // Tentatively clear the hidden property. If the receiver is the same as | 1334 // Tentatively clear the hidden property. If the receiver is the same as |
1335 // holder, we release the raw stack trace this way. | 1335 // holder, we release the raw stack trace this way. |
1336 %GetAndClearOverflowedStackTrace(this); | 1336 %GetAndClearOverflowedStackTrace(this); |
1337 }; | 1337 }; |
1338 | 1338 |
1339 %DefineOrRedefineAccessorProperty( | 1339 %DefineOrRedefineAccessorProperty( |
1340 boilerplate, 'stack', getter, setter, DONT_ENUM); | 1340 boilerplate, 'stack', getter, setter, DONT_ENUM); |
1341 | 1341 |
1342 return boilerplate; | 1342 return boilerplate; |
1343 } | 1343 } |
1344 | 1344 |
1345 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); | 1345 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |
OLD | NEW |