Numerous fixes to compiler and verifier for cts vm-tests.

ClassNotFoundExceptions in ResolveType are converted to
NoClassDefFoundErrors.

Compiler checks for puts into final fields.

Method resolution searches direct methods if an appropriate virtual
method can't be found.

Invocations of <clinit> are rejected by the verifier.

Invoke-super and invoke-virtual can't be used on private methods.

Using invoke-interface on non-interface methods and not using
invoke-interface on interface methods leads do an error.

Change-Id: Ia589f1ffccf91b62812ee34c8c5fae1aaf3798c6
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 449bb53..f48a25c 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -188,6 +188,7 @@
   "Ldalvik/system/BaseDexClassLoader;",
   "Ldalvik/system/PathClassLoader;",
   "Ljava/lang/Throwable;",
+  "Ljava/lang/ClassNotFoundException;",
   "Ljava/lang/StackTraceElement;",
   "Z",
   "B",
@@ -458,9 +459,11 @@
   SetClassRoot(kDalvikSystemPathClassLoader, dalvik_system_PathClassLoader);
   PathClassLoader::SetClass(dalvik_system_PathClassLoader);
 
-  // Set up java.lang.Throwable and java.lang.StackTraceElement as a convenience
+  // Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
+  // java.lang.StackTraceElement as a convenience
   SetClassRoot(kJavaLangThrowable, FindSystemClass("Ljava/lang/Throwable;"));
   Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
+  SetClassRoot(kJavaLangClassNotFoundException, FindSystemClass("Ljava/lang/ClassNotFoundException;"));
   SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;"));
   SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;"));
   StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
@@ -3180,6 +3183,11 @@
     } else {
       CHECK(Thread::Current()->IsExceptionPending())
           << "Expected pending exception for failed resolution of: " << descriptor;
+      // Convert a ClassNotFoundException to a NoClassDefFoundError
+      if (Thread::Current()->GetException()->InstanceOf(GetClassRoot(kJavaLangClassNotFoundException))) {
+        Thread::Current()->ClearException();
+        ThrowNoClassDefFoundError("Failed resolution of: %s", descriptor);
+      }
     }
   }
   return resolved;
@@ -3218,6 +3226,12 @@
       resolved = klass->FindInterfaceMethod(name, signature);
     } else {
       resolved = klass->FindVirtualMethod(name, signature);
+      // If a virtual method isn't found, search the direct methods. This can
+      // happen when trying to access private methods directly, and allows the
+      // proper exception to be thrown in the caller.
+      if (resolved == NULL) {
+        resolved = klass->FindDirectMethod(name, signature);
+      }
     }
     if (resolved == NULL) {
       ThrowNoSuchMethodError(is_direct, klass, name, signature);