1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * java.lang.reflect.Field
19 */
20 #include "Dalvik.h"
21 #include "native/InternalNativePriv.h"
22
23
24 /*
25 * Validate access to a field. Returns a pointer to the Field struct.
26 *
27 * "declaringClass" is the class in which the field was declared. For an
28 * instance field, "obj" is the object that holds the field data; for a
29 * static field its value is ignored.
30 *
31 * "If the underlying field is static, the class that declared the
32 * field is initialized if it has not already been initialized."
33 *
34 * On failure, throws an exception and returns NULL.
35 *
36 * The documentation lists exceptional conditions and the exceptions that
37 * should be thrown, but doesn't say which exception prevails when two or
38 * more exceptional conditions exist at the same time. For example,
39 * attempting to set a protected field from an unrelated class causes an
40 * IllegalAccessException, while passing in a data type that doesn't match
41 * the field causes an IllegalArgumentException. If code does both at the
42 * same time, we have to choose one or the other.
43 *
44 * The expected order is:
45 * (1) Check for illegal access. Throw IllegalAccessException.
46 * (2) Make sure the object actually has the field. Throw
47 * IllegalArgumentException.
48 * (3) Make sure the field matches the expected type, e.g. if we issued
49 * a "getInteger" call make sure the field is an integer or can be
50 * converted to an int with a widening conversion. Throw
51 * IllegalArgumentException.
52 * (4) Make sure "obj" is not null. Throw NullPointerException.
53 *
54 * TODO: we're currently handling #3 after #4, because we don't check the
55 * widening conversion until we're actually extracting the value from the
56 * object (which won't work well if it's a null reference).
57 */
validateFieldAccess(Object * obj,ClassObject * declaringClass,int slot,bool isSetOperation,bool noAccessCheck)58 static Field* validateFieldAccess(Object* obj, ClassObject* declaringClass,
59 int slot, bool isSetOperation, bool noAccessCheck)
60 {
61 Field* field;
62
63 field = dvmSlotToField(declaringClass, slot);
64 assert(field != NULL);
65
66 /* verify access */
67 if (!noAccessCheck) {
68 if (isSetOperation && dvmIsFinalField(field)) {
69 dvmThrowIllegalAccessException("field is marked 'final'");
70 return NULL;
71 }
72
73 ClassObject* callerClass =
74 dvmGetCaller2Class(dvmThreadSelf()->interpSave.curFrame);
75
76 /*
77 * We need to check two things:
78 * (1) Would an instance of the calling class have access to the field?
79 * (2) If the field is "protected", is the object an instance of the
80 * calling class, or is the field's declaring class in the same
81 * package as the calling class?
82 *
83 * #1 is basic access control. #2 ensures that, just because
84 * you're a subclass of Foo, you can't mess with protected fields
85 * in arbitrary Foo objects from other packages.
86 */
87 if (!dvmCheckFieldAccess(callerClass, field)) {
88 dvmThrowIllegalAccessException("access to field not allowed");
89 return NULL;
90 }
91 if (dvmIsProtectedField(field)) {
92 bool isInstance, samePackage;
93
94 if (obj != NULL)
95 isInstance = dvmInstanceof(obj->clazz, callerClass);
96 else
97 isInstance = false;
98 samePackage = dvmInSamePackage(declaringClass, callerClass);
99
100 if (!isInstance && !samePackage) {
101 dvmThrowIllegalAccessException(
102 "access to protected field not allowed");
103 return NULL;
104 }
105 }
106 }
107
108 if (dvmIsStaticField(field)) {
109 /* init class if necessary, then return ptr to storage in "field" */
110 if (!dvmIsClassInitialized(declaringClass)) {
111 if (!dvmInitClass(declaringClass)) {
112 assert(dvmCheckException(dvmThreadSelf()));
113 return NULL;
114 }
115 }
116
117 } else {
118 /*
119 * Verify object is of correct type (i.e. it actually has the
120 * expected field in it), then grab a pointer to obj storage.
121 * The call to dvmVerifyObjectInClass throws an NPE if "obj" is NULL.
122 */
123 if (!dvmVerifyObjectInClass(obj, declaringClass)) {
124 assert(dvmCheckException(dvmThreadSelf()));
125 return NULL;
126 }
127 }
128
129 return field;
130 }
131
132 /*
133 * Extracts the value of a static field. Provides appropriate barriers
134 * for volatile fields.
135 *
136 * Sub-32-bit values are sign- or zero-extended to fill out 32 bits.
137 */
getStaticFieldValue(const StaticField * sfield,JValue * value)138 static void getStaticFieldValue(const StaticField* sfield, JValue* value)
139 {
140 if (!dvmIsVolatileField(sfield)) {
141 /* just copy the whole thing */
142 *value = sfield->value;
143 } else {
144 /* need memory barriers and/or 64-bit atomic ops */
145 switch (sfield->signature[0]) {
146 case 'Z':
147 value->i = dvmGetStaticFieldBooleanVolatile(sfield);
148 break;
149 case 'B':
150 value->i = dvmGetStaticFieldByteVolatile(sfield);
151 break;
152 case 'S':
153 value->i = dvmGetStaticFieldShortVolatile(sfield);
154 break;
155 case 'C':
156 value->i = dvmGetStaticFieldCharVolatile(sfield);
157 break;
158 case 'I':
159 value->i = dvmGetStaticFieldIntVolatile(sfield);
160 break;
161 case 'F':
162 value->f = dvmGetStaticFieldFloatVolatile(sfield);
163 break;
164 case 'J':
165 value->j = dvmGetStaticFieldLongVolatile(sfield);
166 break;
167 case 'D':
168 value->d = dvmGetStaticFieldDoubleVolatile(sfield);
169 break;
170 case 'L':
171 case '[':
172 value->l = dvmGetStaticFieldObjectVolatile(sfield);
173 break;
174 default:
175 ALOGE("Unhandled field signature '%s'", sfield->signature);
176 dvmAbort();
177 }
178 }
179 }
180
181 /*
182 * Extracts the value of an instance field. Provides appropriate barriers
183 * for volatile fields.
184 *
185 * Sub-32-bit values are sign- or zero-extended to fill out 32 bits.
186 */
getInstFieldValue(const InstField * ifield,Object * obj,JValue * value)187 static void getInstFieldValue(const InstField* ifield, Object* obj,
188 JValue* value)
189 {
190 if (!dvmIsVolatileField(ifield)) {
191 /* use type-specific get; really just 32-bit vs. 64-bit */
192 switch (ifield->signature[0]) {
193 case 'Z':
194 value->i = dvmGetFieldBoolean(obj, ifield->byteOffset);
195 break;
196 case 'B':
197 value->i = dvmGetFieldByte(obj, ifield->byteOffset);
198 break;
199 case 'S':
200 value->i = dvmGetFieldShort(obj, ifield->byteOffset);
201 break;
202 case 'C':
203 value->i = dvmGetFieldChar(obj, ifield->byteOffset);
204 break;
205 case 'I':
206 value->i = dvmGetFieldInt(obj, ifield->byteOffset);
207 break;
208 case 'F':
209 value->f = dvmGetFieldFloat(obj, ifield->byteOffset);
210 break;
211 case 'J':
212 value->j = dvmGetFieldLong(obj, ifield->byteOffset);
213 break;
214 case 'D':
215 value->d = dvmGetFieldDouble(obj, ifield->byteOffset);
216 break;
217 case 'L':
218 case '[':
219 value->l = dvmGetFieldObject(obj, ifield->byteOffset);
220 break;
221 default:
222 ALOGE("Unhandled field signature '%s'", ifield->signature);
223 dvmAbort();
224 }
225 } else {
226 /* need memory barriers and/or 64-bit atomic ops */
227 switch (ifield->signature[0]) {
228 case 'Z':
229 value->i = dvmGetFieldBooleanVolatile(obj, ifield->byteOffset);
230 break;
231 case 'B':
232 value->i = dvmGetFieldByteVolatile(obj, ifield->byteOffset);
233 break;
234 case 'S':
235 value->i = dvmGetFieldShortVolatile(obj, ifield->byteOffset);
236 break;
237 case 'C':
238 value->i = dvmGetFieldCharVolatile(obj, ifield->byteOffset);
239 break;
240 case 'I':
241 value->i = dvmGetFieldIntVolatile(obj, ifield->byteOffset);
242 break;
243 case 'F':
244 value->f = dvmGetFieldFloatVolatile(obj, ifield->byteOffset);
245 break;
246 case 'J':
247 value->j = dvmGetFieldLongVolatile(obj, ifield->byteOffset);
248 break;
249 case 'D':
250 value->d = dvmGetFieldDoubleVolatile(obj, ifield->byteOffset);
251 break;
252 case 'L':
253 case '[':
254 value->l = dvmGetFieldObjectVolatile(obj, ifield->byteOffset);
255 break;
256 default:
257 ALOGE("Unhandled field signature '%s'", ifield->signature);
258 dvmAbort();
259 }
260 }
261 }
262
263 /*
264 * Copies the value of the static or instance field into "*value".
265 */
getFieldValue(const Field * field,Object * obj,JValue * value)266 static void getFieldValue(const Field* field, Object* obj, JValue* value)
267 {
268 if (dvmIsStaticField(field)) {
269 return getStaticFieldValue((const StaticField*) field, value);
270 } else {
271 return getInstFieldValue((const InstField*) field, obj, value);
272 }
273 }
274
275 /*
276 * Sets the value of a static field. Provides appropriate barriers
277 * for volatile fields.
278 */
setStaticFieldValue(StaticField * sfield,const JValue * value)279 static void setStaticFieldValue(StaticField* sfield, const JValue* value)
280 {
281 if (!dvmIsVolatileField(sfield)) {
282 switch (sfield->signature[0]) {
283 case 'L':
284 case '[':
285 dvmSetStaticFieldObject(sfield, (Object*)value->l);
286 break;
287 default:
288 /* just copy the whole thing */
289 sfield->value = *value;
290 break;
291 }
292 } else {
293 /* need memory barriers and/or 64-bit atomic ops */
294 switch (sfield->signature[0]) {
295 case 'Z':
296 dvmSetStaticFieldBooleanVolatile(sfield, value->z);
297 break;
298 case 'B':
299 dvmSetStaticFieldByteVolatile(sfield, value->b);
300 break;
301 case 'S':
302 dvmSetStaticFieldShortVolatile(sfield, value->s);
303 break;
304 case 'C':
305 dvmSetStaticFieldCharVolatile(sfield, value->c);
306 break;
307 case 'I':
308 dvmSetStaticFieldIntVolatile(sfield, value->i);
309 break;
310 case 'F':
311 dvmSetStaticFieldFloatVolatile(sfield, value->f);
312 break;
313 case 'J':
314 dvmSetStaticFieldLongVolatile(sfield, value->j);
315 break;
316 case 'D':
317 dvmSetStaticFieldDoubleVolatile(sfield, value->d);
318 break;
319 case 'L':
320 case '[':
321 dvmSetStaticFieldObjectVolatile(sfield, (Object*)value->l);
322 break;
323 default:
324 ALOGE("Unhandled field signature '%s'", sfield->signature);
325 dvmAbort();
326 }
327 }
328 }
329
330 /*
331 * Sets the value of an instance field. Provides appropriate barriers
332 * for volatile fields.
333 */
setInstFieldValue(InstField * ifield,Object * obj,const JValue * value)334 static void setInstFieldValue(InstField* ifield, Object* obj,
335 const JValue* value)
336 {
337 if (!dvmIsVolatileField(ifield)) {
338 /* use type-specific set; really just 32-bit vs. 64-bit */
339 switch (ifield->signature[0]) {
340 case 'Z':
341 dvmSetFieldBoolean(obj, ifield->byteOffset, value->z);
342 break;
343 case 'B':
344 dvmSetFieldByte(obj, ifield->byteOffset, value->b);
345 break;
346 case 'S':
347 dvmSetFieldShort(obj, ifield->byteOffset, value->s);
348 break;
349 case 'C':
350 dvmSetFieldChar(obj, ifield->byteOffset, value->c);
351 break;
352 case 'I':
353 dvmSetFieldInt(obj, ifield->byteOffset, value->i);
354 break;
355 case 'F':
356 dvmSetFieldFloat(obj, ifield->byteOffset, value->f);
357 break;
358 case 'J':
359 dvmSetFieldLong(obj, ifield->byteOffset, value->j);
360 break;
361 case 'D':
362 dvmSetFieldDouble(obj, ifield->byteOffset, value->d);
363 break;
364 case 'L':
365 case '[':
366 dvmSetFieldObject(obj, ifield->byteOffset, (Object *)value->l);
367 break;
368 default:
369 ALOGE("Unhandled field signature '%s'", ifield->signature);
370 dvmAbort();
371 }
372 #if ANDROID_SMP != 0
373 /*
374 * Special handling for final fields on SMP systems. We need a
375 * store/store barrier here (JMM requirement).
376 */
377 if (dvmIsFinalField(ifield)) {
378 ANDROID_MEMBAR_STORE();
379 }
380 #endif
381 } else {
382 /* need memory barriers and/or 64-bit atomic ops */
383 switch (ifield->signature[0]) {
384 case 'Z':
385 dvmSetFieldBooleanVolatile(obj, ifield->byteOffset, value->z);
386 break;
387 case 'B':
388 dvmSetFieldByteVolatile(obj, ifield->byteOffset, value->b);
389 break;
390 case 'S':
391 dvmSetFieldShortVolatile(obj, ifield->byteOffset, value->s);
392 break;
393 case 'C':
394 dvmSetFieldCharVolatile(obj, ifield->byteOffset, value->c);
395 break;
396 case 'I':
397 dvmSetFieldIntVolatile(obj, ifield->byteOffset, value->i);
398 break;
399 case 'F':
400 dvmSetFieldFloatVolatile(obj, ifield->byteOffset, value->f);
401 break;
402 case 'J':
403 dvmSetFieldLongVolatile(obj, ifield->byteOffset, value->j);
404 break;
405 case 'D':
406 dvmSetFieldDoubleVolatile(obj, ifield->byteOffset, value->d);
407 break;
408 case 'L':
409 case '[':
410 dvmSetFieldObjectVolatile(obj, ifield->byteOffset, (Object*)value->l);
411 break;
412 default:
413 ALOGE("Unhandled field signature '%s'", ifield->signature);
414 dvmAbort();
415 }
416 }
417 }
418
419 /*
420 * Copy "*value" into the static or instance field.
421 */
setFieldValue(Field * field,Object * obj,const JValue * value)422 static void setFieldValue(Field* field, Object* obj, const JValue* value)
423 {
424 if (dvmIsStaticField(field)) {
425 return setStaticFieldValue((StaticField*) field, value);
426 } else {
427 return setInstFieldValue((InstField*) field, obj, value);
428 }
429 }
430
431
432
433 /*
434 * public int getFieldModifiers(Class declaringClass, int slot)
435 */
Dalvik_java_lang_reflect_Field_getFieldModifiers(const u4 * args,JValue * pResult)436 static void Dalvik_java_lang_reflect_Field_getFieldModifiers(const u4* args,
437 JValue* pResult)
438 {
439 /* ignore thisPtr in args[0] */
440 ClassObject* declaringClass = (ClassObject*) args[1];
441 int slot = args[2];
442 Field* field;
443
444 field = dvmSlotToField(declaringClass, slot);
445 RETURN_INT(field->accessFlags & JAVA_FLAGS_MASK);
446 }
447
448 /*
449 * private Object getField(Object o, Class declaringClass, Class type,
450 * int slot, boolean noAccessCheck)
451 *
452 * Primitive types need to be boxed.
453 */
Dalvik_java_lang_reflect_Field_getField(const u4 * args,JValue * pResult)454 static void Dalvik_java_lang_reflect_Field_getField(const u4* args,
455 JValue* pResult)
456 {
457 /* ignore thisPtr in args[0] */
458 Object* obj = (Object*) args[1];
459 ClassObject* declaringClass = (ClassObject*) args[2];
460 ClassObject* fieldType = (ClassObject*) args[3];
461 int slot = args[4];
462 bool noAccessCheck = (args[5] != 0);
463 Field* field;
464 JValue value;
465 DataObject* result;
466
467 //dvmDumpClass(obj->clazz, kDumpClassFullDetail);
468
469 /* get a pointer to the Field after validating access */
470 field = validateFieldAccess(obj, declaringClass, slot, false,noAccessCheck);
471 if (field == NULL)
472 RETURN_VOID();
473
474 getFieldValue(field, obj, &value);
475
476 /* if it's primitive, box it up */
477 result = dvmBoxPrimitive(value, fieldType);
478 dvmReleaseTrackedAlloc((Object*) result, NULL);
479 RETURN_PTR(result);
480 }
481
482 /*
483 * private void setField(Object o, Class declaringClass, Class type,
484 * int slot, boolean noAccessCheck, Object value)
485 *
486 * When assigning into a primitive field we will automatically extract
487 * the value from box types.
488 */
Dalvik_java_lang_reflect_Field_setField(const u4 * args,JValue * pResult)489 static void Dalvik_java_lang_reflect_Field_setField(const u4* args,
490 JValue* pResult)
491 {
492 /* ignore thisPtr in args[0] */
493 Object* obj = (Object*) args[1];
494 ClassObject* declaringClass = (ClassObject*) args[2];
495 ClassObject* fieldType = (ClassObject*) args[3];
496 int slot = args[4];
497 bool noAccessCheck = (args[5] != 0);
498 Object* valueObj = (Object*) args[6];
499 Field* field;
500 JValue value;
501
502 /* unbox primitive, or verify object type */
503 if (!dvmUnboxPrimitive(valueObj, fieldType, &value)) {
504 dvmThrowIllegalArgumentException("invalid value for field");
505 RETURN_VOID();
506 }
507
508 /* get a pointer to the Field after validating access */
509 field = validateFieldAccess(obj, declaringClass, slot, true, noAccessCheck);
510
511 if (field != NULL) {
512 setFieldValue(field, obj, &value);
513 }
514 RETURN_VOID();
515 }
516
517 /*
518 * Primitive field getters, e.g.:
519 * private double getIField(Object o, Class declaringClass,
520 * Class type, int slot, boolean noAccessCheck, char descriptor)
521 */
Dalvik_java_lang_reflect_Field_getPrimitiveField(const u4 * args,JValue * pResult)522 static void Dalvik_java_lang_reflect_Field_getPrimitiveField(const u4* args,
523 JValue* pResult)
524 {
525 /* ignore thisPtr in args[0] */
526 Object* obj = (Object*) args[1];
527 ClassObject* declaringClass = (ClassObject*) args[2];
528 ClassObject* fieldType = (ClassObject*) args[3];
529 int slot = args[4];
530 bool noAccessCheck = (args[5] != 0);
531 jchar descriptor = args[6];
532 PrimitiveType targetType = dexGetPrimitiveTypeFromDescriptorChar(descriptor);
533 const Field* field;
534 JValue value;
535
536 if (!dvmIsPrimitiveClass(fieldType)) {
537 dvmThrowIllegalArgumentException("not a primitive field");
538 RETURN_VOID();
539 }
540
541 /* get a pointer to the Field after validating access */
542 field = validateFieldAccess(obj, declaringClass, slot, false,noAccessCheck);
543 if (field == NULL)
544 RETURN_VOID();
545
546 getFieldValue(field, obj, &value);
547
548 /* retrieve value, performing a widening conversion if necessary */
549 if (dvmConvertPrimitiveValue(fieldType->primitiveType, targetType,
550 &(value.i), &(pResult->i)) < 0)
551 {
552 dvmThrowIllegalArgumentException("invalid primitive conversion");
553 RETURN_VOID();
554 }
555 }
556
557 /*
558 * Primitive field setters, e.g.:
559 * private void setIField(Object o, Class declaringClass,
560 * Class type, int slot, boolean noAccessCheck, char descriptor, int value)
561 */
Dalvik_java_lang_reflect_Field_setPrimitiveField(const u4 * args,JValue * pResult)562 static void Dalvik_java_lang_reflect_Field_setPrimitiveField(const u4* args,
563 JValue* pResult)
564 {
565 /* ignore thisPtr in args[0] */
566 Object* obj = (Object*) args[1];
567 ClassObject* declaringClass = (ClassObject*) args[2];
568 ClassObject* fieldType = (ClassObject*) args[3];
569 int slot = args[4];
570 bool noAccessCheck = (args[5] != 0);
571 jchar descriptor = args[6];
572 const s4* valuePtr = (s4*) &args[7]; /* 64-bit vars spill into args[8] */
573 PrimitiveType srcType = dexGetPrimitiveTypeFromDescriptorChar(descriptor);
574 Field* field;
575 JValue value;
576
577 if (!dvmIsPrimitiveClass(fieldType)) {
578 dvmThrowIllegalArgumentException("not a primitive field");
579 RETURN_VOID();
580 }
581
582 /* convert the 32/64-bit arg to a JValue matching the field type */
583 if (dvmConvertPrimitiveValue(srcType, fieldType->primitiveType,
584 valuePtr, &(value.i)) < 0)
585 {
586 dvmThrowIllegalArgumentException("invalid primitive conversion");
587 RETURN_VOID();
588 }
589
590 /* get a pointer to the Field after validating access */
591 field = validateFieldAccess(obj, declaringClass, slot, true, noAccessCheck);
592
593 if (field != NULL) {
594 setFieldValue(field, obj, &value);
595 }
596 RETURN_VOID();
597 }
598
599 /*
600 * private static Annotation[] getDeclaredAnnotations(
601 * Class declaringClass, int slot)
602 *
603 * Return the annotations declared for this field.
604 */
Dalvik_java_lang_reflect_Field_getDeclaredAnnotations(const u4 * args,JValue * pResult)605 static void Dalvik_java_lang_reflect_Field_getDeclaredAnnotations(
606 const u4* args, JValue* pResult)
607 {
608 ClassObject* declaringClass = (ClassObject*) args[0];
609 int slot = args[1];
610 Field* field;
611
612 field = dvmSlotToField(declaringClass, slot);
613 assert(field != NULL);
614
615 ArrayObject* annos = dvmGetFieldAnnotations(field);
616 dvmReleaseTrackedAlloc((Object*) annos, NULL);
617 RETURN_PTR(annos);
618 }
619
620 /*
621 * static Annotation getAnnotation(
622 * Class declaringClass, int slot, Class annotationType);
623 */
Dalvik_java_lang_reflect_Field_getAnnotation(const u4 * args,JValue * pResult)624 static void Dalvik_java_lang_reflect_Field_getAnnotation(const u4* args,
625 JValue* pResult)
626 {
627 ClassObject* clazz = (ClassObject*) args[0];
628 int slot = args[1];
629 ClassObject* annotationClazz = (ClassObject*) args[2];
630
631 Field* field = dvmSlotToField(clazz, slot);
632 RETURN_PTR(dvmGetFieldAnnotation(clazz, field, annotationClazz));
633 }
634
635 /*
636 * static boolean isAnnotationPresent(
637 * Class declaringClass, int slot, Class annotationType);
638 */
Dalvik_java_lang_reflect_Field_isAnnotationPresent(const u4 * args,JValue * pResult)639 static void Dalvik_java_lang_reflect_Field_isAnnotationPresent(const u4* args,
640 JValue* pResult)
641 {
642 ClassObject* clazz = (ClassObject*) args[0];
643 int slot = args[1];
644 ClassObject* annotationClazz = (ClassObject*) args[2];
645
646 Field* field = dvmSlotToField(clazz, slot);
647 RETURN_BOOLEAN(dvmIsFieldAnnotationPresent(clazz, field, annotationClazz));
648 }
649
650 /*
651 * private Object[] getSignatureAnnotation()
652 *
653 * Returns the signature annotation.
654 */
Dalvik_java_lang_reflect_Field_getSignatureAnnotation(const u4 * args,JValue * pResult)655 static void Dalvik_java_lang_reflect_Field_getSignatureAnnotation(const u4* args,
656 JValue* pResult)
657 {
658 /* ignore thisPtr in args[0] */
659 ClassObject* declaringClass = (ClassObject*) args[1];
660 int slot = args[2];
661 Field* field;
662
663 field = dvmSlotToField(declaringClass, slot);
664 assert(field != NULL);
665
666 ArrayObject* arr = dvmGetFieldSignatureAnnotation(field);
667 dvmReleaseTrackedAlloc((Object*) arr, NULL);
668 RETURN_PTR(arr);
669 }
670
671 const DalvikNativeMethod dvm_java_lang_reflect_Field[] = {
672 { "getFieldModifiers", "(Ljava/lang/Class;I)I",
673 Dalvik_java_lang_reflect_Field_getFieldModifiers },
674 { "getField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;",
675 Dalvik_java_lang_reflect_Field_getField },
676 { "getBField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)B",
677 Dalvik_java_lang_reflect_Field_getPrimitiveField },
678 { "getCField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)C",
679 Dalvik_java_lang_reflect_Field_getPrimitiveField },
680 { "getDField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)D",
681 Dalvik_java_lang_reflect_Field_getPrimitiveField },
682 { "getFField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)F",
683 Dalvik_java_lang_reflect_Field_getPrimitiveField },
684 { "getIField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)I",
685 Dalvik_java_lang_reflect_Field_getPrimitiveField },
686 { "getJField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)J",
687 Dalvik_java_lang_reflect_Field_getPrimitiveField },
688 { "getSField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)S",
689 Dalvik_java_lang_reflect_Field_getPrimitiveField },
690 { "getZField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)Z",
691 Dalvik_java_lang_reflect_Field_getPrimitiveField },
692 { "setField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZLjava/lang/Object;)V",
693 Dalvik_java_lang_reflect_Field_setField },
694 { "setBField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCB)V",
695 Dalvik_java_lang_reflect_Field_setPrimitiveField },
696 { "setCField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCC)V",
697 Dalvik_java_lang_reflect_Field_setPrimitiveField },
698 { "setDField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCD)V",
699 Dalvik_java_lang_reflect_Field_setPrimitiveField },
700 { "setFField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCF)V",
701 Dalvik_java_lang_reflect_Field_setPrimitiveField },
702 { "setIField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCI)V",
703 Dalvik_java_lang_reflect_Field_setPrimitiveField },
704 { "setJField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCJ)V",
705 Dalvik_java_lang_reflect_Field_setPrimitiveField },
706 { "setSField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCS)V",
707 Dalvik_java_lang_reflect_Field_setPrimitiveField },
708 { "setZField", "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCZ)V",
709 Dalvik_java_lang_reflect_Field_setPrimitiveField },
710 { "getDeclaredAnnotations", "(Ljava/lang/Class;I)[Ljava/lang/annotation/Annotation;",
711 Dalvik_java_lang_reflect_Field_getDeclaredAnnotations },
712 { "getAnnotation", "(Ljava/lang/Class;ILjava/lang/Class;)Ljava/lang/annotation/Annotation;",
713 Dalvik_java_lang_reflect_Field_getAnnotation },
714 { "isAnnotationPresent", "(Ljava/lang/Class;ILjava/lang/Class;)Z",
715 Dalvik_java_lang_reflect_Field_isAnnotationPresent },
716 { "getSignatureAnnotation", "(Ljava/lang/Class;I)[Ljava/lang/Object;",
717 Dalvik_java_lang_reflect_Field_getSignatureAnnotation },
718 { NULL, NULL, NULL },
719 };
720