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

Unified Diff: runtime/vm/service.cc

Issue 895943002: Support root-level json rpc requests in the vm service. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 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/vm/service.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/service.cc
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index e9b0cc70418b9b21e0a5778841030de924189d32..acb947fc21798bea6c548790379fb14d888d5ebb 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -841,6 +841,7 @@ struct RootMessageHandlerEntry {
};
static RootMessageHandler FindRootMessageHandler(const char* command);
+static RootMessageHandler FindRootMessageHandlerNew(const char* command);
static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) {
@@ -1456,6 +1457,54 @@ static RawObject* LookupHeapObjectClasses(Isolate* isolate,
}
+static RawObject* LookupHeapObjectCode(Isolate* isolate,
+ char** parts, int num_parts) {
+ if (num_parts != 2) {
+ return Object::sentinel().raw();
+ }
+ uword pc;
+ static const char* kCollectedPrefix = "collected-";
+ static intptr_t kCollectedPrefixLen = strlen(kCollectedPrefix);
+ static const char* kNativePrefix = "native-";
+ static intptr_t kNativePrefixLen = strlen(kNativePrefix);
+ static const char* kReusedPrefix = "reused-";
+ static intptr_t kReusedPrefixLen = strlen(kReusedPrefix);
+ const char* id = parts[1];
+ if (strncmp(kCollectedPrefix, id, kCollectedPrefixLen) == 0) {
+ if (!GetUnsignedIntegerId(&id[kCollectedPrefixLen], &pc, 16)) {
+ return Object::sentinel().raw();
+ }
+ // TODO(turnidge): Return "collected" instead.
+ return Object::null();
+ }
+ if (strncmp(kNativePrefix, id, kNativePrefixLen) == 0) {
+ if (!GetUnsignedIntegerId(&id[kNativePrefixLen], &pc, 16)) {
+ return Object::sentinel().raw();
+ }
+ // TODO(johnmccutchan): Support native Code.
+ return Object::null();
+ }
+ if (strncmp(kReusedPrefix, id, kReusedPrefixLen) == 0) {
+ if (!GetUnsignedIntegerId(&id[kReusedPrefixLen], &pc, 16)) {
+ return Object::sentinel().raw();
+ }
+ // TODO(turnidge): Return "expired" instead.
+ return Object::null();
+ }
+ int64_t timestamp = 0;
+ if (!GetCodeId(id, &timestamp, &pc) || (timestamp < 0)) {
+ return Object::sentinel().raw();
+ }
+ Code& code = Code::Handle(Code::FindCode(pc, timestamp));
+ if (!code.IsNull()) {
+ return code.raw();
+ }
+
+ // Not found.
+ return Object::sentinel().raw();
+}
+
+
static RawObject* LookupHeapObject(Isolate* isolate,
const char* id_original,
ObjectIdRing::LookupResult* result) {
@@ -1504,6 +1553,8 @@ static RawObject* LookupHeapObject(Isolate* isolate,
return LookupHeapObjectLibraries(isolate, parts, num_parts);
} else if (strcmp(parts[0], "classes") == 0) {
return LookupHeapObjectClasses(isolate, parts, num_parts);
+ } else if (strcmp(parts[0], "code") == 0) {
+ return LookupHeapObjectCode(isolate, parts, num_parts);
}
// Not found.
@@ -2909,10 +2960,10 @@ static IsolateMessageHandler FindIsolateMessageHandler(const char* command) {
static bool HandleIsolateGetObject(Isolate* isolate, JSONStream* js) {
- const char* id = js->LookupOption("id");
+ const char* id = js->LookupOption("objectId");
if (id == NULL) {
// TODO(turnidge): Print the isolate here instead.
- PrintError(js, "GetObject expects an 'id' parameter\n",
+ PrintError(js, "GetObject expects an 'objectId' parameter\n",
js->num_arguments());
return true;
}
@@ -2952,6 +3003,7 @@ static bool HandleIsolateGetClassList(Isolate* isolate, JSONStream* js) {
static IsolateMessageHandlerEntry isolate_handlers_new[] = {
+ { "getIsolate", HandleIsolate },
{ "getObject", HandleIsolateGetObject },
{ "getBreakpoints", HandleIsolateGetBreakpoints },
{ "pause", HandleIsolatePause },
@@ -2990,6 +3042,64 @@ static IsolateMessageHandler FindIsolateMessageHandlerNew(const char* command) {
}
+void Service::HandleRootMessageNew(const Array& msg) {
+ Isolate* isolate = Isolate::Current();
+ ASSERT(!msg.IsNull());
+
+ {
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+
+ const Array& message = Array::Cast(msg);
+ // Message is a list with five entries.
+ ASSERT(message.Length() == 5);
+
+ Instance& reply_port = Instance::Handle(isolate);
+ String& method = String::Handle(isolate);
+ Array& param_keys = Array::Handle(isolate);
+ Array& param_values = Array::Handle(isolate);
+ reply_port ^= msg.At(1);
+ method ^= msg.At(2);
+ param_keys ^= msg.At(3);
+ param_values ^= msg.At(4);
+
+ ASSERT(!method.IsNull());
+ ASSERT(!param_keys.IsNull());
+ ASSERT(!param_values.IsNull());
+ ASSERT(param_keys.Length() == param_values.Length());
+
+ if (!reply_port.IsSendPort()) {
+ FATAL("SendPort expected.");
+ }
+
+ RootMessageHandler handler =
+ FindRootMessageHandlerNew(method.ToCString());
+ {
+ JSONStream js;
+ js.SetupNew(zone.GetZone(), SendPort::Cast(reply_port).Id(),
+ method, param_keys, param_values);
+ if (handler == NULL) {
+ // Check for an embedder handler.
+ EmbedderServiceHandler* e_handler =
+ FindRootEmbedderHandler(method.ToCString());
+ if (e_handler != NULL) {
+ EmbedderHandleMessage(e_handler, &js);
+ } else {
+ PrintError(&js, "Unrecognized path");
+ }
+ js.PostReply();
+ } else {
+ if (handler(&js)) {
+ // Handler returns true if the reply is ready to be posted.
+ // TODO(johnmccutchan): Support asynchronous replies.
+ js.PostReply();
+ }
+ }
+ }
+ }
+}
+
+
void Service::HandleRootMessage(const Instance& msg) {
Isolate* isolate = Isolate::Current();
ASSERT(!msg.IsNull());
@@ -3003,6 +3113,12 @@ void Service::HandleRootMessage(const Instance& msg) {
// Message is a list with five entries.
ASSERT(message.Length() == 5);
+ Object& tmp = Object::Handle(isolate);
+ tmp = message.At(2);
+ if (tmp.IsString()) {
+ return Service::HandleRootMessageNew(message);
+ }
+
Instance& reply_port = Instance::Handle(isolate);
GrowableObjectArray& path = GrowableObjectArray::Handle(isolate);
Array& option_keys = Array::Handle(isolate);
@@ -3179,6 +3295,27 @@ static RootMessageHandler FindRootMessageHandler(const char* command) {
}
+static RootMessageHandlerEntry root_handlers_new[] = {
+ { "getVM", HandleVM },
+};
+
+
+static RootMessageHandler FindRootMessageHandlerNew(const char* command) {
+ intptr_t num_message_handlers = sizeof(root_handlers_new) /
+ sizeof(root_handlers_new[0]);
+ for (intptr_t i = 0; i < num_message_handlers; i++) {
+ const RootMessageHandlerEntry& entry = root_handlers_new[i];
+ if (strcmp(command, entry.command) == 0) {
+ return entry.handler;
+ }
+ }
+ if (FLAG_trace_service) {
+ OS::Print("vm-service: No root message handler for <%s>.\n", command);
+ }
+ return NULL;
+}
+
+
void Service::SendEvent(intptr_t eventId, const Object& eventMessage) {
if (!IsRunning()) {
return;
« no previous file with comments | « runtime/vm/service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698