Merge "Throw if ResolveMethod fails." into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index aa69c30..67acf9d 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -51,6 +51,19 @@
   va_end(args);
 }
 
+void ThrowNoSuchMethodError(const char* kind,
+    Class* c, const StringPiece& name, const StringPiece& signature) {
+  DexCache* dex_cache = c->GetDexCache();
+  std::stringstream msg;
+  msg << "no " << kind << " method " << name << "." << signature
+      << " in class " << c->GetDescriptor()->ToModifiedUtf8()
+      << " or its superclasses";
+  if (dex_cache) {
+    msg << " (defined in " << dex_cache->GetLocation()->ToModifiedUtf8() << ")";
+  }
+  Thread::Current()->ThrowNewException("Ljava/lang/NoSuchMethodError;", "%s", msg.str().c_str());
+}
+
 void ThrowEarlierClassFailure(Class* c) {
   /*
    * The class failed to initialize on a previous attempt, so we want to throw
@@ -2263,6 +2276,7 @@
   const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
   Class* klass = ResolveType(dex_file, method_id.class_idx_, dex_cache, class_loader);
   if (klass == NULL) {
+    DCHECK(Thread::Current()->IsExceptionPending());
     return NULL;
   }
 
@@ -2278,7 +2292,7 @@
   if (resolved != NULL) {
     dex_cache->SetResolvedMethod(method_idx, resolved);
   } else {
-    DCHECK(Thread::Current()->IsExceptionPending());
+    ThrowNoSuchMethodError(is_direct ? "direct" : "virtual", klass, name, signature);
   }
   return resolved;
 }
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 7adbaeb..5ab8692 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -288,11 +288,10 @@
   }
 
   if (method == NULL || method->IsStatic() != is_static) {
-    Thread* self = Thread::Current();
     std::string method_name(PrettyMethod(method));
     // TODO: try searching for the opposite kind of method from is_static
     // for better diagnostics?
-    self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+    ts.Self()->ThrowNewException("Ljava/lang/NoSuchMethodError;",
         "no %s method %s", is_static ? "static" : "non-static",
         method_name.c_str());
     return NULL;
@@ -2119,16 +2118,14 @@
         m = c->FindVirtualMethod(name, sig);
       }
       if (m == NULL) {
-        Thread* self = Thread::Current();
         std::string class_descriptor(c->GetDescriptor()->ToModifiedUtf8());
-        self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+        ts.Self()->ThrowNewException("Ljava/lang/NoSuchMethodError;",
             "no method \"%s.%s%s\"",
             class_descriptor.c_str(), name, sig);
         return JNI_ERR;
       } else if (!m->IsNative()) {
-        Thread* self = Thread::Current();
         std::string class_descriptor(c->GetDescriptor()->ToModifiedUtf8());
-        self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+        ts.Self()->ThrowNewException("Ljava/lang/NoSuchMethodError;",
             "method \"%s.%s%s\" is not native",
             class_descriptor.c_str(), name, sig);
         return JNI_ERR;
diff --git a/src/object.cc b/src/object.cc
index 5017c23..0e8e176 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -1139,9 +1139,9 @@
 }
 
 Method* Class::FindVirtualMethod(const StringPiece& name,
-                                 const StringPiece& descriptor) {
+                                 const StringPiece& signature) {
   for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
-    Method* method = klass->FindDeclaredVirtualMethod(name, descriptor);
+    Method* method = klass->FindDeclaredVirtualMethod(name, signature);
     if (method != NULL) {
       return method;
     }