Fixed access checks on class resolution in interpreter.

Also made interpreter throw AbstractMethodError when interpreting
abstract methods.

Change-Id: Id6396fd31e500613150407d0281383b556de9605
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 0a66a21..e68896a 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -696,9 +696,11 @@
         shadow_frame.SetReferenceAndVReg(dec_insn.vA, s);
         break;
       }
-      case Instruction::CONST_CLASS:
-        shadow_frame.SetReferenceAndVReg(dec_insn.vA, mh.ResolveClass(dec_insn.vB));
+      case Instruction::CONST_CLASS: {
+        Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
+        shadow_frame.SetReferenceAndVReg(dec_insn.vA, c);
         break;
+      }
       case Instruction::MONITOR_ENTER: {
         Object* obj = shadow_frame.GetReference(dec_insn.vA);
         if (UNLIKELY(obj == NULL)) {
@@ -718,7 +720,7 @@
         break;
       }
       case Instruction::CHECK_CAST: {
-        Class* c = mh.ResolveClass(dec_insn.vB);
+        Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
         if (UNLIKELY(c == NULL)) {
           CHECK(self->IsExceptionPending());
         } else {
@@ -733,7 +735,7 @@
         break;
       }
       case Instruction::INSTANCE_OF: {
-        Class* c = mh.ResolveClass(dec_insn.vC);
+        Class* c = ResolveVerifyAndClinit(dec_insn.vC, shadow_frame.GetMethod(), self, false, true);
         if (UNLIKELY(c == NULL)) {
           CHECK(self->IsExceptionPending());
         } else {
@@ -767,7 +769,7 @@
         bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE);
         int32_t length = dec_insn.vA;
         CHECK(is_range || length <= 5);
-        Class* arrayClass = mh.ResolveClass(dec_insn.vB);
+        Class* arrayClass = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
         CHECK(arrayClass->IsArrayClass());
         if (arrayClass->GetComponentType()->IsPrimitiveInt()) {
           IntArray* newArray = IntArray::Alloc(self, length);
@@ -1761,6 +1763,10 @@
   if (code_item != NULL) {
     num_regs =  code_item->registers_size_;
     num_ins = code_item->ins_size_;
+  } else if (method->IsAbstract()) {
+    self->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;", "abstract method \"%s\"",
+                             PrettyMethod(method).c_str());
+    return;
   } else {
     DCHECK(method->IsNative());
     num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
diff --git a/src/object_utils.h b/src/object_utils.h
index 661773a..6924f4e 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -677,14 +677,6 @@
     return s;
   }
 
-  Class* ResolveClass(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    Class* c = GetDexCacheResolvedType(type_idx);
-    if (UNLIKELY(c == NULL)) {
-      c = GetClassLinker()->ResolveType(GetDexFile(), type_idx, GetDexCache(), GetClassLoader());
-    }
-    return c;
-  }
-
  private:
   // Set the method_ field, for proxy methods looking up the interface method via the resolved
   // methods table.