| 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 |