Better unresolved type support.

Also fix bug where miranda methods were changing their declaring class
and thereby breaking their return type indices.
Add support for dumping stacks on abort.

Change-Id: I3782864736b12d1f81ab9aea4909213d3344ba13
diff --git a/src/object.cc b/src/object.cc
index 91328aa..78a1976 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -400,6 +400,16 @@
              new_return_type_idx, false);
 }
 
+const char* Method::GetReturnTypeDescriptor() const {
+  Class* declaring_class = GetDeclaringClass();
+  DexCache* dex_cache = declaring_class->GetDexCache();
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  const DexFile& dex_file = class_linker->FindDexFile(dex_cache);
+  const char* descriptor = dex_file.dexStringByTypeIdx(GetReturnTypeIdx());
+  DCHECK(descriptor != NULL);
+  return descriptor;
+}
+
 Class* Method::GetReturnType() const {
   DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous())
       << PrettyMethod(this);
@@ -1468,6 +1478,25 @@
   return !InstanceOf(jlre);
 }
 
+std::string Throwable::Dump() const {
+  Object* stack_state = GetStackState();
+  if (stack_state == NULL || !stack_state->IsObjectArray()) {
+    // missing or corrupt stack state
+    return "";
+  }
+  // Decode the internal stack trace into the depth and method trace
+  ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
+  int32_t depth = method_trace->GetLength() - 1;
+  std::string result;
+  for (int32_t i = 0; i < depth; ++i) {
+    Method* method = down_cast<Method*>(method_trace->Get(i));
+    result += "  at ";
+    result += PrettyMethod(method, true);
+    result += "\n";
+  }
+  return result;
+}
+
 Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
 
 void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {