| 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" |
| 11 #include "vm/coverage.h" | 11 #include "vm/coverage.h" |
| 12 #include "vm/cpu.h" | 12 #include "vm/cpu.h" |
| 13 #include "vm/dart_api_impl.h" | 13 #include "vm/dart_api_impl.h" |
| 14 #include "vm/dart_entry.h" | 14 #include "vm/dart_entry.h" |
| 15 #include "vm/debugger.h" | 15 #include "vm/debugger.h" |
| 16 #include "vm/isolate.h" | 16 #include "vm/isolate.h" |
| 17 #include "vm/lockers.h" | |
| 18 #include "vm/message.h" | 17 #include "vm/message.h" |
| 19 #include "vm/message_handler.h" | 18 #include "vm/message_handler.h" |
| 20 #include "vm/native_entry.h" | 19 #include "vm/native_entry.h" |
| 21 #include "vm/native_arguments.h" | 20 #include "vm/native_arguments.h" |
| 22 #include "vm/object.h" | 21 #include "vm/object.h" |
| 23 #include "vm/object_graph.h" | 22 #include "vm/object_graph.h" |
| 24 #include "vm/object_id_ring.h" | 23 #include "vm/object_id_ring.h" |
| 25 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
| 26 #include "vm/parser.h" | 25 #include "vm/parser.h" |
| 27 #include "vm/port.h" | 26 #include "vm/port.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 static void SendRootServiceMessage(Dart_NativeArguments args) { | 240 static void SendRootServiceMessage(Dart_NativeArguments args) { |
| 242 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 241 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 243 Isolate* isolate = arguments->isolate(); | 242 Isolate* isolate = arguments->isolate(); |
| 244 StackZone zone(isolate); | 243 StackZone zone(isolate); |
| 245 HANDLESCOPE(isolate); | 244 HANDLESCOPE(isolate); |
| 246 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(0)); | 245 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(0)); |
| 247 Service::HandleRootMessage(message); | 246 Service::HandleRootMessage(message); |
| 248 } | 247 } |
| 249 | 248 |
| 250 | 249 |
| 251 Dart_Port Service::WaitForLoadPort() { | |
| 252 MonitorLocker ml(monitor_); | |
| 253 | |
| 254 while (initializing_ && (load_port_ == ILLEGAL_PORT)) { | |
| 255 ml.Wait(); | |
| 256 } | |
| 257 | |
| 258 return load_port_; | |
| 259 } | |
| 260 | |
| 261 | |
| 262 Dart_Port Service::LoadPort() { | |
| 263 MonitorLocker ml(monitor_); | |
| 264 return load_port_; | |
| 265 } | |
| 266 | |
| 267 | |
| 268 void Service::SetLoadPort(Dart_Port port) { | |
| 269 MonitorLocker ml(monitor_); | |
| 270 load_port_ = port; | |
| 271 } | |
| 272 | |
| 273 | |
| 274 void Service::SetEventMask(uint32_t mask) { | 250 void Service::SetEventMask(uint32_t mask) { |
| 275 event_mask_ = mask; | 251 event_mask_ = mask; |
| 276 } | 252 } |
| 277 | 253 |
| 278 | 254 |
| 279 static void SetEventMask(Dart_NativeArguments args) { | 255 static void SetEventMask(Dart_NativeArguments args) { |
| 280 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 256 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 281 Isolate* isolate = arguments->isolate(); | 257 Isolate* isolate = arguments->isolate(); |
| 282 StackZone zone(isolate); | 258 StackZone zone(isolate); |
| 283 HANDLESCOPE(isolate); | 259 HANDLESCOPE(isolate); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); | 317 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); |
| 342 const String& name = String::Handle(String::New(isolate->name())); | 318 const String& name = String::Handle(String::New(isolate->name())); |
| 343 ASSERT(!name.IsNull()); | 319 ASSERT(!name.IsNull()); |
| 344 const Array& args = Array::Handle(Array::New(3)); | 320 const Array& args = Array::Handle(Array::New(3)); |
| 345 ASSERT(!args.IsNull()); | 321 ASSERT(!args.IsNull()); |
| 346 args.SetAt(0, port_int); | 322 args.SetAt(0, port_int); |
| 347 args.SetAt(1, send_port); | 323 args.SetAt(1, send_port); |
| 348 args.SetAt(2, name); | 324 args.SetAt(2, name); |
| 349 Object& r = Object::Handle(service_isolate_); | 325 Object& r = Object::Handle(service_isolate_); |
| 350 r = DartEntry::InvokeFunction(register_function_, args); | 326 r = DartEntry::InvokeFunction(register_function_, args); |
| 351 if (FLAG_trace_service) { | |
| 352 OS::Print("Isolate %s %" Pd64 " registered with service \n", | |
| 353 name.ToCString(), | |
| 354 port_id); | |
| 355 } | |
| 356 ASSERT(!r.IsError()); | 327 ASSERT(!r.IsError()); |
| 357 } | 328 } |
| 358 | 329 |
| 359 private: | 330 private: |
| 360 Function& register_function_; | 331 Function& register_function_; |
| 361 Isolate* service_isolate_; | 332 Isolate* service_isolate_; |
| 362 }; | 333 }; |
| 363 | 334 |
| 364 | 335 |
| 365 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { | 336 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { |
| 366 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); | 337 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); |
| 367 if (rp.IsNull()) { | 338 if (rp.IsNull()) { |
| 368 return ILLEGAL_PORT; | 339 return ILLEGAL_PORT; |
| 369 } | 340 } |
| 370 return rp.Id(); | 341 return rp.Id(); |
| 371 } | 342 } |
| 372 | 343 |
| 373 | 344 |
| 374 static void OnStart(Dart_NativeArguments args) { | 345 static void OnStart(Dart_NativeArguments args) { |
| 375 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 346 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 376 Isolate* isolate = arguments->isolate(); | 347 Isolate* isolate = arguments->isolate(); |
| 377 StackZone zone(isolate); | 348 StackZone zone(isolate); |
| 378 HANDLESCOPE(isolate); | 349 HANDLESCOPE(isolate); |
| 379 { | 350 { |
| 380 if (FLAG_trace_service) { | |
| 381 OS::Print("Booting dart:vmservice library\n"); | |
| 382 } | |
| 383 // Boot the dart:vmservice library. | 351 // Boot the dart:vmservice library. |
| 384 Dart_EnterScope(); | 352 Dart_EnterScope(); |
| 385 Dart_Handle url_str = | 353 Dart_Handle url_str = |
| 386 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); | 354 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); |
| 387 Dart_Handle library = Dart_LookupLibrary(url_str); | 355 Dart_Handle library = Dart_LookupLibrary(url_str); |
| 388 ASSERT(Dart_IsLibrary(library)); | 356 ASSERT(Dart_IsLibrary(library)); |
| 389 Dart_Handle result = | 357 Dart_Handle result = |
| 390 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); | 358 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); |
| 391 ASSERT(!Dart_IsError(result)); | 359 ASSERT(!Dart_IsError(result)); |
| 392 Dart_Port port = ExtractPort(isolate, result); | 360 Dart_Port port = ExtractPort(isolate, result); |
| 393 ASSERT(port != ILLEGAL_PORT); | 361 ASSERT(port != ILLEGAL_PORT); |
| 394 Service::set_port(port); | 362 Service::set_port(port); |
| 395 Dart_ExitScope(); | 363 Dart_ExitScope(); |
| 396 } | 364 } |
| 397 | |
| 398 { | 365 { |
| 399 if (FLAG_trace_service) { | |
| 400 OS::Print("Registering running isolates\n"); | |
| 401 } | |
| 402 // Register running isolates with service. | 366 // Register running isolates with service. |
| 403 RegisterRunningIsolatesVisitor register_isolates(isolate); | 367 RegisterRunningIsolatesVisitor register_isolates(isolate); |
| 404 Isolate::VisitIsolates(®ister_isolates); | 368 Isolate::VisitIsolates(®ister_isolates); |
| 405 } | 369 } |
| 406 } | 370 } |
| 407 | 371 |
| 408 | 372 |
| 409 struct VmServiceNativeEntry { | 373 struct VmServiceNativeEntry { |
| 410 const char* name; | 374 const char* name; |
| 411 int num_arguments; | 375 int num_arguments; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 437 for (intptr_t i = 0; i < n; i++) { | 401 for (intptr_t i = 0; i < n; i++) { |
| 438 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; | 402 VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; |
| 439 if ((strcmp(function_name, entry.name) == 0) && | 403 if ((strcmp(function_name, entry.name) == 0) && |
| 440 (num_arguments == entry.num_arguments)) { | 404 (num_arguments == entry.num_arguments)) { |
| 441 return entry.function; | 405 return entry.function; |
| 442 } | 406 } |
| 443 } | 407 } |
| 444 return NULL; | 408 return NULL; |
| 445 } | 409 } |
| 446 | 410 |
| 447 const char* Service::kServiceIsolateName = "vm-service"; | 411 |
| 448 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; | 412 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; |
| 449 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; | 413 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; |
| 450 Isolate* Service::service_isolate_ = NULL; | 414 Isolate* Service::service_isolate_ = NULL; |
| 415 Dart_LibraryTagHandler Service::embedder_provided_handler_ = NULL; |
| 451 Dart_Port Service::port_ = ILLEGAL_PORT; | 416 Dart_Port Service::port_ = ILLEGAL_PORT; |
| 452 Dart_Port Service::load_port_ = ILLEGAL_PORT; | |
| 453 Monitor* Service::monitor_ = NULL; | |
| 454 bool Service::initializing_ = true; | |
| 455 uint32_t Service::event_mask_ = 0; | 417 uint32_t Service::event_mask_ = 0; |
| 456 | 418 |
| 419 Isolate* Service::GetServiceIsolate(void* callback_data) { |
| 420 if (service_isolate_ != NULL) { |
| 421 // Already initialized, return service isolate. |
| 422 return service_isolate_; |
| 423 } |
| 424 Dart_ServiceIsolateCreateCalback create_callback = |
| 425 Isolate::ServiceCreateCallback(); |
| 426 if (create_callback == NULL) { |
| 427 return NULL; |
| 428 } |
| 429 Isolate::SetCurrent(NULL); |
| 430 char* error = NULL; |
| 431 Isolate* isolate = |
| 432 reinterpret_cast<Isolate*>(create_callback(callback_data, &error)); |
| 433 if (isolate == NULL) { |
| 434 return NULL; |
| 435 } |
| 436 StartIsolateScope isolate_scope(isolate); |
| 437 { |
| 438 // Install the dart:vmservice library. |
| 439 StackZone zone(isolate); |
| 440 HANDLESCOPE(isolate); |
| 441 Library& library = |
| 442 Library::Handle(isolate, isolate->object_store()->root_library()); |
| 443 // Isolate is empty. |
| 444 ASSERT(library.IsNull()); |
| 445 // Grab embedder tag handler. |
| 446 embedder_provided_handler_ = isolate->library_tag_handler(); |
| 447 // Temporarily install our own. |
| 448 isolate->set_library_tag_handler(LibraryTagHandler); |
| 449 // Get script resource. |
| 450 const char* resource = NULL; |
| 451 const char* path = "/vmservice.dart"; |
| 452 intptr_t r = Resources::ResourceLookup(path, &resource); |
| 453 ASSERT(r != Resources::kNoSuchInstance); |
| 454 ASSERT(resource != NULL); |
| 455 const String& source_str = String::Handle( |
| 456 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r)); |
| 457 ASSERT(!source_str.IsNull()); |
| 458 const String& url_str = String::Handle(Symbols::DartVMService().raw()); |
| 459 library ^= Library::LookupLibrary(url_str); |
| 460 ASSERT(library.IsNull()); |
| 461 // Setup library. |
| 462 library = Library::New(url_str); |
| 463 library.Register(); |
| 464 const Script& script = Script::Handle( |
| 465 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag)); |
| 466 library.SetLoadInProgress(); |
| 467 Dart_EnterScope(); // Need to enter scope for tag handler. |
| 468 const Error& error = Error::Handle(isolate, |
| 469 Compiler::Compile(library, script)); |
| 470 ASSERT(error.IsNull()); |
| 471 Dart_Handle result = Dart_FinalizeLoading(false); |
| 472 ASSERT(!Dart_IsError(result)); |
| 473 Dart_ExitScope(); |
| 457 | 474 |
| 458 bool Service::IsServiceIsolateName(const char* name) { | 475 // Install embedder default library tag handler again. |
| 459 ASSERT(name != NULL); | 476 isolate->set_library_tag_handler(embedder_provided_handler_); |
| 460 return strcmp(name, kServiceIsolateName) == 0; | 477 embedder_provided_handler_ = NULL; |
| 478 library.set_native_entry_resolver(VmServiceNativeResolver); |
| 479 } |
| 480 service_isolate_ = reinterpret_cast<Isolate*>(isolate); |
| 481 return service_isolate_; |
| 461 } | 482 } |
| 462 | 483 |
| 463 | 484 |
| 464 bool Service::SendIsolateStartupMessage() { | 485 bool Service::SendIsolateStartupMessage() { |
| 465 if (!IsRunning()) { | 486 if (!IsRunning()) { |
| 466 return false; | 487 return false; |
| 467 } | 488 } |
| 468 Isolate* isolate = Isolate::Current(); | 489 Isolate* isolate = Isolate::Current(); |
| 469 if (IsServiceIsolate(isolate)) { | |
| 470 return false; | |
| 471 } | |
| 472 ASSERT(isolate != NULL); | 490 ASSERT(isolate != NULL); |
| 473 HANDLESCOPE(isolate); | 491 HANDLESCOPE(isolate); |
| 474 const String& name = String::Handle(String::New(isolate->name())); | 492 const String& name = String::Handle(String::New(isolate->name())); |
| 475 ASSERT(!name.IsNull()); | 493 ASSERT(!name.IsNull()); |
| 476 const Array& list = Array::Handle( | 494 const Array& list = Array::Handle( |
| 477 MakeServiceControlMessage(Dart_GetMainPortId(), | 495 MakeServiceControlMessage(Dart_GetMainPortId(), |
| 478 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, | 496 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID, |
| 479 name)); | 497 name)); |
| 480 ASSERT(!list.IsNull()); | 498 ASSERT(!list.IsNull()); |
| 481 uint8_t* data = NULL; | 499 uint8_t* data = NULL; |
| 482 MessageWriter writer(&data, &allocator, false); | 500 MessageWriter writer(&data, &allocator, false); |
| 483 writer.WriteMessage(list); | 501 writer.WriteMessage(list); |
| 484 intptr_t len = writer.BytesWritten(); | 502 intptr_t len = writer.BytesWritten(); |
| 485 if (FLAG_trace_service) { | 503 if (FLAG_trace_service) { |
| 486 OS::Print("Isolate %s %" Pd64 " registered with service \n", | 504 OS::Print("Isolate %s %" Pd64 " registered with service \n", |
| 487 name.ToCString(), | 505 name.ToCString(), |
| 488 Dart_GetMainPortId()); | 506 Dart_GetMainPortId()); |
| 489 } | 507 } |
| 490 return PortMap::PostMessage( | 508 return PortMap::PostMessage( |
| 491 new Message(port_, data, len, Message::kNormalPriority)); | 509 new Message(port_, data, len, Message::kNormalPriority)); |
| 492 } | 510 } |
| 493 | 511 |
| 494 | 512 |
| 495 bool Service::SendIsolateShutdownMessage() { | 513 bool Service::SendIsolateShutdownMessage() { |
| 496 if (!IsRunning()) { | 514 if (!IsRunning()) { |
| 497 return false; | 515 return false; |
| 498 } | 516 } |
| 499 Isolate* isolate = Isolate::Current(); | 517 Isolate* isolate = Isolate::Current(); |
| 500 if (IsServiceIsolate(isolate)) { | |
| 501 return false; | |
| 502 } | |
| 503 ASSERT(isolate != NULL); | 518 ASSERT(isolate != NULL); |
| 504 HANDLESCOPE(isolate); | 519 HANDLESCOPE(isolate); |
| 505 const String& name = String::Handle(String::New(isolate->name())); | 520 const String& name = String::Handle(String::New(isolate->name())); |
| 506 ASSERT(!name.IsNull()); | 521 ASSERT(!name.IsNull()); |
| 507 const Array& list = Array::Handle( | 522 const Array& list = Array::Handle( |
| 508 MakeServiceControlMessage(Dart_GetMainPortId(), | 523 MakeServiceControlMessage(Dart_GetMainPortId(), |
| 509 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, | 524 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID, |
| 510 name)); | 525 name)); |
| 511 ASSERT(!list.IsNull()); | 526 ASSERT(!list.IsNull()); |
| 512 uint8_t* data = NULL; | 527 uint8_t* data = NULL; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 538 const uint8_t* str = Resources::Resource(i); | 553 const uint8_t* str = Resources::Resource(i); |
| 539 intptr_t length = Resources::Length(i); | 554 intptr_t length = Resources::Length(i); |
| 540 return Dart_NewStringFromUTF8(str, length); | 555 return Dart_NewStringFromUTF8(str, length); |
| 541 } | 556 } |
| 542 i++; | 557 i++; |
| 543 } | 558 } |
| 544 return Dart_Null(); | 559 return Dart_Null(); |
| 545 } | 560 } |
| 546 | 561 |
| 547 | 562 |
| 548 Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, | 563 Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, |
| 549 Dart_Handle library, | |
| 550 Dart_Handle url) { | 564 Dart_Handle url) { |
| 551 if (!Dart_IsLibrary(library)) { | 565 if (!Dart_IsLibrary(library)) { |
| 552 return Dart_NewApiError("not a library"); | 566 return Dart_NewApiError("not a library"); |
| 553 } | 567 } |
| 554 if (!Dart_IsString(url)) { | 568 if (!Dart_IsString(url)) { |
| 555 return Dart_NewApiError("url is not a string"); | 569 return Dart_NewApiError("url is not a string"); |
| 556 } | 570 } |
| 557 const char* url_string = NULL; | 571 const char* url_string = NULL; |
| 558 Dart_Handle result = Dart_StringToCString(url, &url_string); | 572 Dart_Handle result = Dart_StringToCString(url, &url_string); |
| 559 if (Dart_IsError(result)) { | 573 if (Dart_IsError(result)) { |
| 560 return result; | 574 return result; |
| 561 } | 575 } |
| 562 if (tag == Dart_kImportTag) { | 576 if (tag == Dart_kImportTag) { |
| 563 OS::Print("Attempting to import %s\n", url_string); | 577 // Embedder handles all requests for external libraries. |
| 564 return Dart_NewApiError("Unable to import module as no library tag " | 578 if (embedder_provided_handler_ == NULL) { |
| 565 "is available"); | 579 return Dart_NewApiError("Unable to import module as no library tag " |
| 580 "handler has been provided by embedder"); |
| 581 } |
| 582 return embedder_provided_handler_(tag, library, url); |
| 566 } | 583 } |
| 567 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); | 584 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); |
| 568 if (tag == Dart_kCanonicalizeUrl) { | 585 if (tag == Dart_kCanonicalizeUrl) { |
| 569 // url is already canonicalized. | 586 // url is already canonicalized. |
| 570 return url; | 587 return url; |
| 571 } | 588 } |
| 572 Dart_Handle source = GetSource(url_string); | 589 Dart_Handle source = GetSource(url_string); |
| 573 if (Dart_IsError(source)) { | 590 if (Dart_IsError(source)) { |
| 574 return source; | 591 return source; |
| 575 } | 592 } |
| 576 return Dart_LoadSource(library, url, source, 0, 0); | 593 return Dart_LoadSource(library, url, source, 0, 0); |
| 577 } | 594 } |
| 578 | 595 |
| 579 | 596 |
| 580 void Service::MaybeInjectVMServiceLibrary(Isolate* isolate) { | |
| 581 if (service_isolate_ != NULL) { | |
| 582 // Service isolate already exists. | |
| 583 return; | |
| 584 } | |
| 585 if (!Service::IsServiceIsolateName(isolate->name())) { | |
| 586 // Not service isolate. | |
| 587 return; | |
| 588 } | |
| 589 service_isolate_ = isolate; | |
| 590 ASSERT(isolate != NULL); | |
| 591 StackZone zone(isolate); | |
| 592 HANDLESCOPE(isolate); | |
| 593 | |
| 594 // Verify that isolate has no root library. | |
| 595 Library& library = | |
| 596 Library::Handle(isolate, isolate->object_store()->root_library()); | |
| 597 ASSERT(library.IsNull()); | |
| 598 | |
| 599 // Verify that isolate doesn't have the dart:vmservice library. | |
| 600 const String& url_str = String::Handle(Symbols::DartVMService().raw()); | |
| 601 library ^= Library::LookupLibrary(url_str); | |
| 602 ASSERT(library.IsNull()); | |
| 603 | |
| 604 // Register dart:vmservice library. | |
| 605 library = Library::New(url_str); | |
| 606 library.Register(); | |
| 607 library.set_native_entry_resolver(VmServiceNativeResolver); | |
| 608 | |
| 609 // Temporarily install our library tag handler. | |
| 610 isolate->set_library_tag_handler(LibraryTagHandler); | |
| 611 | |
| 612 // Get script source. | |
| 613 const char* resource = NULL; | |
| 614 const char* path = "/vmservice.dart"; | |
| 615 intptr_t r = Resources::ResourceLookup(path, &resource); | |
| 616 ASSERT(r != Resources::kNoSuchInstance); | |
| 617 ASSERT(resource != NULL); | |
| 618 const String& source_str = String::Handle( | |
| 619 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r)); | |
| 620 ASSERT(!source_str.IsNull()); | |
| 621 const Script& script = Script::Handle( | |
| 622 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag)); | |
| 623 | |
| 624 // Compile script. | |
| 625 Dart_EnterScope(); // Need to enter scope for tag handler. | |
| 626 library.SetLoadInProgress(); | |
| 627 const Error& error = Error::Handle(isolate, | |
| 628 Compiler::Compile(library, script)); | |
| 629 ASSERT(error.IsNull()); | |
| 630 Dart_Handle result = Dart_FinalizeLoading(false); | |
| 631 ASSERT(!Dart_IsError(result)); | |
| 632 Dart_ExitScope(); | |
| 633 | |
| 634 // Uninstall our library tag handler. | |
| 635 isolate->set_library_tag_handler(NULL); | |
| 636 } | |
| 637 | |
| 638 | |
| 639 void Service::FinishedInitializing() { | |
| 640 MonitorLocker ml(monitor_); | |
| 641 initializing_ = false; | |
| 642 ml.NotifyAll(); | |
| 643 } | |
| 644 | |
| 645 | |
| 646 static void ShutdownIsolate(uword parameter) { | |
| 647 Isolate* isolate = reinterpret_cast<Isolate*>(parameter); | |
| 648 { | |
| 649 // Print the error if there is one. This may execute dart code to | |
| 650 // print the exception object, so we need to use a StartIsolateScope. | |
| 651 StartIsolateScope start_scope(isolate); | |
| 652 StackZone zone(isolate); | |
| 653 HandleScope handle_scope(isolate); | |
| 654 Error& error = Error::Handle(); | |
| 655 error = isolate->object_store()->sticky_error(); | |
| 656 if (!error.IsNull()) { | |
| 657 OS::PrintErr("Service shutting down: %s\n", error.ToErrorCString()); | |
| 658 } | |
| 659 Dart::RunShutdownCallback(); | |
| 660 } | |
| 661 { | |
| 662 // Shut the isolate down. | |
| 663 SwitchIsolateScope switch_scope(isolate); | |
| 664 Dart::ShutdownIsolate(); | |
| 665 } | |
| 666 } | |
| 667 | |
| 668 | |
| 669 class RunServiceTask : public ThreadPool::Task { | |
| 670 public: | |
| 671 virtual void Run() { | |
| 672 ASSERT(Isolate::Current() == NULL); | |
| 673 | |
| 674 Dart_IsolateCreateCallback create_callback = Isolate::CreateCallback(); | |
| 675 if (create_callback == NULL) { | |
| 676 Service::FinishedInitializing(); | |
| 677 return; | |
| 678 } | |
| 679 | |
| 680 char* error = NULL; | |
| 681 Isolate* isolate = | |
| 682 reinterpret_cast<Isolate*>(create_callback(Service::kServiceIsolateName, | |
| 683 NULL, | |
| 684 NULL, | |
| 685 NULL, | |
| 686 &error)); | |
| 687 Isolate::SetCurrent(NULL); | |
| 688 | |
| 689 if (isolate == NULL) { | |
| 690 OS::PrintErr("Service startup error: %s\n", error); | |
| 691 Service::FinishedInitializing(); | |
| 692 return; | |
| 693 } | |
| 694 | |
| 695 RunMain(isolate); | |
| 696 | |
| 697 Service::FinishedInitializing(); | |
| 698 | |
| 699 isolate->message_handler()->Run(Dart::thread_pool(), | |
| 700 NULL, | |
| 701 ShutdownIsolate, | |
| 702 reinterpret_cast<uword>(isolate)); | |
| 703 } | |
| 704 | |
| 705 protected: | |
| 706 void RunMain(Isolate* isolate) { | |
| 707 StartIsolateScope iso_scope(isolate); | |
| 708 StackZone zone(isolate); | |
| 709 HANDLESCOPE(isolate); | |
| 710 // Invoke main which will return the loadScriptPort. | |
| 711 const Library& root_library = | |
| 712 Library::Handle(isolate, isolate->object_store()->root_library()); | |
| 713 if (root_library.IsNull()) { | |
| 714 // Service isolate is not supported by embedder. | |
| 715 return; | |
| 716 } | |
| 717 ASSERT(!root_library.IsNull()); | |
| 718 const String& entry_name = String::Handle(isolate, String::New("main")); | |
| 719 ASSERT(!entry_name.IsNull()); | |
| 720 const Function& entry = | |
| 721 Function::Handle(isolate, | |
| 722 root_library.LookupFunctionAllowPrivate(entry_name)); | |
| 723 if (entry.IsNull()) { | |
| 724 // Service isolate is not supported by embedder. | |
| 725 return; | |
| 726 } | |
| 727 ASSERT(!entry.IsNull()); | |
| 728 const Object& result = | |
| 729 Object::Handle(isolate, | |
| 730 DartEntry::InvokeFunction(entry, | |
| 731 Object::empty_array())); | |
| 732 ASSERT(!result.IsNull()); | |
| 733 if (result.IsError()) { | |
| 734 // Service isolate did not initialize properly. | |
| 735 return; | |
| 736 } | |
| 737 ASSERT(result.IsReceivePort()); | |
| 738 const ReceivePort& rp = ReceivePort::Cast(result); | |
| 739 Service::SetLoadPort(rp.Id()); | |
| 740 } | |
| 741 }; | |
| 742 | |
| 743 | |
| 744 void Service::RunService() { | |
| 745 ASSERT(monitor_ == NULL); | |
| 746 monitor_ = new Monitor(); | |
| 747 ASSERT(monitor_ != NULL); | |
| 748 Dart::thread_pool()->Run(new RunServiceTask()); | |
| 749 } | |
| 750 | |
| 751 // A handler for a per-isolate request. | 597 // A handler for a per-isolate request. |
| 752 // | 598 // |
| 753 // If a handler returns true, the reply is complete and ready to be | 599 // If a handler returns true, the reply is complete and ready to be |
| 754 // posted. If a handler returns false, then it is responsible for | 600 // posted. If a handler returns false, then it is responsible for |
| 755 // posting the reply (this can be used for asynchronous delegation of | 601 // posting the reply (this can be used for asynchronous delegation of |
| 756 // the response handling). | 602 // the response handling). |
| 757 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); | 603 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); |
| 758 | 604 |
| 759 struct IsolateMessageHandlerEntry { | 605 struct IsolateMessageHandlerEntry { |
| 760 const char* command; | 606 const char* command; |
| (...skipping 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2934 while (current != NULL) { | 2780 while (current != NULL) { |
| 2935 if (strcmp(name, current->name()) == 0) { | 2781 if (strcmp(name, current->name()) == 0) { |
| 2936 return current; | 2782 return current; |
| 2937 } | 2783 } |
| 2938 current = current->next(); | 2784 current = current->next(); |
| 2939 } | 2785 } |
| 2940 return NULL; | 2786 return NULL; |
| 2941 } | 2787 } |
| 2942 | 2788 |
| 2943 } // namespace dart | 2789 } // namespace dart |
| OLD | NEW |