Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: runtime/vm/service.cc

Issue 98253009: Refactor VM service IDs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/service.h" 5 #include "vm/service.h"
6 6
7 #include "vm/cpu.h" 7 #include "vm/cpu.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/debugger.h" 9 #include "vm/debugger.h"
10 #include "vm/heap_histogram.h" 10 #include "vm/heap_histogram.h"
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 232
233 233
234 // Print an error message if there is no ID argument. 234 // Print an error message if there is no ID argument.
235 #define REQUIRE_COLLECTION_ID(collection) \ 235 #define REQUIRE_COLLECTION_ID(collection) \
236 if (js->num_arguments() == 1) { \ 236 if (js->num_arguments() == 1) { \
237 PrintError(js, "Must specify collection object id: /%s/id", collection); \ 237 PrintError(js, "Must specify collection object id: /%s/id", collection); \
238 return; \ 238 return; \
239 } 239 }
240 240
241 241
242 #define CHECK_COLLECTION_ID_BOUNDS(collection, length, arg, id, js) \
243 if (!GetIntegerId(arg, &id)) { \
244 PrintError(js, "Must specify collection object id: %s/id", collection); \
245 return; \
246 } \
247 if ((id < 0) || (id >= length)) { \
248 PrintError(js, "%s id (%" Pd ") must be in [0, %" Pd ").", collection, id, \
249 length); \
turnidge 2013/12/20 17:44:45 For discussion only - this message exposes that we
250 return; \
251 }
252
253
254 static bool GetIntegerId(const char* s, intptr_t* id) {
255 if ((s == NULL) || (*s == '\0')) {
256 // Empty string.
257 return false;
258 }
259 if (id == NULL) {
260 // No id pointer.
261 return false;
262 }
263 intptr_t r = 0;
264 char* end_ptr = NULL;
265 r = strtol(s, &end_ptr, 10);
266 if (end_ptr == s) {
267 // String was not advanced at all, cannot be valid.
268 return false;
269 }
270 *id = r;
271 return true;
272 }
273
274
275 static void HandleClassesClosures(Isolate* isolate, const Class& cls,
276 JSONStream* js) {
277 const GrowableObjectArray& closures =
278 GrowableObjectArray::Handle(cls.closures());
279 intptr_t id;
280 CHECK_COLLECTION_ID_BOUNDS("closures", closures.Length(), js->GetArgument(3),
281 id, js);
turnidge 2013/12/20 17:44:45 Add check that js->num_arguments() == 4 with nice
Cutch 2013/12/20 18:23:46 Done.
282 Function& function = Function::Handle();
283 function ^= closures.At(id);
284 ASSERT(!function.IsNull());
285 function.PrintToJSONStream(js, false);
286 }
287
288
289 static void HandleClassesFunctions(Isolate* isolate, const Class& cls,
290 JSONStream* js) {
291 const Array& functions =
292 Array::Handle(cls.functions());
293 intptr_t id;
294 CHECK_COLLECTION_ID_BOUNDS("functions", functions.Length(),
295 js->GetArgument(3), id, js);
296 Function& function = Function::Handle();
297 function ^= functions.At(id);
298 ASSERT(!function.IsNull());
299 function.PrintToJSONStream(js, false);
300 }
301
302
303 static void HandleClassesFields(Isolate* isolate, const Class& cls,
304 JSONStream* js) {
305 const Array& fields =
306 Array::Handle(cls.fields());
307 intptr_t id;
308 CHECK_COLLECTION_ID_BOUNDS("fields", fields.Length(), js->GetArgument(3),
309 id, js);
310 Field& field = Field::Handle();
311 field ^= fields.At(id);
312 ASSERT(!field.IsNull());
313 field.PrintToJSONStream(js, false);
314 }
315
316
242 static void HandleClasses(Isolate* isolate, JSONStream* js) { 317 static void HandleClasses(Isolate* isolate, JSONStream* js) {
243 if (js->num_arguments() == 1) { 318 if (js->num_arguments() == 1) {
244 ClassTable* table = isolate->class_table(); 319 ClassTable* table = isolate->class_table();
245 table->PrintToJSONStream(js); 320 table->PrintToJSONStream(js);
246 return; 321 return;
247 } 322 }
248 ASSERT(js->num_arguments() >= 2); 323 ASSERT(js->num_arguments() >= 2);
249 intptr_t id = atoi(js->GetArgument(1)); 324 intptr_t id;
325 if (!GetIntegerId(js->GetArgument(1), &id)) {
326 PrintError(js, "Must specify collection object id: /classes/id");
327 return;
328 }
250 ClassTable* table = isolate->class_table(); 329 ClassTable* table = isolate->class_table();
251 if (!table->IsValidIndex(id)) { 330 if (!table->IsValidIndex(id)) {
252 Object::null_object().PrintToJSONStream(js, false); 331 PrintError(js, "%" Pd " is not a valid class id.", id);;
253 } else { 332 return;
254 Class& cls = Class::Handle(table->At(id)); 333 }
334 Class& cls = Class::Handle(table->At(id));
335 if (js->num_arguments() == 2) {
255 cls.PrintToJSONStream(js, false); 336 cls.PrintToJSONStream(js, false);
337 return;
338 } else if (js->num_arguments() >= 3) {
339 const char* second = js->GetArgument(2);
340 if (!strcmp(second, "closures")) {
341 HandleClassesClosures(isolate, cls, js);
342 } else if (!strcmp(second, "fields")) {
343 HandleClassesFields(isolate, cls, js);
344 } else if (!strcmp(second, "functions")) {
345 HandleClassesFunctions(isolate, cls, js);
346 } else {
347 PrintError(js, "Invalid sub collection %s", second);
348 }
349 return;
256 } 350 }
351 UNREACHABLE();
257 } 352 }
258 353
259 354
260 static void HandleLibrary(Isolate* isolate, JSONStream* js) { 355 static void HandleLibrary(Isolate* isolate, JSONStream* js) {
261 if (js->num_arguments() == 1) { 356 if (js->num_arguments() == 1) {
262 const Library& lib = 357 const Library& lib =
263 Library::Handle(isolate->object_store()->root_library()); 358 Library::Handle(isolate->object_store()->root_library());
264 lib.PrintToJSONStream(js, false); 359 lib.PrintToJSONStream(js, false);
265 return; 360 return;
266 } 361 }
267 PrintGenericError(js); 362 PrintGenericError(js);
268 } 363 }
269 364
270 365
366 static void HandleLibraries(Isolate* isolate, JSONStream* js) {
367 // TODO(johnmccutchan): Support fields and functions on libraries.
368 REQUIRE_COLLECTION_ID("libraries");
369 const GrowableObjectArray& libs =
370 GrowableObjectArray::Handle(isolate->object_store()->libraries());
371 ASSERT(!libs.IsNull());
372 intptr_t id = 0;
373 CHECK_COLLECTION_ID_BOUNDS("libraries", libs.Length(), js->GetArgument(1),
374 id, js);
375 Library& lib = Library::Handle();
376 lib ^= libs.At(id);
377 ASSERT(!lib.IsNull());
378 lib.PrintToJSONStream(js, false);
379 }
380
381
271 static void HandleObjects(Isolate* isolate, JSONStream* js) { 382 static void HandleObjects(Isolate* isolate, JSONStream* js) {
272 REQUIRE_COLLECTION_ID("objects"); 383 REQUIRE_COLLECTION_ID("objects");
273 ASSERT(js->num_arguments() >= 2); 384 ASSERT(js->num_arguments() >= 2);
274 ObjectIdRing* ring = isolate->object_id_ring(); 385 ObjectIdRing* ring = isolate->object_id_ring();
275 ASSERT(ring != NULL); 386 ASSERT(ring != NULL);
276 intptr_t id = atoi(js->GetArgument(1)); 387 intptr_t id = -1;
388 if (!GetIntegerId(js->GetArgument(1), &id)) {
389 Object::null_object().PrintToJSONStream(js, false);
390 return;
391 }
277 Object& obj = Object::Handle(ring->GetObjectForId(id)); 392 Object& obj = Object::Handle(ring->GetObjectForId(id));
278 obj.PrintToJSONStream(js, false); 393 obj.PrintToJSONStream(js, false);
279 } 394 }
280 395
281 396
397
398 static void HandleScriptsEnumerate(Isolate* isolate, JSONStream* js) {
399 JSONObject jsobj(js);
400 jsobj.AddProperty("type", "ScriptList");
401 {
402 JSONArray members(&jsobj, "members");
403 const GrowableObjectArray& libs =
404 GrowableObjectArray::Handle(isolate->object_store()->libraries());
405 int num_libs = libs.Length();
406 Library &lib = Library::Handle();
407 Script& script = Script::Handle();
408 for (intptr_t i = 0; i < num_libs; i++) {
409 lib ^= libs.At(i);
410 ASSERT(!lib.IsNull());
411 ASSERT(Smi::IsValid(lib.index()));
412 const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
413 ASSERT(!loaded_scripts.IsNull());
414 intptr_t num_scripts = loaded_scripts.Length();
415 for (intptr_t i = 0; i < num_scripts; i++) {
416 script ^= loaded_scripts.At(i);
417 members.AddValue(script);
418 }
419 }
420 }
421 }
422
423
424 static void HandleScriptsFetch(Isolate* isolate, JSONStream* js) {
425 const GrowableObjectArray& libs =
426 GrowableObjectArray::Handle(isolate->object_store()->libraries());
427 int num_libs = libs.Length();
428 Library &lib = Library::Handle();
429 Script& script = Script::Handle();
430 String& url = String::Handle();
431 const String& id = String::Handle(String::New(js->GetArgument(1)));
432 ASSERT(!id.IsNull());
433 // The id is the url of the script % encoded, decode it.
434 String& requested_url = String::Handle(String::DecodeURI(id));
435 for (intptr_t i = 0; i < num_libs; i++) {
436 lib ^= libs.At(i);
437 ASSERT(!lib.IsNull());
438 ASSERT(Smi::IsValid(lib.index()));
439 const Array& loaded_scripts = Array::Handle(lib.LoadedScripts());
440 ASSERT(!loaded_scripts.IsNull());
441 intptr_t num_scripts = loaded_scripts.Length();
442 for (intptr_t i = 0; i < num_scripts; i++) {
443 script ^= loaded_scripts.At(i);
444 ASSERT(!script.IsNull());
445 url ^= script.url();
446 if (url.Equals(requested_url)) {
447 script.PrintToJSONStream(js, false);
448 return;
449 }
450 }
451 }
452 PrintError(js, "Cannot find script %s\n", requested_url.ToCString());
453 }
454
455
456 static void HandleScripts(Isolate* isolate, JSONStream* js) {
457 if (js->num_arguments() == 1) {
458 // Enumerate all scripts.
459 HandleScriptsEnumerate(isolate, js);
460 } else if (js->num_arguments() == 2) {
461 // Fetch specific script.
462 HandleScriptsFetch(isolate, js);
463 } else {
464 PrintError(js, "Command too long");
465 }
466 }
467
468
282 static void HandleDebug(Isolate* isolate, JSONStream* js) { 469 static void HandleDebug(Isolate* isolate, JSONStream* js) {
283 if (js->num_arguments() == 1) { 470 if (js->num_arguments() == 1) {
284 PrintError(js, "Must specify a subcommand"); 471 PrintError(js, "Must specify a subcommand");
285 return; 472 return;
286 } 473 }
287 const char* command = js->GetArgument(1); 474 const char* command = js->GetArgument(1);
288 if (!strcmp(command, "breakpoints")) { 475 if (!strcmp(command, "breakpoints")) {
289 if (js->num_arguments() == 2) { 476 if (js->num_arguments() == 2) {
290 // Print breakpoint list. 477 // Print breakpoint list.
291 JSONObject jsobj(js); 478 JSONObject jsobj(js);
292 jsobj.AddProperty("type", "BreakpointList"); 479 jsobj.AddProperty("type", "BreakpointList");
293 JSONArray jsarr(&jsobj, "breakpoints"); 480 JSONArray jsarr(&jsobj, "breakpoints");
294 isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr); 481 isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr);
295 482
296 } else if (js->num_arguments() == 3) { 483 } else if (js->num_arguments() == 3) {
297 // Print individual breakpoint. 484 // Print individual breakpoint.
298 intptr_t id = atoi(js->GetArgument(2)); 485 intptr_t id = 0;
299 SourceBreakpoint* bpt = isolate->debugger()->GetBreakpointById(id); 486 SourceBreakpoint* bpt = NULL;
487 if (GetIntegerId(js->GetArgument(2), &id)) {
488 bpt = isolate->debugger()->GetBreakpointById(id);
489 }
300 if (bpt != NULL) { 490 if (bpt != NULL) {
301 bpt->PrintToJSONStream(js); 491 bpt->PrintToJSONStream(js);
302 } else { 492 } else {
303 PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2)); 493 PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2));
304 } 494 }
305 495
306 } else { 496 } else {
307 PrintError(js, "Command too long"); 497 PrintError(js, "Command too long");
308 } 498 }
309 } else { 499 } else {
310 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); 500 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1));
311 } 501 }
312 } 502 }
313 503
314 504
315 static void HandleCpu(Isolate* isolate, JSONStream* js) { 505 static void HandleCpu(Isolate* isolate, JSONStream* js) {
316 JSONObject jsobj(js); 506 JSONObject jsobj(js);
317 jsobj.AddProperty("type", "CPU"); 507 jsobj.AddProperty("type", "CPU");
318 jsobj.AddProperty("architecture", CPU::Id()); 508 jsobj.AddProperty("architecture", CPU::Id());
319 } 509 }
320 510
321 511
322 static ServiceMessageHandlerEntry __message_handlers[] = { 512 static ServiceMessageHandlerEntry __message_handlers[] = {
323 { "_echo", HandleEcho }, 513 { "_echo", HandleEcho },
324 { "classes", HandleClasses }, 514 { "classes", HandleClasses },
325 { "cpu", HandleCpu }, 515 { "cpu", HandleCpu },
326 { "debug", HandleDebug }, 516 { "debug", HandleDebug },
517 { "libraries", HandleLibraries },
327 { "library", HandleLibrary }, 518 { "library", HandleLibrary },
328 { "name", HandleName }, 519 { "name", HandleName },
329 { "objecthistogram", HandleObjectHistogram}, 520 { "objecthistogram", HandleObjectHistogram},
330 { "objects", HandleObjects }, 521 { "objects", HandleObjects },
522 { "scripts", HandleScripts },
331 { "stacktrace", HandleStackTrace }, 523 { "stacktrace", HandleStackTrace },
332 }; 524 };
333 525
334 526
335 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { 527 static void HandleFallthrough(Isolate* isolate, JSONStream* js) {
336 JSONObject jsobj(js); 528 JSONObject jsobj(js);
337 jsobj.AddProperty("type", "Error"); 529 jsobj.AddProperty("type", "Error");
338 jsobj.AddProperty("text", "request not understood."); 530 jsobj.AddProperty("text", "request not understood.");
339 PrintArgumentsAndOptions(jsobj, js); 531 PrintArgumentsAndOptions(jsobj, js);
340 } 532 }
341 533
342 534
343 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { 535 static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
344 intptr_t num_message_handlers = sizeof(__message_handlers) / 536 intptr_t num_message_handlers = sizeof(__message_handlers) /
345 sizeof(__message_handlers[0]); 537 sizeof(__message_handlers[0]);
346 for (intptr_t i = 0; i < num_message_handlers; i++) { 538 for (intptr_t i = 0; i < num_message_handlers; i++) {
347 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; 539 const ServiceMessageHandlerEntry& entry = __message_handlers[i];
348 if (!strcmp(command, entry.command)) { 540 if (!strcmp(command, entry.command)) {
349 return entry.handler; 541 return entry.handler;
350 } 542 }
351 } 543 }
352 return HandleFallthrough; 544 return HandleFallthrough;
353 } 545 }
354 546
355 } // namespace dart 547 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698