Class getField/Method returns NULL if type/args are unresolved.

These changes check that a field's type is resolved before returning it
through getDeclaredField, and that a method's return type and argument
types are resolved before returning it through getDeclaredMethods. This
fixes test failures in libcore MissingClassesTest.

(cherry picked from commit 1ae431a01516b6c91f031aff37c756b7e4f63dd1)

Change-Id: I6bd5601a975e677be6438b1efcb1b1f1ecde900c
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index 5c834f7..6cf7a2c 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -138,9 +138,15 @@
   }
 
   std::vector<Field*> fields;
+  FieldHelper fh;
   for (size_t i = 0; i < c->NumInstanceFields(); ++i) {
     Field* f = c->GetInstanceField(i);
+    fh.ChangeField(f);
     if (IsVisibleField(f, publicOnly)) {
+      if (fh.GetType() == NULL) {
+        DCHECK(env->ExceptionOccurred());
+        return NULL;
+      }
       fields.push_back(f);
     }
     if (env->ExceptionOccurred()) {
@@ -149,7 +155,12 @@
   }
   for (size_t i = 0; i < c->NumStaticFields(); ++i) {
     Field* f = c->GetStaticField(i);
+    fh.ChangeField(f);
     if (IsVisibleField(f, publicOnly)) {
+      if (fh.GetType() == NULL) {
+        DCHECK(env->ExceptionOccurred());
+        return NULL;
+      }
       fields.push_back(f);
     }
     if (env->ExceptionOccurred()) {
@@ -174,15 +185,22 @@
 }
 
 static jobjectArray Class_getDeclaredMethods(JNIEnv* env, jclass javaClass, jboolean publicOnly) {
+  ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
   Class* c = DecodeClass(env, javaClass);
   if (c == NULL) {
     return NULL;
   }
 
   std::vector<Method*> methods;
+  MethodHelper mh;
   for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
     Method* m = c->GetVirtualMethod(i);
+    mh.ChangeMethod(m);
     if (IsVisibleMethod(m, publicOnly)) {
+      if (mh.GetReturnType() == NULL || mh.GetParameterTypes() == NULL) {
+        DCHECK(env->ExceptionOccurred());
+        return NULL;
+      }
       methods.push_back(m);
     }
     if (env->ExceptionOccurred()) {
@@ -191,7 +209,12 @@
   }
   for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
     Method* m = c->GetDirectMethod(i);
+    mh.ChangeMethod(m);
     if (IsVisibleMethod(m, publicOnly)) {
+      if (mh.GetReturnType() == NULL || mh.GetParameterTypes() == NULL) {
+        DCHECK(env->ExceptionOccurred());
+        return NULL;
+      }
       methods.push_back(m);
     }
     if (env->ExceptionOccurred()) {
@@ -283,6 +306,7 @@
 }
 
 static jobject Class_getDeclaredFieldNative(JNIEnv* env, jclass java_class, jobject jname) {
+  ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
   Class* c = DecodeClass(env, java_class);
   if (c == NULL) {
     return NULL;
@@ -296,6 +320,10 @@
     Field* f = c->GetInstanceField(i);
     fh.ChangeField(f);
     if (name->Equals(fh.GetName())) {
+      if (fh.GetType() == NULL) {
+        DCHECK(env->ExceptionOccurred());
+        return NULL;
+      }
       return AddLocalReference<jclass>(env, f);
     }
   }
@@ -303,6 +331,10 @@
     Field* f = c->GetStaticField(i);
     fh.ChangeField(f);
     if (name->Equals(fh.GetName())) {
+      if (fh.GetType() == NULL) {
+        DCHECK(env->ExceptionOccurred());
+        return NULL;
+      }
       return AddLocalReference<jclass>(env, f);
     }
   }
diff --git a/src/object_utils.h b/src/object_utils.h
index cbad7b0..631425e 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -456,6 +456,10 @@
     ObjectArray<Class>* result = ObjectArray<Class>::Alloc(array_class, num_params);
     for (uint32_t i = 0; i < num_params; i++) {
       Class* param_type = GetClassFromTypeIdx(params->GetTypeItem(i).type_idx_);
+      if (param_type == NULL) {
+        DCHECK(Thread::Current()->IsExceptionPending());
+        return NULL;
+      }
       result->Set(i, param_type);
     }
     return result;
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index e76e89f..93d4728 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -1164,7 +1164,10 @@
   // reset index, will index into param type array which doesn't include the receiver
   param_index = 0;
   ObjectArray<Class>* param_types = proxy_mh.GetParameterTypes();
-  DCHECK(param_types != NULL);
+  if (param_types == NULL) {
+    CHECK(self->IsExceptionPending());
+    return;
+  }
   // Check number of parameter types agrees with number from the Method - less 1 for the receiver.
   DCHECK_EQ(static_cast<size_t>(param_types->GetLength()), num_params - 1);
   while (cur_arg < args_in_regs && param_index < (num_params - 1)) {