OSDN Git Service

7ef0bdedd9cf6141f4b95f148334cab65cf5d377
[android-x86/dalvik.git] / vm / reflect / Annotation.cpp
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  * Annotations.
18  *
19  * We're not expecting to make much use of runtime annotations, so speed vs.
20  * space choices are weighted heavily toward small size.
21  *
22  * It would have been nice to treat "system" annotations in the same way
23  * we do "real" annotations, but that doesn't work.  The chief difficulty
24  * is that some of them have member types that are not legal in annotations,
25  * such as Method and Annotation.  Another source of pain comes from the
26  * AnnotationDefault annotation, which by virtue of being an annotation
27  * could itself have default values, requiring some additional checks to
28  * prevent recursion.
29  *
30  * It's simpler, and more efficient, to handle the system annotations
31  * entirely inside the VM.  There are empty classes defined for the system
32  * annotation types, but their only purpose is to allow the system
33  * annotations to share name space with standard annotations.
34  */
35 #include "Dalvik.h"
36
37 // fwd
38 static Object* processEncodedAnnotation(const ClassObject* clazz,\
39     const u1** pPtr);
40 static bool skipEncodedAnnotation(const ClassObject* clazz, const u1** pPtr);
41
42 /*
43  * System annotation descriptors.
44  */
45 static const char* kDescrAnnotationDefault
46                                     = "Ldalvik/annotation/AnnotationDefault;";
47 static const char* kDescrEnclosingClass
48                                     = "Ldalvik/annotation/EnclosingClass;";
49 static const char* kDescrEnclosingMethod
50                                     = "Ldalvik/annotation/EnclosingMethod;";
51 static const char* kDescrInnerClass = "Ldalvik/annotation/InnerClass;";
52 static const char* kDescrMemberClasses
53                                     = "Ldalvik/annotation/MemberClasses;";
54 static const char* kDescrSignature  = "Ldalvik/annotation/Signature;";
55 static const char* kDescrThrows     = "Ldalvik/annotation/Throws;";
56
57 /*
58  * Read an unsigned LEB128 value from a buffer.  Advances "pBuf".
59  */
60 static u4 readUleb128(const u1** pBuf)
61 {
62     u4 result = 0;
63     int shift = 0;
64     const u1* buf = *pBuf;
65     u1 val;
66
67     do {
68         /*
69          * Worst-case on bad data is we read too much data and return a bogus
70          * result.  Safe to assume that we will encounter a byte with its
71          * high bit clear before the end of the mapped file.
72          */
73         assert(shift < 32);
74
75         val = *buf++;
76         result |= (val & 0x7f) << shift;
77         shift += 7;
78     } while ((val & 0x80) != 0);
79
80     *pBuf = buf;
81     return result;
82 }
83
84 /*
85  * Get the annotations directory item.
86  */
87 static const DexAnnotationsDirectoryItem* getAnnoDirectory(DexFile* pDexFile,
88     const ClassObject* clazz)
89 {
90     const DexClassDef* pClassDef;
91
92     /*
93      * Find the class def in the DEX file.  For better performance we should
94      * stash this in the ClassObject.
95      */
96     pClassDef = dexFindClass(pDexFile, clazz->descriptor);
97     assert(pClassDef != NULL);
98     return dexGetAnnotationsDirectoryItem(pDexFile, pClassDef);
99 }
100
101 /*
102  * Return a zero-length array of Annotation objects.
103  *
104  * TODO: this currently allocates a new array each time, but I think we
105  * can get away with returning a canonical copy.
106  *
107  * Caller must call dvmReleaseTrackedAlloc().
108  */
109 static ArrayObject* emptyAnnoArray()
110 {
111     return dvmAllocArrayByClass(
112         gDvm.classJavaLangAnnotationAnnotationArray, 0, ALLOC_DEFAULT);
113 }
114
115 /*
116  * Return an array of empty arrays of Annotation objects.
117  *
118  * Caller must call dvmReleaseTrackedAlloc().
119  */
120 static ArrayObject* emptyAnnoArrayArray(int numElements)
121 {
122     Thread* self = dvmThreadSelf();
123     ArrayObject* arr;
124     int i;
125
126     arr = dvmAllocArrayByClass(gDvm.classJavaLangAnnotationAnnotationArrayArray,
127             numElements, ALLOC_DEFAULT);
128     if (arr != NULL) {
129         ArrayObject** elems = (ArrayObject**)(void*)arr->contents;
130         for (i = 0; i < numElements; i++) {
131             elems[i] = emptyAnnoArray();
132             dvmReleaseTrackedAlloc((Object*)elems[i], self);
133         }
134     }
135
136     return arr;
137 }
138
139 /*
140  * Read a signed integer.  "zwidth" is the zero-based byte count.
141  */
142 static s4 readSignedInt(const u1* ptr, int zwidth)
143 {
144     s4 val = 0;
145     int i;
146
147     for (i = zwidth; i >= 0; --i)
148         val = ((u4)val >> 8) | (((s4)*ptr++) << 24);
149     val >>= (3 - zwidth) * 8;
150
151     return val;
152 }
153
154 /*
155  * Read an unsigned integer.  "zwidth" is the zero-based byte count,
156  * "fillOnRight" indicates which side we want to zero-fill from.
157  */
158 static u4 readUnsignedInt(const u1* ptr, int zwidth, bool fillOnRight)
159 {
160     u4 val = 0;
161     int i;
162
163     if (!fillOnRight) {
164         for (i = zwidth; i >= 0; --i)
165             val = (val >> 8) | (((u4)*ptr++) << 24);
166         val >>= (3 - zwidth) * 8;
167     } else {
168         for (i = zwidth; i >= 0; --i)
169             val = (val >> 8) | (((u4)*ptr++) << 24);
170     }
171     return val;
172 }
173
174 /*
175  * Read a signed long.  "zwidth" is the zero-based byte count.
176  */
177 static s8 readSignedLong(const u1* ptr, int zwidth)
178 {
179     s8 val = 0;
180     int i;
181
182     for (i = zwidth; i >= 0; --i)
183         val = ((u8)val >> 8) | (((s8)*ptr++) << 56);
184     val >>= (7 - zwidth) * 8;
185
186     return val;
187 }
188
189 /*
190  * Read an unsigned long.  "zwidth" is the zero-based byte count,
191  * "fillOnRight" indicates which side we want to zero-fill from.
192  */
193 static u8 readUnsignedLong(const u1* ptr, int zwidth, bool fillOnRight)
194 {
195     u8 val = 0;
196     int i;
197
198     if (!fillOnRight) {
199         for (i = zwidth; i >= 0; --i)
200             val = (val >> 8) | (((u8)*ptr++) << 56);
201         val >>= (7 - zwidth) * 8;
202     } else {
203         for (i = zwidth; i >= 0; --i)
204             val = (val >> 8) | (((u8)*ptr++) << 56);
205     }
206     return val;
207 }
208
209
210 /*
211  * ===========================================================================
212  *      Element extraction
213  * ===========================================================================
214  */
215
216 /*
217  * An annotation in "clazz" refers to a method by index.  This just gives
218  * us the name of the class and the name and signature of the method.  We
219  * need to find the method's class, and then find the method within that
220  * class.  If the method has been resolved before, we can just use the
221  * results of the previous lookup.
222  *
223  * Normally we do this as part of method invocation in the interpreter, which
224  * provides us with a bit of context: is it virtual or direct, do we need
225  * to initialize the class because it's a static method, etc.  We don't have
226  * that information here, so we have to do a bit of searching.
227  *
228  * Returns NULL if the method was not found (exception may be pending).
229  */
230 static Method* resolveAmbiguousMethod(const ClassObject* referrer, u4 methodIdx)
231 {
232     DexFile* pDexFile;
233     ClassObject* resClass;
234     Method* resMethod;
235     const DexMethodId* pMethodId;
236     const char* name;
237
238     /* if we've already resolved this method, return it */
239     resMethod = dvmDexGetResolvedMethod(referrer->pDvmDex, methodIdx);
240     if (resMethod != NULL)
241         return resMethod;
242
243     pDexFile = referrer->pDvmDex->pDexFile;
244     pMethodId = dexGetMethodId(pDexFile, methodIdx);
245     resClass = dvmResolveClass(referrer, pMethodId->classIdx, true);
246     if (resClass == NULL) {
247         /* note exception will be pending */
248         ALOGD("resolveAmbiguousMethod: unable to find class %d", methodIdx);
249         return NULL;
250     }
251     if (dvmIsInterfaceClass(resClass)) {
252         /* method is part of an interface -- not expecting that */
253         ALOGD("resolveAmbiguousMethod: method in interface?");
254         return NULL;
255     }
256
257     // TODO - consider a method access flag that indicates direct vs. virtual
258     name = dexStringById(pDexFile, pMethodId->nameIdx);
259
260     DexProto proto;
261     dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
262
263     if (name[0] == '<') {
264         /*
265          * Constructor or class initializer.  Only need to examine the
266          * "direct" list, and don't need to look up the class hierarchy.
267          */
268         resMethod = dvmFindDirectMethod(resClass, name, &proto);
269     } else {
270         /*
271          * Do a hierarchical scan for direct and virtual methods.
272          *
273          * This uses the search order from the VM spec (v2 5.4.3.3), which
274          * seems appropriate here.
275          */
276         resMethod = dvmFindMethodHier(resClass, name, &proto);
277     }
278
279     return resMethod;
280 }
281
282 /*
283  * constants for processAnnotationValue indicating what style of
284  * result is wanted
285  */
286 enum AnnotationResultStyle {
287     kAllObjects,         /* return everything as an object */
288     kAllRaw,             /* return everything as a raw value or index */
289     kPrimitivesOrObjects /* return primitives as-is but the rest as objects */
290 };
291
292 /*
293  * Recursively process an annotation value.
294  *
295  * "clazz" is the class on which the annotations are defined.  It may be
296  * NULL when "resultStyle" is "kAllRaw".
297  *
298  * If "resultStyle" is "kAllObjects", the result will always be an Object of an
299  * appropriate type (in pValue->value.l).  For primitive types, the usual
300  * wrapper objects will be created.
301  *
302  * If "resultStyle" is "kAllRaw", numeric constants are stored directly into
303  * "pValue", and indexed values like String and Method are returned as
304  * indexes.  Complex values like annotations and arrays are not handled.
305  *
306  * If "resultStyle" is "kPrimitivesOrObjects", numeric constants are stored
307  * directly into "pValue", and everything else is constructed as an Object
308  * of appropriate type (in pValue->value.l).
309  *
310  * The caller must call dvmReleaseTrackedAlloc on returned objects, when
311  * using "kAllObjects" or "kPrimitivesOrObjects".
312  *
313  * Returns "true" on success, "false" if the value could not be processed
314  * or an object could not be allocated.  On allocation failure an exception
315  * will be raised.
316  */
317 static bool processAnnotationValue(const ClassObject* clazz,
318     const u1** pPtr, AnnotationValue* pValue,
319     AnnotationResultStyle resultStyle)
320 {
321     Thread* self = dvmThreadSelf();
322     Object* elemObj = NULL;
323     bool setObject = false;
324     const u1* ptr = *pPtr;
325     u1 valueType, valueArg;
326     int width;
327     u4 idx;
328
329     valueType = *ptr++;
330     valueArg = valueType >> kDexAnnotationValueArgShift;
331     width = valueArg + 1;       /* assume, correct later */
332
333     ALOGV("----- type is 0x%02x %d, ptr=%p [0x%06x]",
334         valueType & kDexAnnotationValueTypeMask, valueArg, ptr-1,
335         (ptr-1) - (u1*)clazz->pDvmDex->pDexFile->baseAddr);
336
337     pValue->type = valueType & kDexAnnotationValueTypeMask;
338
339     switch (valueType & kDexAnnotationValueTypeMask) {
340     case kDexAnnotationByte:
341         pValue->value.i = (s1) readSignedInt(ptr, valueArg);
342         if (resultStyle == kAllObjects) {
343             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
344                         dvmFindPrimitiveClass('B'));
345             setObject = true;
346         }
347         break;
348     case kDexAnnotationShort:
349         pValue->value.i = (s2) readSignedInt(ptr, valueArg);
350         if (resultStyle == kAllObjects) {
351             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
352                         dvmFindPrimitiveClass('S'));
353             setObject = true;
354         }
355         break;
356     case kDexAnnotationChar:
357         pValue->value.i = (u2) readUnsignedInt(ptr, valueArg, false);
358         if (resultStyle == kAllObjects) {
359             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
360                         dvmFindPrimitiveClass('C'));
361             setObject = true;
362         }
363         break;
364     case kDexAnnotationInt:
365         pValue->value.i = readSignedInt(ptr, valueArg);
366         if (resultStyle == kAllObjects) {
367             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
368                         dvmFindPrimitiveClass('I'));
369             setObject = true;
370         }
371         break;
372     case kDexAnnotationLong:
373         pValue->value.j = readSignedLong(ptr, valueArg);
374         if (resultStyle == kAllObjects) {
375             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
376                         dvmFindPrimitiveClass('J'));
377             setObject = true;
378         }
379         break;
380     case kDexAnnotationFloat:
381         pValue->value.i = readUnsignedInt(ptr, valueArg, true);
382         if (resultStyle == kAllObjects) {
383             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
384                         dvmFindPrimitiveClass('F'));
385             setObject = true;
386         }
387         break;
388     case kDexAnnotationDouble:
389         pValue->value.j = readUnsignedLong(ptr, valueArg, true);
390         if (resultStyle == kAllObjects) {
391             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
392                         dvmFindPrimitiveClass('D'));
393             setObject = true;
394         }
395         break;
396     case kDexAnnotationBoolean:
397         pValue->value.i = (valueArg != 0);
398         if (resultStyle == kAllObjects) {
399             elemObj = (Object*) dvmBoxPrimitive(pValue->value,
400                         dvmFindPrimitiveClass('Z'));
401             setObject = true;
402         }
403         width = 0;
404         break;
405
406     case kDexAnnotationString:
407         idx = readUnsignedInt(ptr, valueArg, false);
408         if (resultStyle == kAllRaw) {
409             pValue->value.i = idx;
410         } else {
411             elemObj = (Object*) dvmResolveString(clazz, idx);
412             setObject = true;
413             if (elemObj == NULL)
414                 return false;
415             dvmAddTrackedAlloc(elemObj, self);      // balance the Release
416         }
417         break;
418     case kDexAnnotationType:
419         idx = readUnsignedInt(ptr, valueArg, false);
420         if (resultStyle == kAllRaw) {
421             pValue->value.i = idx;
422         } else {
423             elemObj = (Object*) dvmResolveClass(clazz, idx, true);
424             setObject = true;
425             if (elemObj == NULL) {
426                 /* we're expected to throw a TypeNotPresentException here */
427                 DexFile* pDexFile = clazz->pDvmDex->pDexFile;
428                 const char* desc = dexStringByTypeIdx(pDexFile, idx);
429                 dvmClearException(self);
430                 dvmThrowTypeNotPresentException(desc);
431                 return false;
432             } else {
433                 dvmAddTrackedAlloc(elemObj, self);      // balance the Release
434             }
435         }
436         break;
437     case kDexAnnotationMethod:
438         idx = readUnsignedInt(ptr, valueArg, false);
439         if (resultStyle == kAllRaw) {
440             pValue->value.i = idx;
441         } else {
442             Method* meth = resolveAmbiguousMethod(clazz, idx);
443             if (meth == NULL)
444                 return false;
445             elemObj = dvmCreateReflectObjForMethod(clazz, meth);
446             setObject = true;
447             if (elemObj == NULL)
448                 return false;
449         }
450         break;
451     case kDexAnnotationField:
452         idx = readUnsignedInt(ptr, valueArg, false);
453         assert(false);      // TODO
454         break;
455     case kDexAnnotationEnum:
456         /* enum values are the contents of a static field */
457         idx = readUnsignedInt(ptr, valueArg, false);
458         if (resultStyle == kAllRaw) {
459             pValue->value.i = idx;
460         } else {
461             StaticField* sfield;
462
463             sfield = dvmResolveStaticField(clazz, idx);
464             if (sfield == NULL) {
465                 return false;
466             } else {
467                 assert(sfield->clazz->descriptor[0] == 'L');
468                 elemObj = sfield->value.l;
469                 setObject = true;
470                 dvmAddTrackedAlloc(elemObj, self);      // balance the Release
471             }
472         }
473         break;
474     case kDexAnnotationArray:
475         /*
476          * encoded_array format, which is a size followed by a stream
477          * of annotation_value.
478          *
479          * We create an array of Object, populate it, and return it.
480          */
481         if (resultStyle == kAllRaw) {
482             return false;
483         } else {
484             ArrayObject* newArray;
485             u4 size, count;
486
487             size = readUleb128(&ptr);
488             LOGVV("--- annotation array, size is %u at %p", size, ptr);
489             newArray = dvmAllocArrayByClass(gDvm.classJavaLangObjectArray,
490                 size, ALLOC_DEFAULT);
491             if (newArray == NULL) {
492                 ALOGE("annotation element array alloc failed (%d)", size);
493                 return false;
494             }
495
496             AnnotationValue avalue;
497             for (count = 0; count < size; count++) {
498                 if (!processAnnotationValue(clazz, &ptr, &avalue,
499                                 kAllObjects)) {
500                     dvmReleaseTrackedAlloc((Object*)newArray, self);
501                     return false;
502                 }
503                 Object* obj = (Object*)avalue.value.l;
504                 dvmSetObjectArrayElement(newArray, count, obj);
505                 dvmReleaseTrackedAlloc(obj, self);
506             }
507
508             elemObj = (Object*) newArray;
509             setObject = true;
510         }
511         width = 0;
512         break;
513     case kDexAnnotationAnnotation:
514         /* encoded_annotation format */
515         if (resultStyle == kAllRaw)
516             return false;
517         elemObj = processEncodedAnnotation(clazz, &ptr);
518         setObject = true;
519         if (elemObj == NULL)
520             return false;
521         dvmAddTrackedAlloc(elemObj, self);      // balance the Release
522         width = 0;
523         break;
524     case kDexAnnotationNull:
525         if (resultStyle == kAllRaw) {
526             pValue->value.i = 0;
527         } else {
528             assert(elemObj == NULL);
529             setObject = true;
530         }
531         width = 0;
532         break;
533     default:
534         ALOGE("Bad annotation element value byte 0x%02x (0x%02x)",
535             valueType, valueType & kDexAnnotationValueTypeMask);
536         assert(false);
537         return false;
538     }
539
540     ptr += width;
541
542     *pPtr = ptr;
543     if (setObject)
544         pValue->value.l = elemObj;
545     return true;
546 }
547
548
549 /*
550  * For most object types, we have nothing to do here, and we just return
551  * "valueObj".
552  *
553  * For an array annotation, the type of the extracted object will always
554  * be java.lang.Object[], but we want it to match the type that the
555  * annotation member is expected to return.  In some cases this may
556  * involve un-boxing primitive values.
557  *
558  * We allocate a second array with the correct type, then copy the data
559  * over.  This releases the tracked allocation on "valueObj" and returns
560  * a new, tracked object.
561  *
562  * On failure, this releases the tracking on "valueObj" and returns NULL
563  * (allowing the call to say "foo = convertReturnType(foo, ..)").
564  */
565 static Object* convertReturnType(Object* valueObj, ClassObject* methodReturn)
566 {
567     if (valueObj == NULL ||
568         !dvmIsArray((ArrayObject*)valueObj) || !dvmIsArrayClass(methodReturn))
569     {
570         return valueObj;
571     }
572
573     Thread* self = dvmThreadSelf();
574     ClassObject* srcElemClass;
575     ClassObject* dstElemClass;
576
577     /*
578      * We always extract kDexAnnotationArray into Object[], so we expect to
579      * find that here.  This means we can skip the FindClass on
580      * (valueObj->clazz->descriptor+1, valueObj->clazz->classLoader).
581      */
582     if (strcmp(valueObj->clazz->descriptor, "[Ljava/lang/Object;") != 0) {
583         ALOGE("Unexpected src type class (%s)", valueObj->clazz->descriptor);
584         return NULL;
585     }
586     srcElemClass = gDvm.classJavaLangObject;
587
588     /*
589      * Skip past the '[' to get element class name.  Note this is not always
590      * the same as methodReturn->elementClass.
591      */
592     char firstChar = methodReturn->descriptor[1];
593     if (firstChar == 'L' || firstChar == '[') {
594         dstElemClass = dvmFindClass(methodReturn->descriptor+1,
595             methodReturn->classLoader);
596     } else {
597         dstElemClass = dvmFindPrimitiveClass(firstChar);
598     }
599     ALOGV("HEY: converting valueObj from [%s to [%s",
600         srcElemClass->descriptor, dstElemClass->descriptor);
601
602     ArrayObject* srcArray = (ArrayObject*) valueObj;
603     u4 length = srcArray->length;
604     ArrayObject* newArray;
605
606     newArray = dvmAllocArrayByClass(methodReturn, length, ALLOC_DEFAULT);
607     if (newArray == NULL) {
608         ALOGE("Failed creating duplicate annotation class (%s %d)",
609             methodReturn->descriptor, length);
610         goto bail;
611     }
612
613     bool success;
614     if (dstElemClass->primitiveType == PRIM_NOT) {
615         success = dvmCopyObjectArray(newArray, srcArray, dstElemClass);
616     } else {
617         success = dvmUnboxObjectArray(newArray, srcArray, dstElemClass);
618     }
619     if (!success) {
620         ALOGE("Annotation array copy failed");
621         dvmReleaseTrackedAlloc((Object*)newArray, self);
622         newArray = NULL;
623         goto bail;
624     }
625
626 bail:
627     /* replace old, return new */
628     dvmReleaseTrackedAlloc(valueObj, self);
629     return (Object*) newArray;
630 }
631
632 /*
633  * Create a new AnnotationMember.
634  *
635  * "clazz" is the class on which the annotations are defined.  "pPtr"
636  * points to a pointer into the annotation data.  "annoClass" is the
637  * annotation's class.
638  *
639  * We extract the annotation's value, create a new AnnotationMember object,
640  * and construct it.
641  *
642  * Returns NULL on failure; an exception may or may not be raised.
643  */
644 static Object* createAnnotationMember(const ClassObject* clazz,
645     const ClassObject* annoClass, const u1** pPtr)
646 {
647     Thread* self = dvmThreadSelf();
648     const DexFile* pDexFile = clazz->pDvmDex->pDexFile;
649     StringObject* nameObj = NULL;
650     Object* valueObj = NULL;
651     Object* newMember = NULL;
652     Object* methodObj = NULL;
653     ClassObject* methodReturn = NULL;
654     u4 elementNameIdx;
655     const char* name;
656     AnnotationValue avalue;
657     JValue unused;
658     bool failed = true;
659
660     elementNameIdx = readUleb128(pPtr);
661
662     if (!processAnnotationValue(clazz, pPtr, &avalue, kAllObjects)) {
663         ALOGW("Failed processing annotation value");
664         goto bail;
665     }
666     valueObj = (Object*)avalue.value.l;
667
668     /* new member to hold the element */
669     newMember =
670         dvmAllocObject(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember,
671         ALLOC_DEFAULT);
672     name = dexStringById(pDexFile, elementNameIdx);
673     nameObj = dvmCreateStringFromCstr(name);
674
675     /* find the method in the annotation class, given only the name */
676     if (name != NULL) {
677         Method* annoMeth = dvmFindVirtualMethodByName(annoClass, name);
678         if (annoMeth == NULL) {
679             ALOGW("WARNING: could not find annotation member %s in %s",
680                 name, annoClass->descriptor);
681         } else {
682             methodObj = dvmCreateReflectObjForMethod(annoClass, annoMeth);
683             methodReturn = dvmGetBoxedReturnType(annoMeth);
684         }
685     }
686     if (newMember == NULL || nameObj == NULL || methodObj == NULL ||
687         methodReturn == NULL)
688     {
689         ALOGE("Failed creating annotation element (m=%p n=%p a=%p r=%p)",
690             newMember, nameObj, methodObj, methodReturn);
691         goto bail;
692     }
693
694     /* convert the return type, if necessary */
695     valueObj = convertReturnType(valueObj, methodReturn);
696     if (valueObj == NULL)
697         goto bail;
698
699     /* call 4-argument constructor */
700     dvmCallMethod(self, gDvm.methOrgApacheHarmonyLangAnnotationAnnotationMember_init,
701         newMember, &unused, nameObj, valueObj, methodReturn, methodObj);
702     if (dvmCheckException(self)) {
703         ALOGD("Failed constructing annotation element");
704         goto bail;
705     }
706
707     failed = false;
708
709 bail:
710     /* release tracked allocations */
711     dvmReleaseTrackedAlloc(newMember, self);
712     dvmReleaseTrackedAlloc((Object*)nameObj, self);
713     dvmReleaseTrackedAlloc(valueObj, self);
714     dvmReleaseTrackedAlloc(methodObj, self);
715     if (failed)
716         return NULL;
717     else
718         return newMember;
719 }
720
721 /*
722  * Create a new Annotation object from what we find in the annotation item.
723  *
724  * "clazz" is the class on which the annotations are defined.  "pPtr"
725  * points to a pointer into the annotation data.
726  *
727  * We use the AnnotationFactory class to create the annotation for us.  The
728  * method we call is:
729  *
730  *  public static Annotation createAnnotation(
731  *      Class<? extends Annotation> annotationType,
732  *      AnnotationMember[] elements)
733  *
734  * Returns a new Annotation, which will NOT be in the local ref table and
735  * not referenced elsewhere, so store it away soon.  On failure, returns NULL
736  * with an exception raised.
737  */
738 static Object* processEncodedAnnotation(const ClassObject* clazz,
739     const u1** pPtr)
740 {
741     Thread* self = dvmThreadSelf();
742     Object* newAnno = NULL;
743     ArrayObject* elementArray = NULL;
744     const ClassObject* annoClass;
745     const u1* ptr;
746     u4 typeIdx, size, count;
747
748     ptr = *pPtr;
749     typeIdx = readUleb128(&ptr);
750     size = readUleb128(&ptr);
751
752     LOGVV("----- processEnc ptr=%p type=%d size=%d", ptr, typeIdx, size);
753
754     annoClass = dvmDexGetResolvedClass(clazz->pDvmDex, typeIdx);
755     if (annoClass == NULL) {
756         annoClass = dvmResolveClass(clazz, typeIdx, true);
757         if (annoClass == NULL) {
758             ALOGE("Unable to resolve %s annotation class %d",
759                 clazz->descriptor, typeIdx);
760             assert(dvmCheckException(self));
761             dvmClearException(self);
762             return NULL;
763         }
764     }
765
766     ALOGV("----- processEnc ptr=%p [0x%06x]  typeIdx=%d size=%d class=%s",
767         *pPtr, *pPtr - (u1*) clazz->pDvmDex->pDexFile->baseAddr,
768         typeIdx, size, annoClass->descriptor);
769
770     /*
771      * Elements are parsed out and stored in an array.  The Harmony
772      * constructor wants an array with just the declared elements --
773      * default values get merged in later.
774      */
775     JValue result;
776
777     if (size > 0) {
778         elementArray = dvmAllocArrayByClass(
779             gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray,
780             size, ALLOC_DEFAULT);
781         if (elementArray == NULL) {
782             ALOGE("failed to allocate annotation member array (%d elements)",
783                 size);
784             goto bail;
785         }
786     }
787
788     /*
789      * "ptr" points to a byte stream with "size" occurrences of
790      * annotation_element.
791      */
792     for (count = 0; count < size; count++) {
793         Object* newMember = createAnnotationMember(clazz, annoClass, &ptr);
794         if (newMember == NULL)
795             goto bail;
796
797         /* add it to the array */
798         dvmSetObjectArrayElement(elementArray, count, newMember);
799     }
800
801     dvmCallMethod(self,
802         gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation,
803         NULL, &result, annoClass, elementArray);
804     if (dvmCheckException(self)) {
805         ALOGD("Failed creating an annotation");
806         //dvmLogExceptionStackTrace();
807         goto bail;
808     }
809
810     newAnno = (Object*)result.l;
811
812 bail:
813     dvmReleaseTrackedAlloc((Object*) elementArray, NULL);
814     *pPtr = ptr;
815     if (newAnno == NULL && !dvmCheckException(self)) {
816         /* make sure an exception is raised */
817         dvmThrowRuntimeException("failure in processEncodedAnnotation");
818     }
819     return newAnno;
820 }
821
822 /*
823  * Run through an annotation set and convert each entry into an Annotation
824  * object.
825  *
826  * Returns an array of Annotation objects, or NULL with an exception raised
827  * on alloc failure.
828  */
829 static ArrayObject* processAnnotationSet(const ClassObject* clazz,
830     const DexAnnotationSetItem* pAnnoSet, int visibility)
831 {
832     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
833     const DexAnnotationItem* pAnnoItem;
834
835     /* we need these later; make sure they're initialized */
836     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory))
837         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory);
838     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember))
839         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember);
840
841     /* count up the number of visible elements */
842     size_t count = 0;
843     for (size_t i = 0; i < pAnnoSet->size; ++i) {
844         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
845         if (pAnnoItem->visibility == visibility) {
846             count++;
847         }
848     }
849
850     ArrayObject* annoArray = dvmAllocArrayByClass(gDvm.classJavaLangAnnotationAnnotationArray,
851                                                   count, ALLOC_DEFAULT);
852     if (annoArray == NULL) {
853         return NULL;
854     }
855
856     /*
857      * Generate Annotation objects.  We must put them into the array
858      * immediately (or add them to the tracked ref table).
859      * We may not be able to resolve all annotations, and should just
860      * ignore those we can't.
861      */
862     u4 dstIndex = 0;
863     for (int i = 0; i < (int) pAnnoSet->size; i++) {
864         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
865         if (pAnnoItem->visibility != visibility)
866             continue;
867         const u1* ptr = pAnnoItem->annotation;
868         Object *anno = processEncodedAnnotation(clazz, &ptr);
869         if (anno != NULL) {
870             dvmSetObjectArrayElement(annoArray, dstIndex, anno);
871             ++dstIndex;
872         }
873     }
874
875     // If we got as many as we expected, we're done...
876     if (dstIndex == count) {
877         return annoArray;
878     }
879
880     // ...otherwise we need to trim the trailing nulls.
881     ArrayObject* trimmedArray = dvmAllocArrayByClass(gDvm.classJavaLangAnnotationAnnotationArray,
882                                                      dstIndex, ALLOC_DEFAULT);
883     if (trimmedArray == NULL) {
884         return NULL;
885     }
886     for (size_t i = 0; i < dstIndex; ++i) {
887         Object** src = (Object**)(void*) annoArray->contents;
888         dvmSetObjectArrayElement(trimmedArray, i, src[i]);
889     }
890     dvmReleaseTrackedAlloc((Object*) annoArray, NULL);
891     return trimmedArray;
892 }
893
894 /*
895  * Return the annotation item of the specified type in the annotation set, or
896  * NULL if the set contains no annotation of that type.
897  */
898 static const DexAnnotationItem* getAnnotationItemFromAnnotationSet(
899         const ClassObject* clazz, const DexAnnotationSetItem* pAnnoSet,
900         int visibility, const ClassObject* annotationClazz)
901 {
902     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
903     const DexAnnotationItem* pAnnoItem;
904     int i;
905     const ClassObject* annoClass;
906     const u1* ptr;
907     u4 typeIdx;
908
909     /* we need these later; make sure they're initialized */
910     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory))
911         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory);
912     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember))
913         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember);
914
915     for (i = 0; i < (int) pAnnoSet->size; i++) {
916         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
917         if (pAnnoItem->visibility != visibility)
918             continue;
919
920         ptr = pAnnoItem->annotation;
921         typeIdx = readUleb128(&ptr);
922
923         annoClass = dvmDexGetResolvedClass(clazz->pDvmDex, typeIdx);
924         if (annoClass == NULL) {
925             annoClass = dvmResolveClass(clazz, typeIdx, true);
926             if (annoClass == NULL) {
927                 ALOGE("Unable to resolve %s annotation class %d",
928                       clazz->descriptor, typeIdx);
929                 Thread* self = dvmThreadSelf();
930                 assert(dvmCheckException(self));
931                 dvmClearException(self);
932                 continue;
933             }
934         }
935
936         if (annoClass == annotationClazz) {
937             return pAnnoItem;
938         }
939     }
940
941     return NULL;
942 }
943
944 /*
945  * Return the Annotation object of the specified type in the annotation set, or
946  * NULL if the set contains no annotation of that type.
947  */
948 static Object* getAnnotationObjectFromAnnotationSet(const ClassObject* clazz,
949         const DexAnnotationSetItem* pAnnoSet, int visibility,
950         const ClassObject* annotationClazz)
951 {
952     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
953             clazz, pAnnoSet, visibility, annotationClazz);
954     if (pAnnoItem == NULL) {
955         return NULL;
956     }
957     const u1* ptr = pAnnoItem->annotation;
958     return processEncodedAnnotation(clazz, &ptr);
959 }
960
961 /*
962  * ===========================================================================
963  *      Skipping and scanning
964  * ===========================================================================
965  */
966
967 /*
968  * Skip past an annotation value.
969  *
970  * "clazz" is the class on which the annotations are defined.
971  *
972  * Returns "true" on success, "false" on parsing failure.
973  */
974 static bool skipAnnotationValue(const ClassObject* clazz, const u1** pPtr)
975 {
976     const u1* ptr = *pPtr;
977     u1 valueType, valueArg;
978     int width;
979
980     valueType = *ptr++;
981     valueArg = valueType >> kDexAnnotationValueArgShift;
982     width = valueArg + 1;       /* assume */
983
984     ALOGV("----- type is 0x%02x %d, ptr=%p [0x%06x]",
985         valueType & kDexAnnotationValueTypeMask, valueArg, ptr-1,
986         (ptr-1) - (u1*)clazz->pDvmDex->pDexFile->baseAddr);
987
988     switch (valueType & kDexAnnotationValueTypeMask) {
989     case kDexAnnotationByte:        break;
990     case kDexAnnotationShort:       break;
991     case kDexAnnotationChar:        break;
992     case kDexAnnotationInt:         break;
993     case kDexAnnotationLong:        break;
994     case kDexAnnotationFloat:       break;
995     case kDexAnnotationDouble:      break;
996     case kDexAnnotationString:      break;
997     case kDexAnnotationType:        break;
998     case kDexAnnotationMethod:      break;
999     case kDexAnnotationField:       break;
1000     case kDexAnnotationEnum:        break;
1001
1002     case kDexAnnotationArray:
1003         /* encoded_array format */
1004         {
1005             u4 size = readUleb128(&ptr);
1006             while (size--) {
1007                 if (!skipAnnotationValue(clazz, &ptr))
1008                     return false;
1009             }
1010         }
1011         width = 0;
1012         break;
1013     case kDexAnnotationAnnotation:
1014         /* encoded_annotation format */
1015         if (!skipEncodedAnnotation(clazz, &ptr))
1016             return false;
1017         width = 0;
1018         break;
1019     case kDexAnnotationBoolean:
1020     case kDexAnnotationNull:
1021         width = 0;
1022         break;
1023     default:
1024         ALOGE("Bad annotation element value byte 0x%02x", valueType);
1025         assert(false);
1026         return false;
1027     }
1028
1029     ptr += width;
1030
1031     *pPtr = ptr;
1032     return true;
1033 }
1034
1035 /*
1036  * Skip past an encoded annotation.  Mainly useful for annotations embedded
1037  * in other annotations.
1038  */
1039 static bool skipEncodedAnnotation(const ClassObject* clazz, const u1** pPtr)
1040 {
1041     const u1* ptr;
1042     u4 size;
1043
1044     ptr = *pPtr;
1045     (void) readUleb128(&ptr);
1046     size = readUleb128(&ptr);
1047
1048     /*
1049      * "ptr" points to a byte stream with "size" occurrences of
1050      * annotation_element.
1051      */
1052     while (size--) {
1053         (void) readUleb128(&ptr);
1054
1055         if (!skipAnnotationValue(clazz, &ptr))
1056             return false;
1057     }
1058
1059     *pPtr = ptr;
1060     return true;
1061 }
1062
1063
1064 /*
1065  * Compare the name of the class in the DEX file to the supplied descriptor.
1066  * Return value is equivalent to strcmp.
1067  */
1068 static int compareClassDescriptor(DexFile* pDexFile, u4 typeIdx,
1069     const char* descriptor)
1070 {
1071     const char* str = dexStringByTypeIdx(pDexFile, typeIdx);
1072
1073     return strcmp(str, descriptor);
1074 }
1075
1076 /*
1077  * Search through the annotation set for an annotation with a matching
1078  * descriptor.
1079  *
1080  * Comparing the string descriptor is slower than comparing an integer class
1081  * index.  If annotation lists are expected to be long, we could look up
1082  * the class' index by name from the DEX file, rather than doing a class
1083  * lookup and string compare on each entry.  (Note the index will be
1084  * different for each DEX file, so we can't cache annotation class indices
1085  * globally.)
1086  */
1087 static const DexAnnotationItem* searchAnnotationSet(const ClassObject* clazz,
1088     const DexAnnotationSetItem* pAnnoSet, const char* descriptor,
1089     int visibility)
1090 {
1091     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1092     const DexAnnotationItem* result = NULL;
1093     u4 typeIdx;
1094     int i;
1095
1096     //printf("##### searchAnnotationSet %s %d\n", descriptor, visibility);
1097
1098     for (i = 0; i < (int) pAnnoSet->size; i++) {
1099         const DexAnnotationItem* pAnnoItem;
1100
1101         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
1102         if (pAnnoItem->visibility != visibility)
1103             continue;
1104         const u1* ptr = pAnnoItem->annotation;
1105         typeIdx = readUleb128(&ptr);
1106
1107         if (compareClassDescriptor(pDexFile, typeIdx, descriptor) == 0) {
1108             //printf("#####  match on %x/%p at %d\n", typeIdx, pDexFile, i);
1109             result = pAnnoItem;
1110             break;
1111         }
1112     }
1113
1114     return result;
1115 }
1116
1117 /*
1118  * Find an annotation value in the annotation_item whose name matches "name".
1119  * A pointer to the annotation_value is returned, or NULL if it's not found.
1120  */
1121 static const u1* searchEncodedAnnotation(const ClassObject* clazz,
1122     const u1* ptr, const char* name)
1123 {
1124     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1125     u4 typeIdx, size;
1126
1127     typeIdx = readUleb128(&ptr);
1128     size = readUleb128(&ptr);
1129     //printf("#####   searching ptr=%p type=%u size=%u\n", ptr, typeIdx, size);
1130
1131     while (size--) {
1132         u4 elementNameIdx;
1133         const char* elemName;
1134
1135         elementNameIdx = readUleb128(&ptr);
1136         elemName = dexStringById(pDexFile, elementNameIdx);
1137         if (strcmp(name, elemName) == 0) {
1138             //printf("#####   item match on %s\n", name);
1139             return ptr;     /* points to start of value */
1140         }
1141
1142         skipAnnotationValue(clazz, &ptr);
1143     }
1144
1145     //printf("#####   no item match on %s\n", name);
1146     return NULL;
1147 }
1148
1149 #define GAV_FAILED  ((Object*) 0x10000001)
1150
1151 /*
1152  * Extract an encoded annotation value from the field specified by "annoName".
1153  *
1154  * "expectedType" is an annotation value type, e.g. kDexAnnotationString.
1155  * "debugAnnoName" is only used in debug messages.
1156  *
1157  * Returns GAV_FAILED on failure.  If an allocation failed, an exception
1158  * will be raised.
1159  */
1160 static Object* getAnnotationValue(const ClassObject* clazz,
1161     const DexAnnotationItem* pAnnoItem, const char* annoName,
1162     int expectedType, const char* debugAnnoName)
1163 {
1164     const u1* ptr;
1165     AnnotationValue avalue;
1166
1167     /* find the annotation */
1168     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, annoName);
1169     if (ptr == NULL) {
1170         ALOGW("%s annotation lacks '%s' member", debugAnnoName, annoName);
1171         return GAV_FAILED;
1172     }
1173
1174     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects))
1175         return GAV_FAILED;
1176
1177     /* make sure it has the expected format */
1178     if (avalue.type != expectedType) {
1179         ALOGW("%s %s has wrong type (0x%02x, expected 0x%02x)",
1180             debugAnnoName, annoName, avalue.type, expectedType);
1181         return GAV_FAILED;
1182     }
1183
1184     return (Object*)avalue.value.l;
1185 }
1186
1187
1188 /*
1189  * Find the Signature attribute and extract its value.  (Signatures can
1190  * be found in annotations on classes, constructors, methods, and fields.)
1191  *
1192  * Caller must call dvmReleaseTrackedAlloc().
1193  *
1194  * Returns NULL if not found.  On memory alloc failure, returns NULL with an
1195  * exception raised.
1196  */
1197 static ArrayObject* getSignatureValue(const ClassObject* clazz,
1198     const DexAnnotationSetItem* pAnnoSet)
1199 {
1200     const DexAnnotationItem* pAnnoItem;
1201     Object* obj;
1202
1203     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrSignature,
1204         kDexVisibilitySystem);
1205     if (pAnnoItem == NULL)
1206         return NULL;
1207
1208     /*
1209      * The Signature annotation has one member, "String value".
1210      */
1211     obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationArray,
1212             "Signature");
1213     if (obj == GAV_FAILED)
1214         return NULL;
1215     assert(obj->clazz == gDvm.classJavaLangObjectArray);
1216
1217     return (ArrayObject*)obj;
1218 }
1219
1220
1221 /*
1222  * ===========================================================================
1223  *      Class
1224  * ===========================================================================
1225  */
1226
1227 /*
1228  * Find the DexAnnotationSetItem for this class.
1229  */
1230 static const DexAnnotationSetItem* findAnnotationSetForClass(
1231     const ClassObject* clazz)
1232 {
1233     DexFile* pDexFile;
1234     const DexAnnotationsDirectoryItem* pAnnoDir;
1235
1236     if (clazz->pDvmDex == NULL)         /* generated class (Proxy, array) */
1237         return NULL;
1238
1239     pDexFile = clazz->pDvmDex->pDexFile;
1240     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1241     if (pAnnoDir != NULL)
1242         return dexGetClassAnnotationSet(pDexFile, pAnnoDir);
1243     else
1244         return NULL;
1245 }
1246
1247 /*
1248  * Return an array of Annotation objects for the class.  Returns an empty
1249  * array if there are no annotations.
1250  *
1251  * Caller must call dvmReleaseTrackedAlloc().
1252  *
1253  * On allocation failure, this returns NULL with an exception raised.
1254  */
1255 ArrayObject* dvmGetClassAnnotations(const ClassObject* clazz)
1256 {
1257     ArrayObject* annoArray;
1258     const DexAnnotationSetItem* pAnnoSet = NULL;
1259
1260     pAnnoSet = findAnnotationSetForClass(clazz);
1261     if (pAnnoSet == NULL) {
1262         /* no annotations for anything in class, or no class annotations */
1263         annoArray = emptyAnnoArray();
1264     } else {
1265         annoArray = processAnnotationSet(clazz, pAnnoSet,
1266                         kDexVisibilityRuntime);
1267     }
1268
1269     return annoArray;
1270 }
1271
1272 /*
1273  * Returns the annotation or NULL if it doesn't exist.
1274  */
1275 Object* dvmGetClassAnnotation(const ClassObject* clazz,
1276         const ClassObject* annotationClazz)
1277 {
1278     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForClass(clazz);
1279     if (pAnnoSet == NULL) {
1280         return NULL;
1281     }
1282     return getAnnotationObjectFromAnnotationSet(clazz, pAnnoSet,
1283             kDexVisibilityRuntime, annotationClazz);
1284 }
1285
1286 /*
1287  * Returns true if the annotation exists.
1288  */
1289 bool dvmIsClassAnnotationPresent(const ClassObject* clazz,
1290         const ClassObject* annotationClazz)
1291 {
1292     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForClass(clazz);
1293     if (pAnnoSet == NULL) {
1294         return NULL;
1295     }
1296     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
1297             clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
1298     return (pAnnoItem != NULL);
1299 }
1300
1301 /*
1302  * Retrieve the Signature annotation, if any.  Returns NULL if no signature
1303  * exists.
1304  *
1305  * Caller must call dvmReleaseTrackedAlloc().
1306  */
1307 ArrayObject* dvmGetClassSignatureAnnotation(const ClassObject* clazz)
1308 {
1309     ArrayObject* signature = NULL;
1310     const DexAnnotationSetItem* pAnnoSet;
1311
1312     pAnnoSet = findAnnotationSetForClass(clazz);
1313     if (pAnnoSet != NULL)
1314         signature = getSignatureValue(clazz, pAnnoSet);
1315
1316     return signature;
1317 }
1318
1319 /*
1320  * Get the EnclosingMethod attribute from an annotation.  Returns a Method
1321  * object, or NULL.
1322  *
1323  * Caller must call dvmReleaseTrackedAlloc().
1324  */
1325 Object* dvmGetEnclosingMethod(const ClassObject* clazz)
1326 {
1327     const DexAnnotationItem* pAnnoItem;
1328     const DexAnnotationSetItem* pAnnoSet;
1329     Object* obj;
1330
1331     pAnnoSet = findAnnotationSetForClass(clazz);
1332     if (pAnnoSet == NULL)
1333         return NULL;
1334
1335     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingMethod,
1336         kDexVisibilitySystem);
1337     if (pAnnoItem == NULL)
1338         return NULL;
1339
1340     /*
1341      * The EnclosingMethod annotation has one member, "Method value".
1342      */
1343     obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationMethod,
1344             "EnclosingMethod");
1345     if (obj == GAV_FAILED)
1346         return NULL;
1347     assert(obj->clazz == gDvm.classJavaLangReflectConstructor ||
1348            obj->clazz == gDvm.classJavaLangReflectMethod);
1349
1350     return obj;
1351 }
1352
1353 /*
1354  * Find a class' enclosing class.  We return what we find in the
1355  * EnclosingClass attribute.
1356  *
1357  * Returns a Class object, or NULL.
1358  *
1359  * Caller must call dvmReleaseTrackedAlloc().
1360  */
1361 ClassObject* dvmGetDeclaringClass(const ClassObject* clazz)
1362 {
1363     const DexAnnotationItem* pAnnoItem;
1364     const DexAnnotationSetItem* pAnnoSet;
1365     Object* obj;
1366
1367     pAnnoSet = findAnnotationSetForClass(clazz);
1368     if (pAnnoSet == NULL)
1369         return NULL;
1370
1371     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingClass,
1372         kDexVisibilitySystem);
1373     if (pAnnoItem == NULL)
1374         return NULL;
1375
1376     /*
1377      * The EnclosingClass annotation has one member, "Class value".
1378      */
1379     obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationType,
1380             "EnclosingClass");
1381     if (obj == GAV_FAILED)
1382         return NULL;
1383
1384     assert(dvmIsClassObject(obj));
1385     return (ClassObject*)obj;
1386 }
1387
1388 /*
1389  * Find a class' enclosing class.  We first search for an EnclosingClass
1390  * attribute, and if that's not found we look for an EnclosingMethod.
1391  *
1392  * Returns a Class object, or NULL.
1393  *
1394  * Caller must call dvmReleaseTrackedAlloc().
1395  */
1396 ClassObject* dvmGetEnclosingClass(const ClassObject* clazz)
1397 {
1398     const DexAnnotationItem* pAnnoItem;
1399     const DexAnnotationSetItem* pAnnoSet;
1400     Object* obj;
1401
1402     pAnnoSet = findAnnotationSetForClass(clazz);
1403     if (pAnnoSet == NULL)
1404         return NULL;
1405
1406     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingClass,
1407         kDexVisibilitySystem);
1408     if (pAnnoItem != NULL) {
1409         /*
1410          * The EnclosingClass annotation has one member, "Class value".
1411          */
1412         obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationType,
1413                 "EnclosingClass");
1414         if (obj != GAV_FAILED) {
1415             assert(dvmIsClassObject(obj));
1416             return (ClassObject*)obj;
1417         }
1418     }
1419
1420     /*
1421      * That didn't work.  Look for an EnclosingMethod.
1422      *
1423      * We could create a java.lang.reflect.Method object and extract the
1424      * declaringClass from it, but that's more work than we want to do.
1425      * Instead, we find the "value" item and parse the index out ourselves.
1426      */
1427     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingMethod,
1428         kDexVisibilitySystem);
1429     if (pAnnoItem == NULL)
1430         return NULL;
1431
1432     /* find the value member */
1433     const u1* ptr;
1434     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "value");
1435     if (ptr == NULL) {
1436         ALOGW("EnclosingMethod annotation lacks 'value' member");
1437         return NULL;
1438     }
1439
1440     /* parse it, verify the type */
1441     AnnotationValue avalue;
1442     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllRaw)) {
1443         ALOGW("EnclosingMethod parse failed");
1444         return NULL;
1445     }
1446     if (avalue.type != kDexAnnotationMethod) {
1447         ALOGW("EnclosingMethod value has wrong type (0x%02x, expected 0x%02x)",
1448             avalue.type, kDexAnnotationMethod);
1449         return NULL;
1450     }
1451
1452     /* pull out the method index and resolve the method */
1453     Method* meth = resolveAmbiguousMethod(clazz, avalue.value.i);
1454     if (meth == NULL)
1455         return NULL;
1456
1457     ClassObject* methClazz = meth->clazz;
1458     dvmAddTrackedAlloc((Object*) methClazz, NULL);      // balance the Release
1459     return methClazz;
1460 }
1461
1462 /*
1463  * Get the EnclosingClass attribute from an annotation.  If found, returns
1464  * "true".  A String with the original name of the class and the original
1465  * access flags are returned through the arguments.  (The name will be NULL
1466  * for an anonymous inner class.)
1467  *
1468  * Caller must call dvmReleaseTrackedAlloc().
1469  */
1470 bool dvmGetInnerClass(const ClassObject* clazz, StringObject** pName,
1471     int* pAccessFlags)
1472 {
1473     const DexAnnotationItem* pAnnoItem;
1474     const DexAnnotationSetItem* pAnnoSet;
1475
1476     pAnnoSet = findAnnotationSetForClass(clazz);
1477     if (pAnnoSet == NULL)
1478         return false;
1479
1480     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrInnerClass,
1481         kDexVisibilitySystem);
1482     if (pAnnoItem == NULL)
1483         return false;
1484
1485     /*
1486      * The InnerClass annotation has two members, "String name" and
1487      * "int accessFlags".  We don't want to get the access flags as an
1488      * Integer, so we process that as a simple value.
1489      */
1490     const u1* ptr;
1491     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "name");
1492     if (ptr == NULL) {
1493         ALOGW("InnerClass annotation lacks 'name' member");
1494         return false;
1495     }
1496
1497     /* parse it into an Object */
1498     AnnotationValue avalue;
1499     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) {
1500         ALOGD("processAnnotationValue failed on InnerClass member 'name'");
1501         return false;
1502     }
1503
1504     /* make sure it has the expected format */
1505     if (avalue.type != kDexAnnotationNull &&
1506         avalue.type != kDexAnnotationString)
1507     {
1508         ALOGW("InnerClass name has bad type (0x%02x, expected STRING or NULL)",
1509             avalue.type);
1510         return false;
1511     }
1512
1513     *pName = (StringObject*) avalue.value.l;
1514     assert(*pName == NULL || (*pName)->clazz == gDvm.classJavaLangString);
1515
1516     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "accessFlags");
1517     if (ptr == NULL) {
1518         ALOGW("InnerClass annotation lacks 'accessFlags' member");
1519         return false;
1520     }
1521
1522     /* parse it, verify the type */
1523     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllRaw)) {
1524         ALOGW("InnerClass accessFlags parse failed");
1525         return false;
1526     }
1527     if (avalue.type != kDexAnnotationInt) {
1528         ALOGW("InnerClass value has wrong type (0x%02x, expected 0x%02x)",
1529             avalue.type, kDexAnnotationInt);
1530         return false;
1531     }
1532
1533     *pAccessFlags = avalue.value.i;
1534
1535     return true;
1536 }
1537
1538 /*
1539  * Extract an array of Class objects from the MemberClasses annotation
1540  * for this class.
1541  *
1542  * Caller must call dvmReleaseTrackedAlloc().
1543  *
1544  * Returns NULL if we don't find any member classes.
1545  */
1546 ArrayObject* dvmGetDeclaredClasses(const ClassObject* clazz)
1547 {
1548     const DexAnnotationSetItem* pAnnoSet;
1549     const DexAnnotationItem* pAnnoItem;
1550     Object* obj;
1551
1552     pAnnoSet = findAnnotationSetForClass(clazz);
1553     if (pAnnoSet == NULL)
1554         return NULL;
1555
1556     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrMemberClasses,
1557         kDexVisibilitySystem);
1558     if (pAnnoItem == NULL)
1559         return NULL;
1560
1561     /*
1562      * The MemberClasses annotation has one member, "Class[] value".
1563      */
1564     obj = getAnnotationValue(clazz, pAnnoItem, "value",
1565             kDexAnnotationArray, "MemberClasses");
1566     if (obj == GAV_FAILED)
1567         return NULL;
1568     assert(dvmIsArray((ArrayObject*)obj));
1569     obj = convertReturnType(obj, gDvm.classJavaLangClassArray);
1570     return (ArrayObject*)obj;
1571 }
1572
1573
1574 /*
1575  * ===========================================================================
1576  *      Method (and Constructor)
1577  * ===========================================================================
1578  */
1579
1580 /*
1581  * Compare the attributes (class name, method name, method signature) of
1582  * the specified method to "method".
1583  */
1584 static int compareMethodStr(DexFile* pDexFile, u4 methodIdx,
1585     const Method* method)
1586 {
1587     const DexMethodId* pMethodId = dexGetMethodId(pDexFile, methodIdx);
1588     const char* str = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
1589     int result = strcmp(str, method->clazz->descriptor);
1590
1591     if (result == 0) {
1592         str = dexStringById(pDexFile, pMethodId->nameIdx);
1593         result = strcmp(str, method->name);
1594         if (result == 0) {
1595             DexProto proto;
1596             dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
1597             result = dexProtoCompare(&proto, &method->prototype);
1598         }
1599     }
1600
1601     return result;
1602 }
1603
1604 /*
1605  * Given a method, determine the method's index.
1606  *
1607  * We could simply store this in the Method*, but that would cost 4 bytes
1608  * per method.  Instead we plow through the DEX data.
1609  *
1610  * We have two choices: look through the class method data, or look through
1611  * the global method_ids table.  The former is awkward because the method
1612  * could have been defined in a superclass or interface.  The latter works
1613  * out reasonably well because it's in sorted order, though we're still left
1614  * doing a fair number of string comparisons.
1615  */
1616 static u4 getMethodIdx(const Method* method)
1617 {
1618     DexFile* pDexFile = method->clazz->pDvmDex->pDexFile;
1619     u4 hi = pDexFile->pHeader->methodIdsSize -1;
1620     u4 lo = 0;
1621     u4 cur;
1622
1623     while (hi >= lo) {
1624         int cmp;
1625         cur = (lo + hi) / 2;
1626
1627         cmp = compareMethodStr(pDexFile, cur, method);
1628         if (cmp < 0) {
1629             lo = cur + 1;
1630         } else if (cmp > 0) {
1631             hi = cur - 1;
1632         } else {
1633             break;
1634         }
1635     }
1636
1637     if (hi < lo) {
1638         /* this should be impossible -- the method came out of this DEX */
1639         char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
1640         ALOGE("Unable to find method %s.%s %s in DEX file!",
1641             method->clazz->descriptor, method->name, desc);
1642         free(desc);
1643         dvmAbort();
1644     }
1645
1646     return cur;
1647 }
1648
1649 /*
1650  * Find the DexAnnotationSetItem for this method.
1651  *
1652  * Returns NULL if none found.
1653  */
1654 static const DexAnnotationSetItem* findAnnotationSetForMethod(
1655     const Method* method)
1656 {
1657     ClassObject* clazz = method->clazz;
1658     DexFile* pDexFile;
1659     const DexAnnotationsDirectoryItem* pAnnoDir;
1660     const DexMethodAnnotationsItem* pMethodList;
1661     const DexAnnotationSetItem* pAnnoSet = NULL;
1662
1663     if (clazz->pDvmDex == NULL)         /* generated class (Proxy, array) */
1664         return NULL;
1665     pDexFile = clazz->pDvmDex->pDexFile;
1666
1667     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1668     if (pAnnoDir != NULL) {
1669         pMethodList = dexGetMethodAnnotations(pDexFile, pAnnoDir);
1670         if (pMethodList != NULL) {
1671             /*
1672              * Run through the list and find a matching method.  We compare the
1673              * method ref indices in the annotation list with the method's DEX
1674              * method_idx value.
1675              *
1676              * TODO: use a binary search for long lists
1677              *
1678              * Alternate approach: for each entry in the annotations list,
1679              * find the method definition in the DEX file and perform string
1680              * comparisons on class name, method name, and signature.
1681              */
1682             u4 methodIdx = getMethodIdx(method);
1683             u4 count = dexGetMethodAnnotationsSize(pDexFile, pAnnoDir);
1684             u4 idx;
1685
1686             for (idx = 0; idx < count; idx++) {
1687                 if (pMethodList[idx].methodIdx == methodIdx) {
1688                     /* found! */
1689                     pAnnoSet = dexGetMethodAnnotationSetItem(pDexFile,
1690                                     &pMethodList[idx]);
1691                     break;
1692                 }
1693             }
1694         }
1695     }
1696
1697     return pAnnoSet;
1698 }
1699
1700 /*
1701  * Return an array of Annotation objects for the method.  Returns an empty
1702  * array if there are no annotations.
1703  *
1704  * Caller must call dvmReleaseTrackedAlloc().
1705  *
1706  * On allocation failure, this returns NULL with an exception raised.
1707  */
1708 ArrayObject* dvmGetMethodAnnotations(const Method* method)
1709 {
1710     ClassObject* clazz = method->clazz;
1711     const DexAnnotationSetItem* pAnnoSet;
1712     ArrayObject* annoArray = NULL;
1713
1714     pAnnoSet = findAnnotationSetForMethod(method);
1715     if (pAnnoSet == NULL) {
1716         /* no matching annotations found */
1717         annoArray = emptyAnnoArray();
1718     } else {
1719         annoArray = processAnnotationSet(clazz, pAnnoSet,kDexVisibilityRuntime);
1720     }
1721
1722     return annoArray;
1723 }
1724
1725 /*
1726  * Returns the annotation or NULL if it doesn't exist.
1727  */
1728 Object* dvmGetMethodAnnotation(const ClassObject* clazz, const Method* method,
1729         const ClassObject* annotationClazz)
1730 {
1731     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForMethod(method);
1732     if (pAnnoSet == NULL) {
1733         return NULL;
1734     }
1735     return getAnnotationObjectFromAnnotationSet(clazz, pAnnoSet,
1736             kDexVisibilityRuntime, annotationClazz);
1737 }
1738
1739 /*
1740  * Returns true if the annotation exists.
1741  */
1742 bool dvmIsMethodAnnotationPresent(const ClassObject* clazz,
1743         const Method* method, const ClassObject* annotationClazz)
1744 {
1745     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForMethod(method);
1746     if (pAnnoSet == NULL) {
1747         return NULL;
1748     }
1749     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
1750             clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
1751     return (pAnnoItem != NULL);
1752 }
1753
1754 /*
1755  * Retrieve the Signature annotation, if any.  Returns NULL if no signature
1756  * exists.
1757  *
1758  * Caller must call dvmReleaseTrackedAlloc().
1759  */
1760 ArrayObject* dvmGetMethodSignatureAnnotation(const Method* method)
1761 {
1762     ClassObject* clazz = method->clazz;
1763     const DexAnnotationSetItem* pAnnoSet;
1764     ArrayObject* signature = NULL;
1765
1766     pAnnoSet = findAnnotationSetForMethod(method);
1767     if (pAnnoSet != NULL)
1768         signature = getSignatureValue(clazz, pAnnoSet);
1769
1770     return signature;
1771 }
1772
1773 /*
1774  * Extract an array of exception classes from the "system" annotation list
1775  * for this method.
1776  *
1777  * Caller must call dvmReleaseTrackedAlloc().
1778  *
1779  * Returns NULL if we don't find any exceptions for this method.
1780  */
1781 ArrayObject* dvmGetMethodThrows(const Method* method)
1782 {
1783     ClassObject* clazz = method->clazz;
1784     const DexAnnotationSetItem* pAnnoSet;
1785     const DexAnnotationItem* pAnnoItem;
1786
1787     /* find the set for this method */
1788     pAnnoSet = findAnnotationSetForMethod(method);
1789     if (pAnnoSet == NULL)
1790         return NULL;        /* nothing for this method */
1791
1792     /* find the "Throws" annotation, if any */
1793     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrThrows,
1794         kDexVisibilitySystem);
1795     if (pAnnoItem == NULL)
1796         return NULL;        /* no Throws */
1797
1798     /*
1799      * The Throws annotation has one member, "Class[] value".
1800      */
1801     Object* obj = getAnnotationValue(clazz, pAnnoItem, "value",
1802         kDexAnnotationArray, "Throws");
1803     if (obj == GAV_FAILED)
1804         return NULL;
1805     assert(dvmIsArray((ArrayObject*)obj));
1806     obj = convertReturnType(obj, gDvm.classJavaLangClassArray);
1807     return (ArrayObject*)obj;
1808 }
1809
1810 /*
1811  * Given an Annotation's method, find the default value, if any.
1812  *
1813  * If this is a CLASS annotation, and we can't find a match for the
1814  * default class value, we need to throw a TypeNotPresentException.
1815  *
1816  * Caller must call dvmReleaseTrackedAlloc().
1817  */
1818 Object* dvmGetAnnotationDefaultValue(const Method* method)
1819 {
1820     const ClassObject* clazz = method->clazz;
1821     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1822     const DexAnnotationsDirectoryItem* pAnnoDir;
1823     const DexAnnotationSetItem* pAnnoSet = NULL;
1824
1825     /*
1826      * The method's declaring class (the annotation) will have an
1827      * AnnotationDefault "system" annotation associated with it if any
1828      * of its methods have default values.  Start by finding the
1829      * DexAnnotationItem associated with the class.
1830      */
1831     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1832     if (pAnnoDir != NULL)
1833         pAnnoSet = dexGetClassAnnotationSet(pDexFile, pAnnoDir);
1834     if (pAnnoSet == NULL) {
1835         /* no annotations for anything in class, or no class annotations */
1836         return NULL;
1837     }
1838
1839     /* find the "AnnotationDefault" annotation, if any */
1840     const DexAnnotationItem* pAnnoItem;
1841     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrAnnotationDefault,
1842         kDexVisibilitySystem);
1843     if (pAnnoItem == NULL) {
1844         /* no default values for any member in this annotation */
1845         //printf("##### no default annotations for %s.%s\n",
1846         //    method->clazz->descriptor, method->name);
1847         return NULL;
1848     }
1849
1850     /*
1851      * The AnnotationDefault annotation has one member, "Annotation value".
1852      * We need to pull that out.
1853      */
1854     const u1* ptr;
1855     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "value");
1856     if (ptr == NULL) {
1857         ALOGW("AnnotationDefault annotation lacks 'value'");
1858         return NULL;
1859     }
1860     if ((*ptr & kDexAnnotationValueTypeMask) != kDexAnnotationAnnotation) {
1861         ALOGW("AnnotationDefault value has wrong type (0x%02x)",
1862             *ptr & kDexAnnotationValueTypeMask);
1863         return NULL;
1864     }
1865
1866     /*
1867      * The value_type byte for VALUE_ANNOTATION is followed by
1868      * encoded_annotation data.  We want to scan through it to find an
1869      * entry whose name matches our method name.
1870      */
1871     ptr++;
1872     ptr = searchEncodedAnnotation(clazz, ptr, method->name);
1873     if (ptr == NULL)
1874         return NULL;        /* no default annotation for this method */
1875
1876     /* got it, pull it out */
1877     AnnotationValue avalue;
1878     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) {
1879         ALOGD("processAnnotationValue failed on default for '%s'",
1880             method->name);
1881         return NULL;
1882     }
1883
1884     /* convert the return type, if necessary */
1885     ClassObject* methodReturn = dvmGetBoxedReturnType(method);
1886     Object* obj = (Object*)avalue.value.l;
1887     obj = convertReturnType(obj, methodReturn);
1888
1889     return obj;
1890 }
1891
1892
1893 /*
1894  * ===========================================================================
1895  *      Field
1896  * ===========================================================================
1897  */
1898
1899 /*
1900  * Compare the attributes (class name, field name, field signature) of
1901  * the specified field to "field".
1902  */
1903 static int compareFieldStr(DexFile* pDexFile, u4 idx, const Field* field)
1904 {
1905     const DexFieldId* pFieldId = dexGetFieldId(pDexFile, idx);
1906     const char* str = dexStringByTypeIdx(pDexFile, pFieldId->classIdx);
1907     int result = strcmp(str, field->clazz->descriptor);
1908
1909     if (result == 0) {
1910         str = dexStringById(pDexFile, pFieldId->nameIdx);
1911         result = strcmp(str, field->name);
1912         if (result == 0) {
1913             str = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
1914             result = strcmp(str, field->signature);
1915         }
1916     }
1917
1918     return result;
1919 }
1920
1921 /*
1922  * Given a field, determine the field's index.
1923  *
1924  * This has the same tradeoffs as getMethodIdx.
1925  */
1926 static u4 getFieldIdx(const Field* field)
1927 {
1928     DexFile* pDexFile = field->clazz->pDvmDex->pDexFile;
1929     u4 hi = pDexFile->pHeader->fieldIdsSize -1;
1930     u4 lo = 0;
1931     u4 cur;
1932
1933     while (hi >= lo) {
1934         int cmp;
1935         cur = (lo + hi) / 2;
1936
1937         cmp = compareFieldStr(pDexFile, cur, field);
1938         if (cmp < 0) {
1939             lo = cur + 1;
1940         } else if (cmp > 0) {
1941             hi = cur - 1;
1942         } else {
1943             break;
1944         }
1945     }
1946
1947     if (hi < lo) {
1948         /* this should be impossible -- the field came out of this DEX */
1949         ALOGE("Unable to find field %s.%s %s in DEX file!",
1950             field->clazz->descriptor, field->name, field->signature);
1951         dvmAbort();
1952     }
1953
1954     return cur;
1955 }
1956
1957 /*
1958  * Find the DexAnnotationSetItem for this field.
1959  *
1960  * Returns NULL if none found.
1961  */
1962 static const DexAnnotationSetItem* findAnnotationSetForField(const Field* field)
1963 {
1964     ClassObject* clazz = field->clazz;
1965     DvmDex* pDvmDex = clazz->pDvmDex;
1966     if (pDvmDex == NULL) {
1967         return NULL;
1968     }
1969
1970     DexFile* pDexFile = pDvmDex->pDexFile;
1971
1972     const DexAnnotationsDirectoryItem* pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1973     if (pAnnoDir == NULL) {
1974         return NULL;
1975     }
1976
1977     const DexFieldAnnotationsItem* pFieldList = dexGetFieldAnnotations(pDexFile, pAnnoDir);
1978     if (pFieldList == NULL) {
1979         return NULL;
1980     }
1981
1982     /*
1983      * Run through the list and find a matching field.  We compare the
1984      * field ref indices in the annotation list with the field's DEX
1985      * field_idx value.
1986      *
1987      * TODO: use a binary search for long lists
1988      *
1989      * Alternate approach: for each entry in the annotations list,
1990      * find the field definition in the DEX file and perform string
1991      * comparisons on class name, field name, and signature.
1992      */
1993     u4 fieldIdx = getFieldIdx(field);
1994     u4 count = dexGetFieldAnnotationsSize(pDexFile, pAnnoDir);
1995     u4 idx;
1996
1997     for (idx = 0; idx < count; idx++) {
1998         if (pFieldList[idx].fieldIdx == fieldIdx) {
1999             /* found! */
2000             return dexGetFieldAnnotationSetItem(pDexFile, &pFieldList[idx]);
2001         }
2002     }
2003
2004     return NULL;
2005 }
2006
2007 /*
2008  * Return an array of Annotation objects for the field.  Returns an empty
2009  * array if there are no annotations.
2010  *
2011  * Caller must call dvmReleaseTrackedAlloc().
2012  *
2013  * On allocation failure, this returns NULL with an exception raised.
2014  */
2015 ArrayObject* dvmGetFieldAnnotations(const Field* field)
2016 {
2017     ClassObject* clazz = field->clazz;
2018     ArrayObject* annoArray = NULL;
2019     const DexAnnotationSetItem* pAnnoSet = NULL;
2020
2021     pAnnoSet = findAnnotationSetForField(field);
2022     if (pAnnoSet == NULL) {
2023         /* no matching annotations found */
2024         annoArray = emptyAnnoArray();
2025     } else {
2026         annoArray = processAnnotationSet(clazz, pAnnoSet,
2027                         kDexVisibilityRuntime);
2028     }
2029
2030     return annoArray;
2031 }
2032
2033 /*
2034  * Returns the annotation or NULL if it doesn't exist.
2035  */
2036 Object* dvmGetFieldAnnotation(const ClassObject* clazz, const Field* field,
2037         const ClassObject* annotationClazz)
2038 {
2039     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForField(field);
2040     if (pAnnoSet == NULL) {
2041         return NULL;
2042     }
2043     return getAnnotationObjectFromAnnotationSet(clazz, pAnnoSet,
2044             kDexVisibilityRuntime, annotationClazz);
2045 }
2046
2047 /*
2048  * Returns true if the annotation exists.
2049  */
2050 bool dvmIsFieldAnnotationPresent(const ClassObject* clazz,
2051         const Field* field, const ClassObject* annotationClazz)
2052 {
2053     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForField(field);
2054     if (pAnnoSet == NULL) {
2055         return NULL;
2056     }
2057     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
2058             clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
2059     return (pAnnoItem != NULL);
2060 }
2061
2062 /*
2063  * Retrieve the Signature annotation, if any.  Returns NULL if no signature
2064  * exists.
2065  *
2066  * Caller must call dvmReleaseTrackedAlloc().
2067  */
2068 ArrayObject* dvmGetFieldSignatureAnnotation(const Field* field)
2069 {
2070     ClassObject* clazz = field->clazz;
2071     const DexAnnotationSetItem* pAnnoSet;
2072     ArrayObject* signature = NULL;
2073
2074     pAnnoSet = findAnnotationSetForField(field);
2075     if (pAnnoSet != NULL)
2076         signature = getSignatureValue(clazz, pAnnoSet);
2077
2078     return signature;
2079 }
2080
2081
2082 /*
2083  * ===========================================================================
2084  *      Parameter
2085  * ===========================================================================
2086  */
2087
2088 /*
2089  * We have an annotation_set_ref_list, which is essentially a list of
2090  * entries that we pass to processAnnotationSet().
2091  *
2092  * The returned object must be released with dvmReleaseTrackedAlloc.
2093  */
2094 static ArrayObject* processAnnotationSetRefList(const ClassObject* clazz,
2095     const DexAnnotationSetRefList* pAnnoSetList, u4 count)
2096 {
2097     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2098     ArrayObject* annoArrayArray = NULL;
2099     u4 idx;
2100
2101     /* allocate an array of Annotation arrays to hold results */
2102     annoArrayArray = dvmAllocArrayByClass(
2103         gDvm.classJavaLangAnnotationAnnotationArrayArray, count, ALLOC_DEFAULT);
2104     if (annoArrayArray == NULL) {
2105         ALOGW("annotation set ref array alloc failed");
2106         goto bail;
2107     }
2108
2109     for (idx = 0; idx < count; idx++) {
2110         Thread* self = dvmThreadSelf();
2111         const DexAnnotationSetRefItem* pItem;
2112         const DexAnnotationSetItem* pAnnoSet;
2113         Object *annoSet;
2114         DexAnnotationSetItem emptySet;
2115         emptySet.size = 0;
2116
2117         pItem = dexGetParameterAnnotationSetRef(pAnnoSetList, idx);
2118         pAnnoSet = dexGetSetRefItemItem(pDexFile, pItem);
2119         if (pAnnoSet == NULL) {
2120             pAnnoSet = &emptySet;
2121         }
2122
2123         annoSet = (Object *)processAnnotationSet(clazz,
2124                                                  pAnnoSet,
2125                                                  kDexVisibilityRuntime);
2126         if (annoSet == NULL) {
2127             ALOGW("processAnnotationSet failed");
2128             annoArrayArray = NULL;
2129             goto bail;
2130         }
2131         dvmSetObjectArrayElement(annoArrayArray, idx, annoSet);
2132         dvmReleaseTrackedAlloc((Object*) annoSet, self);
2133     }
2134
2135 bail:
2136     return annoArrayArray;
2137 }
2138
2139 /*
2140  * Find the DexAnnotationSetItem for this parameter.
2141  *
2142  * Returns NULL if none found.
2143  */
2144 static const DexParameterAnnotationsItem* findAnnotationsItemForMethod(
2145     const Method* method)
2146 {
2147     ClassObject* clazz = method->clazz;
2148     DexFile* pDexFile;
2149     const DexAnnotationsDirectoryItem* pAnnoDir;
2150     const DexParameterAnnotationsItem* pParameterList;
2151
2152     if (clazz->pDvmDex == NULL)         /* generated class (Proxy, array) */
2153         return NULL;
2154
2155     pDexFile = clazz->pDvmDex->pDexFile;
2156     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
2157     if (pAnnoDir == NULL)
2158         return NULL;
2159
2160     pParameterList = dexGetParameterAnnotations(pDexFile, pAnnoDir);
2161     if (pParameterList == NULL)
2162         return NULL;
2163
2164     /*
2165      * Run through the list and find a matching method.  We compare the
2166      * method ref indices in the annotation list with the method's DEX
2167      * method_idx value.
2168      *
2169      * TODO: use a binary search for long lists
2170      *
2171      * Alternate approach: for each entry in the annotations list,
2172      * find the method definition in the DEX file and perform string
2173      * comparisons on class name, method name, and signature.
2174      */
2175     u4 methodIdx = getMethodIdx(method);
2176     u4 count = dexGetParameterAnnotationsSize(pDexFile, pAnnoDir);
2177     u4 idx;
2178
2179     for (idx = 0; idx < count; idx++) {
2180         if (pParameterList[idx].methodIdx == methodIdx) {
2181             /* found! */
2182             return &pParameterList[idx];
2183         }
2184     }
2185
2186     return NULL;
2187 }
2188
2189
2190 /*
2191  * Count up the number of arguments the method takes.  The "this" pointer
2192  * doesn't count.
2193  */
2194 static int countMethodArguments(const Method* method)
2195 {
2196     /* method->shorty[0] is the return type */
2197     return strlen(method->shorty + 1);
2198 }
2199
2200 /*
2201  * Return an array of arrays of Annotation objects.  The outer array has
2202  * one entry per method parameter, the inner array has the list of annotations
2203  * associated with that parameter.
2204  *
2205  * If the method has no parameters, we return an array of length zero.  If
2206  * the method has one or more parameters, we return an array whose length
2207  * is equal to the number of parameters; if a given parameter does not have
2208  * an annotation, the corresponding entry will be null.
2209  *
2210  * Caller must call dvmReleaseTrackedAlloc().
2211  */
2212 ArrayObject* dvmGetParameterAnnotations(const Method* method)
2213 {
2214     ClassObject* clazz = method->clazz;
2215     const DexParameterAnnotationsItem* pItem;
2216     ArrayObject* annoArrayArray = NULL;
2217
2218     pItem = findAnnotationsItemForMethod(method);
2219     if (pItem != NULL) {
2220         DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2221         const DexAnnotationSetRefList* pAnnoSetList;
2222         u4 size;
2223
2224         size = dexGetParameterAnnotationSetRefSize(pDexFile, pItem);
2225         pAnnoSetList = dexGetParameterAnnotationSetRefList(pDexFile, pItem);
2226         annoArrayArray = processAnnotationSetRefList(clazz, pAnnoSetList, size);
2227     } else {
2228         /* no matching annotations found */
2229         annoArrayArray = emptyAnnoArrayArray(countMethodArguments(method));
2230     }
2231
2232     return annoArrayArray;
2233 }
2234
2235
2236 /*
2237  * ===========================================================================
2238  *      DexEncodedArray interpretation
2239  * ===========================================================================
2240  */
2241
2242 /**
2243  * Initializes an encoded array iterator.
2244  *
2245  * @param iterator iterator to initialize
2246  * @param encodedArray encoded array to iterate over
2247  * @param clazz class to use when resolving strings and types
2248  */
2249 void dvmEncodedArrayIteratorInitialize(EncodedArrayIterator* iterator,
2250         const DexEncodedArray* encodedArray, const ClassObject* clazz) {
2251     iterator->encodedArray = encodedArray;
2252     iterator->cursor = encodedArray->array;
2253     iterator->size = readUleb128(&iterator->cursor);
2254     iterator->elementsLeft = iterator->size;
2255     iterator->clazz = clazz;
2256 }
2257
2258 /**
2259  * Returns whether there are more elements to be read.
2260  */
2261 bool dvmEncodedArrayIteratorHasNext(const EncodedArrayIterator* iterator) {
2262     return (iterator->elementsLeft != 0);
2263 }
2264
2265 /**
2266  * Returns the next decoded value from the iterator, advancing its
2267  * cursor. This returns primitive values in their corresponding union
2268  * slots, and returns everything else (including nulls) as object
2269  * references in the "l" union slot.
2270  *
2271  * The caller must call dvmReleaseTrackedAlloc() on any returned reference.
2272  *
2273  * @param value pointer to store decoded value into
2274  * @returns true if a value was decoded and the cursor advanced; false if
2275  * the last value had already been decoded or if there was a problem decoding
2276  */
2277 bool dvmEncodedArrayIteratorGetNext(EncodedArrayIterator* iterator,
2278         AnnotationValue* value) {
2279     bool processed;
2280
2281     if (iterator->elementsLeft == 0) {
2282         return false;
2283     }
2284
2285     processed = processAnnotationValue(iterator->clazz, &iterator->cursor,
2286             value, kPrimitivesOrObjects);
2287
2288     if (! processed) {
2289         ALOGE("Failed to process array element %d from %p",
2290                 iterator->size - iterator->elementsLeft,
2291                 iterator->encodedArray);
2292         iterator->elementsLeft = 0;
2293         return false;
2294     }
2295
2296     iterator->elementsLeft--;
2297     return true;
2298 }