Start implementing jdb "locals".

This lets us show the names and types of the locals, but all the values
will show up as 0/null. We're going to have to walk the whole stack and
take callee-save frames into account to do that right.

Change-Id: Ic6e115513b6e65ae7ed4b7274e70bc514e83190a
diff --git a/src/jdwp/jdwp_constants.h b/src/jdwp/jdwp_constants.h
index dc6d1bc..6d550f2 100644
--- a/src/jdwp/jdwp_constants.h
+++ b/src/jdwp/jdwp_constants.h
@@ -217,7 +217,7 @@
 /*
  * Tag constants.
  */
-enum JdwpType {
+enum JdwpTag {
   JT_ARRAY                 = '[',
   JT_BYTE                  = 'B',
   JT_CHAR                  = 'C',
@@ -235,7 +235,7 @@
   JT_CLASS_LOADER          = 'l',
   JT_CLASS_OBJECT          = 'c',
 };
-std::ostream& operator<<(std::ostream& os, const JdwpType& value);
+std::ostream& operator<<(std::ostream& os, const JdwpTag& value);
 
 }  // namespace JDWP
 
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index 5bf95f1..3d00930 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -68,7 +68,7 @@
 /*
  * Helper function: read a variable-width value from the input buffer.
  */
-static uint64_t jdwpReadValue(const uint8_t** pBuf, int width) {
+static uint64_t jdwpReadValue(const uint8_t** pBuf, size_t width) {
   uint64_t value = -1;
   switch (width) {
   case 1:     value = Read1(pBuf); break;
@@ -119,7 +119,7 @@
 
   for (uint32_t i = 0; i < numArgs; i++) {
     uint8_t typeTag = Read1(&buf);
-    int width = Dbg::GetTagWidth(typeTag);
+    size_t width = Dbg::GetTagWidth(typeTag);
     uint64_t value = jdwpReadValue(&buf, width);
 
     LOG(VERBOSE) << StringPrintf("          '%c'(%d): 0x%llx", typeTag, width, value);
@@ -142,7 +142,7 @@
       expandBufAdd1(pReply, JT_OBJECT);
       expandBufAddObjectId(pReply, objectId);
     } else {
-      int width = Dbg::GetTagWidth(resultTag);
+      size_t width = Dbg::GetTagWidth(resultTag);
 
       expandBufAdd1(pReply, resultTag);
       if (width != 0) {
@@ -660,7 +660,7 @@
   for (uint32_t i = 0; i < values; i++) {
     FieldId fieldId = ReadFieldId(&buf);
     uint8_t fieldTag = Dbg::GetStaticFieldBasicTag(classId, fieldId);
-    int width = Dbg::GetTagWidth(fieldTag);
+    size_t width = Dbg::GetTagWidth(fieldTag);
     uint64_t value = jdwpReadValue(&buf, width);
 
     LOG(VERBOSE) << StringPrintf("    --> field=%x tag=%c -> %lld", fieldId, fieldTag, value);
@@ -808,7 +808,7 @@
     FieldId fieldId = ReadFieldId(&buf);
 
     uint8_t fieldTag = Dbg::GetFieldBasicTag(objectId, fieldId);
-    int width = Dbg::GetTagWidth(fieldTag);
+    size_t width = Dbg::GetTagWidth(fieldTag);
     uint64_t value = jdwpReadValue(&buf, width);
 
     LOG(VERBOSE) << StringPrintf("    --> fieldId=%x tag='%c'(%d) value=%lld", fieldId, fieldTag, width, value);
@@ -1446,11 +1446,11 @@
   expandBufAdd4BE(pReply, slots);     /* "int values" */
   for (uint32_t i = 0; i < slots; i++) {
     uint32_t slot = Read4BE(&buf);
-    uint8_t reqSigByte = Read1(&buf);
+    JDWP::JdwpTag reqSigByte = static_cast<JDWP::JdwpTag>(Read1(&buf));
 
     LOG(VERBOSE) << StringPrintf("    --> slot %d '%c'", slot, reqSigByte);
 
-    int width = Dbg::GetTagWidth(reqSigByte);
+    size_t width = Dbg::GetTagWidth(reqSigByte);
     uint8_t* ptr = expandBufAddSpace(pReply, width+1);
     Dbg::GetLocalValue(threadId, frameId, slot, reqSigByte, ptr, width);
   }
@@ -1470,8 +1470,8 @@
 
   for (uint32_t i = 0; i < slots; i++) {
     uint32_t slot = Read4BE(&buf);
-    uint8_t sigByte = Read1(&buf);
-    int width = Dbg::GetTagWidth(sigByte);
+    JDWP::JdwpTag sigByte = static_cast<JDWP::JdwpTag>(Read1(&buf));
+    size_t width = Dbg::GetTagWidth(sigByte);
     uint64_t value = jdwpReadValue(&buf, width);
 
     LOG(VERBOSE) << StringPrintf("    --> slot %d '%c' %llx", slot, sigByte, value);
diff --git a/src/jdwp/jdwp_main.cc b/src/jdwp/jdwp_main.cc
index 3bc0d41..28ea303 100644
--- a/src/jdwp/jdwp_main.cc
+++ b/src/jdwp/jdwp_main.cc
@@ -457,6 +457,30 @@
   return os;
 }
 
+std::ostream& operator<<(std::ostream& os, const JdwpTag& value) {
+  switch (value) {
+  case JT_ARRAY: os << "JT_ARRAY"; break;
+  case JT_BYTE: os << "JT_BYTE"; break;
+  case JT_CHAR: os << "JT_CHAR"; break;
+  case JT_OBJECT: os << "JT_OBJECT"; break;
+  case JT_FLOAT: os << "JT_FLOAT"; break;
+  case JT_DOUBLE: os << "JT_DOUBLE"; break;
+  case JT_INT: os << "JT_INT"; break;
+  case JT_LONG: os << "JT_LONG"; break;
+  case JT_SHORT: os << "JT_SHORT"; break;
+  case JT_VOID: os << "JT_VOID"; break;
+  case JT_BOOLEAN: os << "JT_BOOLEAN"; break;
+  case JT_STRING: os << "JT_STRING"; break;
+  case JT_THREAD: os << "JT_THREAD"; break;
+  case JT_THREAD_GROUP: os << "JT_THREAD_GROUP"; break;
+  case JT_CLASS_LOADER: os << "JT_CLASS_LOADER"; break;
+  case JT_CLASS_OBJECT: os << "JT_CLASS_OBJECT"; break;
+  default:
+    os << "JdwpTag[" << static_cast<int32_t>(value) << "]";
+  }
+  return os;
+}
+
 }  // namespace JDWP
 
 }  // namespace art