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 "bin/vmservice_impl.h" | 5 #include "bin/vmservice_impl.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "bin/builtin.h" | 9 #include "bin/builtin.h" |
10 #include "bin/dartutils.h" | 10 #include "bin/dartutils.h" |
| 11 #include "bin/isolate_data.h" |
11 #include "bin/resources.h" | 12 #include "bin/resources.h" |
12 #include "bin/thread.h" | 13 #include "bin/thread.h" |
13 #include "bin/isolate_data.h" | |
14 | 14 |
| 15 #include "vm/dart_api_impl.h" |
| 16 #include "vm/dart_entry.h" |
| 17 #include "vm/isolate.h" |
| 18 #include "vm/message.h" |
| 19 #include "vm/native_entry.h" |
| 20 #include "vm/native_arguments.h" |
| 21 #include "vm/object.h" |
| 22 #include "vm/port.h" |
| 23 #include "vm/snapshot.h" |
15 | 24 |
16 namespace dart { | 25 namespace dart { |
17 namespace bin { | 26 namespace bin { |
18 | 27 |
19 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise | 28 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise |
20 // it is initialized to NULL. | 29 // it is initialized to NULL. |
21 extern const uint8_t* snapshot_buffer; | 30 extern const uint8_t* snapshot_buffer; |
22 #define RETURN_ERROR_HANDLE(handle) \ | 31 #define RETURN_ERROR_HANDLE(handle) \ |
23 if (Dart_IsError(handle)) { \ | 32 if (Dart_IsError(handle)) { \ |
24 return handle; \ | 33 return handle; \ |
25 } | 34 } |
26 | 35 |
27 #define SHUTDOWN_ON_ERROR(handle) \ | 36 #define SHUTDOWN_ON_ERROR(handle) \ |
28 if (Dart_IsError(handle)) { \ | 37 if (Dart_IsError(handle)) { \ |
29 error_msg_ = strdup(Dart_GetError(handle)); \ | 38 error_msg_ = strdup(Dart_GetError(handle)); \ |
30 Dart_ExitScope(); \ | 39 Dart_ExitScope(); \ |
31 Dart_ShutdownIsolate(); \ | 40 Dart_ShutdownIsolate(); \ |
32 return false; \ | 41 return false; \ |
33 } | 42 } |
34 | 43 |
35 #define kLibraryResourceNamePrefix "/vmservice" | 44 #define kLibraryResourceNamePrefix "/vmservice" |
36 static const char* kLibraryScriptResourceName = | 45 static const char* kLibraryScriptResourceName = |
37 kLibraryResourceNamePrefix "/vmservice.dart"; | 46 kLibraryResourceNamePrefix "/vmservice.dart"; |
38 static const char* kLibrarySourceResourceNames[] = { | 47 static const char* kLibrarySourceResourceNames[] = { |
| 48 kLibraryResourceNamePrefix "/constants.dart", |
| 49 kLibraryResourceNamePrefix "/resources.dart", |
| 50 kLibraryResourceNamePrefix "/running_isolate.dart", |
| 51 kLibraryResourceNamePrefix "/running_isolates.dart", |
| 52 kLibraryResourceNamePrefix "/server.dart", |
| 53 kLibraryResourceNamePrefix "/service_request.dart", |
| 54 kLibraryResourceNamePrefix "/service_request_router.dart", |
| 55 kLibraryResourceNamePrefix "/vmservice_io.dart", |
39 NULL | 56 NULL |
40 }; | 57 }; |
41 | 58 |
42 #define kClientResourceNamePrefix "/client/web/out" | 59 #define kClientResourceNamePrefix "/client/web/out" |
43 | 60 |
44 Dart_Isolate VmService::isolate_ = NULL; | 61 Dart_Isolate VmService::isolate_ = NULL; |
45 Dart_Port VmService::port_ = ILLEGAL_PORT; | 62 Dart_Port VmService::port_ = ILLEGAL_PORT; |
46 dart::Monitor* VmService::monitor_ = NULL; | 63 dart::Monitor* VmService::monitor_ = NULL; |
47 const char* VmService::error_msg_ = NULL; | 64 const char* VmService::error_msg_ = NULL; |
48 | 65 |
49 // These must be kept in sync with vmservice/constants.dart | 66 // These must be kept in sync with vmservice/constants.dart |
50 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 | 67 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 |
51 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 | 68 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 |
52 | 69 |
53 | 70 |
| 71 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name, |
| 72 int num_arguments); |
| 73 |
| 74 |
54 bool VmService::Start(intptr_t server_port) { | 75 bool VmService::Start(intptr_t server_port) { |
55 monitor_ = new dart::Monitor(); | 76 monitor_ = new dart::Monitor(); |
56 ASSERT(monitor_ != NULL); | 77 ASSERT(monitor_ != NULL); |
57 error_msg_ = NULL; | 78 error_msg_ = NULL; |
58 | 79 |
59 | 80 |
60 { | 81 { |
61 // Take lock before spawning new thread. | 82 // Take lock before spawning new thread. |
62 MonitorLocker ml(monitor_); | 83 MonitorLocker ml(monitor_); |
63 // Spawn new thread. | 84 // Spawn new thread. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 if (!retval) { | 143 if (!retval) { |
123 Dart_EnterIsolate(isolate_); | 144 Dart_EnterIsolate(isolate_); |
124 Dart_ShutdownIsolate(); | 145 Dart_ShutdownIsolate(); |
125 error_msg_ = "Invalid isolate state - Unable to make it runnable."; | 146 error_msg_ = "Invalid isolate state - Unable to make it runnable."; |
126 return false; | 147 return false; |
127 } | 148 } |
128 | 149 |
129 Dart_EnterIsolate(isolate_); | 150 Dart_EnterIsolate(isolate_); |
130 Dart_EnterScope(); | 151 Dart_EnterScope(); |
131 | 152 |
| 153 |
132 Dart_Handle library = Dart_RootLibrary(); | 154 Dart_Handle library = Dart_RootLibrary(); |
| 155 // Set requested port. |
| 156 DartUtils::SetIntegerField(library, "_port", server_port); |
| 157 // Install native resolver. |
| 158 result = Dart_SetNativeResolver(library, VmServiceNativeResolver); |
| 159 SHUTDOWN_ON_ERROR(result); |
133 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL); | 160 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL); |
134 SHUTDOWN_ON_ERROR(result); | 161 SHUTDOWN_ON_ERROR(result); |
135 | 162 |
136 result = LoadResources(library); | 163 result = LoadResources(library); |
137 SHUTDOWN_ON_ERROR(result); | 164 SHUTDOWN_ON_ERROR(result); |
138 | 165 |
139 port_ = Dart_GetMainPortId(); | 166 port_ = Dart_GetMainPortId(); |
140 | 167 |
141 Dart_ExitScope(); | 168 Dart_ExitScope(); |
142 Dart_ExitIsolate(); | 169 Dart_ExitIsolate(); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 Dart_EnterScope(); | 304 Dart_EnterScope(); |
278 | 305 |
279 Dart_Handle receievePort = Dart_GetReceivePort(port_); | 306 Dart_Handle receievePort = Dart_GetReceivePort(port_); |
280 ASSERT(!Dart_IsError(receievePort)); | 307 ASSERT(!Dart_IsError(receievePort)); |
281 monitor_->Notify(); | 308 monitor_->Notify(); |
282 } | 309 } |
283 | 310 |
284 // Keep handling messages until the last active receive port is closed. | 311 // Keep handling messages until the last active receive port is closed. |
285 Dart_Handle result = Dart_RunLoop(); | 312 Dart_Handle result = Dart_RunLoop(); |
286 if (Dart_IsError(result)) { | 313 if (Dart_IsError(result)) { |
287 printf("VmService error %s\n", Dart_GetError(result)); | 314 printf("VmService has exited with an error:\n%s\n", Dart_GetError(result)); |
288 } | 315 } |
289 | 316 |
290 _Stop(); | 317 _Stop(); |
291 | 318 |
292 Dart_ExitScope(); | 319 Dart_ExitScope(); |
293 Dart_ExitIsolate(); | 320 Dart_ExitIsolate(); |
294 } | 321 } |
295 | 322 |
296 | 323 |
297 | |
298 | |
299 static Dart_Handle MakeServiceControlMessage(Dart_Port port) { | 324 static Dart_Handle MakeServiceControlMessage(Dart_Port port) { |
300 Dart_Handle list = Dart_NewList(2); | 325 Dart_Handle list = Dart_NewList(2); |
301 ASSERT(!Dart_IsError(list)); | 326 ASSERT(!Dart_IsError(list)); |
302 Dart_Handle sendPort = Dart_NewSendPort(port); | 327 Dart_Handle sendPort = Dart_NewSendPort(port); |
303 ASSERT(!Dart_IsError(sendPort)); | 328 ASSERT(!Dart_IsError(sendPort)); |
304 Dart_ListSetAt(list, 1, sendPort); | 329 Dart_ListSetAt(list, 1, sendPort); |
305 return list; | 330 return list; |
306 } | 331 } |
307 | 332 |
308 | 333 |
(...skipping 18 matching lines...) Expand all Loading... |
327 Dart_Isolate isolate = Dart_CurrentIsolate(); | 352 Dart_Isolate isolate = Dart_CurrentIsolate(); |
328 ASSERT(isolate != NULL); | 353 ASSERT(isolate != NULL); |
329 ASSERT(Dart_GetMainPortId() == port); | 354 ASSERT(Dart_GetMainPortId() == port); |
330 Dart_Handle list = MakeServiceControlMessage(port); | 355 Dart_Handle list = MakeServiceControlMessage(port); |
331 Dart_ListSetAt(list, 0, | 356 Dart_ListSetAt(list, 0, |
332 Dart_NewInteger(VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID)); | 357 Dart_NewInteger(VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID)); |
333 return Dart_Post(port_, list); | 358 return Dart_Post(port_, list); |
334 } | 359 } |
335 | 360 |
336 | 361 |
| 362 void VmService::VmServiceShutdownCallback(void* callback_data) { |
| 363 ASSERT(Dart_CurrentIsolate() != NULL); |
| 364 Dart_EnterScope(); |
| 365 VmService::SendIsolateShutdownMessage(Dart_GetMainPortId()); |
| 366 Dart_ExitScope(); |
| 367 } |
| 368 |
| 369 |
| 370 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
| 371 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 372 return reinterpret_cast<uint8_t*>(new_ptr); |
| 373 } |
| 374 |
| 375 |
| 376 static void SendServiceMessage(Dart_NativeArguments args) { |
| 377 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 378 Isolate* isolate = arguments->isolate(); |
| 379 StackZone zone(isolate); |
| 380 HANDLESCOPE(isolate); |
| 381 GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0)); |
| 382 GET_NON_NULL_NATIVE_ARGUMENT(Instance, rp, arguments->NativeArgAt(1)); |
| 383 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(2)); |
| 384 |
| 385 // Extract SendPort port id. |
| 386 const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp)); |
| 387 if (sp_id_obj.IsError()) { |
| 388 Exceptions::PropagateError(Error::Cast(sp_id_obj)); |
| 389 } |
| 390 Integer& id = Integer::Handle(); |
| 391 id ^= sp_id_obj.raw(); |
| 392 Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value()); |
| 393 |
| 394 // Extract ReceivePort port id. |
| 395 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp)); |
| 396 if (rp_id_obj.IsError()) { |
| 397 Exceptions::PropagateError(Error::Cast(rp_id_obj)); |
| 398 } |
| 399 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint()); |
| 400 id ^= rp_id_obj.raw(); |
| 401 Dart_Port rp_id = static_cast<Dart_Port>(id.AsInt64Value()); |
| 402 |
| 403 // Both are valid ports. |
| 404 ASSERT(sp_id != ILLEGAL_PORT); |
| 405 ASSERT(rp_id != ILLEGAL_PORT); |
| 406 |
| 407 // Serialize message. |
| 408 uint8_t* data = NULL; |
| 409 MessageWriter writer(&data, &allocator); |
| 410 writer.WriteMessage(message); |
| 411 |
| 412 // TODO(turnidge): Throw an exception when the return value is false? |
| 413 PortMap::PostMessage(new Message(sp_id, rp_id, data, writer.BytesWritten(), |
| 414 Message::kOOBPriority)); |
| 415 } |
| 416 |
| 417 |
| 418 struct VmServiceNativeEntry { |
| 419 const char* name; |
| 420 int num_arguments; |
| 421 Dart_NativeFunction function; |
| 422 }; |
| 423 |
| 424 |
| 425 static VmServiceNativeEntry _VmServiceNativeEntries[] = { |
| 426 {"SendServiceMessage", 3, SendServiceMessage} |
| 427 }; |
| 428 |
| 429 |
| 430 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name, |
| 431 int num_arguments) { |
| 432 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); |
| 433 if (!obj.IsString()) { |
| 434 return NULL; |
| 435 } |
| 436 const char* function_name = obj.ToCString(); |
| 437 ASSERT(function_name != NULL); |
| 438 intptr_t n = |
| 439 sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]); |
| 440 for (intptr_t i = 0; i < n; i++) { |
| 441 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; |
| 442 if (!strcmp(function_name, entry.name) && |
| 443 (num_arguments == entry.num_arguments)) { |
| 444 return entry.function; |
| 445 } |
| 446 } |
| 447 return NULL; |
| 448 } |
| 449 |
337 } // namespace bin | 450 } // namespace bin |
338 } // namespace dart | 451 } // namespace dart |
OLD | NEW |