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