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/resources.h" | 11 #include "bin/resources.h" |
12 #include "bin/thread.h" | 12 #include "bin/thread.h" |
13 #include "bin/isolate_data.h" | 13 #include "bin/isolate_data.h" |
14 | 14 |
15 #include "vm/dart_api_impl.h" | |
16 #include "vm/object.h" | |
17 #include "vm/dart_entry.h" | |
18 #include "vm/snapshot.h" | |
19 #include "vm/native_entry.h" | |
20 #include "vm/native_arguments.h" | |
21 #include "vm/isolate.h" | |
22 #include "vm/port.h" | |
23 #include "vm/message.h" | |
siva
2013/07/19 17:41:16
We usually sort the include headers alphabetically
Cutch
2013/07/19 18:15:02
Done.
| |
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 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 ASSERT(sp_id_obj.IsSmi() || sp_id_obj.IsMint()); | |
siva
2013/07/19 17:41:16
Why do you need the assert? the call AsInt64Value(
Cutch
2013/07/19 18:15:02
Done.
| |
391 Integer& id = Integer::Handle(); | |
392 id ^= sp_id_obj.raw(); | |
393 Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value()); | |
394 | |
395 // Extract ReceivePort port id. | |
396 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp)); | |
397 if (rp_id_obj.IsError()) { | |
398 Exceptions::PropagateError(Error::Cast(rp_id_obj)); | |
399 } | |
400 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint()); | |
401 id ^= rp_id_obj.raw(); | |
402 Dart_Port rp_id = static_cast<Dart_Port>(id.AsInt64Value()); | |
403 | |
404 // Both are valid ports. | |
405 ASSERT(sp_id != ILLEGAL_PORT); | |
406 ASSERT(rp_id != ILLEGAL_PORT); | |
407 | |
408 // Serialize message. | |
409 uint8_t* data = NULL; | |
410 MessageWriter writer(&data, &allocator); | |
411 writer.WriteMessage(message); | |
412 | |
413 // TODO(turnidge): Throw an exception when the return value is false? | |
414 PortMap::PostMessage(new Message(sp_id, rp_id, data, writer.BytesWritten(), | |
415 Message::kOOBPriority, | |
416 Message::kServiceType)); | |
417 } | |
418 | |
419 | |
420 struct VmServiceNativeEntry { | |
421 const char* name; | |
422 int num_arguments; | |
423 Dart_NativeFunction function; | |
424 }; | |
425 | |
426 | |
427 static VmServiceNativeEntry _VmServiceNativeEntries[] = { | |
428 {"SendServiceMessage", 3, SendServiceMessage} | |
429 }; | |
430 | |
431 | |
432 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name, | |
433 int num_arguments) { | |
434 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); | |
435 if (!obj.IsString()) { | |
436 return NULL; | |
437 } | |
438 const char* function_name = obj.ToCString(); | |
439 ASSERT(function_name != NULL); | |
440 intptr_t n = | |
441 sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]); | |
442 for (intptr_t i = 0; i < n; i++) { | |
443 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; | |
444 if (!strcmp(function_name, entry.name) && | |
445 (num_arguments == entry.num_arguments)) { | |
446 return entry.function; | |
447 } | |
448 } | |
siva
2013/07/19 17:41:16
Do you think there will be more than 1 native entr
Cutch
2013/07/19 18:15:02
It's possible.
| |
449 return NULL; | |
450 } | |
451 | |
337 } // namespace bin | 452 } // namespace bin |
338 } // namespace dart | 453 } // namespace dart |
OLD | NEW |