Chromium Code Reviews| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 | 97 |
| 98 static ResourcesEntry* ResourceTable() { | 98 static ResourcesEntry* ResourceTable() { |
| 99 return &__service_resources_[0]; | 99 return &__service_resources_[0]; |
| 100 } | 100 } |
| 101 | 101 |
| 102 DISALLOW_ALLOCATION(); | 102 DISALLOW_ALLOCATION(); |
| 103 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources); | 103 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources); |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 | 106 |
| 107 class EmbedderServiceHandler { | |
| 108 public: | |
| 109 explicit EmbedderServiceHandler(const char* name) : name_(NULL), | |
| 110 callback_(NULL), | |
| 111 user_data_(NULL), | |
| 112 next_(NULL) { | |
| 113 ASSERT(name != NULL); | |
| 114 name_ = strdup(name); | |
| 115 } | |
| 116 | |
| 117 ~EmbedderServiceHandler() { | |
| 118 free(name_); | |
| 119 } | |
| 120 | |
| 121 const char* name() const { return name_; } | |
| 122 | |
| 123 Dart_ServiceRequestCallback callback() const { return callback_; } | |
| 124 void set_callback(Dart_ServiceRequestCallback callback) { | |
| 125 callback_ = callback; | |
| 126 } | |
| 127 | |
| 128 void* user_data() const { return user_data_; } | |
| 129 void set_user_data(void* user_data) { | |
| 130 user_data_ = user_data; | |
| 131 } | |
| 132 | |
| 133 EmbedderServiceHandler* next() const { return next_; } | |
| 134 void set_next(EmbedderServiceHandler* next) { | |
| 135 next_ = next; | |
| 136 } | |
| 137 | |
| 138 private: | |
| 139 char* name_; | |
| 140 Dart_ServiceRequestCallback callback_; | |
| 141 void* user_data_; | |
| 142 EmbedderServiceHandler* next_; | |
| 143 }; | |
| 144 | |
| 145 | |
| 107 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 146 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| 108 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 147 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 109 return reinterpret_cast<uint8_t*>(new_ptr); | 148 return reinterpret_cast<uint8_t*>(new_ptr); |
| 110 } | 149 } |
| 111 | 150 |
| 112 | 151 |
| 113 static void SendIsolateServiceMessage(Dart_NativeArguments args) { | 152 static void SendIsolateServiceMessage(Dart_NativeArguments args) { |
| 114 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 153 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 115 Isolate* isolate = arguments->isolate(); | 154 Isolate* isolate = arguments->isolate(); |
| 116 StackZone zone(isolate); | 155 StackZone zone(isolate); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; | 218 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; |
| 180 if (!strcmp(function_name, entry.name) && | 219 if (!strcmp(function_name, entry.name) && |
| 181 (num_arguments == entry.num_arguments)) { | 220 (num_arguments == entry.num_arguments)) { |
| 182 return entry.function; | 221 return entry.function; |
| 183 } | 222 } |
| 184 } | 223 } |
| 185 return NULL; | 224 return NULL; |
| 186 } | 225 } |
| 187 | 226 |
| 188 | 227 |
| 228 EmbedderServiceHandler* Service::service_handler_head_ = NULL; | |
| 189 Isolate* Service::service_isolate_ = NULL; | 229 Isolate* Service::service_isolate_ = NULL; |
| 190 Dart_LibraryTagHandler Service::default_handler_ = NULL; | 230 Dart_LibraryTagHandler Service::default_handler_ = NULL; |
| 191 Dart_Port Service::port_ = ILLEGAL_PORT; | 231 Dart_Port Service::port_ = ILLEGAL_PORT; |
| 192 | 232 |
| 233 | |
| 193 static Dart_Port ExtractPort(Dart_Handle receivePort) { | 234 static Dart_Port ExtractPort(Dart_Handle receivePort) { |
| 194 HANDLESCOPE(Isolate::Current()); | 235 HANDLESCOPE(Isolate::Current()); |
| 195 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort)); | 236 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort)); |
| 196 const Instance& rp = Instance::Cast(unwrapped_rp); | 237 const Instance& rp = Instance::Cast(unwrapped_rp); |
| 197 // Extract RawReceivePort port id. | 238 // Extract RawReceivePort port id. |
| 198 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp)); | 239 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp)); |
| 199 if (rp_id_obj.IsError()) { | 240 if (rp_id_obj.IsError()) { |
| 200 return ILLEGAL_PORT; | 241 return ILLEGAL_PORT; |
| 201 } | 242 } |
| 202 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint()); | 243 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint()); |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 if (path.Length() > 0) { | 558 if (path.Length() > 0) { |
| 518 path_segment ^= path.At(0); | 559 path_segment ^= path.At(0); |
| 519 } else { | 560 } else { |
| 520 path_segment ^= Symbols::Empty().raw(); | 561 path_segment ^= Symbols::Empty().raw(); |
| 521 } | 562 } |
| 522 ASSERT(!path_segment.IsNull()); | 563 ASSERT(!path_segment.IsNull()); |
| 523 const char* path_segment_c = path_segment.ToCString(); | 564 const char* path_segment_c = path_segment.ToCString(); |
| 524 | 565 |
| 525 IsolateMessageHandler handler = | 566 IsolateMessageHandler handler = |
| 526 FindIsolateMessageHandler(path_segment_c); | 567 FindIsolateMessageHandler(path_segment_c); |
| 568 if (handler == NULL) { | |
| 569 // Check for an embedder handler. | |
| 570 EmbedderServiceHandler* e_handler = FindEmbedderHandler(path_segment_c); | |
| 571 if (e_handler != NULL) { | |
| 572 JSONStream js; | |
| 573 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values); | |
| 574 EmbedderHandleIsolateMessage(e_handler, &js); | |
|
turnidge
2014/02/18 21:27:05
Do we want to allow for asynchronous replies? Sho
| |
| 575 js.PostReply(); | |
| 576 } | |
| 577 } | |
| 527 { | 578 { |
| 528 JSONStream js; | 579 JSONStream js; |
| 529 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values); | 580 js.Setup(zone.GetZone(), reply_port, path, option_keys, option_values); |
| 530 | |
| 531 if (handler == NULL) { | 581 if (handler == NULL) { |
| 532 PrintError(&js, "Unrecognized path"); | 582 PrintError(&js, "Unrecognized path"); |
| 533 js.PostReply(); | 583 js.PostReply(); |
| 534 } else { | 584 } else { |
| 535 if (handler(isolate, &js)) { | 585 if (handler(isolate, &js)) { |
| 536 // Handler returns true if the reply is ready to be posted. | 586 // Handler returns true if the reply is ready to be posted. |
| 537 js.PostReply(); | 587 js.PostReply(); |
| 538 } | 588 } |
| 539 } | 589 } |
| 540 } | 590 } |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1149 if (!strcmp(command, entry.command)) { | 1199 if (!strcmp(command, entry.command)) { |
| 1150 return entry.handler; | 1200 return entry.handler; |
| 1151 } | 1201 } |
| 1152 } | 1202 } |
| 1153 if (FLAG_trace_service) { | 1203 if (FLAG_trace_service) { |
| 1154 OS::Print("Service has no root message handler for <%s>\n", command); | 1204 OS::Print("Service has no root message handler for <%s>\n", command); |
| 1155 } | 1205 } |
| 1156 return NULL; | 1206 return NULL; |
| 1157 } | 1207 } |
| 1158 | 1208 |
| 1209 | |
| 1210 void Service::EmbedderHandleIsolateMessage(EmbedderServiceHandler* handler, | |
| 1211 JSONStream* js) { | |
| 1212 ASSERT(handler != NULL); | |
| 1213 Dart_ServiceRequestCallback callback = handler->callback(); | |
| 1214 ASSERT(callback != NULL); | |
| 1215 const char* r = NULL; | |
| 1216 const char* name = js->command(); | |
| 1217 const char** arguments = js->arguments(); | |
| 1218 const char** keys = js->option_keys(); | |
| 1219 const char** values = js->option_values(); | |
| 1220 r = callback(name, arguments, js->num_arguments(), keys, values, | |
| 1221 js->num_options(), handler->user_data()); | |
| 1222 ASSERT(r != NULL); | |
| 1223 // TODO(johnmccutchan): Allow for NULL returns? | |
| 1224 TextBuffer* buffer = js->buffer(); | |
| 1225 buffer->AddString(r); | |
| 1226 free(const_cast<char*>(r)); | |
| 1227 } | |
| 1228 | |
| 1229 | |
| 1230 void Service::RegisterEmbedderCallback(const char* name, | |
| 1231 Dart_ServiceRequestCallback callback, | |
| 1232 void* user_data) { | |
|
turnidge
2014/02/18 21:27:05
Add a heartbeat unit test for embedder callbacks i
Cutch
2014/02/18 22:18:51
Done.
| |
| 1233 if (name == NULL) { | |
| 1234 return; | |
| 1235 } | |
| 1236 EmbedderServiceHandler* handler = FindEmbedderHandler(name); | |
| 1237 if (handler != NULL) { | |
| 1238 // Update existing handler entry. | |
| 1239 handler->set_callback(callback); | |
| 1240 handler->set_user_data(user_data); | |
| 1241 return; | |
| 1242 } | |
| 1243 // Create a new handler. | |
| 1244 handler = new EmbedderServiceHandler(name); | |
| 1245 handler->set_callback(callback); | |
| 1246 handler->set_user_data(user_data); | |
| 1247 | |
| 1248 // Insert into list. | |
| 1249 handler->set_next(service_handler_head_); | |
| 1250 service_handler_head_ = handler; | |
| 1251 } | |
| 1252 | |
| 1253 | |
| 1254 EmbedderServiceHandler* Service::FindEmbedderHandler( | |
| 1255 const char* name) { | |
| 1256 EmbedderServiceHandler* current = service_handler_head_; | |
| 1257 while (current != NULL) { | |
| 1258 if (!strcmp(name, current->name())) { | |
| 1259 return current; | |
| 1260 } | |
| 1261 } | |
| 1262 return NULL; | |
| 1263 } | |
| 1264 | |
| 1265 | |
| 1159 } // namespace dart | 1266 } // namespace dart |
| OLD | NEW |