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/compiler.cc b/src/compiler.cc
index c917736..37a7414 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -456,7 +456,7 @@
 }
 
 bool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, CompilationUnit* cUnit,
-                                        int& field_offset, bool& is_volatile) {
+                                        int& field_offset, bool& is_volatile, bool is_put) {
   // Conservative defaults
   field_offset = -1;
   is_volatile = true;
@@ -466,10 +466,11 @@
     Class* referrer_class = ComputeReferrerClass(cUnit);
     // Try to resolve referring class then access check, failure to pass the
     Class* fields_class = resolved_field->GetDeclaringClass();
-    if (referrer_class != NULL &&
-        referrer_class->CanAccess(fields_class) &&
-        referrer_class->CanAccessMember(fields_class,
-                                        resolved_field->GetAccessFlags())) {
+    bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() &&
+                                              fields_class != referrer_class;
+    if (referrer_class != NULL && referrer_class->CanAccess(fields_class) &&
+        referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) &&
+        !is_write_to_final_from_wrong_class) {
       field_offset = resolved_field->GetOffset().Int32Value();
       is_volatile = resolved_field->IsVolatile();
       stats_->ResolvedInstanceField();
@@ -487,7 +488,7 @@
 
 bool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, CompilationUnit* cUnit,
                                       int& field_offset, int& ssb_index,
-                                      bool& is_referrers_class, bool& is_volatile) {
+                                      bool& is_referrers_class, bool& is_volatile, bool is_put) {
   // Conservative defaults
   field_offset = -1;
   ssb_index = -1;
@@ -499,17 +500,18 @@
     DCHECK(resolved_field->IsStatic());
     Class* referrer_class = ComputeReferrerClass(cUnit);
     if (referrer_class != NULL) {
-      if (resolved_field->GetDeclaringClass() == referrer_class) {
+      Class* fields_class = resolved_field->GetDeclaringClass();
+      if (fields_class == referrer_class) {
         is_referrers_class = true;  // implies no worrying about class initialization
         field_offset = resolved_field->GetOffset().Int32Value();
         is_volatile = resolved_field->IsVolatile();
         stats_->ResolvedLocalStaticField();
         return true;  // fast path
       } else {
-        Class* fields_class = resolved_field->GetDeclaringClass();
+        bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal();
         if (referrer_class->CanAccess(fields_class) &&
-            referrer_class->CanAccessMember(fields_class,
-                                            resolved_field->GetAccessFlags())) {
+            referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) &&
+            !is_write_to_final_from_wrong_class) {
           // We have the resolved field, we must make it into a ssbIndex for the referrer
           // in its static storage base (which may fail if it doesn't have a slot for it)
           // TODO: for images we can elide the static storage base null check