| 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 |