| 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/service.h" | 5 #include "vm/service.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/coverage.h" | 10 #include "vm/coverage.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "vm/object_id_ring.h" | 21 #include "vm/object_id_ring.h" |
| 22 #include "vm/object_store.h" | 22 #include "vm/object_store.h" |
| 23 #include "vm/port.h" | 23 #include "vm/port.h" |
| 24 #include "vm/profiler.h" | 24 #include "vm/profiler.h" |
| 25 #include "vm/stack_frame.h" | 25 #include "vm/stack_frame.h" |
| 26 #include "vm/symbols.h" | 26 #include "vm/symbols.h" |
| 27 | 27 |
| 28 | 28 |
| 29 namespace dart { | 29 namespace dart { |
| 30 | 30 |
| 31 DEFINE_FLAG(bool, trace_service, false, "Trace VM service requests."); |
| 32 |
| 31 struct ResourcesEntry { | 33 struct ResourcesEntry { |
| 32 const char* path_; | 34 const char* path_; |
| 33 const char* resource_; | 35 const char* resource_; |
| 34 int length_; | 36 int length_; |
| 35 }; | 37 }; |
| 36 | 38 |
| 37 extern ResourcesEntry __service_resources_[]; | 39 extern ResourcesEntry __service_resources_[]; |
| 38 | 40 |
| 39 class Resources { | 41 class Resources { |
| 40 public: | 42 public: |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 typedef bool (*RootMessageHandler)(JSONStream* stream); | 434 typedef bool (*RootMessageHandler)(JSONStream* stream); |
| 433 | 435 |
| 434 struct RootMessageHandlerEntry { | 436 struct RootMessageHandlerEntry { |
| 435 const char* command; | 437 const char* command; |
| 436 RootMessageHandler handler; | 438 RootMessageHandler handler; |
| 437 }; | 439 }; |
| 438 | 440 |
| 439 static RootMessageHandler FindRootMessageHandler(const char* command); | 441 static RootMessageHandler FindRootMessageHandler(const char* command); |
| 440 | 442 |
| 441 | 443 |
| 442 static void PostReply(JSONStream* js) { | |
| 443 Dart_Port reply_port = js->reply_port(); | |
| 444 ASSERT(reply_port != ILLEGAL_PORT); | |
| 445 js->set_reply_port(ILLEGAL_PORT); // Prevent double replies. | |
| 446 | |
| 447 const String& reply = String::Handle(String::New(js->ToCString())); | |
| 448 ASSERT(!reply.IsNull()); | |
| 449 | |
| 450 uint8_t* data = NULL; | |
| 451 MessageWriter writer(&data, &allocator); | |
| 452 writer.WriteMessage(reply); | |
| 453 PortMap::PostMessage(new Message(reply_port, data, | |
| 454 writer.BytesWritten(), | |
| 455 Message::kNormalPriority)); | |
| 456 } | |
| 457 | |
| 458 | |
| 459 static void SetupJSONStream(JSONStream* js, Zone* zone, | |
| 460 const Instance& reply_port, | |
| 461 const GrowableObjectArray& path, | |
| 462 const GrowableObjectArray& option_keys, | |
| 463 const GrowableObjectArray& option_values) { | |
| 464 // Setup the reply port. | |
| 465 const Object& id_obj = Object::Handle( | |
| 466 DartLibraryCalls::PortGetId(reply_port)); | |
| 467 if (id_obj.IsError()) { | |
| 468 Exceptions::PropagateError(Error::Cast(id_obj)); | |
| 469 } | |
| 470 const Integer& id = Integer::Cast(id_obj); | |
| 471 Dart_Port port = static_cast<Dart_Port>(id.AsInt64Value()); | |
| 472 ASSERT(port != ILLEGAL_PORT); | |
| 473 js->set_reply_port(port); | |
| 474 | |
| 475 // Setup JSONStream arguments and options. The arguments and options | |
| 476 // are zone allocated and will be freed immediately after handling the | |
| 477 // message. | |
| 478 const char** arguments = zone->Alloc<const char*>(path.Length()); | |
| 479 String& string_iterator = String::Handle(); | |
| 480 for (intptr_t i = 0; i < path.Length(); i++) { | |
| 481 string_iterator ^= path.At(i); | |
| 482 arguments[i] = zone->MakeCopyOfString(string_iterator.ToCString()); | |
| 483 } | |
| 484 js->SetArguments(arguments, path.Length()); | |
| 485 if (option_keys.Length() > 0) { | |
| 486 const char** option_keys_native = | |
| 487 zone->Alloc<const char*>(option_keys.Length()); | |
| 488 const char** option_values_native = | |
| 489 zone->Alloc<const char*>(option_keys.Length()); | |
| 490 for (intptr_t i = 0; i < option_keys.Length(); i++) { | |
| 491 string_iterator ^= option_keys.At(i); | |
| 492 option_keys_native[i] = | |
| 493 zone->MakeCopyOfString(string_iterator.ToCString()); | |
| 494 string_iterator ^= option_values.At(i); | |
| 495 option_values_native[i] = | |
| 496 zone->MakeCopyOfString(string_iterator.ToCString()); | |
| 497 } | |
| 498 js->SetOptions(option_keys_native, option_values_native, | |
| 499 option_keys.Length()); | |
| 500 } | |
| 501 } | |
| 502 | |
| 503 | |
| 504 static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) { | 444 static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) { |
| 505 JSONObject jsobj(&obj, "message"); | 445 JSONObject jsobj(&obj, "message"); |
| 506 { | 446 { |
| 507 JSONArray jsarr(&jsobj, "arguments"); | 447 JSONArray jsarr(&jsobj, "arguments"); |
| 508 for (intptr_t i = 0; i < js->num_arguments(); i++) { | 448 for (intptr_t i = 0; i < js->num_arguments(); i++) { |
| 509 jsarr.AddValue(js->GetArgument(i)); | 449 jsarr.AddValue(js->GetArgument(i)); |
| 510 } | 450 } |
| 511 } | 451 } |
| 512 { | 452 { |
| 513 JSONArray jsarr(&jsobj, "option_keys"); | 453 JSONArray jsarr(&jsobj, "option_keys"); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 path ^= message.At(1); | 506 path ^= message.At(1); |
| 567 option_keys ^= message.At(2); | 507 option_keys ^= message.At(2); |
| 568 option_values ^= message.At(3); | 508 option_values ^= message.At(3); |
| 569 | 509 |
| 570 ASSERT(!path.IsNull()); | 510 ASSERT(!path.IsNull()); |
| 571 ASSERT(!option_keys.IsNull()); | 511 ASSERT(!option_keys.IsNull()); |
| 572 ASSERT(!option_values.IsNull()); | 512 ASSERT(!option_values.IsNull()); |
| 573 // Same number of option keys as values. | 513 // Same number of option keys as values. |
| 574 ASSERT(option_keys.Length() == option_values.Length()); | 514 ASSERT(option_keys.Length() == option_values.Length()); |
| 575 | 515 |
| 576 String& pathSegment = String::Handle(); | 516 String& path_segment = String::Handle(); |
| 577 if (path.Length() > 0) { | 517 if (path.Length() > 0) { |
| 578 pathSegment ^= path.At(0); | 518 path_segment ^= path.At(0); |
| 579 } else { | 519 } else { |
| 580 pathSegment ^= Symbols::Empty().raw(); | 520 path_segment ^= Symbols::Empty().raw(); |
| 581 } | 521 } |
| 582 ASSERT(!pathSegment.IsNull()); | 522 ASSERT(!path_segment.IsNull()); |
| 523 const char* path_segment_c = path_segment.ToCString(); |
| 583 | 524 |
| 584 IsolateMessageHandler handler = | 525 IsolateMessageHandler handler = |
| 585 FindIsolateMessageHandler(pathSegment.ToCString()); | 526 FindIsolateMessageHandler(path_segment_c); |
| 586 { | 527 { |
| 587 JSONStream js; | 528 JSONStream js; |
| 588 SetupJSONStream(&js, zone.GetZone(), | 529 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values); |
| 589 reply_port, path, option_keys, option_values); | 530 |
| 590 if (handler == NULL) { | 531 if (handler == NULL) { |
| 591 PrintError(&js, "Unrecognized path"); | 532 PrintError(&js, "Unrecognized path"); |
| 592 PostReply(&js); | 533 js.PostReply(); |
| 593 } else { | 534 } else { |
| 594 if (handler(isolate, &js)) { | 535 if (handler(isolate, &js)) { |
| 595 // Handler returns true if the reply is ready to be posted. | 536 // Handler returns true if the reply is ready to be posted. |
| 596 PostReply(&js); | 537 js.PostReply(); |
| 597 } | 538 } |
| 598 } | 539 } |
| 599 } | 540 } |
| 600 } | 541 } |
| 601 } | 542 } |
| 602 | 543 |
| 603 | 544 |
| 604 static bool HandleIsolate(Isolate* isolate, JSONStream* js) { | 545 static bool HandleIsolate(Isolate* isolate, JSONStream* js) { |
| 605 isolate->PrintToJSONStream(js); | 546 isolate->PrintToJSONStream(js); |
| 606 return true; | 547 return true; |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 | 1051 |
| 1111 static IsolateMessageHandler FindIsolateMessageHandler(const char* command) { | 1052 static IsolateMessageHandler FindIsolateMessageHandler(const char* command) { |
| 1112 intptr_t num_message_handlers = sizeof(isolate_handlers) / | 1053 intptr_t num_message_handlers = sizeof(isolate_handlers) / |
| 1113 sizeof(isolate_handlers[0]); | 1054 sizeof(isolate_handlers[0]); |
| 1114 for (intptr_t i = 0; i < num_message_handlers; i++) { | 1055 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 1115 const IsolateMessageHandlerEntry& entry = isolate_handlers[i]; | 1056 const IsolateMessageHandlerEntry& entry = isolate_handlers[i]; |
| 1116 if (!strcmp(command, entry.command)) { | 1057 if (!strcmp(command, entry.command)) { |
| 1117 return entry.handler; | 1058 return entry.handler; |
| 1118 } | 1059 } |
| 1119 } | 1060 } |
| 1061 if (FLAG_trace_service) { |
| 1062 OS::Print("Service has no isolate message handler for <%s>\n", command); |
| 1063 } |
| 1120 return NULL; | 1064 return NULL; |
| 1121 } | 1065 } |
| 1122 | 1066 |
| 1123 | 1067 |
| 1124 void Service::HandleRootMessage(const Instance& msg) { | 1068 void Service::HandleRootMessage(const Instance& msg) { |
| 1125 Isolate* isolate = Isolate::Current(); | 1069 Isolate* isolate = Isolate::Current(); |
| 1126 ASSERT(!msg.IsNull()); | 1070 ASSERT(!msg.IsNull()); |
| 1127 ASSERT(msg.IsGrowableObjectArray()); | 1071 ASSERT(msg.IsGrowableObjectArray()); |
| 1128 | 1072 |
| 1129 { | 1073 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1144 option_values ^= message.At(3); | 1088 option_values ^= message.At(3); |
| 1145 | 1089 |
| 1146 ASSERT(!path.IsNull()); | 1090 ASSERT(!path.IsNull()); |
| 1147 ASSERT(!option_keys.IsNull()); | 1091 ASSERT(!option_keys.IsNull()); |
| 1148 ASSERT(!option_values.IsNull()); | 1092 ASSERT(!option_values.IsNull()); |
| 1149 // Path always has at least one entry in it. | 1093 // Path always has at least one entry in it. |
| 1150 ASSERT(path.Length() > 0); | 1094 ASSERT(path.Length() > 0); |
| 1151 // Same number of option keys as values. | 1095 // Same number of option keys as values. |
| 1152 ASSERT(option_keys.Length() == option_values.Length()); | 1096 ASSERT(option_keys.Length() == option_values.Length()); |
| 1153 | 1097 |
| 1154 String& pathSegment = String::Handle(); | 1098 String& path_segment = String::Handle(); |
| 1155 pathSegment ^= path.At(0); | 1099 path_segment ^= path.At(0); |
| 1156 ASSERT(!pathSegment.IsNull()); | 1100 ASSERT(!path_segment.IsNull()); |
| 1101 const char* path_segment_c = path_segment.ToCString(); |
| 1102 RootMessageHandler handler = |
| 1103 FindRootMessageHandler(path_segment_c); |
| 1157 | 1104 |
| 1158 RootMessageHandler handler = | |
| 1159 FindRootMessageHandler(pathSegment.ToCString()); | |
| 1160 { | 1105 { |
| 1161 JSONStream js; | 1106 JSONStream js; |
| 1162 SetupJSONStream(&js, zone.GetZone(), | 1107 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values); |
| 1163 reply_port, path, option_keys, option_values); | |
| 1164 if (handler == NULL) { | 1108 if (handler == NULL) { |
| 1165 PrintError(&js, "Unrecognized path"); | 1109 PrintError(&js, "Unrecognized path"); |
| 1166 PostReply(&js); | 1110 js.PostReply(); |
| 1167 } else { | 1111 } else { |
| 1168 if (handler(&js)) { | 1112 if (handler(&js)) { |
| 1169 // Handler returns true if the reply is ready to be posted. | 1113 // Handler returns true if the reply is ready to be posted. |
| 1170 PostReply(&js); | 1114 js.PostReply(); |
| 1171 } | 1115 } |
| 1172 } | 1116 } |
| 1173 } | 1117 } |
| 1174 } | 1118 } |
| 1175 } | 1119 } |
| 1176 | 1120 |
| 1177 | 1121 |
| 1178 static bool HandleRootEcho(JSONStream* js) { | 1122 static bool HandleRootEcho(JSONStream* js) { |
| 1179 JSONObject jsobj(js); | 1123 JSONObject jsobj(js); |
| 1180 jsobj.AddProperty("type", "message"); | 1124 jsobj.AddProperty("type", "message"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1199 | 1143 |
| 1200 static RootMessageHandler FindRootMessageHandler(const char* command) { | 1144 static RootMessageHandler FindRootMessageHandler(const char* command) { |
| 1201 intptr_t num_message_handlers = sizeof(root_handlers) / | 1145 intptr_t num_message_handlers = sizeof(root_handlers) / |
| 1202 sizeof(root_handlers[0]); | 1146 sizeof(root_handlers[0]); |
| 1203 for (intptr_t i = 0; i < num_message_handlers; i++) { | 1147 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 1204 const RootMessageHandlerEntry& entry = root_handlers[i]; | 1148 const RootMessageHandlerEntry& entry = root_handlers[i]; |
| 1205 if (!strcmp(command, entry.command)) { | 1149 if (!strcmp(command, entry.command)) { |
| 1206 return entry.handler; | 1150 return entry.handler; |
| 1207 } | 1151 } |
| 1208 } | 1152 } |
| 1153 if (FLAG_trace_service) { |
| 1154 OS::Print("Service has no root message handler for <%s>\n", command); |
| 1155 } |
| 1209 return NULL; | 1156 return NULL; |
| 1210 } | 1157 } |
| 1211 | 1158 |
| 1212 } // namespace dart | 1159 } // namespace dart |
| OLD | NEW |