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 |