Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Unified Diff: runtime/bin/vmservice_impl.cc

Issue 19231005: Initial NOOP VM Service (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/vmservice_impl.cc
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..42a98c62f096050c54cea8f8b1baade95d2da491
--- /dev/null
+++ b/runtime/bin/vmservice_impl.cc
@@ -0,0 +1,332 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "bin/vmservice_impl.h"
+
+#include "include/dart_api.h"
+
+#include "bin/builtin.h"
+#include "bin/dartutils.h"
+#include "bin/resources.h"
+#include "bin/thread.h"
+#include "bin/isolate_data.h"
+
+
+namespace dart {
+namespace bin {
+
+// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
+// it is initialized to NULL.
+extern const uint8_t* snapshot_buffer;
+#define RETURN_ERROR_HANDLE(handle) \
+ if (Dart_IsError(handle)) { \
+ return handle; \
+ }
+
+#define SHUTDOWN_ON_ERROR(handle) \
+ if (Dart_IsError(handle)) { \
+ error_msg_ = strdup(Dart_GetError(handle)); \
+ Dart_ExitScope(); \
+ Dart_ShutdownIsolate(); \
+ return false; \
+ }
+
+#define kLibraryResourceNamePrefix "/vmservice"
+static const char* kLibraryScriptResourceName =
+ kLibraryResourceNamePrefix "/vmservice.dart";
+static const char* kLibrarySourceResourceNames[] = {
+ NULL
+};
+
+#define kClientResourceNamePrefix "/client/web/out"
+
+Dart_Isolate VmService::isolate_ = NULL;
+Dart_Port VmService::port_ = ILLEGAL_PORT;
+dart::Monitor* VmService::monitor_ = NULL;
+const char* VmService::error_msg_ = NULL;
+
+// These must be kept in sync with vmservice/constants.dart
+#define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
+#define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
+
+
+bool VmService::Start(intptr_t server_port) {
+ monitor_ = new dart::Monitor();
+ ASSERT(monitor_ != NULL);
+ error_msg_ = NULL;
+
+ // The VM service is initialized on a new thread.
+ dart::Thread::Start(ThreadMain, server_port);
+ {
+ // Wait until service is running.
+ MonitorLocker ml(monitor_);
+ ml.Wait();
+ }
+ return port_ != ILLEGAL_PORT;
+}
+
+
+bool VmService::_Start(intptr_t server_port) {
+ ASSERT(isolate_ == NULL);
+ char* error = NULL;
+ isolate_ = Dart_CreateIsolate("vmservice:", "main", snapshot_buffer,
+ new IsolateData(),
+ &error);
+ if (isolate_ == NULL) {
+ error_msg_ = error;
+ return false;
+ }
+
+ Dart_EnterScope();
+
+ if (snapshot_buffer != NULL) {
+ // Setup the native resolver as the snapshot does not carry it.
+ Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
+ Builtin::SetNativeResolver(Builtin::kIOLibrary);
+ }
+
+ // Set up the library tag handler for this isolate.
+ Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
+ SHUTDOWN_ON_ERROR(result);
+
+ // Load the specified application script into the newly created isolate.
+
+ // Prepare builtin and its dependent libraries for use to resolve URIs.
+ // The builtin library is part of the core snapshot and would already be
+ // available here in the case of script snapshot loading.
+ Dart_Handle builtin_lib =
+ Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+ SHUTDOWN_ON_ERROR(builtin_lib);
+
+ // Prepare for script loading by setting up the 'print' and 'timer'
+ // closures and setting up 'package root' for URI resolution.
+ result = DartUtils::PrepareForScriptLoading("", builtin_lib);
+ SHUTDOWN_ON_ERROR(result);
+
+ {
+ // Load source into service isolate.
+ Dart_Handle library = LoadScript(kLibraryScriptResourceName);
+ SHUTDOWN_ON_ERROR(library);
+ result = LoadSources(library, kLibrarySourceResourceNames);
+ SHUTDOWN_ON_ERROR(result);
+ }
+
+ // Make the isolate runnable so that it is ready to handle messages.
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+
+ bool retval = Dart_IsolateMakeRunnable(isolate_);
+ if (!retval) {
+ Dart_EnterIsolate(isolate_);
+ Dart_ShutdownIsolate();
+ error_msg_ = "Invalid isolate state - Unable to make it runnable.";
+ return false;
+ }
+
+ Dart_EnterIsolate(isolate_);
+ Dart_EnterScope();
+
+ Dart_Handle library = Dart_RootLibrary();
+ result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
+ SHUTDOWN_ON_ERROR(result);
+
+ result = LoadResources(library);
+ SHUTDOWN_ON_ERROR(result);
+
+ port_ = Dart_GetMainPortId();
+
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+
+ return true;
+}
+
+
+void VmService::_Stop() {
+ port_ = ILLEGAL_PORT;
+}
+
+
+const char* VmService::GetErrorMessage() {
+ return error_msg_ == NULL ? "No error." : error_msg_;
+}
+
+
+Dart_Port VmService::port() {
+ return port_;
+}
+
+
+bool VmService::IsRunning() {
+ return port_ != ILLEGAL_PORT;
+}
+
+
+Dart_Handle VmService::LoadScript(const char* name) {
+ Dart_Handle url = Dart_NewStringFromCString(name);
+ const char* vmservice_source = NULL;
+ int r = Resources::ResourceLookup(name, &vmservice_source);
+ ASSERT(r != Resources::kNoSuchInstance);
+ Dart_Handle source = Dart_NewStringFromCString(vmservice_source);
+ return Dart_LoadScript(url, source, 0, 0);
+}
+
+
+Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
+ Dart_Handle url = Dart_NewStringFromCString(name);
+ const char* vmservice_source = NULL;
+ int r = Resources::ResourceLookup(name, &vmservice_source);
+ if (r == Resources::kNoSuchInstance) {
+ printf("Can't find %s\n", name);
+ }
+ ASSERT(r != Resources::kNoSuchInstance);
+ Dart_Handle source = Dart_NewStringFromCString(vmservice_source);
+ return Dart_LoadSource(library, url, source);
+}
+
+
+Dart_Handle VmService::LoadSources(Dart_Handle library, const char* names[]) {
+ Dart_Handle result = Dart_Null();
+ for (int i = 0; names[i] != NULL; i++) {
+ result = LoadSource(library, names[i]);
+ if (Dart_IsError(result)) {
+ break;
+ }
+ }
+ return result;
+}
+
+
+Dart_Handle VmService::LoadResource(Dart_Handle library,
+ const char* resource_name,
+ const char* prefix) {
+ intptr_t prefix_len = strlen(prefix);
+ // Prepare for invoke call.
+ Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len);
+ RETURN_ERROR_HANDLE(name);
+ const char* data_buffer = NULL;
+ int data_buffer_length = Resources::ResourceLookup(resource_name,
+ &data_buffer);
+ if (data_buffer_length == Resources::kNoSuchInstance) {
+ printf("Could not find %s %s\n", resource_name, resource_name+prefix_len);
+ }
+ ASSERT(data_buffer_length != Resources::kNoSuchInstance);
+ Dart_Handle data_list = Dart_NewTypedData(Dart_TypedData_kUint8,
+ data_buffer_length);
+ RETURN_ERROR_HANDLE(data_list);
+ Dart_TypedData_Type type = Dart_TypedData_kInvalid;
+ void* data_list_buffer = NULL;
+ intptr_t data_list_buffer_length = 0;
+ Dart_Handle result = Dart_TypedDataAcquireData(data_list, &type,
+ &data_list_buffer,
+ &data_list_buffer_length);
+ RETURN_ERROR_HANDLE(result);
+ ASSERT(data_buffer_length == data_list_buffer_length);
+ ASSERT(data_list_buffer != NULL);
+ ASSERT(type = Dart_TypedData_kUint8);
+ memmove(data_list_buffer, &data_buffer[0], data_buffer_length);
+ result = Dart_TypedDataReleaseData(data_list);
+ RETURN_ERROR_HANDLE(result);
+
+ // Make invoke call.
+ const intptr_t kNumArgs = 2;
+ Dart_Handle args[kNumArgs] = { name, data_list };
+ result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
+ kNumArgs, args);
+ return result;
+}
+
+
+Dart_Handle VmService::LoadResources(Dart_Handle library) {
+ Dart_Handle result = Dart_Null();
+ intptr_t prefixLen = strlen(kClientResourceNamePrefix);
+ for (intptr_t i = 0; i < Resources::get_resource_count(); i++) {
+ const char* path = Resources::get_resource_path(i);
+ if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) {
+ result = LoadResource(library, path, kClientResourceNamePrefix);
+ if (Dart_IsError(result)) {
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+
+void VmService::ThreadMain(uword parameters) {
+ ASSERT(Dart_CurrentIsolate() == NULL);
+ ASSERT(isolate_ == NULL);
siva 2013/07/16 00:00:04 I think you would have to close the MonitorLocker
+ MonitorLocker ml(monitor_);
+ intptr_t server_port = static_cast<intptr_t>(parameters);
+ ASSERT(server_port >= 0);
+
+ bool r = _Start(server_port);
+ if (!r) {
+ port_ = ILLEGAL_PORT;
+ monitor_->Notify();
+ return;
+ }
+
+ Dart_EnterIsolate(isolate_);
+ Dart_EnterScope();
+
+ Dart_Handle receievePort = Dart_GetReceivePort(port_);
+ ASSERT(!Dart_IsError(receievePort));
+
+ monitor_->Notify();
siva 2013/07/16 00:00:04 }
+ // Keep handling messages until the last active receive port is closed.
+ Dart_Handle result = Dart_RunLoop();
+ if (Dart_IsError(result)) {
+ printf("VmService error %s\n", Dart_GetError(result));
+ }
+
+ _Stop();
+
+ Dart_ExitScope();
+ Dart_ExitIsolate();
+}
+
+
+
+
+static Dart_Handle MakeServiceControlMessage(Dart_Port port) {
+ Dart_Handle list = Dart_NewList(2);
+ ASSERT(!Dart_IsError(list));
+ Dart_Handle sendPort = Dart_NewSendPort(port);
+ ASSERT(!Dart_IsError(sendPort));
+ Dart_ListSetAt(list, 1, sendPort);
+ return list;
+}
+
+
+bool VmService::SendIsolateStartupMessage(Dart_Port port) {
+ if (!IsRunning()) {
+ return false;
+ }
+ Dart_Isolate isolate = Dart_CurrentIsolate();
+ ASSERT(isolate != NULL);
+ ASSERT(Dart_GetMainPortId() == port);
+ Dart_Handle list = MakeServiceControlMessage(port);
+ Dart_ListSetAt(list, 0,
+ Dart_NewInteger(VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID));
+ return Dart_Post(port_, list);
+}
+
+
+bool VmService::SendIsolateShutdownMessage(Dart_Port port) {
+ if (!IsRunning()) {
+ return false;
+ }
+ Dart_Isolate isolate = Dart_CurrentIsolate();
+ ASSERT(isolate != NULL);
+ ASSERT(Dart_GetMainPortId() == port);
+ Dart_Handle list = MakeServiceControlMessage(port);
+ Dart_ListSetAt(list, 0,
+ Dart_NewInteger(VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID));
+ return Dart_Post(port_, list);
+}
+
+
+} // namespace bin
+} // namespace dart
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698