Implement reflective method invocation.
Change-Id: Ib3af9d7e00bf226398610b5ac6efbfe3eb2d15e8
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index 9ca171b..69ad910 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -67,53 +67,43 @@
return AddLocalReference<jclass>(env, Decode<Class*>(env, javaThis)->GetComponentType());
}
+bool MethodMatches(Method* m, String* name, const std::string& signature) {
+ if (!m->GetName()->Equals(name)) {
+ return false;
+ }
+ std::string method_signature = m->GetSignature()->ToModifiedUtf8();
+ if (!StringPiece(method_signature).starts_with(signature)) {
+ return false;
+ }
+ m->InitJavaFields();
+ return true;
+}
+
jobject Class_getDeclaredConstructorOrMethod(JNIEnv* env, jclass,
- jclass jklass, jstring jname, jobjectArray jsignature) {
- Class* klass = Decode<Class*>(env, jklass);
- DCHECK(klass->IsClass());
- String* name = Decode<String*>(env, jname);
- DCHECK(name->IsString());
- Object* signature_obj = Decode<Object*>(env, jsignature);
- DCHECK(signature_obj->IsArrayInstance());
- // check that this is a Class[] by checking that component type is Class
- // foo->GetClass()->GetClass() is an idiom for getting java.lang.Class from an arbitrary object
- DCHECK(signature_obj->GetClass()->GetComponentType() == signature_obj->GetClass()->GetClass());
- ObjectArray<Class>* signature = down_cast<ObjectArray<Class>*>(signature_obj);
+ jclass javaClass, jstring javaName, jobjectArray javaSignature) {
+ Class* c = Decode<Class*>(env, javaClass);
+ String* name = Decode<String*>(env, javaName);
+ ObjectArray<Class>* signature_array = Decode<ObjectArray<Class>*>(env, javaSignature);
- std::string name_string = name->ToModifiedUtf8();
- std::string signature_string;
- signature_string += "(";
- for (int i = 0; i < signature->GetLength(); i++) {
- Class* argument_class = signature->Get(0);
- if (argument_class == NULL) {
- UNIMPLEMENTED(FATAL) << "throw null pointer exception?";
- }
- signature_string += argument_class->GetDescriptor()->ToModifiedUtf8();
+ std::string signature;
+ signature += "(";
+ for (int i = 0; i < signature_array->GetLength(); i++) {
+ signature += signature_array->Get(i)->GetDescriptor()->ToModifiedUtf8();
}
- signature_string += ")";
+ signature += ")";
- for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
- Method* method = klass->GetVirtualMethod(i);
- if (!method->GetName()->Equals(name)) {
- continue;
+ for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
+ Method* m = c->GetVirtualMethod(i);
+ if (MethodMatches(m, name, signature)) {
+ return AddLocalReference<jobject>(env, m);
}
- std::string method_signature = method->GetSignature()->ToModifiedUtf8();
- if (!StringPiece(method_signature).starts_with(signature_string)) {
- continue;
- }
- return AddLocalReference<jobject>(env, method);
}
- for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
- Method* method = klass->GetDirectMethod(i);
- if (!method->GetName()->Equals(name)) {
- continue;
+ for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
+ Method* m = c->GetDirectMethod(i);
+ if (MethodMatches(m, name, signature)) {
+ return AddLocalReference<jobject>(env, m);
}
- std::string method_signature = method->GetSignature()->ToModifiedUtf8();
- if (!StringPiece(method_signature).starts_with(signature_string)) {
- continue;
- }
- return AddLocalReference<jobject>(env, method);
}
return NULL;
@@ -326,7 +316,6 @@
NATIVE_METHOD(Class, getEnclosingConstructor, "()Ljava/lang/reflect/Constructor;"),
NATIVE_METHOD(Class, getEnclosingMethod, "()Ljava/lang/reflect/Method;"),
//NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"),
- //NATIVE_METHOD(Class, getInterfaces, "()[Ljava/lang/Class;"),
//NATIVE_METHOD(Class, getModifiers, "(Ljava/lang/Class;Z)I"),
NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
NATIVE_METHOD(Class, getSuperclass, "()Ljava/lang/Class;"),