Fix/improve exception detail messages for unboxing.

This fixes libcore/luni/src/test/java/libcore/java/lang/reflect/MethodTest.java
failures.

Change-Id: Idf6aae169bd72f0534d4094170536e6b2515ca07
diff --git a/src/reflection.cc b/src/reflection.cc
index 46b2ff3..c317be0 100644
--- a/src/reflection.cc
+++ b/src/reflection.cc
@@ -91,7 +91,8 @@
     Object* arg = objects->Get(i);
     Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_);
     if (dst_class->IsPrimitive()) {
-      if (!UnboxPrimitive(env, arg, dst_class, decoded_args[i])) {
+      std::string what(StringPrintf("argument %d", i + 1)); // Humans count from 1.
+      if (!UnboxPrimitive(env, arg, dst_class, decoded_args[i], what.c_str())) {
         return NULL;
       }
     } else {
@@ -119,16 +120,17 @@
 }
 
 bool VerifyObjectInClass(JNIEnv* env, Object* o, Class* c) {
+  const char* exception = NULL;
   if (o == NULL) {
-    jniThrowNullPointerException(env, "receiver for non-static field access was null");
-    return false;
+    exception = "java/lang/NullPointerException";
+  } else if (!o->InstanceOf(c)) {
+    exception = "java/lang/IllegalArgumentException";
   }
-  if (!o->InstanceOf(c)) {
-    std::string expectedClassName(PrettyDescriptor(c));
-    std::string actualClassName(PrettyTypeOf(o));
-    jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
-        "expected receiver of type %s, but got %s",
-        expectedClassName.c_str(), actualClassName.c_str());
+  if (exception != NULL) {
+    std::string expected_class_name(PrettyDescriptor(c));
+    std::string actual_class_name(PrettyTypeOf(o));
+    jniThrowExceptionFmt(env, exception, "expected receiver of type %s, but got %s",
+                         expected_class_name.c_str(), actual_class_name.c_str());
     return false;
   }
   return true;
@@ -281,26 +283,30 @@
   m->Invoke(self, NULL, args.get(), &value);
 }
 
-bool UnboxPrimitive(JNIEnv* env, Object* o, Class* dst_class, JValue& unboxed_value) {
+bool UnboxPrimitive(JNIEnv* env, Object* o, Class* dst_class, JValue& unboxed_value, const char* what) {
   if (!dst_class->IsPrimitive()) {
     if (o != NULL && !o->InstanceOf(dst_class)) {
-      jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
-          "expected object of type %s, but got %s",
-          PrettyDescriptor(dst_class).c_str(),
-          PrettyTypeOf(o).c_str());
+      Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
+                                            "boxed object for %s should have type %s, but got %s",
+                                            what,
+                                            PrettyDescriptor(dst_class).c_str(),
+                                            PrettyTypeOf(o).c_str());
       return false;
     }
     unboxed_value.l = o;
     return true;
   } else if (dst_class->GetPrimitiveType() == Primitive::kPrimVoid) {
-    Thread::Current()->ThrowNewException("Ljava/lang/IllegalArgumentException;",
-        "can't unbox to void");
+    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
+                                          "can't unbox %s to void",
+                                          what);
     return false;
   }
 
   if (o == NULL) {
-    Thread::Current()->ThrowNewException("Ljava/lang/IllegalArgumentException;",
-        "null passed for boxed primitive type");
+    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
+                                          "%s should have type %s, got null",
+                                          what,
+                                          PrettyDescriptor(dst_class).c_str());
     return false;
   }
 
@@ -335,7 +341,10 @@
     boxed_value.i = primitive_field->GetShort(o);  // and extend read value to 32bits
   } else {
     Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
-        "%s is not a boxed primitive type", PrettyDescriptor(src_descriptor.c_str()).c_str());
+                                          "%s should have type %s, got %s",
+                                          what,
+                                          PrettyDescriptor(dst_class).c_str(),
+                                          PrettyDescriptor(src_descriptor.c_str()).c_str());
     return false;
   }