OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
6 #include "vm/heap_histogram.h" | 6 #include "vm/heap_histogram.h" |
7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
8 #include "vm/message.h" | 8 #include "vm/message.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/object_id_ring.h" |
| 11 #include "vm/object_store.h" |
10 #include "vm/port.h" | 12 #include "vm/port.h" |
11 #include "vm/service.h" | 13 #include "vm/service.h" |
12 | 14 |
13 namespace dart { | 15 namespace dart { |
14 | 16 |
15 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); | 17 typedef void (*ServiceMessageHandler)(Isolate* isolate, JSONStream* stream); |
16 | 18 |
17 struct ServiceMessageHandlerEntry { | 19 struct ServiceMessageHandlerEntry { |
18 const char* command; | 20 const char* command; |
19 ServiceMessageHandler handler; | 21 ServiceMessageHandler handler; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 | 111 |
110 handler(isolate, &js); | 112 handler(isolate, &js); |
111 const String& reply = String::Handle(String::New(buffer.buf())); | 113 const String& reply = String::Handle(String::New(buffer.buf())); |
112 ASSERT(!reply.IsNull()); | 114 ASSERT(!reply.IsNull()); |
113 PostReply(reply, reply_port); | 115 PostReply(reply, reply_port); |
114 } | 116 } |
115 } | 117 } |
116 } | 118 } |
117 | 119 |
118 | 120 |
| 121 static void PrintArgumentsAndOptions(JSONStream* js) { |
| 122 js->OpenObject("message"); |
| 123 js->OpenArray("arguments"); |
| 124 for (intptr_t i = 0; i < js->num_arguments(); i++) { |
| 125 js->PrintValue(js->GetArgument(i)); |
| 126 } |
| 127 js->CloseArray(); |
| 128 js->OpenArray("option_keys"); |
| 129 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 130 js->PrintValue(js->GetOptionKey(i)); |
| 131 } |
| 132 js->CloseArray(); |
| 133 js->OpenArray("option_values"); |
| 134 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 135 js->PrintValue(js->GetOptionValue(i)); |
| 136 } |
| 137 js->CloseArray(); |
| 138 js->CloseObject(); |
| 139 } |
| 140 |
| 141 |
| 142 static void PrintCollectionErrorResponse(const char* collection_name, |
| 143 JSONStream* js) { |
| 144 js->OpenObject(); |
| 145 js->PrintProperty("type", "error"); |
| 146 js->PrintfProperty("text", "Must specify collection object id: /%s/id", |
| 147 collection_name); |
| 148 js->CloseObject(); |
| 149 } |
| 150 |
| 151 |
119 static void HandleName(Isolate* isolate, JSONStream* js) { | 152 static void HandleName(Isolate* isolate, JSONStream* js) { |
120 js->OpenObject(); | 153 js->OpenObject(); |
121 js->PrintProperty("type", "IsolateName"); | 154 js->PrintProperty("type", "IsolateName"); |
122 js->PrintProperty("id", static_cast<intptr_t>(isolate->main_port())); | 155 js->PrintProperty("id", static_cast<intptr_t>(isolate->main_port())); |
123 js->PrintProperty("name", isolate->name()); | 156 js->PrintProperty("name", isolate->name()); |
124 js->CloseObject(); | 157 js->CloseObject(); |
125 } | 158 } |
126 | 159 |
127 | 160 |
128 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { | 161 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { |
(...skipping 18 matching lines...) Expand all Loading... |
147 } | 180 } |
148 js->CloseArray(); | 181 js->CloseArray(); |
149 js->CloseObject(); | 182 js->CloseObject(); |
150 } | 183 } |
151 | 184 |
152 | 185 |
153 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { | 186 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { |
154 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); | 187 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); |
155 if (histogram == NULL) { | 188 if (histogram == NULL) { |
156 js->OpenObject(); | 189 js->OpenObject(); |
157 js->PrintProperty("type", "ObjectHistogram"); | 190 js->PrintProperty("type", "error"); |
158 js->PrintProperty("error", "Run with --print_object_histogram"); | 191 js->PrintProperty("text", "Run with --print_object_histogram"); |
159 js->CloseObject(); | 192 js->CloseObject(); |
160 return; | 193 return; |
161 } | 194 } |
162 histogram->PrintToJSONStream(js); | 195 histogram->PrintToJSONStream(js); |
163 } | 196 } |
164 | 197 |
165 | 198 |
166 static void PrintArgumentsAndOptions(JSONStream* js) { | |
167 js->OpenObject("message"); | |
168 js->OpenArray("arguments"); | |
169 for (intptr_t i = 0; i < js->num_arguments(); i++) { | |
170 js->PrintValue(js->GetArgument(i)); | |
171 } | |
172 js->CloseArray(); | |
173 js->OpenArray("option_keys"); | |
174 for (intptr_t i = 0; i < js->num_options(); i++) { | |
175 js->PrintValue(js->GetOptionKey(i)); | |
176 } | |
177 js->CloseArray(); | |
178 js->OpenArray("option_values"); | |
179 for (intptr_t i = 0; i < js->num_options(); i++) { | |
180 js->PrintValue(js->GetOptionValue(i)); | |
181 } | |
182 js->CloseArray(); | |
183 js->CloseObject(); | |
184 } | |
185 | |
186 | |
187 static void HandleEcho(Isolate* isolate, JSONStream* js) { | 199 static void HandleEcho(Isolate* isolate, JSONStream* js) { |
188 js->OpenObject(); | 200 js->OpenObject(); |
189 js->PrintProperty("type", "message"); | 201 js->PrintProperty("type", "message"); |
190 PrintArgumentsAndOptions(js); | 202 PrintArgumentsAndOptions(js); |
191 js->CloseObject(); | 203 js->CloseObject(); |
192 } | 204 } |
193 | 205 |
| 206 // Print an error message if there is no ID argument. |
| 207 #define REQUIRE_COLLECTION_ID(collection) \ |
| 208 if (js->num_arguments() == 1) { \ |
| 209 PrintCollectionErrorResponse(collection, js); \ |
| 210 return; \ |
| 211 } |
| 212 |
| 213 // Print a Dart object to the stream if found in ring. Otherwise print null. |
| 214 #define PRINT_RING_OBJ(type) \ |
| 215 ASSERT(js->num_arguments() >= 2); \ |
| 216 ObjectIdRing* ring = isolate->object_id_ring(); \ |
| 217 ASSERT(ring != NULL); \ |
| 218 intptr_t id = atoi(js->GetArgument(1)); \ |
| 219 Object& obj = Object::Handle(ring->GetObjectForId(id)); \ |
| 220 if (!obj.Is##type()) { \ |
| 221 /* Object is not type, replace with null. */ \ |
| 222 obj = Object::null(); \ |
| 223 } \ |
| 224 js->PrintValue(obj, false) |
| 225 |
| 226 |
| 227 static void HandleLibraries(Isolate* isolate, JSONStream* js) { |
| 228 if (js->num_arguments() == 1) { |
| 229 js->PrintValue(Library::Handle(isolate->object_store()->root_library())); |
| 230 return; |
| 231 } |
| 232 PRINT_RING_OBJ(Library); |
| 233 } |
| 234 |
| 235 |
| 236 static void HandleFunctions(Isolate* isolate, JSONStream* js) { |
| 237 REQUIRE_COLLECTION_ID("functions"); |
| 238 PRINT_RING_OBJ(Function); |
| 239 } |
| 240 |
| 241 |
| 242 static void HandleClasses(Isolate* isolate, JSONStream* js) { |
| 243 REQUIRE_COLLECTION_ID("classes"); |
| 244 PRINT_RING_OBJ(Class); |
| 245 } |
| 246 |
| 247 |
| 248 static void HandleCodes(Isolate* isolate, JSONStream* js) { |
| 249 REQUIRE_COLLECTION_ID("codes"); |
| 250 PRINT_RING_OBJ(Code); |
| 251 } |
| 252 |
194 | 253 |
195 static ServiceMessageHandlerEntry __message_handlers[] = { | 254 static ServiceMessageHandlerEntry __message_handlers[] = { |
196 { "name", HandleName }, | 255 { "name", HandleName }, |
197 { "stacktrace", HandleStackTrace }, | 256 { "stacktrace", HandleStackTrace }, |
198 { "objecthistogram", HandleObjectHistogram}, | 257 { "objecthistogram", HandleObjectHistogram}, |
| 258 { "libraries", HandleLibraries }, |
| 259 { "functions", HandleFunctions }, |
| 260 { "classes", HandleClasses }, |
| 261 { "codes", HandleCodes }, |
199 { "_echo", HandleEcho }, | 262 { "_echo", HandleEcho }, |
200 }; | 263 }; |
201 | 264 |
202 | 265 |
203 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { | 266 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { |
204 js->OpenObject(); | 267 js->OpenObject(); |
205 js->PrintProperty("type", "error"); | 268 js->PrintProperty("type", "error"); |
206 js->PrintProperty("text", "request not understood."); | 269 js->PrintProperty("text", "request not understood."); |
207 PrintArgumentsAndOptions(js); | 270 PrintArgumentsAndOptions(js); |
208 js->CloseObject(); | 271 js->CloseObject(); |
209 } | 272 } |
210 | 273 |
211 | 274 |
212 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { | 275 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { |
213 intptr_t num_message_handlers = sizeof(__message_handlers) / | 276 intptr_t num_message_handlers = sizeof(__message_handlers) / |
214 sizeof(__message_handlers[0]); | 277 sizeof(__message_handlers[0]); |
215 for (intptr_t i = 0; i < num_message_handlers; i++) { | 278 for (intptr_t i = 0; i < num_message_handlers; i++) { |
216 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; | 279 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; |
217 if (!strcmp(command, entry.command)) { | 280 if (!strcmp(command, entry.command)) { |
218 return entry.handler; | 281 return entry.handler; |
219 } | 282 } |
220 } | 283 } |
221 return HandleFallthrough; | 284 return HandleFallthrough; |
222 } | 285 } |
223 | 286 |
224 } // namespace dart | 287 } // namespace dart |
OLD | NEW |