| Index: runtime/vm/service.cc
|
| diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
|
| index 4f4913c3be879b6887b41ac64e4e1d64a7e82d87..a3f0370cd5d6b46e14e10bb050631d7de6d68351 100644
|
| --- a/runtime/vm/service.cc
|
| +++ b/runtime/vm/service.cc
|
| @@ -323,6 +323,11 @@ class RegisterRunningIsolatesVisitor : public IsolateVisitor {
|
| args.SetAt(2, name);
|
| Object& r = Object::Handle(service_isolate_);
|
| r = DartEntry::InvokeFunction(register_function_, args);
|
| + if (FLAG_trace_service) {
|
| + OS::Print("Isolate %s %" Pd64 " registered with service \n",
|
| + name.ToCString(),
|
| + port_id);
|
| + }
|
| ASSERT(!r.IsError());
|
| }
|
|
|
| @@ -347,6 +352,9 @@ static void OnStart(Dart_NativeArguments args) {
|
| StackZone zone(isolate);
|
| HANDLESCOPE(isolate);
|
| {
|
| + if (FLAG_trace_service) {
|
| + OS::Print("Booting dart:vmservice library\n");
|
| + }
|
| // Boot the dart:vmservice library.
|
| Dart_EnterScope();
|
| Dart_Handle url_str =
|
| @@ -361,7 +369,11 @@ static void OnStart(Dart_NativeArguments args) {
|
| Service::set_port(port);
|
| Dart_ExitScope();
|
| }
|
| +
|
| {
|
| + if (FLAG_trace_service) {
|
| + OS::Print("Registering running isolates\n");
|
| + }
|
| // Register running isolates with service.
|
| RegisterRunningIsolatesVisitor register_isolates(isolate);
|
| Isolate::VisitIsolates(®ister_isolates);
|
| @@ -411,76 +423,9 @@ static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
|
| EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL;
|
| EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
|
| Isolate* Service::service_isolate_ = NULL;
|
| -Dart_LibraryTagHandler Service::embedder_provided_handler_ = NULL;
|
| Dart_Port Service::port_ = ILLEGAL_PORT;
|
| uint32_t Service::event_mask_ = 0;
|
|
|
| -Isolate* Service::GetServiceIsolate(void* callback_data) {
|
| - if (service_isolate_ != NULL) {
|
| - // Already initialized, return service isolate.
|
| - return service_isolate_;
|
| - }
|
| - Dart_ServiceIsolateCreateCalback create_callback =
|
| - Isolate::ServiceCreateCallback();
|
| - if (create_callback == NULL) {
|
| - return NULL;
|
| - }
|
| - Isolate::SetCurrent(NULL);
|
| - char* error = NULL;
|
| - Isolate* isolate =
|
| - reinterpret_cast<Isolate*>(create_callback(callback_data, &error));
|
| - if (isolate == NULL) {
|
| - return NULL;
|
| - }
|
| - StartIsolateScope isolate_scope(isolate);
|
| - {
|
| - // Install the dart:vmservice library.
|
| - StackZone zone(isolate);
|
| - HANDLESCOPE(isolate);
|
| - Library& library =
|
| - Library::Handle(isolate, isolate->object_store()->root_library());
|
| - // Isolate is empty.
|
| - ASSERT(library.IsNull());
|
| - // Grab embedder tag handler.
|
| - embedder_provided_handler_ = isolate->library_tag_handler();
|
| - // Temporarily install our own.
|
| - isolate->set_library_tag_handler(LibraryTagHandler);
|
| - // Get script resource.
|
| - const char* resource = NULL;
|
| - const char* path = "/vmservice.dart";
|
| - intptr_t r = Resources::ResourceLookup(path, &resource);
|
| - ASSERT(r != Resources::kNoSuchInstance);
|
| - ASSERT(resource != NULL);
|
| - const String& source_str = String::Handle(
|
| - String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
|
| - ASSERT(!source_str.IsNull());
|
| - const String& url_str = String::Handle(Symbols::DartVMService().raw());
|
| - library ^= Library::LookupLibrary(url_str);
|
| - ASSERT(library.IsNull());
|
| - // Setup library.
|
| - library = Library::New(url_str);
|
| - library.Register();
|
| - const Script& script = Script::Handle(
|
| - isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
|
| - library.SetLoadInProgress();
|
| - Dart_EnterScope(); // Need to enter scope for tag handler.
|
| - const Error& error = Error::Handle(isolate,
|
| - Compiler::Compile(library, script));
|
| - ASSERT(error.IsNull());
|
| - Dart_Handle result = Dart_FinalizeLoading(false);
|
| - ASSERT(!Dart_IsError(result));
|
| - Dart_ExitScope();
|
| -
|
| - // Install embedder default library tag handler again.
|
| - isolate->set_library_tag_handler(embedder_provided_handler_);
|
| - embedder_provided_handler_ = NULL;
|
| - library.set_native_entry_resolver(VmServiceNativeResolver);
|
| - }
|
| - service_isolate_ = reinterpret_cast<Isolate*>(isolate);
|
| - return service_isolate_;
|
| -}
|
| -
|
| -
|
| bool Service::SendIsolateStartupMessage() {
|
| if (!IsRunning()) {
|
| return false;
|
| @@ -573,12 +518,8 @@ Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
|
| return result;
|
| }
|
| if (tag == Dart_kImportTag) {
|
| - // Embedder handles all requests for external libraries.
|
| - if (embedder_provided_handler_ == NULL) {
|
| - return Dart_NewApiError("Unable to import module as no library tag "
|
| - "handler has been provided by embedder");
|
| - }
|
| - return embedder_provided_handler_(tag, library, url);
|
| + return Dart_NewApiError("Unable to import module as no library tag "
|
| + "is available");
|
| }
|
| ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
|
| if (tag == Dart_kCanonicalizeUrl) {
|
| @@ -593,6 +534,107 @@ Dart_Handle Service::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle library,
|
| }
|
|
|
|
|
| +void Service::MaybeInjectVMServiceLibrary(Isolate* isolate) {
|
| + if (service_isolate_ != NULL) {
|
| + // vm-service isolate already exists.
|
| + return;
|
| + }
|
| + const char* vm_service_prefix = "vm-service$main";
|
| + const intptr_t vm_service_prefix_len = strlen(vm_service_prefix);
|
| + if (strncmp(isolate->name(), vm_service_prefix, vm_service_prefix_len) != 0) {
|
| + // Not vm-service isolate.
|
| + return;
|
| + }
|
| + service_isolate_ = isolate;
|
| + ASSERT(isolate != NULL);
|
| + StackZone zone(isolate);
|
| + HANDLESCOPE(isolate);
|
| + Library& library =
|
| + Library::Handle(isolate, isolate->object_store()->root_library());
|
| + // Isolate is empty.
|
| + ASSERT(library.IsNull());
|
| + // Temporarily install our library tag handler.
|
| + isolate->set_library_tag_handler(LibraryTagHandler);
|
| + // Get script resource.
|
| + const char* resource = NULL;
|
| + const char* path = "/vmservice.dart";
|
| + intptr_t r = Resources::ResourceLookup(path, &resource);
|
| + ASSERT(r != Resources::kNoSuchInstance);
|
| + ASSERT(resource != NULL);
|
| + const String& source_str = String::Handle(
|
| + String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
|
| + ASSERT(!source_str.IsNull());
|
| + const String& url_str = String::Handle(Symbols::DartVMService().raw());
|
| + library ^= Library::LookupLibrary(url_str);
|
| + ASSERT(library.IsNull());
|
| + // Setup library.
|
| + library = Library::New(url_str);
|
| + library.Register();
|
| + const Script& script = Script::Handle(
|
| + isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
|
| + library.SetLoadInProgress();
|
| + Dart_EnterScope(); // Need to enter scope for tag handler.
|
| + const Error& error = Error::Handle(isolate,
|
| + Compiler::Compile(library, script));
|
| + ASSERT(error.IsNull());
|
| + Dart_Handle result = Dart_FinalizeLoading(false);
|
| + ASSERT(!Dart_IsError(result));
|
| + Dart_ExitScope();
|
| +
|
| + // Uninstall our library tag handler.
|
| + isolate->set_library_tag_handler(NULL);
|
| + library.set_native_entry_resolver(VmServiceNativeResolver);
|
| +}
|
| +
|
| +
|
| +class RunServiceTask : public ThreadPool::Task {
|
| + public:
|
| + virtual void Run() {
|
| + ASSERT(Isolate::Current() == NULL);
|
| +
|
| + Dart_IsolateCreateCallback create_callback = Isolate::CreateCallback();
|
| + if (create_callback == NULL) {
|
| + return;
|
| + }
|
| +
|
| + char* error = NULL;
|
| + Isolate* isolate =
|
| + reinterpret_cast<Isolate*>(create_callback("vm-service",
|
| + NULL,
|
| + NULL,
|
| + &error));
|
| + if (isolate == NULL) {
|
| + printf("error: %s\n", error);
|
| + return;
|
| + }
|
| +
|
| + ASSERT(Isolate::Current() == NULL);
|
| +
|
| + // Quick hack to test invocation:
|
| + Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(isolate));
|
| + Dart_EnterScope();
|
| + Dart_Handle library = Dart_RootLibrary();
|
| + ASSERT(!Dart_IsError(library));
|
| + Dart_Handle function_name =
|
| + Dart_NewStringFromCString("main");
|
| + ASSERT(!Dart_IsError(function_name));
|
| + Dart_Handle result = Dart_Invoke(library, function_name, 0, NULL);
|
| + ASSERT(!Dart_IsError(result));
|
| +
|
| + result = Dart_RunLoop();
|
| + if (Dart_IsError(result)) {
|
| + printf("Service exited with an error:\n%s\n", Dart_GetError(result));
|
| + }
|
| + Dart_ExitScope();
|
| + Dart_ExitIsolate();
|
| + }
|
| +};
|
| +
|
| +
|
| +void Service::RunService() {
|
| + Dart::thread_pool()->Run(new RunServiceTask());
|
| +}
|
| +
|
| // A handler for a per-isolate request.
|
| //
|
| // If a handler returns true, the reply is complete and ready to be
|
|
|