| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 NewFunctionEvent.prototype.setBreakPoint = function(p) { | 884 NewFunctionEvent.prototype.setBreakPoint = function(p) { |
| 885 Debug.setBreakPoint(this.func, p || 0); | 885 Debug.setBreakPoint(this.func, p || 0); |
| 886 }; | 886 }; |
| 887 | 887 |
| 888 | 888 |
| 889 function DebugCommandProcessor(exec_state) { | 889 function DebugCommandProcessor(exec_state) { |
| 890 this.exec_state_ = exec_state; | 890 this.exec_state_ = exec_state; |
| 891 }; | 891 }; |
| 892 | 892 |
| 893 | 893 |
| 894 // Convenience function for C debugger code to process a text command. This | 894 DebugCommandProcessor.prototype.processDebugRequest = function (request) { |
| 895 // function converts the text command to a JSON request, performs the request | 895 return this.processDebugJSONRequest(request); |
| 896 // and converts the request to a text result for display. The result is an | |
| 897 // object containing the text result and the intermediate results. | |
| 898 DebugCommandProcessor.prototype.processDebugCommand = function (command) { | |
| 899 var request; | |
| 900 var response; | |
| 901 var text_result; | |
| 902 var running; | |
| 903 | |
| 904 request = this.commandToJSONRequest(command); | |
| 905 response = this.processDebugJSONRequest(request); | |
| 906 text_result = this.responseToText(response); | |
| 907 running = this.isRunning(response); | |
| 908 | |
| 909 return { "request" : request, | |
| 910 "response" : response, | |
| 911 "text_result" : text_result, | |
| 912 "running" : running }; | |
| 913 } | 896 } |
| 914 | 897 |
| 915 | 898 |
| 916 // Converts a text command to a JSON request. | 899 DebugCommandProcessor.prototype.responseIsRunning = function (response) { |
| 917 DebugCommandProcessor.prototype.commandToJSONRequest = function(cmd_line) { | 900 return this.isRunning(response); |
| 918 // If the wery first character is a { assume that a JSON request have been | |
| 919 // entered as a command. Converting that to a JSON request is trivial. | |
| 920 if (cmd_line && cmd_line.length > 0 && cmd_line.charAt(0) == '{') { | |
| 921 return cmd_line; | |
| 922 } | |
| 923 | |
| 924 // Trim string for leading and trailing whitespace. | |
| 925 cmd_line = cmd_line.replace(/^\s+|\s+$/g, ""); | |
| 926 | |
| 927 // Find the command. | |
| 928 var pos = cmd_line.indexOf(" "); | |
| 929 var cmd; | |
| 930 var args; | |
| 931 if (pos == -1) { | |
| 932 cmd = cmd_line; | |
| 933 args = ""; | |
| 934 } else { | |
| 935 cmd = cmd_line.slice(0, pos); | |
| 936 args = cmd_line.slice(pos).replace(/^\s+|\s+$/g, ""); | |
| 937 } | |
| 938 | |
| 939 // Switch on command. | |
| 940 if (cmd == 'continue' || cmd == 'c') { | |
| 941 return this.continueCommandToJSONRequest_(args); | |
| 942 } else if (cmd == 'step' || cmd == 's') { | |
| 943 return this.stepCommandToJSONRequest_(args); | |
| 944 } else if (cmd == 'backtrace' || cmd == 'bt') { | |
| 945 return this.backtraceCommandToJSONRequest_(args); | |
| 946 } else if (cmd == 'frame' || cmd == 'f') { | |
| 947 return this.frameCommandToJSONRequest_(args); | |
| 948 } else if (cmd == 'print' || cmd == 'p') { | |
| 949 return this.printCommandToJSONRequest_(args); | |
| 950 } else if (cmd == 'source') { | |
| 951 return this.sourceCommandToJSONRequest_(args); | |
| 952 } else if (cmd == 'scripts') { | |
| 953 return this.scriptsCommandToJSONRequest_(args); | |
| 954 } else if (cmd[0] == '{') { | |
| 955 return cmd_line; | |
| 956 } else { | |
| 957 throw new Error('Unknown command "' + cmd + '"'); | |
| 958 } | |
| 959 }; | |
| 960 | |
| 961 | |
| 962 // Create a JSON request for the continue command. | |
| 963 DebugCommandProcessor.prototype.continueCommandToJSONRequest_ = function(args) { | |
| 964 var request = this.createRequest('continue'); | |
| 965 return request.toJSONProtocol(); | |
| 966 }; | |
| 967 | |
| 968 | |
| 969 // Create a JSON request for the step command. | |
| 970 DebugCommandProcessor.prototype.stepCommandToJSONRequest_ = function(args) { | |
| 971 // Requesting a step is through the continue command with additional | |
| 972 // arguments. | |
| 973 var request = this.createRequest('continue'); | |
| 974 request.arguments = {}; | |
| 975 | |
| 976 // Process arguments if any. | |
| 977 if (args && args.length > 0) { | |
| 978 args = args.split(/\s*[ ]+\s*/g); | |
| 979 | |
| 980 if (args.length > 2) { | |
| 981 throw new Error('Invalid step arguments.'); | |
| 982 } | |
| 983 | |
| 984 if (args.length > 0) { | |
| 985 // Get step count argument if any. | |
| 986 if (args.length == 2) { | |
| 987 request.arguments.stepcount = %ToNumber(args[1]); | |
| 988 } | |
| 989 | |
| 990 // Get the step action. | |
| 991 if (args[0] == 'in' || args[0] == 'i') { | |
| 992 request.arguments.stepaction = 'in'; | |
| 993 } else if (args[0] == 'min' || args[0] == 'm') { | |
| 994 request.arguments.stepaction = 'min'; | |
| 995 } else if (args[0] == 'next' || args[0] == 'n') { | |
| 996 request.arguments.stepaction = 'next'; | |
| 997 } else if (args[0] == 'out' || args[0] == 'o') { | |
| 998 request.arguments.stepaction = 'out'; | |
| 999 } else { | |
| 1000 throw new Error('Invalid step argument "' + args[0] + '".'); | |
| 1001 } | |
| 1002 } | |
| 1003 } else { | |
| 1004 // Default is step next. | |
| 1005 request.arguments.stepaction = 'next'; | |
| 1006 } | |
| 1007 | |
| 1008 return request.toJSONProtocol(); | |
| 1009 }; | |
| 1010 | |
| 1011 | |
| 1012 // Create a JSON request for the backtrace command. | |
| 1013 DebugCommandProcessor.prototype.backtraceCommandToJSONRequest_ = function(args)
{ | |
| 1014 // Build a backtrace request from the text command. | |
| 1015 var request = this.createRequest('backtrace'); | |
| 1016 args = args.split(/\s*[ ]+\s*/g); | |
| 1017 if (args.length == 2) { | |
| 1018 request.arguments = {}; | |
| 1019 request.arguments.fromFrame = %ToNumber(args[0]); | |
| 1020 request.arguments.toFrame = %ToNumber(args[1]) + 1; | |
| 1021 } | |
| 1022 return request.toJSONProtocol(); | |
| 1023 }; | |
| 1024 | |
| 1025 | |
| 1026 // Create a JSON request for the frame command. | |
| 1027 DebugCommandProcessor.prototype.frameCommandToJSONRequest_ = function(args) { | |
| 1028 // Build a frame request from the text command. | |
| 1029 var request = this.createRequest('frame'); | |
| 1030 args = args.split(/\s*[ ]+\s*/g); | |
| 1031 if (args.length > 0 && args[0].length > 0) { | |
| 1032 request.arguments = {}; | |
| 1033 request.arguments.number = args[0]; | |
| 1034 } | |
| 1035 return request.toJSONProtocol(); | |
| 1036 }; | |
| 1037 | |
| 1038 | |
| 1039 // Create a JSON request for the print command. | |
| 1040 DebugCommandProcessor.prototype.printCommandToJSONRequest_ = function(args) { | |
| 1041 // Build a evaluate request from the text command. | |
| 1042 var request = this.createRequest('evaluate'); | |
| 1043 if (args.length == 0) { | |
| 1044 throw new Error('Missing expression.'); | |
| 1045 } | |
| 1046 | |
| 1047 request.arguments = {}; | |
| 1048 request.arguments.expression = args; | |
| 1049 | |
| 1050 return request.toJSONProtocol(); | |
| 1051 }; | |
| 1052 | |
| 1053 | |
| 1054 // Create a JSON request for the source command. | |
| 1055 DebugCommandProcessor.prototype.sourceCommandToJSONRequest_ = function(args) { | |
| 1056 // Build a evaluate request from the text command. | |
| 1057 var request = this.createRequest('source'); | |
| 1058 | |
| 1059 // Default is one line before and two lines after current location. | |
| 1060 var before = 1; | |
| 1061 var after = 2; | |
| 1062 | |
| 1063 // Parse the arguments. | |
| 1064 args = args.split(/\s*[ ]+\s*/g); | |
| 1065 if (args.length > 1 && args[0].length > 0 && args[1].length > 0) { | |
| 1066 before = %ToNumber(args[0]); | |
| 1067 after = %ToNumber(args[1]); | |
| 1068 } else if (args.length > 0 && args[0].length > 0) { | |
| 1069 after = %ToNumber(args[0]); | |
| 1070 } | |
| 1071 | |
| 1072 // Request source arround current source location. | |
| 1073 request.arguments = {}; | |
| 1074 request.arguments.fromLine = this.exec_state_.frame().sourceLine() - before; | |
| 1075 if (request.arguments.fromLine < 0) { | |
| 1076 request.arguments.fromLine = 0 | |
| 1077 } | |
| 1078 request.arguments.toLine = this.exec_state_.frame().sourceLine() + after + 1; | |
| 1079 | |
| 1080 return request.toJSONProtocol(); | |
| 1081 }; | |
| 1082 | |
| 1083 | |
| 1084 // Create a JSON request for the scripts command. | |
| 1085 DebugCommandProcessor.prototype.scriptsCommandToJSONRequest_ = function(args) { | |
| 1086 // Build a evaluate request from the text command. | |
| 1087 var request = this.createRequest('scripts'); | |
| 1088 | |
| 1089 // Process arguments if any. | |
| 1090 if (args && args.length > 0) { | |
| 1091 args = args.split(/\s*[ ]+\s*/g); | |
| 1092 | |
| 1093 if (args.length > 1) { | |
| 1094 throw new Error('Invalid scripts arguments.'); | |
| 1095 } | |
| 1096 | |
| 1097 request.arguments = {}; | |
| 1098 if (args[0] == 'natives') { | |
| 1099 request.arguments.types = ScriptTypeFlag(Debug.ScriptType.Native); | |
| 1100 } else if (args[0] == 'extensions') { | |
| 1101 request.arguments.types = ScriptTypeFlag(Debug.ScriptType.Extension); | |
| 1102 } else if (args[0] == 'all') { | |
| 1103 request.arguments.types = | |
| 1104 ScriptTypeFlag(Debug.ScriptType.Normal) | | |
| 1105 ScriptTypeFlag(Debug.ScriptType.Native) | | |
| 1106 ScriptTypeFlag(Debug.ScriptType.Extension); | |
| 1107 } else { | |
| 1108 throw new Error('Invalid argument "' + args[0] + '".'); | |
| 1109 } | |
| 1110 } | |
| 1111 | |
| 1112 return request.toJSONProtocol(); | |
| 1113 }; | |
| 1114 | |
| 1115 | |
| 1116 // Convert a JSON response to text for display in a text based debugger. | |
| 1117 DebugCommandProcessor.prototype.responseToText = function(json_response) { | |
| 1118 try { | |
| 1119 // Convert the JSON string to an object. | |
| 1120 response = %CompileString('(' + json_response + ')', 0, false)(); | |
| 1121 | |
| 1122 if (!response.success) { | |
| 1123 return response.message; | |
| 1124 } | |
| 1125 | |
| 1126 if (response.command == 'backtrace') { | |
| 1127 var body = response.body; | |
| 1128 var result = 'Frames #' + body.fromFrame + ' to #' + | |
| 1129 (body.toFrame - 1) + ' of ' + body.totalFrames + '\n'; | |
| 1130 for (i = 0; i < body.frames.length; i++) { | |
| 1131 if (i != 0) result += '\n'; | |
| 1132 result += body.frames[i].text; | |
| 1133 } | |
| 1134 return result; | |
| 1135 } else if (response.command == 'frame') { | |
| 1136 return SourceUnderline(response.body.sourceLineText, | |
| 1137 response.body.column); | |
| 1138 } else if (response.command == 'evaluate') { | |
| 1139 return response.body.text; | |
| 1140 } else if (response.command == 'source') { | |
| 1141 // Get the source from the response. | |
| 1142 var source = response.body.source; | |
| 1143 | |
| 1144 // Get rid of last line terminator. | |
| 1145 var remove_count = 0; | |
| 1146 if (source[source.length - 1] == '\n') remove_count++; | |
| 1147 if (source[source.length - 2] == '\r') remove_count++; | |
| 1148 if (remove_count > 0) source = source.substring(0, source.length - remove_
count); | |
| 1149 | |
| 1150 return source; | |
| 1151 } else if (response.command == 'scripts') { | |
| 1152 var result = ''; | |
| 1153 for (i = 0; i < response.body.length; i++) { | |
| 1154 if (i != 0) result += '\n'; | |
| 1155 if (response.body[i].name) { | |
| 1156 result += response.body[i].name; | |
| 1157 } else { | |
| 1158 result += '[unnamed] '; | |
| 1159 var sourceStart = response.body[i].sourceStart; | |
| 1160 if (sourceStart.length > 40) { | |
| 1161 sourceStart = sourceStart.substring(0, 37) + '...'; | |
| 1162 } | |
| 1163 result += sourceStart; | |
| 1164 } | |
| 1165 result += ' (lines: '; | |
| 1166 result += response.body[i].sourceLines; | |
| 1167 result += ', length: '; | |
| 1168 result += response.body[i].sourceLength; | |
| 1169 if (response.body[i].type == Debug.ScriptType.Native) { | |
| 1170 result += ', native'; | |
| 1171 } else if (response.body[i].type == Debug.ScriptType.Extension) { | |
| 1172 result += ', extension'; | |
| 1173 } | |
| 1174 result += ')'; | |
| 1175 } | |
| 1176 return result; | |
| 1177 } | |
| 1178 } catch (e) { | |
| 1179 return 'Error: "' + %ToString(e) + '" formatting response'; | |
| 1180 } | |
| 1181 }; | |
| 1182 | |
| 1183 | |
| 1184 function SourceUnderline(source_text, position) { | |
| 1185 if (IS_UNDEFINED(source_text)) { | |
| 1186 return; | |
| 1187 } | |
| 1188 | |
| 1189 // Create an underline with a caret pointing to the source position. If the | |
| 1190 // source contains a tab character the underline will have a tab character in | |
| 1191 // the same place otherwise the underline will have a space character. | |
| 1192 var underline = ''; | |
| 1193 for (var i = 0; i < position; i++) { | |
| 1194 if (source_text[i] == '\t') { | |
| 1195 underline += '\t'; | |
| 1196 } else { | |
| 1197 underline += ' '; | |
| 1198 } | |
| 1199 } | |
| 1200 underline += '^'; | |
| 1201 | |
| 1202 // Return the source line text with the underline beneath. | |
| 1203 return source_text + '\n' + underline; | |
| 1204 } | |
| 1205 | |
| 1206 | |
| 1207 function FrameSourceUnderline(frame) { | |
| 1208 var location = frame.sourceLocation(); | |
| 1209 if (location) { | |
| 1210 return SourceUnderline(location.sourceText(), location.position - location.s
tart); | |
| 1211 } | |
| 1212 } | 901 } |
| 1213 | 902 |
| 1214 | 903 |
| 1215 function RequestPacket(command) { | 904 function RequestPacket(command) { |
| 1216 this.seq = 0; | 905 this.seq = 0; |
| 1217 this.type = 'request'; | 906 this.type = 'request'; |
| 1218 this.command = command; | 907 this.command = command; |
| 1219 } | 908 } |
| 1220 | 909 |
| 1221 | 910 |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1908 json += NumberToJSON_(elem); | 1597 json += NumberToJSON_(elem); |
| 1909 } else if (IS_STRING(elem)) { | 1598 } else if (IS_STRING(elem)) { |
| 1910 json += StringToJSON_(elem); | 1599 json += StringToJSON_(elem); |
| 1911 } else { | 1600 } else { |
| 1912 json += elem; | 1601 json += elem; |
| 1913 } | 1602 } |
| 1914 } | 1603 } |
| 1915 json += ']'; | 1604 json += ']'; |
| 1916 return json; | 1605 return json; |
| 1917 } | 1606 } |
| OLD | NEW |