Support reflective lookup of single fields.
Change-Id: Ie7058fa9de8212b0f52d5d9b0ec7d46242a851fc
http://b/4087759
diff --git a/vm/native/java_lang_Class.c b/vm/native/java_lang_Class.c
index 1a78e54..65fbbb7 100644
--- a/vm/native/java_lang_Class.c
+++ b/vm/native/java_lang_Class.c
@@ -242,7 +242,6 @@
/*
* static Field[] getDeclaredFields(Class klass, boolean publicOnly)
- * throws SecurityException
*/
static void Dalvik_java_lang_Class_getDeclaredFields(const u4* args,
JValue* pResult)
@@ -258,6 +257,19 @@
}
/*
+ * static Field getDeclaredField(Class klass, String name)
+ */
+static void Dalvik_java_lang_Class_getDeclaredField(const u4* args,
+ JValue* pResult)
+{
+ ClassObject* clazz = (ClassObject*) args[0];
+ StringObject* nameObj = (StringObject*) args[1];
+ Object* fieldObj = dvmGetDeclaredField(clazz, nameObj);
+ dvmReleaseTrackedAlloc((Object*) fieldObj, NULL);
+ RETURN_PTR(fieldObj);
+}
+
+/*
* static Method[] getDeclaredMethods(Class clazz, boolean publicOnly)
* throws SecurityException
*/
@@ -777,6 +789,8 @@
Dalvik_java_lang_Class_getDeclaredFields },
{ "getDeclaredMethods", "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;",
Dalvik_java_lang_Class_getDeclaredMethods },
+ { "getDeclaredField", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;",
+ Dalvik_java_lang_Class_getDeclaredField },
{ "getDeclaredConstructorOrMethod", "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;",
Dalvik_java_lang_Class_getDeclaredConstructorOrMethod },
{ "getInterfaces", "()[Ljava/lang/Class;",
diff --git a/vm/reflect/Reflect.c b/vm/reflect/Reflect.c
index ae165dc..7a21ef3 100644
--- a/vm/reflect/Reflect.c
+++ b/vm/reflect/Reflect.c
@@ -801,6 +801,39 @@
}
/*
+ * Get the named field.
+ */
+Object* dvmGetDeclaredField(ClassObject* clazz, StringObject* nameObj)
+{
+ int i;
+ Object* fieldObj = NULL;
+ char* name = dvmCreateCstrFromString(nameObj);
+
+ if (!dvmIsClassInitialized(gDvm.classJavaLangReflectField))
+ dvmInitClass(gDvm.classJavaLangReflectField);
+
+ for (i = 0; i < clazz->sfieldCount; i++) {
+ Field* field = &clazz->sfields[i].field;
+ if (strcmp(name, field->name) == 0) {
+ fieldObj = createFieldObject(field, clazz);
+ break;
+ }
+ }
+ if (fieldObj == NULL) {
+ for (i = 0; i < clazz->ifieldCount; i++) {
+ Field* field = &clazz->ifields[i].field;
+ if (strcmp(name, field->name) == 0) {
+ fieldObj = createFieldObject(field, clazz);
+ break;
+ }
+ }
+ }
+
+ free(name);
+ return fieldObj;
+}
+
+/*
* Get all interfaces a class implements. If this is unable to allocate
* the result array, this raises an OutOfMemoryError and returns NULL.
*/
diff --git a/vm/reflect/Reflect.h b/vm/reflect/Reflect.h
index c1f2276..80e96fa 100644
--- a/vm/reflect/Reflect.h
+++ b/vm/reflect/Reflect.h
@@ -32,6 +32,11 @@
ArrayObject* dvmGetDeclaredFields(ClassObject* clazz, bool publicOnly);
/*
+ * Get the named field.
+ */
+Object* dvmGetDeclaredField(ClassObject* clazz, StringObject* nameObj);
+
+/*
* Get all constructors declared by a class.
*/
ArrayObject* dvmGetDeclaredConstructors(ClassObject* clazz, bool publicOnly);