Chromium Code Reviews| 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 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 805 var script = %FunctionGetScript(this.fun); | 805 var script = %FunctionGetScript(this.fun); |
| 806 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { | 806 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { |
| 807 return "eval"; | 807 return "eval"; |
| 808 } | 808 } |
| 809 return null; | 809 return null; |
| 810 } | 810 } |
| 811 | 811 |
| 812 function CallSiteGetMethodName() { | 812 function CallSiteGetMethodName() { |
| 813 // See if we can find a unique property on the receiver that holds | 813 // See if we can find a unique property on the receiver that holds |
| 814 // this function. | 814 // this function. |
| 815 var ownName = this.fun.name; | 815 var ownName = this.fun.name; |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
If we ever change property descriptor for our 'nam
| |
| 816 if (ownName && this.receiver && | 816 if (ownName && this.receiver && |
| 817 (%_CallFunction(this.receiver, | 817 (%_CallFunction(this.receiver, |
| 818 ownName, | 818 ownName, |
| 819 ObjectLookupGetter) === this.fun || | 819 ObjectLookupGetter) === this.fun || |
| 820 %_CallFunction(this.receiver, | 820 %_CallFunction(this.receiver, |
| 821 ownName, | 821 ownName, |
| 822 ObjectLookupSetter) === this.fun || | 822 ObjectLookupSetter) === this.fun || |
| 823 this.receiver[ownName] === this.fun)) { | 823 this.receiver[ownName] === this.fun)) { |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
I can detect GC through here by doing:
var obj =
| |
| 824 // To handle DontEnum properties we guess that the method has | 824 // To handle DontEnum properties we guess that the method has |
| 825 // the same name as the function. | 825 // the same name as the function. |
| 826 return ownName; | 826 return ownName; |
| 827 } | 827 } |
| 828 var name = null; | 828 var name = null; |
| 829 for (var prop in this.receiver) { | 829 for (var prop in this.receiver) { |
| 830 if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun || | 830 if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun || |
| 831 %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun || | 831 %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun || |
| 832 (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) && | 832 (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) && |
| 833 this.receiver[prop] === this.fun)) { | 833 this.receiver[prop] === this.fun)) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1009 eval_origin += ")"; | 1009 eval_origin += ")"; |
| 1010 } else { | 1010 } else { |
| 1011 eval_origin += " (unknown source)"; | 1011 eval_origin += " (unknown source)"; |
| 1012 } | 1012 } |
| 1013 } | 1013 } |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 return eval_origin; | 1016 return eval_origin; |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 function FormatStackTrace(error, frames) { | 1019 |
| 1020 var lines = []; | 1020 function FormatErrorString(error) { |
| 1021 try { | 1021 try { |
| 1022 lines.push(error.toString()); | 1022 return %_CallFunction(error, ErrorToString); |
| 1023 } catch (e) { | 1023 } catch (e) { |
| 1024 try { | 1024 try { |
| 1025 lines.push("<error: " + e + ">"); | 1025 return "<error: " + e + ">"; |
| 1026 } catch (ee) { | 1026 } catch (ee) { |
| 1027 lines.push("<error>"); | 1027 return "<error>"; |
| 1028 } | 1028 } |
| 1029 } | 1029 } |
| 1030 } | |
| 1031 | |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
one more empty line
| |
| 1032 function GetStackFrames(raw_stack) { | |
| 1033 var frames = []; | |
| 1034 for (var i = 0; i < raw_stack.length; i += 4) { | |
| 1035 var recv = raw_stack[i]; | |
| 1036 var fun = raw_stack[i + 1]; | |
| 1037 var code = raw_stack[i + 2]; | |
| 1038 var pc = raw_stack[i + 3]; | |
| 1039 var pos = %FunctionGetPositionForOffset(code, pc); | |
| 1040 %_CallFunction(frames, new CallSite(recv, fun, pos), ArrayPush) | |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
This code can still be broken (formatting detected
| |
| 1041 } | |
| 1042 return frames; | |
| 1043 } | |
| 1044 | |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
ditto
| |
| 1045 function FormatStackTrace(error_string, frames) { | |
| 1046 var lines = [error_string]; | |
| 1030 for (var i = 0; i < frames.length; i++) { | 1047 for (var i = 0; i < frames.length; i++) { |
| 1031 var frame = frames[i]; | 1048 var frame = frames[i]; |
| 1032 var line; | 1049 var line; |
| 1033 try { | 1050 try { |
| 1034 line = frame.toString(); | 1051 line = %_CallFunction(frame, CallSiteToString); |
| 1035 } catch (e) { | 1052 } catch (e) { |
| 1036 try { | 1053 try { |
| 1037 line = "<error: " + e + ">"; | 1054 line = "<error: " + e + ">"; |
| 1038 } catch (ee) { | 1055 } catch (ee) { |
| 1039 // Any code that reaches this point is seriously nasty! | 1056 // Any code that reaches this point is seriously nasty! |
| 1040 line = "<error>"; | 1057 line = "<error>"; |
| 1041 } | 1058 } |
| 1042 } | 1059 } |
| 1043 lines.push(" at " + line); | 1060 %_CallFunction(lines, " at " + line, ArrayPush); |
| 1044 } | 1061 } |
| 1045 return lines.join("\n"); | 1062 return %_CallFunction(lines, "\n", ArrayJoin); |
| 1046 } | |
| 1047 | |
| 1048 function FormatRawStackTrace(error, raw_stack) { | |
| 1049 var frames = [ ]; | |
| 1050 for (var i = 0; i < raw_stack.length; i += 4) { | |
| 1051 var recv = raw_stack[i]; | |
| 1052 var fun = raw_stack[i + 1]; | |
| 1053 var code = raw_stack[i + 2]; | |
| 1054 var pc = raw_stack[i + 3]; | |
| 1055 var pos = %FunctionGetPositionForOffset(code, pc); | |
| 1056 frames.push(new CallSite(recv, fun, pos)); | |
| 1057 } | |
| 1058 if (IS_FUNCTION($Error.prepareStackTrace)) { | |
| 1059 return $Error.prepareStackTrace(error, frames); | |
| 1060 } else { | |
| 1061 return FormatStackTrace(error, frames); | |
| 1062 } | |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 function GetTypeName(obj, requireConstructor) { | 1065 function GetTypeName(obj, requireConstructor) { |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
ditto
| |
| 1066 var constructor = obj.receiver.constructor; | 1066 var constructor = obj.receiver.constructor; |
| 1067 if (!constructor) { | 1067 if (!constructor) { |
| 1068 return requireConstructor ? null : | 1068 return requireConstructor ? null : |
| 1069 %_CallFunction(obj.receiver, ObjectToString); | 1069 %_CallFunction(obj.receiver, ObjectToString); |
| 1070 } | 1070 } |
| 1071 var constructorName = constructor.name; | 1071 var constructorName = constructor.name; |
| 1072 if (!constructorName) { | 1072 if (!constructorName) { |
| 1073 return requireConstructor ? null : | 1073 return requireConstructor ? null : |
| 1074 %_CallFunction(obj.receiver, ObjectToString); | 1074 %_CallFunction(obj.receiver, ObjectToString); |
| 1075 } | 1075 } |
| 1076 return constructorName; | 1076 return constructorName; |
| 1077 } | 1077 } |
| 1078 | 1078 |
| 1079 function captureStackTrace(obj, cons_opt) { | 1079 function captureStackTrace(obj, cons_opt) { |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
ditto
| |
| 1080 var stackTraceLimit = $Error.stackTraceLimit; | 1080 var stackTraceLimit = $Error.stackTraceLimit; |
| 1081 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; | 1081 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; |
| 1082 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { | 1082 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { |
| 1083 stackTraceLimit = 10000; | 1083 stackTraceLimit = 10000; |
| 1084 } | 1084 } |
| 1085 var raw_stack = %CollectStackTrace(obj, | 1085 var raw_stack = %CollectStackTrace(obj, |
| 1086 cons_opt ? cons_opt : captureStackTrace, | 1086 cons_opt ? cons_opt : captureStackTrace, |
| 1087 stackTraceLimit); | 1087 stackTraceLimit); |
| 1088 | |
| 1089 // Don't be lazy if the error stack formatting is custom (observable). | |
| 1090 if (IS_FUNCTION($Error.prepareStackTrace)) { | |
| 1091 obj.stack = $Error.prepareStackTrace(obj, GetStackFrames(raw_stack)); | |
|
Vyacheslav Egorov (Google)
2012/12/10 14:46:45
should we maybe catch an error if it flies from pr
| |
| 1092 return; | |
| 1093 } | |
| 1094 | |
| 1095 var error_string = FormatErrorString(obj); | |
| 1088 // Note that 'obj' and 'this' maybe different when called on objects that | 1096 // Note that 'obj' and 'this' maybe different when called on objects that |
| 1089 // have the error object on its prototype chain. The getter replaces itself | 1097 // have the error object on its prototype chain. The getter replaces itself |
| 1090 // with a data property as soon as the stack trace has been formatted. | 1098 // with a data property as soon as the stack trace has been formatted. |
| 1091 var getter = function() { | 1099 var getter = function() { |
| 1092 var value = FormatRawStackTrace(obj, raw_stack); | 1100 var value = FormatStackTrace(error_string, GetStackFrames(raw_stack)); |
| 1093 %DefineOrRedefineDataProperty(obj, 'stack', value, NONE); | 1101 %DefineOrRedefineDataProperty(obj, 'stack', value, NONE); |
| 1094 return value; | 1102 return value; |
| 1095 }; | 1103 }; |
| 1104 %MarkOneShotGetter(getter); | |
| 1105 | |
| 1096 // The 'stack' property of the receiver is set as data property. If | 1106 // The 'stack' property of the receiver is set as data property. If |
| 1097 // the receiver is the same as holder, this accessor pair is replaced. | 1107 // the receiver is the same as holder, this accessor pair is replaced. |
| 1098 var setter = function(v) { | 1108 var setter = function(v) { |
| 1099 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1109 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
| 1100 }; | 1110 }; |
| 1101 | 1111 |
| 1102 %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM); | 1112 %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM); |
| 1103 } | 1113 } |
| 1104 | 1114 |
| 1105 | 1115 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1232 // Boilerplate for exceptions for stack overflows. Used from | 1242 // Boilerplate for exceptions for stack overflows. Used from |
| 1233 // Isolate::StackOverflow(). | 1243 // Isolate::StackOverflow(). |
| 1234 function SetUpStackOverflowBoilerplate() { | 1244 function SetUpStackOverflowBoilerplate() { |
| 1235 var boilerplate = MakeRangeError('stack_overflow', []); | 1245 var boilerplate = MakeRangeError('stack_overflow', []); |
| 1236 | 1246 |
| 1237 // The raw stack trace is stored as hidden property of the copy of this | 1247 // The raw stack trace is stored as hidden property of the copy of this |
| 1238 // boilerplate error object. Note that the receiver 'this' may not be that | 1248 // boilerplate error object. Note that the receiver 'this' may not be that |
| 1239 // error object copy, but can be found on the prototype chain of 'this'. | 1249 // error object copy, but can be found on the prototype chain of 'this'. |
| 1240 // When the stack trace is formatted, this accessor property is replaced by | 1250 // When the stack trace is formatted, this accessor property is replaced by |
| 1241 // a data property. | 1251 // a data property. |
| 1252 var error_string = boilerplate.name + ": " + boilerplate.message; | |
| 1253 | |
| 1242 function getter() { | 1254 function getter() { |
| 1243 var holder = this; | 1255 var holder = this; |
| 1244 while (!IS_ERROR(holder)) { | 1256 while (!IS_ERROR(holder)) { |
| 1245 holder = %GetPrototype(holder); | 1257 holder = %GetPrototype(holder); |
| 1246 if (holder == null) return MakeSyntaxError('illegal_access', []); | 1258 if (holder == null) return MakeSyntaxError('illegal_access', []); |
| 1247 } | 1259 } |
| 1248 var raw_stack = %GetOverflowedRawStackTrace(holder); | 1260 var raw_stack = %GetOverflowedRawStackTrace(holder); |
| 1249 var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack) | 1261 var result = IS_ARRAY(raw_stack) |
| 1250 : void 0; | 1262 ? FormatStackTrace(error_string, GetStackFrames(raw_stack)) |
| 1263 : void 0; | |
| 1251 %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); | 1264 %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); |
| 1252 return result; | 1265 return result; |
| 1253 } | 1266 } |
| 1267 %MarkOneShotGetter(getter); | |
| 1254 | 1268 |
| 1255 // The 'stack' property of the receiver is set as data property. If | 1269 // The 'stack' property of the receiver is set as data property. If |
| 1256 // the receiver is the same as holder, this accessor pair is replaced. | 1270 // the receiver is the same as holder, this accessor pair is replaced. |
| 1257 function setter(v) { | 1271 function setter(v) { |
| 1258 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1272 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); |
| 1259 } | 1273 } |
| 1260 | 1274 |
| 1261 %DefineOrRedefineAccessorProperty( | 1275 %DefineOrRedefineAccessorProperty( |
| 1262 boilerplate, 'stack', getter, setter, DONT_ENUM); | 1276 boilerplate, 'stack', getter, setter, DONT_ENUM); |
| 1263 | 1277 |
| 1264 return boilerplate; | 1278 return boilerplate; |
| 1265 } | 1279 } |
| 1266 | 1280 |
| 1267 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); | 1281 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |
| OLD | NEW |