| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * java.lang.reflect.Field |
| */ |
| #include "Dalvik.h" |
| #include "native/InternalNativePriv.h" |
| |
| |
| /* |
| * Validate access to a field. Returns a pointer to the Field struct. |
| * |
| * "declaringClass" is the class in which the field was declared. For an |
| * instance field, "obj" is the object that holds the field data; for a |
| * static field its value is ignored. |
| * |
| * "If the underlying field is static, the class that declared the |
| * field is initialized if it has not already been initialized." |
| * |
| * On failure, throws an exception and returns NULL. |
| * |
| * The documentation lists exceptional conditions and the exceptions that |
| * should be thrown, but doesn't say which exception prevails when two or |
| * more exceptional conditions exist at the same time. For example, |
| * attempting to set a protected field from an unrelated class causes an |
| * IllegalAccessException, while passing in a data type that doesn't match |
| * the field causes an IllegalArgumentException. If code does both at the |
| * same time, we have to choose one or the other. |
| * |
| * The expected order is: |
| * (1) Check for illegal access. Throw IllegalAccessException. |
| * (2) Make sure the object actually has the field. Throw |
| * IllegalArgumentException. |
| * (3) Make sure the field matches the expected type, e.g. if we issued |
| * a "getInteger" call make sure the field is an integer or can be |
| * converted to an int with a widening conversion. Throw |
| * IllegalArgumentException. |
| * (4) Make sure "obj" is not null. Throw NullPointerException. |
| * |
| * TODO: we're currently handling #3 after #4, because we don't check the |
| * widening conversion until we're actually extracting the value from the |
| * object (which won't work well if it's a null reference). |
| */ |
| static Field* validateFieldAccess(Object* obj, ClassObject* declaringClass, |
| int slot, bool isSetOperation, bool noAccessCheck) |
| { |
| Field* field; |
| |
| field = dvmSlotToField(declaringClass, slot); |
| assert(field != NULL); |
| |
| /* verify access */ |
| if (!noAccessCheck) { |
| if (isSetOperation && dvmIsFinalField(field)) { |
| dvmThrowException("Ljava/lang/IllegalAccessException;", |
| "field is marked 'final'"); |
| return NULL; |
| } |
| |
| ClassObject* callerClass = |
| dvmGetCaller2Class(dvmThreadSelf()->curFrame); |
| |
| /* |
| * We need to check two things: |
| * (1) Would an instance of the calling class have access to the field? |
| * (2) If the field is "protected", is the object an instance of the |
| * calling class, or is the field's declaring class in the same |
| * package as the calling class? |
| * |
| * #1 is basic access control. #2 ensures that, just because |
| * you're a subclass of Foo, you can't mess with protected fields |
| * in arbitrary Foo objects from other packages. |
| */ |
| if (!dvmCheckFieldAccess(callerClass, field)) { |
| dvmThrowException("Ljava/lang/IllegalAccessException;", |
| "access to field not allowed"); |
| return NULL; |
| } |
| if (dvmIsProtectedField(field)) { |
| bool isInstance, samePackage; |
| |
| if (obj != NULL) |
| isInstance = dvmInstanceof(obj->clazz, callerClass); |
| else |
| isInstance = false; |
| samePackage = dvmInSamePackage(declaringClass, callerClass); |
| |
| if (!isInstance && !samePackage) { |
| dvmThrowException("Ljava/lang/IllegalAccessException;", |
| "access to protected field not allowed"); |
| return NULL; |
| } |
| } |
| } |
| |
| if (dvmIsStaticField(field)) { |
| /* init class if necessary, then return ptr to storage in "field" */ |
| if (!dvmIsClassInitialized(declaringClass)) { |
| if (!dvmInitClass(declaringClass)) { |
| assert(dvmCheckException(dvmThreadSelf())); |
| return NULL; |
| } |
| } |
| |
| } else { |
| /* |
| * Verify object is of correct type (i.e. it actually has the |
| * expected field in it), then grab a pointer to obj storage. |
| * The call to dvmVerifyObjectInClass throws an NPE if "obj" is NULL. |
| */ |
| if (!dvmVerifyObjectInClass(obj, declaringClass)) { |
| assert(dvmCheckException(dvmThreadSelf())); |
| if (obj != NULL) { |
| LOGD("Wrong object type for field access: %s is not a %s\n", |
| obj->clazz->descriptor, declaringClass->descriptor); |
| } |
| return NULL; |
| } |
| } |
| |
| return field; |
| } |
| |
| /* |
| * Extracts the value of a static field. Provides appropriate barriers |
| * for volatile fields. |
| * |
| * Sub-32-bit values are sign- or zero-extended to fill out 32 bits. |
| */ |
| static void getStaticFieldValue(const StaticField* sfield, JValue* value) |
| { |
| if (!dvmIsVolatileField(&sfield->field)) { |
| /* just copy the whole thing */ |
| *value = sfield->value; |
| } else { |
| /* need memory barriers and/or 64-bit atomic ops */ |
| switch (sfield->field.signature[0]) { |
| case 'Z': |
| value->i = dvmGetStaticFieldBooleanVolatile(sfield); |
| break; |
| case 'B': |
| value->i = dvmGetStaticFieldByteVolatile(sfield); |
| break; |
| case 'S': |
| value->i = dvmGetStaticFieldShortVolatile(sfield); |
| break; |
| case 'C': |
| value->i = dvmGetStaticFieldCharVolatile(sfield); |
| break; |
| case 'I': |
| value->i = dvmGetStaticFieldIntVolatile(sfield); |
| break; |
| case 'F': |
| value->f = dvmGetStaticFieldFloatVolatile(sfield); |
| break; |
| case 'J': |
| value->j = dvmGetStaticFieldLongVolatile(sfield); |
| break; |
| case 'D': |
| value->d = dvmGetStaticFieldDoubleVolatile(sfield); |
| break; |
| case 'L': |
| case '[': |
| value->l = dvmGetStaticFieldObjectVolatile(sfield); |
| break; |
| default: |
| LOGE("Unhandled field signature '%s'\n", sfield->field.signature); |
| dvmAbort(); |
| } |
| } |
| } |
| |
| /* |
| * Extracts the value of an instance field. Provides appropriate barriers |
| * for volatile fields. |
| * |
| * Sub-32-bit values are sign- or zero-extended to fill out 32 bits. |
| */ |
| static void getInstFieldValue(const InstField* ifield, Object* obj, |
| JValue* value) |
| { |
| if (!dvmIsVolatileField(&ifield->field)) { |
| /* use type-specific get; really just 32-bit vs. 64-bit */ |
| switch (ifield->field.signature[0]) { |
| case 'Z': |
| value->i = dvmGetFieldBoolean(obj, ifield->byteOffset); |
| break; |
| case 'B': |
| value->i = dvmGetFieldByte(obj, ifield->byteOffset); |
| break; |
| case 'S': |
| value->i = dvmGetFieldShort(obj, ifield->byteOffset); |
| break; |
| case 'C': |
| value->i = dvmGetFieldChar(obj, ifield->byteOffset); |
| break; |
| case 'I': |
| value->i = dvmGetFieldInt(obj, ifield->byteOffset); |
| break; |
| case 'F': |
| value->f = dvmGetFieldFloat(obj, ifield->byteOffset); |
| break; |
| case 'J': |
| value->j = dvmGetFieldLong(obj, ifield->byteOffset); |
| break; |
| case 'D': |
| value->d = dvmGetFieldDouble(obj, ifield->byteOffset); |
| break; |
| case 'L': |
| case '[': |
| value->l = dvmGetFieldObject(obj, ifield->byteOffset); |
| break; |
| default: |
| LOGE("Unhandled field signature '%s'\n", ifield->field.signature); |
| dvmAbort(); |
| } |
| } else { |
| /* need memory barriers and/or 64-bit atomic ops */ |
| switch (ifield->field.signature[0]) { |
| case 'Z': |
| value->i = dvmGetFieldBooleanVolatile(obj, ifield->byteOffset); |
| break; |
| case 'B': |
| value->i = dvmGetFieldByteVolatile(obj, ifield->byteOffset); |
| break; |
| case 'S': |
| value->i = dvmGetFieldShortVolatile(obj, ifield->byteOffset); |
| break; |
| case 'C': |
| value->i = dvmGetFieldCharVolatile(obj, ifield->byteOffset); |
| break; |
| case 'I': |
| value->i = dvmGetFieldIntVolatile(obj, ifield->byteOffset); |
| break; |
| case 'F': |
| value->f = dvmGetFieldFloatVolatile(obj, ifield->byteOffset); |
| break; |
| case 'J': |
| value->j = dvmGetFieldLongVolatile(obj, ifield->byteOffset); |
| break; |
| case 'D': |
| value->d = dvmGetFieldDoubleVolatile(obj, ifield->byteOffset); |
| break; |
| case 'L': |
| case '[': |
| value->l = dvmGetFieldObjectVolatile(obj, ifield->byteOffset); |
| break; |
| default: |
| LOGE("Unhandled field signature '%s'\n", ifield->field.signature); |
| dvmAbort(); |
| } |
| } |
| } |
| |
| /* |
| * Copies the value of the static or instance field into "*value". |
| */ |
| static void getFieldValue(const Field* field, Object* obj, JValue* value) |
| { |
| if (dvmIsStaticField(field)) { |
| return getStaticFieldValue((const StaticField*) field, value); |
| } else { |
| return getInstFieldValue((const InstField*) field, obj, value); |
| } |
| } |
| |
| /* |
| * Sets the value of a static field. Provides appropriate barriers |
| * for volatile fields. |
| */ |
| static void setStaticFieldValue(StaticField* sfield, const JValue* value) |
| { |
| if (!dvmIsVolatileField(&sfield->field)) { |
| switch (sfield->field.signature[0]) { |
| case 'L': |
| case '[': |
| dvmSetStaticFieldObject(sfield, value->l); |
| break; |
| default: |
| /* just copy the whole thing */ |
| sfield->value = *value; |
| break; |
| } |
| } else { |
| /* need memory barriers and/or 64-bit atomic ops */ |
| switch (sfield->field.signature[0]) { |
| case 'Z': |
| dvmSetStaticFieldBooleanVolatile(sfield, value->z); |
| break; |
| case 'B': |
| dvmSetStaticFieldByteVolatile(sfield, value->b); |
| break; |
| case 'S': |
| dvmSetStaticFieldShortVolatile(sfield, value->s); |
| break; |
| case 'C': |
| dvmSetStaticFieldCharVolatile(sfield, value->c); |
| break; |
| case 'I': |
| dvmSetStaticFieldIntVolatile(sfield, value->i); |
| break; |
| case 'F': |
| dvmSetStaticFieldFloatVolatile(sfield, value->f); |
| break; |
| case 'J': |
| dvmSetStaticFieldLongVolatile(sfield, value->j); |
| break; |
| case 'D': |
| dvmSetStaticFieldDoubleVolatile(sfield, value->d); |
| break; |
| case 'L': |
| case '[': |
| dvmSetStaticFieldObjectVolatile(sfield, value->l); |
| break; |
| default: |
| LOGE("Unhandled field signature '%s'\n", sfield->field.signature); |
| dvmAbort(); |
| } |
| } |
| } |
| |
| /* |
| * Sets the value of an instance field. Provides appropriate barriers |
| * for volatile fields. |
| */ |
| static void setInstFieldValue(InstField* ifield, Object* obj, |
| const JValue* value) |
| { |
| if (!dvmIsVolatileField(&ifield->field)) { |
| /* use type-specific set; really just 32-bit vs. 64-bit */ |
| switch (ifield->field.signature[0]) { |
| case 'Z': |
| dvmSetFieldBoolean(obj, ifield->byteOffset, value->z); |
| break; |
| case 'B': |
| dvmSetFieldByte(obj, ifield->byteOffset, value->b); |
| break; |
| case 'S': |
| dvmSetFieldShort(obj, ifield->byteOffset, value->s); |
| break; |
| case 'C': |
| dvmSetFieldChar(obj, ifield->byteOffset, value->c); |
| break; |
| case 'I': |
| dvmSetFieldInt(obj, ifield->byteOffset, value->i); |
| break; |
| case 'F': |
| dvmSetFieldFloat(obj, ifield->byteOffset, value->f); |
| break; |
| case 'J': |
| dvmSetFieldLong(obj, ifield->byteOffset, value->j); |
| break; |
| case 'D': |
| dvmSetFieldDouble(obj, ifield->byteOffset, value->d); |
| break; |
| case 'L': |
| case '[': |
| dvmSetFieldObject(obj, ifield->byteOffset, value->l); |
| break; |
| default: |
| LOGE("Unhandled field signature '%s'\n", ifield->field.signature); |
| dvmAbort(); |
| } |
| #if ANDROID_SMP != 0 |
| /* |
| * Special handling for final fields on SMP systems. We need a |
| * store/store barrier here (JMM requirement). |
| */ |
| if (dvmIsFinalField(&ifield->field)) { |
| ANDROID_MEMBAR_STORE(); |
| } |
| #endif |
| } else { |
| /* need memory barriers and/or 64-bit atomic ops */ |
| switch (ifield->field.signature[0]) { |
| case 'Z': |
| dvmSetFieldBooleanVolatile(obj, ifield->byteOffset, value->z); |
| break; |
| case 'B': |
| dvmSetFieldByteVolatile(obj, ifield->byteOffset, value->b); |
| break; |
| case 'S': |
| dvmSetFieldShortVolatile(obj, ifield->byteOffset, value->s); |
| break; |
| case 'C': |
| dvmSetFieldCharVolatile(obj, ifield->byteOffset, value->c); |
| break; |
| case 'I': |
| dvmSetFieldIntVolatile(obj, ifield->byteOffset, value->i); |
| break; |
| case 'F': |
| dvmSetFieldFloatVolatile(obj, ifield->byteOffset, value->f); |
| break; |
| case 'J': |
| dvmSetFieldLongVolatile(obj, ifield->byteOffset, value->j); |
| break; |
| case 'D': |
| dvmSetFieldDoubleVolatile(obj, ifield->byteOffset, value->d); |
| break; |
| case 'L': |
| case '[': |
| dvmSetFieldObjectVolatile(obj, ifield->byteOffset, value->l); |
| break; |
| default: |
| LOGE("Unhandled field signature '%s'\n", ifield->field.signature); |
| dvmAbort(); |
| } |
| } |
| } |
| |
| /* |
| * Copy "*value" into the static or instance field. |
| */ |
| static void setFieldValue(Field* field, Object* obj, const JValue* value) |
| { |
| if (dvmIsStaticField(field)) { |
| return setStaticFieldValue((StaticField*) field, value); |
| } else { |
| return setInstFieldValue((InstField*) field, obj, value); |
| } |
| } |
| |
| |
| |
| /* |
| * public int getFieldModifiers(Class declaringClass, int slot) |
| */ |
| static void Dalvik_java_lang_reflect_Field_getFieldModifiers(const u4* args, |
| JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| ClassObject* declaringClass = (ClassObject*) args[1]; |
| int slot = args[2]; |
| Field* field; |
| |
| field = dvmSlotToField(declaringClass, slot); |
| RETURN_INT(field->accessFlags & JAVA_FLAGS_MASK); |
| } |
| |
| /* |
| * private Object getField(Object o, Class declaringClass, Class type, |
| * int slot, boolean noAccessCheck) |
| * |
| * Primitive types need to be boxed. |
| */ |
| static void Dalvik_java_lang_reflect_Field_getField(const u4* args, |
| JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| Object* obj = (Object*) args[1]; |
| ClassObject* declaringClass = (ClassObject*) args[2]; |
| ClassObject* fieldType = (ClassObject*) args[3]; |
| int slot = args[4]; |
| bool noAccessCheck = (args[5] != 0); |
| Field* field; |
| JValue value; |
| DataObject* result; |
| |
| //dvmDumpClass(obj->clazz, kDumpClassFullDetail); |
| |
| /* get a pointer to the Field after validating access */ |
| field = validateFieldAccess(obj, declaringClass, slot, false,noAccessCheck); |
| if (field == NULL) |
| RETURN_VOID(); |
| |
| getFieldValue(field, obj, &value); |
| |
| /* if it's primitive, box it up */ |
| result = dvmBoxPrimitive(value, fieldType); |
| dvmReleaseTrackedAlloc((Object*) result, NULL); |
| RETURN_PTR(result); |
| } |
| |
| /* |
| * private void setField(Object o, Class declaringClass, Class type, |
| * int slot, boolean noAccessCheck, Object value) |
| * |
| * When assigning into a primitive field we will automatically extract |
| * the value from box types. |
| */ |
| static void Dalvik_java_lang_reflect_Field_setField(const u4* args, |
| JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| Object* obj = (Object*) args[1]; |
| ClassObject* declaringClass = (ClassObject*) args[2]; |
| ClassObject* fieldType = (ClassObject*) args[3]; |
| int slot = args[4]; |
| bool noAccessCheck = (args[5] != 0); |
| Object* valueObj = (Object*) args[6]; |
| Field* field; |
| JValue value; |
| |
| /* unbox primitive, or verify object type */ |
| if (!dvmUnboxPrimitive(valueObj, fieldType, &value)) { |
| dvmThrowException("Ljava/lang/IllegalArgumentException;", |
| "invalid value for field"); |
| RETURN_VOID(); |
| } |
| |
| /* get a pointer to the Field after validating access */ |
| field = validateFieldAccess(obj, declaringClass, slot, true, noAccessCheck); |
| |
| if (field != NULL) { |
| setFieldValue(field, obj, &value); |
| } |
| RETURN_VOID(); |
| } |
| |
| /* |
| * Convert a reflection primitive type ordinal (inherited from the previous |
| * VM's reflection classes) to our value. |
| */ |
| static PrimitiveType convPrimType(int typeNum) |
| { |
| static const PrimitiveType conv[PRIM_MAX] = { |
| PRIM_NOT, PRIM_BOOLEAN, PRIM_BYTE, PRIM_CHAR, PRIM_SHORT, |
| PRIM_INT, PRIM_FLOAT, PRIM_LONG, PRIM_DOUBLE |
| }; |
| if (typeNum <= 0 || typeNum > 8) |
| return PRIM_NOT; |
| return conv[typeNum]; |
| } |
| |
| /* |
| * Primitive field getters, e.g.: |
| * private double getIField(Object o, Class declaringClass, |
| * Class type, int slot, boolean noAccessCheck, int type_no) |
| * |
| * The "type_no" is defined by the java.lang.reflect.Field class. |
| */ |
| static void Dalvik_java_lang_reflect_Field_getPrimitiveField(const u4* args, |
| JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| Object* obj = (Object*) args[1]; |
| ClassObject* declaringClass = (ClassObject*) args[2]; |
| ClassObject* fieldType = (ClassObject*) args[3]; |
| int slot = args[4]; |
| bool noAccessCheck = (args[5] != 0); |
| int typeNum = args[6]; |
| PrimitiveType targetType = convPrimType(typeNum); |
| const Field* field; |
| JValue value; |
| |
| if (!dvmIsPrimitiveClass(fieldType)) { |
| dvmThrowException("Ljava/lang/IllegalArgumentException;", |
| "not a primitive field"); |
| RETURN_VOID(); |
| } |
| |
| /* get a pointer to the Field after validating access */ |
| field = validateFieldAccess(obj, declaringClass, slot, false,noAccessCheck); |
| if (field == NULL) |
| RETURN_VOID(); |
| |
| getFieldValue(field, obj, &value); |
| |
| /* retrieve value, performing a widening conversion if necessary */ |
| if (dvmConvertPrimitiveValue(fieldType->primitiveType, targetType, |
| &(value.i), &(pResult->i)) < 0) |
| { |
| dvmThrowException("Ljava/lang/IllegalArgumentException;", |
| "invalid primitive conversion"); |
| RETURN_VOID(); |
| } |
| } |
| |
| /* |
| * Primitive field setters, e.g.: |
| * private void setIField(Object o, Class declaringClass, |
| * Class type, int slot, boolean noAccessCheck, int type_no, int value) |
| * |
| * The "type_no" is defined by the java.lang.reflect.Field class. |
| */ |
| static void Dalvik_java_lang_reflect_Field_setPrimitiveField(const u4* args, |
| JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| Object* obj = (Object*) args[1]; |
| ClassObject* declaringClass = (ClassObject*) args[2]; |
| ClassObject* fieldType = (ClassObject*) args[3]; |
| int slot = args[4]; |
| bool noAccessCheck = (args[5] != 0); |
| int typeNum = args[6]; |
| const s4* valuePtr = (s4*) &args[7]; /* 64-bit vars spill into args[8] */ |
| PrimitiveType srcType = convPrimType(typeNum); |
| Field* field; |
| JValue value; |
| |
| if (!dvmIsPrimitiveClass(fieldType)) { |
| dvmThrowException("Ljava/lang/IllegalArgumentException;", |
| "not a primitive field"); |
| RETURN_VOID(); |
| } |
| |
| /* convert the 32/64-bit arg to a JValue matching the field type */ |
| if (dvmConvertPrimitiveValue(srcType, fieldType->primitiveType, |
| valuePtr, &(value.i)) < 0) |
| { |
| dvmThrowException("Ljava/lang/IllegalArgumentException;", |
| "invalid primitive conversion"); |
| RETURN_VOID(); |
| } |
| |
| /* get a pointer to the Field after validating access */ |
| field = validateFieldAccess(obj, declaringClass, slot, true, noAccessCheck); |
| |
| if (field != NULL) { |
| setFieldValue(field, obj, &value); |
| } |
| RETURN_VOID(); |
| } |
| |
| /* |
| * public Annotation[] getDeclaredAnnotations(Class declaringClass, int slot) |
| * |
| * Return the annotations declared for this field. |
| */ |
| static void Dalvik_java_lang_reflect_Field_getDeclaredAnnotations( |
| const u4* args, JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| ClassObject* declaringClass = (ClassObject*) args[1]; |
| int slot = args[2]; |
| Field* field; |
| |
| field = dvmSlotToField(declaringClass, slot); |
| assert(field != NULL); |
| |
| ArrayObject* annos = dvmGetFieldAnnotations(field); |
| dvmReleaseTrackedAlloc((Object*) annos, NULL); |
| RETURN_PTR(annos); |
| } |
| |
| /* |
| * private Object[] getSignatureAnnotation() |
| * |
| * Returns the signature annotation. |
| */ |
| static void Dalvik_java_lang_reflect_Field_getSignatureAnnotation(const u4* args, |
| JValue* pResult) |
| { |
| /* ignore thisPtr in args[0] */ |
| ClassObject* declaringClass = (ClassObject*) args[1]; |
| int slot = args[2]; |
| Field* field; |
| |
| field = dvmSlotToField(declaringClass, slot); |
| assert(field != NULL); |
| |
| ArrayObject* arr = dvmGetFieldSignatureAnnotation(field); |
| dvmReleaseTrackedAlloc((Object*) arr, NULL); |
| RETURN_PTR(arr); |
| } |
| |
| const DalvikNativeMethod dvm_java_lang_reflect_Field[] = { |
| { "getFieldModifiers", "(Ljava/lang/Class;I)I", |
| Dalvik_java_lang_reflect_Field_getFieldModifiers }, |
| { "getField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;", |
| Dalvik_java_lang_reflect_Field_getField }, |
| { "getBField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)B", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getCField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)C", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getDField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)D", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getFField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)F", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getIField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)I", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getJField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)J", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getSField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)S", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "getZField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZI)Z", |
| Dalvik_java_lang_reflect_Field_getPrimitiveField }, |
| { "setField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZLjava/lang/Object;)V", |
| Dalvik_java_lang_reflect_Field_setField }, |
| { "setBField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZIB)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setCField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZIC)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setDField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZID)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setFField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZIF)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setIField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZII)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setJField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZIJ)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setSField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZIS)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "setZField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZIZ)V", |
| Dalvik_java_lang_reflect_Field_setPrimitiveField }, |
| { "getDeclaredAnnotations", "(Ljava/lang/Class;I)[Ljava/lang/annotation/Annotation;", |
| Dalvik_java_lang_reflect_Field_getDeclaredAnnotations }, |
| { "getSignatureAnnotation", "(Ljava/lang/Class;I)[Ljava/lang/Object;", |
| Dalvik_java_lang_reflect_Field_getSignatureAnnotation }, |
| { NULL, NULL, NULL }, |
| }; |