| 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/debugger.h" | 5 #include "vm/debugger.h" |
| 6 #include "vm/heap_histogram.h" | 6 #include "vm/heap_histogram.h" |
| 7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
| 8 #include "vm/message.h" | 8 #include "vm/message.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/object_id_ring.h" | 10 #include "vm/object_id_ring.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 ASSERT(option_keys.Length() == option_values.Length()); | 70 ASSERT(option_keys.Length() == option_values.Length()); |
| 71 | 71 |
| 72 String& pathSegment = String::Handle(); | 72 String& pathSegment = String::Handle(); |
| 73 pathSegment ^= path.At(0); | 73 pathSegment ^= path.At(0); |
| 74 ASSERT(!pathSegment.IsNull()); | 74 ASSERT(!pathSegment.IsNull()); |
| 75 | 75 |
| 76 ServiceMessageHandler handler = | 76 ServiceMessageHandler handler = |
| 77 FindServiceMessageHandler(pathSegment.ToCString()); | 77 FindServiceMessageHandler(pathSegment.ToCString()); |
| 78 ASSERT(handler != NULL); | 78 ASSERT(handler != NULL); |
| 79 { | 79 { |
| 80 TextBuffer buffer(256); | 80 JSONStream js; |
| 81 JSONStream js(&buffer); | |
| 82 | 81 |
| 83 // Setup JSONStream arguments and options. The arguments and options | 82 // Setup JSONStream arguments and options. The arguments and options |
| 84 // are zone allocated and will be freed immediately after handling the | 83 // are zone allocated and will be freed immediately after handling the |
| 85 // message. | 84 // message. |
| 86 Zone* zoneAllocator = zone.GetZone(); | 85 Zone* zoneAllocator = zone.GetZone(); |
| 87 const char** arguments = zoneAllocator->Alloc<const char*>(path.Length()); | 86 const char** arguments = zoneAllocator->Alloc<const char*>(path.Length()); |
| 88 String& string_iterator = String::Handle(); | 87 String& string_iterator = String::Handle(); |
| 89 for (intptr_t i = 0; i < path.Length(); i++) { | 88 for (intptr_t i = 0; i < path.Length(); i++) { |
| 90 string_iterator ^= path.At(i); | 89 string_iterator ^= path.At(i); |
| 91 arguments[i] = | 90 arguments[i] = |
| (...skipping 11 matching lines...) Expand all Loading... |
| 103 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); | 102 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); |
| 104 string_iterator ^= option_values.At(i); | 103 string_iterator ^= option_values.At(i); |
| 105 option_values_native[i] = | 104 option_values_native[i] = |
| 106 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); | 105 zoneAllocator->MakeCopyOfString(string_iterator.ToCString()); |
| 107 } | 106 } |
| 108 js.SetOptions(option_keys_native, option_values_native, | 107 js.SetOptions(option_keys_native, option_values_native, |
| 109 option_keys.Length()); | 108 option_keys.Length()); |
| 110 } | 109 } |
| 111 | 110 |
| 112 handler(isolate, &js); | 111 handler(isolate, &js); |
| 113 const String& reply = String::Handle(String::New(buffer.buf())); | 112 const String& reply = String::Handle(String::New(js.ToCString())); |
| 114 ASSERT(!reply.IsNull()); | 113 ASSERT(!reply.IsNull()); |
| 115 PostReply(reply, reply_port); | 114 PostReply(reply, reply_port); |
| 116 } | 115 } |
| 117 } | 116 } |
| 118 } | 117 } |
| 119 | 118 |
| 120 | 119 |
| 121 static void PrintArgumentsAndOptions(JSONStream* js) { | 120 static void PrintArgumentsAndOptions(const JSONObject& obj, JSONStream* js) { |
| 122 js->OpenObject("message"); | 121 JSONObject jsobj(obj, "message"); |
| 123 js->OpenArray("arguments"); | 122 { |
| 124 for (intptr_t i = 0; i < js->num_arguments(); i++) { | 123 JSONArray jsarr(jsobj, "arguments"); |
| 125 js->PrintValue(js->GetArgument(i)); | 124 for (intptr_t i = 0; i < js->num_arguments(); i++) { |
| 125 jsarr.AddValue(js->GetArgument(i)); |
| 126 } |
| 126 } | 127 } |
| 127 js->CloseArray(); | 128 { |
| 128 js->OpenArray("option_keys"); | 129 JSONArray jsarr(jsobj, "option_keys"); |
| 129 for (intptr_t i = 0; i < js->num_options(); i++) { | 130 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 130 js->PrintValue(js->GetOptionKey(i)); | 131 jsarr.AddValue(js->GetOptionKey(i)); |
| 132 } |
| 131 } | 133 } |
| 132 js->CloseArray(); | 134 { |
| 133 js->OpenArray("option_values"); | 135 JSONArray jsarr(jsobj, "option_values"); |
| 134 for (intptr_t i = 0; i < js->num_options(); i++) { | 136 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 135 js->PrintValue(js->GetOptionValue(i)); | 137 jsarr.AddValue(js->GetOptionValue(i)); |
| 138 } |
| 136 } | 139 } |
| 137 js->CloseArray(); | |
| 138 js->CloseObject(); | |
| 139 } | 140 } |
| 140 | 141 |
| 141 | 142 |
| 142 static void PrintCollectionErrorResponse(const char* collection_name, | 143 static void PrintCollectionErrorResponse(const char* collection_name, |
| 143 JSONStream* js) { | 144 JSONStream* js) { |
| 144 js->OpenObject(); | 145 JSONObject jsobj(js); |
| 145 js->PrintProperty("type", "error"); | 146 jsobj.AddProperty("type", "error"); |
| 146 js->PrintfProperty("text", "Must specify collection object id: /%s/id", | 147 jsobj.AddPropertyF("text", "Must specify collection object id: /%s/id", |
| 147 collection_name); | 148 collection_name); |
| 148 js->CloseObject(); | |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 static void HandleName(Isolate* isolate, JSONStream* js) { | 152 static void HandleName(Isolate* isolate, JSONStream* js) { |
| 153 js->OpenObject(); | 153 JSONObject jsobj(js); |
| 154 js->PrintProperty("type", "IsolateName"); | 154 jsobj.AddProperty("type", "IsolateName"); |
| 155 js->PrintProperty("id", static_cast<intptr_t>(isolate->main_port())); | 155 jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port())); |
| 156 js->PrintProperty("name", isolate->name()); | 156 jsobj.AddProperty("name", isolate->name()); |
| 157 js->CloseObject(); | |
| 158 } | 157 } |
| 159 | 158 |
| 160 | 159 |
| 161 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { | 160 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { |
| 162 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); | 161 DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); |
| 163 js->OpenObject(); | 162 JSONObject jsobj(js); |
| 164 js->PrintProperty("type", "StackTrace"); | 163 jsobj.AddProperty("type", "StackTrace"); |
| 165 js->OpenArray("members"); | 164 JSONArray jsarr(jsobj, "members"); |
| 166 intptr_t n_frames = stack->Length(); | 165 intptr_t n_frames = stack->Length(); |
| 167 String& url = String::Handle(); | 166 String& url = String::Handle(); |
| 168 String& function = String::Handle(); | 167 String& function = String::Handle(); |
| 169 for (int i = 0; i < n_frames; i++) { | 168 for (int i = 0; i < n_frames; i++) { |
| 170 ActivationFrame* frame = stack->FrameAt(i); | 169 ActivationFrame* frame = stack->FrameAt(i); |
| 171 url ^= frame->SourceUrl(); | 170 url ^= frame->SourceUrl(); |
| 172 function ^= frame->function().UserVisibleName(); | 171 function ^= frame->function().UserVisibleName(); |
| 173 js->OpenObject(); | 172 JSONObject jsobj(jsarr); |
| 174 js->PrintProperty("name", function.ToCString()); | 173 jsobj.AddProperty("name", function.ToCString()); |
| 175 js->PrintProperty("url", url.ToCString()); | 174 jsobj.AddProperty("url", url.ToCString()); |
| 176 js->PrintProperty("line", frame->LineNumber()); | 175 jsobj.AddProperty("line", frame->LineNumber()); |
| 177 js->PrintProperty("function", frame->function()); | 176 jsobj.AddProperty("function", frame->function()); |
| 178 js->PrintProperty("code", frame->code()); | 177 jsobj.AddProperty("code", frame->code()); |
| 179 js->CloseObject(); | |
| 180 } | 178 } |
| 181 js->CloseArray(); | |
| 182 js->CloseObject(); | |
| 183 } | 179 } |
| 184 | 180 |
| 185 | 181 |
| 186 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { | 182 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { |
| 187 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); | 183 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); |
| 188 if (histogram == NULL) { | 184 if (histogram == NULL) { |
| 189 js->OpenObject(); | 185 JSONObject jsobj(js); |
| 190 js->PrintProperty("type", "error"); | 186 jsobj.AddProperty("type", "error"); |
| 191 js->PrintProperty("text", "Run with --print_object_histogram"); | 187 jsobj.AddProperty("text", "Run with --print_object_histogram"); |
| 192 js->CloseObject(); | |
| 193 return; | 188 return; |
| 194 } | 189 } |
| 195 histogram->PrintToJSONStream(js); | 190 histogram->PrintToJSONStream(js); |
| 196 } | 191 } |
| 197 | 192 |
| 198 | 193 |
| 199 static void HandleEcho(Isolate* isolate, JSONStream* js) { | 194 static void HandleEcho(Isolate* isolate, JSONStream* js) { |
| 200 js->OpenObject(); | 195 JSONObject jsobj(js); |
| 201 js->PrintProperty("type", "message"); | 196 jsobj.AddProperty("type", "message"); |
| 202 PrintArgumentsAndOptions(js); | 197 PrintArgumentsAndOptions(jsobj, js); |
| 203 js->CloseObject(); | |
| 204 } | 198 } |
| 205 | 199 |
| 206 // Print an error message if there is no ID argument. | 200 // Print an error message if there is no ID argument. |
| 207 #define REQUIRE_COLLECTION_ID(collection) \ | 201 #define REQUIRE_COLLECTION_ID(collection) \ |
| 208 if (js->num_arguments() == 1) { \ | 202 if (js->num_arguments() == 1) { \ |
| 209 PrintCollectionErrorResponse(collection, js); \ | 203 PrintCollectionErrorResponse(collection, js); \ |
| 210 return; \ | 204 return; \ |
| 211 } | 205 } |
| 212 | 206 |
| 213 // Print a Dart object to the stream if found in ring. Otherwise print null. | 207 // Print a Dart object to the stream if found in ring. Otherwise print null. |
| 214 #define PRINT_RING_OBJ(type) \ | 208 #define PRINT_RING_OBJ(type) \ |
| 215 ASSERT(js->num_arguments() >= 2); \ | 209 ASSERT(js->num_arguments() >= 2); \ |
| 216 ObjectIdRing* ring = isolate->object_id_ring(); \ | 210 ObjectIdRing* ring = isolate->object_id_ring(); \ |
| 217 ASSERT(ring != NULL); \ | 211 ASSERT(ring != NULL); \ |
| 218 intptr_t id = atoi(js->GetArgument(1)); \ | 212 intptr_t id = atoi(js->GetArgument(1)); \ |
| 219 Object& obj = Object::Handle(ring->GetObjectForId(id)); \ | 213 Object& obj = Object::Handle(ring->GetObjectForId(id)); \ |
| 220 if (!obj.Is##type()) { \ | 214 if (!obj.Is##type()) { \ |
| 221 /* Object is not type, replace with null. */ \ | 215 /* Object is not type, replace with null. */ \ |
| 222 obj = Object::null(); \ | 216 obj = Object::null(); \ |
| 223 } \ | 217 } \ |
| 224 js->PrintValue(obj, false) | 218 obj.PrintToJSONStream(js, false) |
| 225 | 219 |
| 226 | 220 |
| 227 static void HandleLibraries(Isolate* isolate, JSONStream* js) { | 221 static void HandleLibraries(Isolate* isolate, JSONStream* js) { |
| 228 if (js->num_arguments() == 1) { | 222 if (js->num_arguments() == 1) { |
| 229 js->PrintValue(Library::Handle(isolate->object_store()->root_library())); | 223 const Library& lib = |
| 230 return; | 224 Library::Handle(isolate->object_store()->root_library()); |
| 225 lib.PrintToJSONStream(js, true); |
| 226 } else { |
| 227 PRINT_RING_OBJ(Library); |
| 231 } | 228 } |
| 232 PRINT_RING_OBJ(Library); | |
| 233 } | 229 } |
| 234 | 230 |
| 235 | 231 |
| 236 static void HandleFunctions(Isolate* isolate, JSONStream* js) { | 232 static void HandleFunctions(Isolate* isolate, JSONStream* js) { |
| 237 REQUIRE_COLLECTION_ID("functions"); | 233 REQUIRE_COLLECTION_ID("functions"); |
| 238 PRINT_RING_OBJ(Function); | 234 PRINT_RING_OBJ(Function); |
| 239 } | 235 } |
| 240 | 236 |
| 241 | 237 |
| 242 static void HandleClasses(Isolate* isolate, JSONStream* js) { | 238 static void HandleClasses(Isolate* isolate, JSONStream* js) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 257 { "objecthistogram", HandleObjectHistogram}, | 253 { "objecthistogram", HandleObjectHistogram}, |
| 258 { "libraries", HandleLibraries }, | 254 { "libraries", HandleLibraries }, |
| 259 { "functions", HandleFunctions }, | 255 { "functions", HandleFunctions }, |
| 260 { "classes", HandleClasses }, | 256 { "classes", HandleClasses }, |
| 261 { "codes", HandleCodes }, | 257 { "codes", HandleCodes }, |
| 262 { "_echo", HandleEcho }, | 258 { "_echo", HandleEcho }, |
| 263 }; | 259 }; |
| 264 | 260 |
| 265 | 261 |
| 266 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { | 262 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { |
| 267 js->OpenObject(); | 263 JSONObject jsobj(js); |
| 268 js->PrintProperty("type", "error"); | 264 jsobj.AddProperty("type", "error"); |
| 269 js->PrintProperty("text", "request not understood."); | 265 jsobj.AddProperty("text", "request not understood."); |
| 270 PrintArgumentsAndOptions(js); | 266 PrintArgumentsAndOptions(jsobj, js); |
| 271 js->CloseObject(); | |
| 272 } | 267 } |
| 273 | 268 |
| 274 | 269 |
| 275 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { | 270 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { |
| 276 intptr_t num_message_handlers = sizeof(__message_handlers) / | 271 intptr_t num_message_handlers = sizeof(__message_handlers) / |
| 277 sizeof(__message_handlers[0]); | 272 sizeof(__message_handlers[0]); |
| 278 for (intptr_t i = 0; i < num_message_handlers; i++) { | 273 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 279 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; | 274 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; |
| 280 if (!strcmp(command, entry.command)) { | 275 if (!strcmp(command, entry.command)) { |
| 281 return entry.handler; | 276 return entry.handler; |
| 282 } | 277 } |
| 283 } | 278 } |
| 284 return HandleFallthrough; | 279 return HandleFallthrough; |
| 285 } | 280 } |
| 286 | 281 |
| 287 } // namespace dart | 282 } // namespace dart |
| OLD | NEW |