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 |