diff options
| -rw-r--r-- | Android.mk | 4 | ||||
| -rw-r--r-- | src/reflection.cc | 39 | ||||
| -rw-r--r-- | src/reflection.h | 3 | ||||
| -rw-r--r-- | test/200-reflection-errors/expected.txt | 4 |
4 files changed, 24 insertions, 26 deletions
diff --git a/Android.mk b/Android.mk index 6eb4299515..aa567a71c6 100644 --- a/Android.mk +++ b/Android.mk @@ -123,7 +123,7 @@ test-art-host-run-test-$(1): test-art-host-dependencies TEST_ART_HOST_RUN_TEST_TARGETS += test-art-host-run-test-$(1) endef -$(foreach test, $(wildcard art/test/0*), $(eval $(call declare-test-art-host-run-test,$(notdir $(test))))) +$(foreach test, $(wildcard art/test/[0-9]*), $(eval $(call declare-test-art-host-run-test,$(notdir $(test))))) .PHONY: test-art-host-run-test test-art-host-run-test: $(TEST_ART_HOST_RUN_TEST_TARGETS) @@ -162,7 +162,7 @@ test-art-target-run-test-$(1): test-art-target-sync TEST_ART_TARGET_RUN_TEST_TARGETS += test-art-target-run-test-$(1) endef -$(foreach test, $(wildcard art/test/0*), $(eval $(call declare-test-art-target-run-test,$(notdir $(test))))) +$(foreach test, $(wildcard art/test/[0-9]*), $(eval $(call declare-test-art-target-run-test,$(notdir $(test))))) .PHONY: test-art-target-run-test test-art-target-run-test: $(TEST_ART_TARGET_RUN_TEST_TARGETS) diff --git a/src/reflection.cc b/src/reflection.cc index 6763100b54..12ecbe195d 100644 --- a/src/reflection.cc +++ b/src/reflection.cc @@ -90,18 +90,13 @@ jobject InvokeMethod(JNIEnv* env, jobject javaMethod, jobject javaReceiver, jobj for (uint32_t i = 0; i < arg_count; ++i) { Object* arg = objects->Get(i); Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_); - if (dst_class->IsPrimitive()) { - if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], i)) { + if (dst_class->IsPrimitive() || (arg != NULL && !arg->InstanceOf(dst_class))) { + // We want to actually unbox primitives, but only reuse the error reporting for reference types. + if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], m, 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 { + // We already tested that these types are compatible. args[i].l = AddLocalReference<jobject>(env, arg); } } @@ -271,9 +266,10 @@ void BoxPrimitive(Primitive::Type src_class, JValue& value) { m->Invoke(self, NULL, args, &value); } -static std::string UnboxingFailureKind(int index, Field* f) { - if (index != -1) { - return StringPrintf("argument %d", index + 1); // Humans count from 1. +static std::string UnboxingFailureKind(Method* m, int index, Field* f) { + if (m != NULL && index != -1) { + ++index; // Humans count from 1. + return StringPrintf("method %s argument %d", PrettyMethod(m, false).c_str(), index); } if (f != NULL) { return "field " + PrettyField(f, false); @@ -281,12 +277,12 @@ static std::string UnboxingFailureKind(int index, Field* f) { return "result"; } -static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, int index, Field* f) { +static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, int index, Field* f) { if (!dst_class->IsPrimitive()) { if (o != NULL && !o->InstanceOf(dst_class)) { Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", "%s has type %s, got %s", - UnboxingFailureKind(index, f).c_str(), + UnboxingFailureKind(m, index, f).c_str(), PrettyDescriptor(dst_class).c_str(), PrettyTypeOf(o).c_str()); return false; @@ -296,14 +292,14 @@ static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, i } else if (dst_class->GetPrimitiveType() == Primitive::kPrimVoid) { Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", "can't unbox %s to void", - UnboxingFailureKind(index, f).c_str()); + UnboxingFailureKind(m, index, f).c_str()); return false; } if (o == NULL) { Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", "%s has type %s, got null", - UnboxingFailureKind(index, f).c_str(), + UnboxingFailureKind(m, index, f).c_str(), PrettyDescriptor(dst_class).c_str()); return false; } @@ -340,7 +336,7 @@ static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, i } else { Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", "%s has type %s, got %s", - UnboxingFailureKind(index, f).c_str(), + UnboxingFailureKind(m, index, f).c_str(), PrettyDescriptor(dst_class).c_str(), PrettyDescriptor(src_descriptor.c_str()).c_str()); return false; @@ -350,17 +346,18 @@ static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, i 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 UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, size_t index) { + CHECK(m != NULL); + return UnboxPrimitive(o, dst_class, unboxed_value, m, 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); + return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, f); } bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value) { - return UnboxPrimitive(o, dst_class, unboxed_value, -1, NULL); + return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, NULL); } } // namespace art diff --git a/src/reflection.h b/src/reflection.h index aabf513060..50c36d7a6c 100644 --- a/src/reflection.h +++ b/src/reflection.h @@ -25,11 +25,12 @@ namespace art { class Class; class Field; union JValue; +class Method; class Object; void InitBoxingMethods(); void BoxPrimitive(Primitive::Type src_class, JValue& value); -bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, size_t index); +bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, 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); diff --git a/test/200-reflection-errors/expected.txt b/test/200-reflection-errors/expected.txt index b5b201d5de..d042d054ca 100644 --- a/test/200-reflection-errors/expected.txt +++ b/test/200-reflection-errors/expected.txt @@ -1,5 +1,5 @@ field A.b has type java.lang.String, got java.lang.Integer field A.i has type int, got null field A.i has type int, got java.lang.String -argument 2 has type java.lang.String, got java.lang.Integer -argument 1 has type int, got null +method A.m argument 2 has type java.lang.String, got java.lang.Integer +method A.m argument 1 has type int, got null |