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 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 var script = %MessageGetScript(message); | 739 var script = %MessageGetScript(message); |
| 740 var start_position = %MessageGetStartPosition(message); | 740 var start_position = %MessageGetStartPosition(message); |
| 741 var location = script.locationFromPosition(start_position, false); | 741 var location = script.locationFromPosition(start_position, false); |
| 742 if (location == null) return -1; | 742 if (location == null) return -1; |
| 743 location.restrict(); | 743 location.restrict(); |
| 744 return start_position - location.start; | 744 return start_position - location.start; |
| 745 } | 745 } |
| 746 | 746 |
| 747 | 747 |
| 748 function GetStackTraceLine(recv, fun, pos, isGlobal) { | 748 function GetStackTraceLine(recv, fun, pos, isGlobal) { |
| 749 return new CallSite(recv, fun, pos).toString(); | 749 return new CallSite(recv, fun, pos, false).toString(); |
| 750 } | 750 } |
| 751 | 751 |
| 752 // ---------------------------------------------------------------------------- | 752 // ---------------------------------------------------------------------------- |
| 753 // Error implementation | 753 // Error implementation |
| 754 | 754 |
| 755 function CallSite(receiver, fun, pos) { | 755 var CallSiteReceiverKey = %CreateSymbol("receiver"); |
|
rossberg
2013/03/28 10:04:33
Nit: do our coding conventions allow this kind of
| |
| 756 this.receiver = receiver; | 756 var CallSiteFunctionKey = %CreateSymbol("function"); |
| 757 this.fun = fun; | 757 var CallSitePositionKey = %CreateSymbol("position"); |
| 758 this.pos = pos; | 758 var CallSiteStrictModeKey = %CreateSymbol("strict mode"); |
| 759 | |
| 760 function CallSite(receiver, fun, pos, strict_mode) { | |
| 761 this[CallSiteReceiverKey] = receiver; | |
| 762 this[CallSiteFunctionKey] = fun; | |
| 763 this[CallSitePositionKey] = pos; | |
| 764 this[CallSiteStrictModeKey] = strict_mode; | |
| 759 } | 765 } |
| 760 | 766 |
| 761 function CallSiteGetThis() { | 767 function CallSiteGetThis() { |
| 762 return this.receiver; | 768 if (this[CallSiteStrictModeKey]) return void 0; |
|
rossberg
2013/03/28 10:04:33
You could use ?: here.
| |
| 769 return this[CallSiteReceiverKey]; | |
| 763 } | 770 } |
| 764 | 771 |
| 765 function CallSiteGetTypeName() { | 772 function CallSiteGetTypeName() { |
| 766 return GetTypeName(this, false); | 773 return GetTypeName(this[CallSiteReceiverKey], false); |
| 767 } | 774 } |
| 768 | 775 |
| 769 function CallSiteIsToplevel() { | 776 function CallSiteIsToplevel() { |
| 770 if (this.receiver == null) { | 777 if (this[CallSiteReceiverKey] == null) { |
| 771 return true; | 778 return true; |
| 772 } | 779 } |
| 773 return IS_GLOBAL(this.receiver); | 780 return IS_GLOBAL(this[CallSiteReceiverKey]); |
| 774 } | 781 } |
| 775 | 782 |
| 776 function CallSiteIsEval() { | 783 function CallSiteIsEval() { |
| 777 var script = %FunctionGetScript(this.fun); | 784 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 778 return script && script.compilation_type == COMPILATION_TYPE_EVAL; | 785 return script && script.compilation_type == COMPILATION_TYPE_EVAL; |
| 779 } | 786 } |
| 780 | 787 |
| 781 function CallSiteGetEvalOrigin() { | 788 function CallSiteGetEvalOrigin() { |
| 782 var script = %FunctionGetScript(this.fun); | 789 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 783 return FormatEvalOrigin(script); | 790 return FormatEvalOrigin(script); |
| 784 } | 791 } |
| 785 | 792 |
| 786 function CallSiteGetScriptNameOrSourceURL() { | 793 function CallSiteGetScriptNameOrSourceURL() { |
| 787 var script = %FunctionGetScript(this.fun); | 794 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 788 return script ? script.nameOrSourceURL() : null; | 795 return script ? script.nameOrSourceURL() : null; |
| 789 } | 796 } |
| 790 | 797 |
| 791 function CallSiteGetFunction() { | 798 function CallSiteGetFunction() { |
| 792 return this.fun; | 799 if (this[CallSiteStrictModeKey]) return void 0; |
|
rossberg
2013/03/28 10:04:33
...same here.
| |
| 800 return this[CallSiteFunctionKey]; | |
| 793 } | 801 } |
| 794 | 802 |
| 795 function CallSiteGetFunctionName() { | 803 function CallSiteGetFunctionName() { |
| 796 // See if the function knows its own name | 804 // See if the function knows its own name |
| 797 var name = this.fun.name; | 805 var name = this[CallSiteFunctionKey].name; |
| 798 if (name) { | 806 if (name) { |
| 799 return name; | 807 return name; |
| 800 } | 808 } |
| 801 name = %FunctionGetInferredName(this.fun); | 809 name = %FunctionGetInferredName(this[CallSiteFunctionKey]); |
| 802 if (name) { | 810 if (name) { |
| 803 return name; | 811 return name; |
| 804 } | 812 } |
| 805 // Maybe this is an evaluation? | 813 // Maybe this is an evaluation? |
| 806 var script = %FunctionGetScript(this.fun); | 814 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 807 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { | 815 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { |
| 808 return "eval"; | 816 return "eval"; |
| 809 } | 817 } |
| 810 return null; | 818 return null; |
| 811 } | 819 } |
| 812 | 820 |
| 813 function CallSiteGetMethodName() { | 821 function CallSiteGetMethodName() { |
| 814 // See if we can find a unique property on the receiver that holds | 822 // See if we can find a unique property on the receiver that holds |
| 815 // this function. | 823 // this function. |
| 816 var ownName = this.fun.name; | 824 var receiver = this[CallSiteReceiverKey]; |
| 817 if (ownName && this.receiver && | 825 var fun = this[CallSiteFunctionKey]; |
| 818 (%_CallFunction(this.receiver, | 826 var ownName = fun.name; |
| 819 ownName, | 827 if (ownName && receiver && |
| 820 ObjectLookupGetter) === this.fun || | 828 (%_CallFunction(receiver, ownName, ObjectLookupGetter) === fun || |
| 821 %_CallFunction(this.receiver, | 829 %_CallFunction(receiver, ownName, ObjectLookupSetter) === fun || |
| 822 ownName, | 830 (IS_OBJECT(receiver) && %GetDataProperty(receiver, ownName) === fun))) { |
| 823 ObjectLookupSetter) === this.fun || | |
| 824 (IS_OBJECT(this.receiver) && | |
| 825 %GetDataProperty(this.receiver, ownName) === this.fun))) { | |
| 826 // To handle DontEnum properties we guess that the method has | 831 // To handle DontEnum properties we guess that the method has |
| 827 // the same name as the function. | 832 // the same name as the function. |
| 828 return ownName; | 833 return ownName; |
| 829 } | 834 } |
| 830 var name = null; | 835 var name = null; |
| 831 for (var prop in this.receiver) { | 836 for (var prop in receiver) { |
| 832 if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun || | 837 if (%_CallFunction(receiver, prop, ObjectLookupGetter) === fun || |
| 833 %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun || | 838 %_CallFunction(receiver, prop, ObjectLookupSetter) === fun || |
| 834 (IS_OBJECT(this.receiver) && | 839 (IS_OBJECT(receiver) && %GetDataProperty(receiver, prop) === fun)) { |
| 835 %GetDataProperty(this.receiver, prop) === this.fun)) { | |
| 836 // If we find more than one match bail out to avoid confusion. | 840 // If we find more than one match bail out to avoid confusion. |
| 837 if (name) { | 841 if (name) { |
| 838 return null; | 842 return null; |
| 839 } | 843 } |
| 840 name = prop; | 844 name = prop; |
| 841 } | 845 } |
| 842 } | 846 } |
| 843 if (name) { | 847 if (name) { |
| 844 return name; | 848 return name; |
| 845 } | 849 } |
| 846 return null; | 850 return null; |
| 847 } | 851 } |
| 848 | 852 |
| 849 function CallSiteGetFileName() { | 853 function CallSiteGetFileName() { |
| 850 var script = %FunctionGetScript(this.fun); | 854 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 851 return script ? script.name : null; | 855 return script ? script.name : null; |
| 852 } | 856 } |
| 853 | 857 |
| 854 function CallSiteGetLineNumber() { | 858 function CallSiteGetLineNumber() { |
| 855 if (this.pos == -1) { | 859 if (this[CallSitePositionKey] == -1) { |
| 856 return null; | 860 return null; |
| 857 } | 861 } |
| 858 var script = %FunctionGetScript(this.fun); | 862 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 859 var location = null; | 863 var location = null; |
| 860 if (script) { | 864 if (script) { |
| 861 location = script.locationFromPosition(this.pos, true); | 865 location = script.locationFromPosition(this[CallSitePositionKey], true); |
| 862 } | 866 } |
| 863 return location ? location.line + 1 : null; | 867 return location ? location.line + 1 : null; |
| 864 } | 868 } |
| 865 | 869 |
| 866 function CallSiteGetColumnNumber() { | 870 function CallSiteGetColumnNumber() { |
| 867 if (this.pos == -1) { | 871 if (this[CallSitePositionKey] == -1) { |
| 868 return null; | 872 return null; |
| 869 } | 873 } |
| 870 var script = %FunctionGetScript(this.fun); | 874 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 871 var location = null; | 875 var location = null; |
| 872 if (script) { | 876 if (script) { |
| 873 location = script.locationFromPosition(this.pos, true); | 877 location = script.locationFromPosition(this[CallSitePositionKey], true); |
| 874 } | 878 } |
| 875 return location ? location.column + 1: null; | 879 return location ? location.column + 1: null; |
| 876 } | 880 } |
| 877 | 881 |
| 878 function CallSiteIsNative() { | 882 function CallSiteIsNative() { |
| 879 var script = %FunctionGetScript(this.fun); | 883 var script = %FunctionGetScript(this[CallSiteFunctionKey]); |
| 880 return script ? (script.type == TYPE_NATIVE) : false; | 884 return script ? (script.type == TYPE_NATIVE) : false; |
| 881 } | 885 } |
| 882 | 886 |
| 883 function CallSiteGetPosition() { | 887 function CallSiteGetPosition() { |
| 884 return this.pos; | 888 return this[CallSitePositionKey]; |
| 885 } | 889 } |
| 886 | 890 |
| 887 function CallSiteIsConstructor() { | 891 function CallSiteIsConstructor() { |
| 888 var receiver = this.receiver; | 892 var receiver = this[CallSiteReceiverKey]; |
| 889 var constructor = | 893 var constructor = |
| 890 IS_OBJECT(receiver) ? %GetDataProperty(receiver, "constructor") : null; | 894 IS_OBJECT(receiver) ? %GetDataProperty(receiver, "constructor") : null; |
| 891 if (!constructor) return false; | 895 if (!constructor) return false; |
| 892 return this.fun === constructor; | 896 return this[CallSiteFunctionKey] === constructor; |
| 893 } | 897 } |
| 894 | 898 |
| 895 function CallSiteToString() { | 899 function CallSiteToString() { |
| 896 var fileName; | 900 var fileName; |
| 897 var fileLocation = ""; | 901 var fileLocation = ""; |
| 898 if (this.isNative()) { | 902 if (this.isNative()) { |
| 899 fileLocation = "native"; | 903 fileLocation = "native"; |
| 900 } else { | 904 } else { |
| 901 if (this.isEval()) { | 905 if (this.isEval()) { |
| 902 fileName = this.getScriptNameOrSourceURL(); | 906 fileName = this.getScriptNameOrSourceURL(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 925 } | 929 } |
| 926 } | 930 } |
| 927 } | 931 } |
| 928 | 932 |
| 929 var line = ""; | 933 var line = ""; |
| 930 var functionName = this.getFunctionName(); | 934 var functionName = this.getFunctionName(); |
| 931 var addSuffix = true; | 935 var addSuffix = true; |
| 932 var isConstructor = this.isConstructor(); | 936 var isConstructor = this.isConstructor(); |
| 933 var isMethodCall = !(this.isToplevel() || isConstructor); | 937 var isMethodCall = !(this.isToplevel() || isConstructor); |
| 934 if (isMethodCall) { | 938 if (isMethodCall) { |
| 935 var typeName = GetTypeName(this, true); | 939 var typeName = GetTypeName([CallSiteReceiverKey], true); |
| 936 var methodName = this.getMethodName(); | 940 var methodName = this.getMethodName(); |
| 937 if (functionName) { | 941 if (functionName) { |
| 938 if (typeName && | 942 if (typeName && |
| 939 %_CallFunction(functionName, typeName, StringIndexOf) != 0) { | 943 %_CallFunction(functionName, typeName, StringIndexOf) != 0) { |
| 940 line += typeName + "."; | 944 line += typeName + "."; |
| 941 } | 945 } |
| 942 line += functionName; | 946 line += functionName; |
| 943 if (methodName && | 947 if (methodName && |
| 944 (%_CallFunction(functionName, "." + methodName, StringIndexOf) != | 948 (%_CallFunction(functionName, "." + methodName, StringIndexOf) != |
| 945 functionName.length - methodName.length - 1)) { | 949 functionName.length - methodName.length - 1)) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1029 return "<error: " + e + ">"; | 1033 return "<error: " + e + ">"; |
| 1030 } catch (ee) { | 1034 } catch (ee) { |
| 1031 return "<error>"; | 1035 return "<error>"; |
| 1032 } | 1036 } |
| 1033 } | 1037 } |
| 1034 } | 1038 } |
| 1035 | 1039 |
| 1036 | 1040 |
| 1037 function GetStackFrames(raw_stack) { | 1041 function GetStackFrames(raw_stack) { |
| 1038 var frames = new InternalArray(); | 1042 var frames = new InternalArray(); |
| 1039 for (var i = 0; i < raw_stack.length; i += 4) { | 1043 var non_strict_frames = raw_stack[0]; |
| 1044 for (var i = 1; i < raw_stack.length; i += 4) { | |
| 1040 var recv = raw_stack[i]; | 1045 var recv = raw_stack[i]; |
| 1041 var fun = raw_stack[i + 1]; | 1046 var fun = raw_stack[i + 1]; |
| 1042 var code = raw_stack[i + 2]; | 1047 var code = raw_stack[i + 2]; |
| 1043 var pc = raw_stack[i + 3]; | 1048 var pc = raw_stack[i + 3]; |
| 1044 var pos = %FunctionGetPositionForOffset(code, pc); | 1049 var pos = %FunctionGetPositionForOffset(code, pc); |
| 1045 frames.push(new CallSite(recv, fun, pos)); | 1050 non_strict_frames--; |
| 1051 var strict_mode = (non_strict_frames < 0); | |
| 1052 frames.push(new CallSite(recv, fun, pos, strict_mode)); | |
|
rossberg
2013/03/28 10:04:33
Could inline def of strict_mode here.
| |
| 1046 } | 1053 } |
| 1047 return frames; | 1054 return frames; |
| 1048 } | 1055 } |
| 1049 | 1056 |
| 1050 | 1057 |
| 1051 function FormatStackTrace(error_string, frames) { | 1058 function FormatStackTrace(error_string, frames) { |
| 1052 var lines = new InternalArray(); | 1059 var lines = new InternalArray(); |
| 1053 lines.push(error_string); | 1060 lines.push(error_string); |
| 1054 for (var i = 0; i < frames.length; i++) { | 1061 for (var i = 0; i < frames.length; i++) { |
| 1055 var frame = frames[i]; | 1062 var frame = frames[i]; |
| 1056 var line; | 1063 var line; |
| 1057 try { | 1064 try { |
| 1058 line = frame.toString(); | 1065 line = frame.toString(); |
| 1059 } catch (e) { | 1066 } catch (e) { |
| 1060 try { | 1067 try { |
| 1061 line = "<error: " + e + ">"; | 1068 line = "<error: " + e + ">"; |
| 1062 } catch (ee) { | 1069 } catch (ee) { |
| 1063 // Any code that reaches this point is seriously nasty! | 1070 // Any code that reaches this point is seriously nasty! |
| 1064 line = "<error>"; | 1071 line = "<error>"; |
| 1065 } | 1072 } |
| 1066 } | 1073 } |
| 1067 lines.push(" at " + line); | 1074 lines.push(" at " + line); |
| 1068 } | 1075 } |
| 1069 return %_CallFunction(lines, "\n", ArrayJoin); | 1076 return %_CallFunction(lines, "\n", ArrayJoin); |
| 1070 } | 1077 } |
| 1071 | 1078 |
| 1072 | 1079 |
| 1073 function GetTypeName(obj, requireConstructor) { | 1080 function GetTypeName(receiver, requireConstructor) { |
| 1074 var constructor = obj.receiver.constructor; | 1081 var constructor = receiver.constructor; |
| 1075 if (!constructor) { | 1082 if (!constructor) { |
| 1076 return requireConstructor ? null : | 1083 return requireConstructor ? null : |
| 1077 %_CallFunction(obj.receiver, ObjectToString); | 1084 %_CallFunction(receiver, ObjectToString); |
| 1078 } | 1085 } |
| 1079 var constructorName = constructor.name; | 1086 var constructorName = constructor.name; |
| 1080 if (!constructorName) { | 1087 if (!constructorName) { |
| 1081 return requireConstructor ? null : | 1088 return requireConstructor ? null : |
| 1082 %_CallFunction(obj.receiver, ObjectToString); | 1089 %_CallFunction(receiver, ObjectToString); |
| 1083 } | 1090 } |
| 1084 return constructorName; | 1091 return constructorName; |
| 1085 } | 1092 } |
| 1086 | 1093 |
| 1087 | 1094 |
| 1088 // Flag to prevent recursive call of Error.prepareStackTrace. | 1095 // Flag to prevent recursive call of Error.prepareStackTrace. |
| 1089 var formatting_custom_stack_trace = false; | 1096 var formatting_custom_stack_trace = false; |
| 1090 | 1097 |
| 1091 | 1098 |
| 1092 function captureStackTrace(obj, cons_opt) { | 1099 function captureStackTrace(obj, cons_opt) { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1303 %SetOverflowedStackTrace(this, void 0); | 1310 %SetOverflowedStackTrace(this, void 0); |
| 1304 } | 1311 } |
| 1305 | 1312 |
| 1306 %DefineOrRedefineAccessorProperty( | 1313 %DefineOrRedefineAccessorProperty( |
| 1307 boilerplate, 'stack', getter, setter, DONT_ENUM); | 1314 boilerplate, 'stack', getter, setter, DONT_ENUM); |
| 1308 | 1315 |
| 1309 return boilerplate; | 1316 return boilerplate; |
| 1310 } | 1317 } |
| 1311 | 1318 |
| 1312 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); | 1319 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |
| OLD | NEW |