Finish implementation of ResolveField and ResolveMethod

Change-Id: I854e17b4cccd05b26f83c77230f7323c898802c9
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 7a93d48..e3912d1 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1866,7 +1866,7 @@
                                    uint32_t method_idx,
                                    DexCache* dex_cache,
                                    const ClassLoader* class_loader,
-                                   /*MethodType*/ int method_type) {
+                                   bool is_direct) {
   Method* resolved = dex_cache->GetResolvedMethod(method_idx);
   if (resolved != NULL) {
     return resolved;
@@ -1877,8 +1877,13 @@
     return NULL;
   }
 
-  // TODO resolve using class, method_id, and method type.
-  // resolved = ...
+  const char* name = dex_file.dexStringById(method_id.name_idx_);
+  const char* signature = dex_file.CreateMethodDescriptor(method_id.proto_idx_, NULL);
+  if (is_direct) {
+    resolved = klass->FindDirectMethod(name, signature);
+  } else {
+    resolved = klass->FindVirtualMethod(name, signature);
+  }
   if (resolved != NULL) {
     dex_cache->SetResolvedMethod(method_idx, resolved);
   } else {
@@ -1902,8 +1907,13 @@
     return NULL;
   }
 
-  // TODO resolve using class, field_id, and is_static.
-  // resolved = ...
+  const char* name = dex_file.dexStringById(field_id.name_idx_);
+  const char* type = dex_file.dexStringByTypeIdx(field_id.type_idx_);
+  if (is_static) {
+    resolved = klass->FindStaticField(name, type);
+  } else {
+    resolved = klass->FindInstanceField(name, type);
+  }
   if (resolved != NULL) {
     dex_cache->SetResolvedfield(field_idx, resolved);
   } else {
diff --git a/src/class_linker.h b/src/class_linker.h
index 4cf82c6..cb21cb1 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -74,7 +74,7 @@
                         uint32_t method_idx,
                         DexCache* dex_cache,
                         const ClassLoader* class_loader,
-                        /*MethodType*/ int method_type);
+                        bool is_direct);
 
   // Resolve a method with a given ID from the DexFile, storing the
   // result in DexCache. The ClassLinker and ClassLoader are used as
diff --git a/src/compiler.cc b/src/compiler.cc
index 52babf7..0324586 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -46,14 +46,18 @@
     class_linker->ResolveType(dex_file, i, dex_cache, class_loader);
   }
   for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
-    // TODO: move resolution into compiler proper where we will know method_type
-    int method_type = 0;
-    class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, method_type);
+    // unknown if direct or virtual, try both
+    Method* method = class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, false);
+    if (method == NULL) {
+      class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, true);
+    }
   }
   for (size_t i = 0; i < dex_cache->NumFields(); i++) {
-    // TODO: move resolution into compiler proper where we will know is_static
-    bool is_static = false;
-    class_linker->ResolveField(dex_file, i, dex_cache, class_loader, is_static);
+    // unknown if instance or static, try both
+    Field* field = class_linker->ResolveField(dex_file, i, dex_cache, class_loader, false);
+    if (field == NULL) {
+      class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, true);
+    }
   }
 }
 
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 997a4e6..5300026 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -86,15 +86,13 @@
   }
   EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumMethods());
   for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
-    // TODO: ClassLinker::ResolveMethod
-    // Method* method = dex_cache->GetResolvedMethod(i);
-    // EXPECT_TRUE(method != NULL);
+    Method* method = dex_cache->GetResolvedMethod(i);
+    EXPECT_TRUE(method != NULL);
   }
   EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumFields());
   for (size_t i = 0; i < dex_cache->NumFields(); i++) {
-    // TODO: ClassLinker::ResolveField
-    // Field* field = dex_cache->GetResolvedField(i);
-    // EXPECT_TRUE(field != NULL);
+    Field* field = dex_cache->GetResolvedField(i);
+    EXPECT_TRUE(field != NULL);
   }
 
 }
diff --git a/src/dex_file.cc b/src/dex_file.cc
index c828df6..f7dec88 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -383,7 +383,6 @@
 // must assemble the descriptor from references in the prototype.
 char* DexFile::CreateMethodDescriptor(uint32_t proto_idx,
                                       int32_t* unicode_length) const {
-  CHECK(unicode_length != NULL);
   const ProtoId& proto_id = GetProtoId(proto_idx);
   std::string descriptor;
   descriptor.push_back('(');
@@ -408,7 +407,9 @@
   // TODO: should this just return a std::string?
   scoped_ptr<char> c_string(new char[descriptor.size() + 1]);
   strcpy(c_string.get(), descriptor.c_str());
-  *unicode_length = parameter_length + return_type_length + 2;  // 2 for ( and )
+  if (unicode_length != NULL) {
+    *unicode_length = parameter_length + return_type_length + 2;  // 2 for ( and )
+  }
   return c_string.release();
 }