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 |