summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler_llvm/runtime_support_llvm.cc2
-rw-r--r--src/native/java_lang_reflect_Field.cc2
-rw-r--r--src/oat/runtime/support_proxy.cc2
-rw-r--r--src/reflection.cc49
-rw-r--r--src/reflection.h5
5 files changed, 46 insertions, 14 deletions
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index a31c27eefa..0db31873e6 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -756,7 +756,7 @@ void art_proxy_invoke_handler_from_code(Method* proxy_method, ...) {
if (result_ref == NULL) {
result_unboxed->SetL(NULL);
} else {
- bool unboxed_okay = UnboxPrimitive(result_ref, proxy_mh.GetReturnType(), *result_unboxed, "result");
+ bool unboxed_okay = UnboxPrimitiveForResult(result_ref, proxy_mh.GetReturnType(), *result_unboxed);
if (!unboxed_okay) {
thread->ClearException();
thread->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
diff --git a/src/native/java_lang_reflect_Field.cc b/src/native/java_lang_reflect_Field.cc
index fe9f79ccc3..3e0c9d7377 100644
--- a/src/native/java_lang_reflect_Field.cc
+++ b/src/native/java_lang_reflect_Field.cc
@@ -213,7 +213,7 @@ static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject j
// Unbox the value, if necessary.
Object* boxed_value = Decode<Object*>(env, javaValue);
JValue unboxed_value;
- if (!UnboxPrimitive(boxed_value, FieldHelper(f).GetType(), unboxed_value, "field")) {
+ if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) {
return;
}
diff --git a/src/oat/runtime/support_proxy.cc b/src/oat/runtime/support_proxy.cc
index 46f231356c..cc375ad6a4 100644
--- a/src/oat/runtime/support_proxy.cc
+++ b/src/oat/runtime/support_proxy.cc
@@ -168,7 +168,7 @@ extern "C" void artProxyInvokeHandler(Method* proxy_method, Object* receiver,
Object* result_ref = self->DecodeJObject(result);
if (result_ref != NULL) {
JValue result_unboxed;
- bool unboxed_okay = UnboxPrimitive(result_ref, proxy_mh.GetReturnType(), result_unboxed, "result");
+ bool unboxed_okay = UnboxPrimitiveForResult(result_ref, proxy_mh.GetReturnType(), result_unboxed);
if (!unboxed_okay) {
self->ClearException();
self->ThrowNewExceptionF("Ljava/lang/ClassCastException;",
diff --git a/src/reflection.cc b/src/reflection.cc
index e919ef18a9..6763100b54 100644
--- a/src/reflection.cc
+++ b/src/reflection.cc
@@ -91,10 +91,16 @@ jobject InvokeMethod(JNIEnv* env, jobject javaMethod, jobject javaReceiver, jobj
Object* arg = objects->Get(i);
Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_);
if (dst_class->IsPrimitive()) {
- std::string what(StringPrintf("argument %d", i + 1)); // Humans count from 1.
- if (!UnboxPrimitive(arg, dst_class, decoded_args[i], what.c_str())) {
+ if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], i)) {
return NULL;
}
+ } else if (arg != NULL && !arg->InstanceOf(dst_class)) {
+ self->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
+ "argument %d has type %s, got %s",
+ i + 1,
+ PrettyDescriptor(dst_class).c_str(),
+ PrettyTypeOf(arg).c_str());
+ return NULL;
} else {
args[i].l = AddLocalReference<jobject>(env, arg);
}
@@ -265,12 +271,22 @@ void BoxPrimitive(Primitive::Type src_class, JValue& value) {
m->Invoke(self, NULL, args, &value);
}
-bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, const char* what) {
+static std::string UnboxingFailureKind(int index, Field* f) {
+ if (index != -1) {
+ return StringPrintf("argument %d", index + 1); // Humans count from 1.
+ }
+ if (f != NULL) {
+ return "field " + PrettyField(f, false);
+ }
+ return "result";
+}
+
+static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, int index, Field* f) {
if (!dst_class->IsPrimitive()) {
if (o != NULL && !o->InstanceOf(dst_class)) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
- "boxed object for %s should have type %s, but got %s",
- what,
+ "%s has type %s, got %s",
+ UnboxingFailureKind(index, f).c_str(),
PrettyDescriptor(dst_class).c_str(),
PrettyTypeOf(o).c_str());
return false;
@@ -280,14 +296,14 @@ bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, const ch
} else if (dst_class->GetPrimitiveType() == Primitive::kPrimVoid) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
"can't unbox %s to void",
- what);
+ UnboxingFailureKind(index, f).c_str());
return false;
}
if (o == NULL) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
- "%s should have type %s, got null",
- what,
+ "%s has type %s, got null",
+ UnboxingFailureKind(index, f).c_str(),
PrettyDescriptor(dst_class).c_str());
return false;
}
@@ -323,8 +339,8 @@ bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, const ch
boxed_value.SetS(primitive_field->GetShort(o));
} else {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
- "%s should have type %s, got %s",
- what,
+ "%s has type %s, got %s",
+ UnboxingFailureKind(index, f).c_str(),
PrettyDescriptor(dst_class).c_str(),
PrettyDescriptor(src_descriptor.c_str()).c_str());
return false;
@@ -334,4 +350,17 @@ bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, const ch
boxed_value, unboxed_value);
}
+bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, size_t index) {
+ return UnboxPrimitive(o, dst_class, unboxed_value, index, NULL);
+}
+
+bool UnboxPrimitiveForField(Object* o, Class* dst_class, JValue& unboxed_value, Field* f) {
+ CHECK(f != NULL);
+ return UnboxPrimitive(o, dst_class, unboxed_value, -1, f);
+}
+
+bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value) {
+ return UnboxPrimitive(o, dst_class, unboxed_value, -1, NULL);
+}
+
} // namespace art
diff --git a/src/reflection.h b/src/reflection.h
index f5173d9599..aabf513060 100644
--- a/src/reflection.h
+++ b/src/reflection.h
@@ -23,12 +23,15 @@
namespace art {
class Class;
+class Field;
union JValue;
class Object;
void InitBoxingMethods();
void BoxPrimitive(Primitive::Type src_class, JValue& value);
-bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, const char* what);
+bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, size_t index);
+bool UnboxPrimitiveForField(Object* o, Class* dst_class, JValue& unboxed_value, Field* f);
+bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value);
bool ConvertPrimitiveValue(Primitive::Type src_class, Primitive::Type dst_class, const JValue& src, JValue& dst);