Chromium Code Reviews| Index: runtime/bin/dbg_connection.cc |
| =================================================================== |
| --- runtime/bin/dbg_connection.cc (revision 7818) |
| +++ runtime/bin/dbg_connection.cc (working copy) |
| @@ -28,9 +28,15 @@ |
| // TODO(hausner): Need better error handling. |
| -#define ASSERT_NOT_ERROR(handle) \ |
| +#define ASSERT_NOT_ERROR(handle) \ |
| ASSERT(!Dart_IsError(handle)) |
| +#define RETURN_IF_ERROR(handle) \ |
| + if (Dart_IsError(handle)) { \ |
| + return Dart_GetError(handle); \ |
| + } |
| + |
| + |
| typedef void (*CommandHandler)(const char* json_cmd); |
| struct JSONDebuggerCommand { |
| @@ -48,6 +54,7 @@ |
| void PopMessage(); |
| int MessageId() const; |
| const char* Params() const; |
| + intptr_t GetIntParam(const char* name) const; |
| char* buf() const { return buf_; } |
| bool Alive() const { return connection_is_alive_; } |
| @@ -117,6 +124,16 @@ |
| } |
| +intptr_t MessageBuffer::GetIntParam(const char* name) const { |
| + const char* params = Params(); |
| + ASSERT(params != NULL); |
| + dart::JSONReader r(params); |
| + r.Seek(name); |
| + ASSERT(r.Type() == dart::JSONReader::kInteger); |
| + return atoi(r.ValueChars()); |
|
siva
2012/05/22 01:49:09
It might be safer to use strtol here as it checks
hausner
2012/05/22 18:03:57
Done.
|
| +} |
| + |
| + |
| void MessageBuffer::ReadData() { |
| ASSERT(data_length_ >= 0); |
| ASSERT(data_length_ < buf_length_); |
| @@ -280,6 +297,98 @@ |
| } |
| +static const char* GetStringChars(Dart_Handle str) { |
| + ASSERT(Dart_IsString(str)); |
| + const char* chars; |
| + Dart_Handle res = Dart_StringToCString(str, &chars); |
| + ASSERT(!Dart_IsError(res)); |
| + return chars; |
| +} |
| + |
| + |
| +static void FormatField(dart::TextBuffer* buf, |
| + Dart_Handle object_name, |
| + Dart_Handle object) { |
| + ASSERT(Dart_IsString(object_name)); |
| + buf->Printf("{\"name\":\"%s\",", GetStringChars(object_name)); |
| + intptr_t obj_id = Dart_CacheObject(object); |
| + ASSERT(obj_id >= 0); |
| + buf->Printf("\"value\":{\"objectId\":%d,", obj_id); |
| + const char* kind = "object"; |
| + if (Dart_IsInteger(object)) { |
| + kind = "integer"; |
| + } else if (Dart_IsString(object)) { |
| + kind = "string"; |
| + } else if (Dart_IsBoolean(object)) { |
| + kind = "boolean"; |
| + } |
| + buf->Printf("\"kind\":\"%s\",", kind); |
| + Dart_Handle text = Dart_ToString(object); |
| + buf->Printf("\"text\":\"%s\"}}", GetStringChars(text)); |
| +} |
| + |
| + |
| +static void FormatFieldList(dart::TextBuffer* buf, |
| + Dart_Handle obj_list) { |
| + ASSERT(Dart_IsList(obj_list)); |
| + intptr_t list_length = 0; |
| + Dart_Handle res = Dart_ListLength(obj_list, &list_length); |
| + ASSERT_NOT_ERROR(res); |
| + ASSERT(list_length % 2 == 0); |
| + buf->Printf("["); |
| + for (int i = 0; i + 1 < list_length; i += 2) { |
| + Dart_Handle name_handle = Dart_ListGetAt(obj_list, i); |
| + ASSERT_NOT_ERROR(name_handle); |
| + Dart_Handle value_handle = Dart_ListGetAt(obj_list, i + 1); |
| + ASSERT_NOT_ERROR(value_handle); |
| + if (i > 0) { |
| + buf->Printf(","); |
| + } |
| + FormatField(buf, name_handle, value_handle); |
| + } |
| + buf->Printf("]"); |
| +} |
| + |
| + |
| +static const char* FormatClassProps(dart::TextBuffer* buf, |
| + intptr_t cls_id) { |
| + Dart_Handle name, library, static_fields; |
| + intptr_t super_id; |
| + Dart_Handle res = |
| + Dart_GetClassInfo(cls_id, &name, &library, &super_id, &static_fields); |
| + RETURN_IF_ERROR(res); |
| + RETURN_IF_ERROR(name); |
| + buf->Printf("{\"name\":\"%s\",", GetStringChars(name)); |
| + if (super_id > 0) { |
| + buf->Printf("\"superclassId\":%d,", super_id); |
| + } |
| + RETURN_IF_ERROR(library); |
| + ASSERT(!Dart_IsNull(library)); |
| + // TODO(hausner): get proper library id. |
| + intptr_t libId = 0; |
| + buf->Printf("\"libraryId\":%d,", libId); |
| + RETURN_IF_ERROR(static_fields); |
| + buf->Printf("\"fields\":"); |
| + FormatFieldList(buf, static_fields); |
| + buf->Printf("}"); |
| + return NULL; |
| +} |
| + |
| + |
| +static const char* FormatObjProps(dart::TextBuffer* buf, |
| + Dart_Handle object) { |
| + intptr_t class_id; |
| + Dart_Handle res = Dart_GetObjClassId(object, &class_id); |
| + RETURN_IF_ERROR(res); |
| + buf->Printf("{\"classId\": %d, \"fields\":", class_id); |
| + Dart_Handle fields = Dart_GetInstanceFields(object); |
| + RETURN_IF_ERROR(fields); |
| + FormatFieldList(buf, fields); |
| + buf->Printf("}"); |
| + return NULL; |
| +} |
| + |
| + |
| static void FormatCallFrames(dart::TextBuffer* msg, Dart_StackTrace trace) { |
| intptr_t trace_len = 0; |
| Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); |
| @@ -304,8 +413,13 @@ |
| ASSERT(Dart_IsString(script_url)); |
| const char* script_url_chars; |
| Dart_StringToCString(script_url, &script_url_chars); |
| - msg->Printf("\"location\": { \"url\": \"%s\", \"lineNumber\": %d }}", |
| + msg->Printf("\"location\": { \"url\": \"%s\", \"lineNumber\":%d},", |
| script_url_chars, line_number); |
| + Dart_Handle locals = Dart_GetLocalVariables(frame); |
| + ASSERT_NOT_ERROR(locals); |
| + msg->Printf("\"locals\":"); |
| + FormatFieldList(msg, locals); |
| + msg->Printf("}"); |
| } |
| msg->Printf("]"); |
| } |
| @@ -354,6 +468,41 @@ |
| } |
| +void DebuggerConnectionHandler::HandleGetObjPropsCmd(const char* json_msg) { |
| + int msg_id = msgbuf_->MessageId(); |
| + intptr_t obj_id = msgbuf_->GetIntParam("objectId"); |
| + Dart_Handle obj = Dart_GetCachedObject(obj_id); |
| + if (Dart_IsError(obj)) { |
| + SendError(msg_id, Dart_GetError(obj)); |
| + return; |
| + } |
| + dart::TextBuffer msg(64); |
| + msg.Printf("{\"id\":%d, \"result\":", msg_id); |
| + const char* err = FormatObjProps(&msg, obj); |
| + if (err != NULL) { |
| + SendError(msg_id, err); |
| + return; |
| + } |
| + msg.Printf("}"); |
| + SendMsg(&msg); |
| +} |
| + |
| + |
| +void DebuggerConnectionHandler::HandleGetClassPropsCmd(const char* json_msg) { |
| + int msg_id = msgbuf_->MessageId(); |
| + intptr_t cls_id = msgbuf_->GetIntParam("classId"); |
| + dart::TextBuffer msg(64); |
| + msg.Printf("{\"id\":%d, \"result\":", msg_id); |
| + const char* err = FormatClassProps(&msg, cls_id); |
| + if (err != NULL) { |
| + SendError(msg_id, err); |
| + return; |
| + } |
| + msg.Printf("}"); |
| + SendMsg(&msg); |
| +} |
| + |
| + |
| void DebuggerConnectionHandler::HandleUnknownMsg(const char* json_msg) { |
| int msg_id = msgbuf_->MessageId(); |
| ASSERT(msg_id >= 0); |
| @@ -364,7 +513,9 @@ |
| void DebuggerConnectionHandler::HandleMessages() { |
| static JSONDebuggerCommand debugger_commands[] = { |
| { "resume", HandleResumeCmd }, |
| - { "getLibraryURLs", HandleGetLibraryURLsCmd}, |
| + { "getLibraryURLs", HandleGetLibraryURLsCmd }, |
| + { "getClassProperties", HandleGetClassPropsCmd }, |
| + { "getObjectProperties", HandleGetObjPropsCmd }, |
| { "getScriptURLs", HandleGetScriptURLsCmd }, |
| { "getStackTrace", HandleGetStackTraceCmd }, |
| { "setBreakpoint", HandleSetBpCmd }, |