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 #include "platform/globals.h" | 8 #include "platform/globals.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); | 316 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); |
317 const String& name = String::Handle(String::New(isolate->name())); | 317 const String& name = String::Handle(String::New(isolate->name())); |
318 ASSERT(!name.IsNull()); | 318 ASSERT(!name.IsNull()); |
319 const Array& args = Array::Handle(Array::New(3)); | 319 const Array& args = Array::Handle(Array::New(3)); |
320 ASSERT(!args.IsNull()); | 320 ASSERT(!args.IsNull()); |
321 args.SetAt(0, port_int); | 321 args.SetAt(0, port_int); |
322 args.SetAt(1, send_port); | 322 args.SetAt(1, send_port); |
323 args.SetAt(2, name); | 323 args.SetAt(2, name); |
324 Object& r = Object::Handle(service_isolate_); | 324 Object& r = Object::Handle(service_isolate_); |
325 r = DartEntry::InvokeFunction(register_function_, args); | 325 r = DartEntry::InvokeFunction(register_function_, args); |
| 326 if (FLAG_trace_service) { |
| 327 OS::Print("Isolate %s %" Pd64 " registered with service \n", |
| 328 name.ToCString(), |
| 329 port_id); |
| 330 } |
326 ASSERT(!r.IsError()); | 331 ASSERT(!r.IsError()); |
327 } | 332 } |
328 | 333 |
329 private: | 334 private: |
330 Function& register_function_; | 335 Function& register_function_; |
331 Isolate* service_isolate_; | 336 Isolate* service_isolate_; |
332 }; | 337 }; |
333 | 338 |
334 | 339 |
335 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { | 340 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { |
336 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); | 341 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); |
337 if (rp.IsNull()) { | 342 if (rp.IsNull()) { |
338 return ILLEGAL_PORT; | 343 return ILLEGAL_PORT; |
339 } | 344 } |
340 return rp.Id(); | 345 return rp.Id(); |
341 } | 346 } |
342 | 347 |
343 | 348 |
344 static void OnStart(Dart_NativeArguments args) { | 349 static void OnStart(Dart_NativeArguments args) { |
345 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 350 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
346 Isolate* isolate = arguments->isolate(); | 351 Isolate* isolate = arguments->isolate(); |
347 StackZone zone(isolate); | 352 StackZone zone(isolate); |
348 HANDLESCOPE(isolate); | 353 HANDLESCOPE(isolate); |
349 { | 354 { |
| 355 if (FLAG_trace_service) { |
| 356 OS::Print("Booting dart:vmservice library\n"); |
| 357 } |
350 // Boot the dart:vmservice library. | 358 // Boot the dart:vmservice library. |
351 Dart_EnterScope(); | 359 Dart_EnterScope(); |
352 Dart_Handle url_str = | 360 Dart_Handle url_str = |
353 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); | 361 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); |
354 Dart_Handle library = Dart_LookupLibrary(url_str); | 362 Dart_Handle library = Dart_LookupLibrary(url_str); |
355 ASSERT(Dart_IsLibrary(library)); | 363 ASSERT(Dart_IsLibrary(library)); |
356 Dart_Handle result = | 364 Dart_Handle result = |
357 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); | 365 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); |
358 ASSERT(!Dart_IsError(result)); | 366 ASSERT(!Dart_IsError(result)); |
359 Dart_Port port = ExtractPort(isolate, result); | 367 Dart_Port port = ExtractPort(isolate, result); |
360 ASSERT(port != ILLEGAL_PORT); | 368 ASSERT(port != ILLEGAL_PORT); |
361 Service::set_port(port); | 369 Service::set_port(port); |
362 Dart_ExitScope(); | 370 Dart_ExitScope(); |
363 } | 371 } |
| 372 |
364 { | 373 { |
| 374 if (FLAG_trace_service) { |
| 375 OS::Print("Registering running isolates\n"); |
| 376 } |
365 // Register running isolates with service. | 377 // Register running isolates with service. |
366 RegisterRunningIsolatesVisitor register_isolates(isolate); | 378 RegisterRunningIsolatesVisitor register_isolates(isolate); |
367 Isolate::VisitIsolates(®ister_isolates); | 379 Isolate::VisitIsolates(®ister_isolates); |
368 } | 380 } |
369 } | 381 } |
370 | 382 |
371 | 383 |
372 struct VmServiceNativeEntry { | 384 struct VmServiceNativeEntry { |
373 const char* name; | 385 const char* name; |
374 int num_arguments; | 386 int num_arguments; |
(...skipping 29 matching lines...) Expand all Loading... |
404 return entry.function; | 416 return entry.function; |
405 } | 417 } |
406 } | 418 } |
407 return NULL; | 419 return NULL; |
408 } | 420 } |
409 | 421 |
410 | 422 |
411 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; | 423 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; |
412 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; | 424 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; |
413 Isolate* Service::service_isolate_ = NULL; | 425 Isolate* Service::service_isolate_ = NULL; |
414 Dart_LibraryTagHandler Service::embedder_provided_handler_ = NULL; | |
415 Dart_Port Service::port_ = ILLEGAL_PORT; | 426 Dart_Port Service::port_ = ILLEGAL_PORT; |
416 uint32_t Service::event_mask_ = 0; | 427 uint32_t Service::event_mask_ = 0; |
417 | 428 |
418 Isolate* Service::GetServiceIsolate(void* callback_data) { | |
419 if (service_isolate_ != NULL) { | |
420 // Already initialized, return service isolate. | |
421 return service_isolate_; | |
422 } | |
423 Dart_ServiceIsolateCreateCalback create_callback = | |
424 Isolate::ServiceCreateCallback(); | |
425 if (create_callback == NULL) { | |
426 return NULL; | |
427 } | |
428 Isolate::SetCurrent(NULL); | |
429 char* error = NULL; | |
430 Isolate* isolate = | |
431 reinterpret_cast<Isolate*>(create_callback(callback_data, &error)); | |
432 if (isolate == NULL) { | |
433 return NULL; | |
434 } | |
435 StartIsolateScope isolate_scope(isolate); | |
436 { | |
437 // Install the dart:vmservice library. | |
438 StackZone zone(isolate); | |
439 HANDLESCOPE(isolate); | |
440 Library& library = | |
441 Library::Handle(isolate, isolate->object_store()->root_library()); | |
442 // Isolate is empty. | |
443 ASSERT(library.IsNull()); | |
444 // Grab embedder tag handler. | |
445 embedder_provided_handler_ = isolate->library_tag_handler(); | |
446 // Temporarily install our own. | |
447 isolate->set_library_tag_handler(LibraryTagHandler); | |
448 // Get script resource. | |
449 const char* resource = NULL; | |
450 const char* path = "/vmservice.dart"; | |
451 intptr_t r = Resources::ResourceLookup(path, &resource); | |
452 ASSERT(r != Resources::kNoSuchInstance); | |
453 ASSERT(resource != NULL); | |
454 const String& source_str = String::Handle( | |
455 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r)); | |
456 ASSERT(!source_str.IsNull()); | |
457 const String& url_str = String::Handle(Symbols::DartVMService().raw()); | |
458 library ^= Library::LookupLibrary(url_str); | |
459 ASSERT(library.IsNull()); | |
460 // Setup library. | |
461 library = Library::New(url_str); | |
462 library.Register(); | |
463 const Script& script = Script::Handle( | |
464 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag)); | |
465 library.SetLoadInProgress(); | |
466 Dart_EnterScope(); // Need to enter scope for tag handler. | |
467 const Error& error = Error::Handle(isolate, | |
468 Compiler::Compile(library, script)); | |
469 ASSERT(error.IsNull()); | |
470 Dart_Handle result = Dart_FinalizeLoading(false); | |
471 ASSERT(!Dart_IsError(result)); | |
472 Dart_ExitScope(); | |
473 | |
474 // Install embedder default library tag handler again. | |
475 isolate->set_library_tag_handler(embedder_provided_handler_); | |
476 embedder_provided_handler_ = NULL; | |
477 library.set_native_entry_resolver(VmServiceNativeResolver); | |
478 } | |
479 service_isolate_ = reinterpret_cast<Isolate*>(isolate); | |
480 return service_isolate_; | |
481 } | |
482 | |
483 | |
484 bool Service::SendIsolateStartupMessage() { | 429 bool Service::SendIsolateStartupMessage() { |
485 if (!IsRunning()) { | 430 if (!IsRunning()) { |
486 return false; | 431 return false; |
487 } | 432 } |
488 Isolate* isolate = Isolate::Current(); | 433 Isolate* isolate = Isolate::Current(); |
489 ASSERT(isolate != NULL); | 434 ASSERT(isolate != NULL); |
490 HANDLESCOPE(isolate); | 435 HANDLESCOPE(isolate); |
491 const String& name = String::Handle(String::New(isolate->name())); | 436 const String& name = String::Handle(String::New(isolate->name())); |
492 ASSERT(!name.IsNull()); | 437 ASSERT(!name.IsNull()); |
493 const Array& list = Array::Handle( | 438 const Array& list = Array::Handle( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 } | 511 } |
567 if (!Dart_IsString(url)) { | 512 if (!Dart_IsString(url)) { |
568 return Dart_NewApiError("url is not a string"); | 513 return Dart_NewApiError("url is not a string"); |
569 } | 514 } |
570 const char* url_string = NULL; | 515 const char* url_string = NULL; |
571 Dart_Handle result = Dart_StringToCString(url, &url_string); | 516 Dart_Handle result = Dart_StringToCString(url, &url_string); |
572 if (Dart_IsError(result)) { | 517 if (Dart_IsError(result)) { |
573 return result; | 518 return result; |
574 } | 519 } |
575 if (tag == Dart_kImportTag) { | 520 if (tag == Dart_kImportTag) { |
576 // Embedder handles all requests for external libraries. | 521 return Dart_NewApiError("Unable to import module as no library tag " |
577 if (embedder_provided_handler_ == NULL) { | 522 "is available"); |
578 return Dart_NewApiError("Unable to import module as no library tag " | |
579 "handler has been provided by embedder"); | |
580 } | |
581 return embedder_provided_handler_(tag, library, url); | |
582 } | 523 } |
583 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); | 524 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); |
584 if (tag == Dart_kCanonicalizeUrl) { | 525 if (tag == Dart_kCanonicalizeUrl) { |
585 // url is already canonicalized. | 526 // url is already canonicalized. |
586 return url; | 527 return url; |
587 } | 528 } |
588 Dart_Handle source = GetSource(url_string); | 529 Dart_Handle source = GetSource(url_string); |
589 if (Dart_IsError(source)) { | 530 if (Dart_IsError(source)) { |
590 return source; | 531 return source; |
591 } | 532 } |
592 return Dart_LoadSource(library, url, source, 0, 0); | 533 return Dart_LoadSource(library, url, source, 0, 0); |
593 } | 534 } |
594 | 535 |
595 | 536 |
| 537 void Service::MaybeInjectVMServiceLibrary(Isolate* isolate) { |
| 538 if (service_isolate_ != NULL) { |
| 539 // vm-service isolate already exists. |
| 540 return; |
| 541 } |
| 542 const char* vm_service_prefix = "vm-service$main"; |
| 543 const intptr_t vm_service_prefix_len = strlen(vm_service_prefix); |
| 544 if (strncmp(isolate->name(), vm_service_prefix, vm_service_prefix_len) != 0) { |
| 545 // Not vm-service isolate. |
| 546 return; |
| 547 } |
| 548 service_isolate_ = isolate; |
| 549 ASSERT(isolate != NULL); |
| 550 StackZone zone(isolate); |
| 551 HANDLESCOPE(isolate); |
| 552 Library& library = |
| 553 Library::Handle(isolate, isolate->object_store()->root_library()); |
| 554 // Isolate is empty. |
| 555 ASSERT(library.IsNull()); |
| 556 // Temporarily install our library tag handler. |
| 557 isolate->set_library_tag_handler(LibraryTagHandler); |
| 558 // Get script resource. |
| 559 const char* resource = NULL; |
| 560 const char* path = "/vmservice.dart"; |
| 561 intptr_t r = Resources::ResourceLookup(path, &resource); |
| 562 ASSERT(r != Resources::kNoSuchInstance); |
| 563 ASSERT(resource != NULL); |
| 564 const String& source_str = String::Handle( |
| 565 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r)); |
| 566 ASSERT(!source_str.IsNull()); |
| 567 const String& url_str = String::Handle(Symbols::DartVMService().raw()); |
| 568 library ^= Library::LookupLibrary(url_str); |
| 569 ASSERT(library.IsNull()); |
| 570 // Setup library. |
| 571 library = Library::New(url_str); |
| 572 library.Register(); |
| 573 const Script& script = Script::Handle( |
| 574 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag)); |
| 575 library.SetLoadInProgress(); |
| 576 Dart_EnterScope(); // Need to enter scope for tag handler. |
| 577 const Error& error = Error::Handle(isolate, |
| 578 Compiler::Compile(library, script)); |
| 579 ASSERT(error.IsNull()); |
| 580 Dart_Handle result = Dart_FinalizeLoading(false); |
| 581 ASSERT(!Dart_IsError(result)); |
| 582 Dart_ExitScope(); |
| 583 |
| 584 // Uninstall our library tag handler. |
| 585 isolate->set_library_tag_handler(NULL); |
| 586 library.set_native_entry_resolver(VmServiceNativeResolver); |
| 587 } |
| 588 |
| 589 |
| 590 class RunServiceTask : public ThreadPool::Task { |
| 591 public: |
| 592 virtual void Run() { |
| 593 ASSERT(Isolate::Current() == NULL); |
| 594 |
| 595 Dart_IsolateCreateCallback create_callback = Isolate::CreateCallback(); |
| 596 if (create_callback == NULL) { |
| 597 return; |
| 598 } |
| 599 |
| 600 char* error = NULL; |
| 601 Isolate* isolate = |
| 602 reinterpret_cast<Isolate*>(create_callback("vm-service", |
| 603 NULL, |
| 604 NULL, |
| 605 &error)); |
| 606 if (isolate == NULL) { |
| 607 printf("error: %s\n", error); |
| 608 return; |
| 609 } |
| 610 |
| 611 ASSERT(Isolate::Current() == NULL); |
| 612 |
| 613 // Quick hack to test invocation: |
| 614 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(isolate)); |
| 615 Dart_EnterScope(); |
| 616 Dart_Handle library = Dart_RootLibrary(); |
| 617 ASSERT(!Dart_IsError(library)); |
| 618 Dart_Handle function_name = |
| 619 Dart_NewStringFromCString("main"); |
| 620 ASSERT(!Dart_IsError(function_name)); |
| 621 Dart_Handle result = Dart_Invoke(library, function_name, 0, NULL); |
| 622 ASSERT(!Dart_IsError(result)); |
| 623 |
| 624 result = Dart_RunLoop(); |
| 625 if (Dart_IsError(result)) { |
| 626 printf("Service exited with an error:\n%s\n", Dart_GetError(result)); |
| 627 } |
| 628 Dart_ExitScope(); |
| 629 Dart_ExitIsolate(); |
| 630 } |
| 631 }; |
| 632 |
| 633 |
| 634 void Service::RunService() { |
| 635 Dart::thread_pool()->Run(new RunServiceTask()); |
| 636 } |
| 637 |
596 // A handler for a per-isolate request. | 638 // A handler for a per-isolate request. |
597 // | 639 // |
598 // If a handler returns true, the reply is complete and ready to be | 640 // If a handler returns true, the reply is complete and ready to be |
599 // posted. If a handler returns false, then it is responsible for | 641 // posted. If a handler returns false, then it is responsible for |
600 // posting the reply (this can be used for asynchronous delegation of | 642 // posting the reply (this can be used for asynchronous delegation of |
601 // the response handling). | 643 // the response handling). |
602 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); | 644 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); |
603 | 645 |
604 struct IsolateMessageHandlerEntry { | 646 struct IsolateMessageHandlerEntry { |
605 const char* command; | 647 const char* command; |
(...skipping 2107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2713 while (current != NULL) { | 2755 while (current != NULL) { |
2714 if (strcmp(name, current->name()) == 0) { | 2756 if (strcmp(name, current->name()) == 0) { |
2715 return current; | 2757 return current; |
2716 } | 2758 } |
2717 current = current->next(); | 2759 current = current->next(); |
2718 } | 2760 } |
2719 return NULL; | 2761 return NULL; |
2720 } | 2762 } |
2721 | 2763 |
2722 } // namespace dart | 2764 } // namespace dart |
OLD | NEW |