OSDN Git Service

am 0c9185fa: Reconcile with jb-mr0-release
[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             return NULL;
762         }
763     }
764
765     ALOGV("----- processEnc ptr=%p [0x%06x]  typeIdx=%d size=%d class=%s",
766         *pPtr, *pPtr - (u1*) clazz->pDvmDex->pDexFile->baseAddr,
767         typeIdx, size, annoClass->descriptor);
768
769     /*
770      * Elements are parsed out and stored in an array.  The Harmony
771      * constructor wants an array with just the declared elements --
772      * default values get merged in later.
773      */
774     JValue result;
775
776     if (size > 0) {
777         elementArray = dvmAllocArrayByClass(
778             gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMemberArray,
779             size, ALLOC_DEFAULT);
780         if (elementArray == NULL) {
781             ALOGE("failed to allocate annotation member array (%d elements)",
782                 size);
783             goto bail;
784         }
785     }
786
787     /*
788      * "ptr" points to a byte stream with "size" occurrences of
789      * annotation_element.
790      */
791     for (count = 0; count < size; count++) {
792         Object* newMember = createAnnotationMember(clazz, annoClass, &ptr);
793         if (newMember == NULL)
794             goto bail;
795
796         /* add it to the array */
797         dvmSetObjectArrayElement(elementArray, count, newMember);
798     }
799
800     dvmCallMethod(self,
801         gDvm.methOrgApacheHarmonyLangAnnotationAnnotationFactory_createAnnotation,
802         NULL, &result, annoClass, elementArray);
803     if (dvmCheckException(self)) {
804         ALOGD("Failed creating an annotation");
805         //dvmLogExceptionStackTrace();
806         goto bail;
807     }
808
809     newAnno = (Object*)result.l;
810
811 bail:
812     dvmReleaseTrackedAlloc((Object*) elementArray, NULL);
813     *pPtr = ptr;
814     if (newAnno == NULL && !dvmCheckException(self)) {
815         /* make sure an exception is raised */
816         dvmThrowRuntimeException("failure in processEncodedAnnotation");
817     }
818     return newAnno;
819 }
820
821 /*
822  * Run through an annotation set and convert each entry into an Annotation
823  * object.
824  *
825  * Returns an array of Annotation objects, or NULL with an exception raised
826  * on alloc failure.
827  */
828 static ArrayObject* processAnnotationSet(const ClassObject* clazz,
829     const DexAnnotationSetItem* pAnnoSet, int visibility)
830 {
831     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
832     const DexAnnotationItem* pAnnoItem;
833     ArrayObject* annoArray;
834     int i, count;
835     u4 dstIndex;
836
837     /* we need these later; make sure they're initialized */
838     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory))
839         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory);
840     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember))
841         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember);
842
843     /* count up the number of visible elements */
844     for (i = count = 0; i < (int) pAnnoSet->size; i++) {
845         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
846         if (pAnnoItem->visibility == visibility)
847             count++;
848     }
849
850     annoArray =
851         dvmAllocArrayByClass(gDvm.classJavaLangAnnotationAnnotationArray,
852                              count, ALLOC_DEFAULT);
853     if (annoArray == NULL)
854         return NULL;
855
856     /*
857      * Generate Annotation objects.  We must put them into the array
858      * immediately (or add them to the tracked ref table).
859      */
860     dstIndex = 0;
861     for (i = 0; i < (int) pAnnoSet->size; i++) {
862         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
863         if (pAnnoItem->visibility != visibility)
864             continue;
865         const u1* ptr = pAnnoItem->annotation;
866         Object *anno = processEncodedAnnotation(clazz, &ptr);
867         if (anno == NULL) {
868             dvmReleaseTrackedAlloc((Object*) annoArray, NULL);
869             return NULL;
870         }
871         dvmSetObjectArrayElement(annoArray, dstIndex, anno);
872         ++dstIndex;
873     }
874
875     return annoArray;
876 }
877
878 /*
879  * Return the annotation item of the specified type in the annotation set, or
880  * NULL if the set contains no annotation of that type.
881  */
882 static const DexAnnotationItem* getAnnotationItemFromAnnotationSet(
883         const ClassObject* clazz, const DexAnnotationSetItem* pAnnoSet,
884         int visibility, const ClassObject* annotationClazz)
885 {
886     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
887     const DexAnnotationItem* pAnnoItem;
888     int i;
889     const ClassObject* annoClass;
890     const u1* ptr;
891     u4 typeIdx;
892
893     /* we need these later; make sure they're initialized */
894     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory))
895         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationFactory);
896     if (!dvmIsClassInitialized(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember))
897         dvmInitClass(gDvm.classOrgApacheHarmonyLangAnnotationAnnotationMember);
898
899     for (i = 0; i < (int) pAnnoSet->size; i++) {
900         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
901         if (pAnnoItem->visibility != visibility)
902             continue;
903
904         ptr = pAnnoItem->annotation;
905         typeIdx = readUleb128(&ptr);
906
907         annoClass = dvmDexGetResolvedClass(clazz->pDvmDex, typeIdx);
908         if (annoClass == NULL) {
909             annoClass = dvmResolveClass(clazz, typeIdx, true);
910             if (annoClass == NULL) {
911                 return NULL; // an exception is pending
912             }
913         }
914
915         if (annoClass == annotationClazz) {
916             return pAnnoItem;
917         }
918     }
919
920     return NULL;
921 }
922
923 /*
924  * Return the Annotation object of the specified type in the annotation set, or
925  * NULL if the set contains no annotation of that type.
926  */
927 static Object* getAnnotationObjectFromAnnotationSet(const ClassObject* clazz,
928         const DexAnnotationSetItem* pAnnoSet, int visibility,
929         const ClassObject* annotationClazz)
930 {
931     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
932             clazz, pAnnoSet, visibility, annotationClazz);
933     if (pAnnoItem == NULL) {
934         return NULL;
935     }
936     const u1* ptr = pAnnoItem->annotation;
937     return processEncodedAnnotation(clazz, &ptr);
938 }
939
940 /*
941  * ===========================================================================
942  *      Skipping and scanning
943  * ===========================================================================
944  */
945
946 /*
947  * Skip past an annotation value.
948  *
949  * "clazz" is the class on which the annotations are defined.
950  *
951  * Returns "true" on success, "false" on parsing failure.
952  */
953 static bool skipAnnotationValue(const ClassObject* clazz, const u1** pPtr)
954 {
955     const u1* ptr = *pPtr;
956     u1 valueType, valueArg;
957     int width;
958
959     valueType = *ptr++;
960     valueArg = valueType >> kDexAnnotationValueArgShift;
961     width = valueArg + 1;       /* assume */
962
963     ALOGV("----- type is 0x%02x %d, ptr=%p [0x%06x]",
964         valueType & kDexAnnotationValueTypeMask, valueArg, ptr-1,
965         (ptr-1) - (u1*)clazz->pDvmDex->pDexFile->baseAddr);
966
967     switch (valueType & kDexAnnotationValueTypeMask) {
968     case kDexAnnotationByte:        break;
969     case kDexAnnotationShort:       break;
970     case kDexAnnotationChar:        break;
971     case kDexAnnotationInt:         break;
972     case kDexAnnotationLong:        break;
973     case kDexAnnotationFloat:       break;
974     case kDexAnnotationDouble:      break;
975     case kDexAnnotationString:      break;
976     case kDexAnnotationType:        break;
977     case kDexAnnotationMethod:      break;
978     case kDexAnnotationField:       break;
979     case kDexAnnotationEnum:        break;
980
981     case kDexAnnotationArray:
982         /* encoded_array format */
983         {
984             u4 size = readUleb128(&ptr);
985             while (size--) {
986                 if (!skipAnnotationValue(clazz, &ptr))
987                     return false;
988             }
989         }
990         width = 0;
991         break;
992     case kDexAnnotationAnnotation:
993         /* encoded_annotation format */
994         if (!skipEncodedAnnotation(clazz, &ptr))
995             return false;
996         width = 0;
997         break;
998     case kDexAnnotationBoolean:
999     case kDexAnnotationNull:
1000         width = 0;
1001         break;
1002     default:
1003         ALOGE("Bad annotation element value byte 0x%02x", valueType);
1004         assert(false);
1005         return false;
1006     }
1007
1008     ptr += width;
1009
1010     *pPtr = ptr;
1011     return true;
1012 }
1013
1014 /*
1015  * Skip past an encoded annotation.  Mainly useful for annotations embedded
1016  * in other annotations.
1017  */
1018 static bool skipEncodedAnnotation(const ClassObject* clazz, const u1** pPtr)
1019 {
1020     const u1* ptr;
1021     u4 size;
1022
1023     ptr = *pPtr;
1024     (void) readUleb128(&ptr);
1025     size = readUleb128(&ptr);
1026
1027     /*
1028      * "ptr" points to a byte stream with "size" occurrences of
1029      * annotation_element.
1030      */
1031     while (size--) {
1032         (void) readUleb128(&ptr);
1033
1034         if (!skipAnnotationValue(clazz, &ptr))
1035             return false;
1036     }
1037
1038     *pPtr = ptr;
1039     return true;
1040 }
1041
1042
1043 /*
1044  * Compare the name of the class in the DEX file to the supplied descriptor.
1045  * Return value is equivalent to strcmp.
1046  */
1047 static int compareClassDescriptor(DexFile* pDexFile, u4 typeIdx,
1048     const char* descriptor)
1049 {
1050     const char* str = dexStringByTypeIdx(pDexFile, typeIdx);
1051
1052     return strcmp(str, descriptor);
1053 }
1054
1055 /*
1056  * Search through the annotation set for an annotation with a matching
1057  * descriptor.
1058  *
1059  * Comparing the string descriptor is slower than comparing an integer class
1060  * index.  If annotation lists are expected to be long, we could look up
1061  * the class' index by name from the DEX file, rather than doing a class
1062  * lookup and string compare on each entry.  (Note the index will be
1063  * different for each DEX file, so we can't cache annotation class indices
1064  * globally.)
1065  */
1066 static const DexAnnotationItem* searchAnnotationSet(const ClassObject* clazz,
1067     const DexAnnotationSetItem* pAnnoSet, const char* descriptor,
1068     int visibility)
1069 {
1070     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1071     const DexAnnotationItem* result = NULL;
1072     u4 typeIdx;
1073     int i;
1074
1075     //printf("##### searchAnnotationSet %s %d\n", descriptor, visibility);
1076
1077     for (i = 0; i < (int) pAnnoSet->size; i++) {
1078         const DexAnnotationItem* pAnnoItem;
1079
1080         pAnnoItem = dexGetAnnotationItem(pDexFile, pAnnoSet, i);
1081         if (pAnnoItem->visibility != visibility)
1082             continue;
1083         const u1* ptr = pAnnoItem->annotation;
1084         typeIdx = readUleb128(&ptr);
1085
1086         if (compareClassDescriptor(pDexFile, typeIdx, descriptor) == 0) {
1087             //printf("#####  match on %x/%p at %d\n", typeIdx, pDexFile, i);
1088             result = pAnnoItem;
1089             break;
1090         }
1091     }
1092
1093     return result;
1094 }
1095
1096 /*
1097  * Find an annotation value in the annotation_item whose name matches "name".
1098  * A pointer to the annotation_value is returned, or NULL if it's not found.
1099  */
1100 static const u1* searchEncodedAnnotation(const ClassObject* clazz,
1101     const u1* ptr, const char* name)
1102 {
1103     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1104     u4 typeIdx, size;
1105
1106     typeIdx = readUleb128(&ptr);
1107     size = readUleb128(&ptr);
1108     //printf("#####   searching ptr=%p type=%u size=%u\n", ptr, typeIdx, size);
1109
1110     while (size--) {
1111         u4 elementNameIdx;
1112         const char* elemName;
1113
1114         elementNameIdx = readUleb128(&ptr);
1115         elemName = dexStringById(pDexFile, elementNameIdx);
1116         if (strcmp(name, elemName) == 0) {
1117             //printf("#####   item match on %s\n", name);
1118             return ptr;     /* points to start of value */
1119         }
1120
1121         skipAnnotationValue(clazz, &ptr);
1122     }
1123
1124     //printf("#####   no item match on %s\n", name);
1125     return NULL;
1126 }
1127
1128 #define GAV_FAILED  ((Object*) 0x10000001)
1129
1130 /*
1131  * Extract an encoded annotation value from the field specified by "annoName".
1132  *
1133  * "expectedType" is an annotation value type, e.g. kDexAnnotationString.
1134  * "debugAnnoName" is only used in debug messages.
1135  *
1136  * Returns GAV_FAILED on failure.  If an allocation failed, an exception
1137  * will be raised.
1138  */
1139 static Object* getAnnotationValue(const ClassObject* clazz,
1140     const DexAnnotationItem* pAnnoItem, const char* annoName,
1141     int expectedType, const char* debugAnnoName)
1142 {
1143     const u1* ptr;
1144     AnnotationValue avalue;
1145
1146     /* find the annotation */
1147     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, annoName);
1148     if (ptr == NULL) {
1149         ALOGW("%s annotation lacks '%s' member", debugAnnoName, annoName);
1150         return GAV_FAILED;
1151     }
1152
1153     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects))
1154         return GAV_FAILED;
1155
1156     /* make sure it has the expected format */
1157     if (avalue.type != expectedType) {
1158         ALOGW("%s %s has wrong type (0x%02x, expected 0x%02x)",
1159             debugAnnoName, annoName, avalue.type, expectedType);
1160         return GAV_FAILED;
1161     }
1162
1163     return (Object*)avalue.value.l;
1164 }
1165
1166
1167 /*
1168  * Find the Signature attribute and extract its value.  (Signatures can
1169  * be found in annotations on classes, constructors, methods, and fields.)
1170  *
1171  * Caller must call dvmReleaseTrackedAlloc().
1172  *
1173  * Returns NULL if not found.  On memory alloc failure, returns NULL with an
1174  * exception raised.
1175  */
1176 static ArrayObject* getSignatureValue(const ClassObject* clazz,
1177     const DexAnnotationSetItem* pAnnoSet)
1178 {
1179     const DexAnnotationItem* pAnnoItem;
1180     Object* obj;
1181
1182     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrSignature,
1183         kDexVisibilitySystem);
1184     if (pAnnoItem == NULL)
1185         return NULL;
1186
1187     /*
1188      * The Signature annotation has one member, "String value".
1189      */
1190     obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationArray,
1191             "Signature");
1192     if (obj == GAV_FAILED)
1193         return NULL;
1194     assert(obj->clazz == gDvm.classJavaLangObjectArray);
1195
1196     return (ArrayObject*)obj;
1197 }
1198
1199
1200 /*
1201  * ===========================================================================
1202  *      Class
1203  * ===========================================================================
1204  */
1205
1206 /*
1207  * Find the DexAnnotationSetItem for this class.
1208  */
1209 static const DexAnnotationSetItem* findAnnotationSetForClass(
1210     const ClassObject* clazz)
1211 {
1212     DexFile* pDexFile;
1213     const DexAnnotationsDirectoryItem* pAnnoDir;
1214
1215     if (clazz->pDvmDex == NULL)         /* generated class (Proxy, array) */
1216         return NULL;
1217
1218     pDexFile = clazz->pDvmDex->pDexFile;
1219     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1220     if (pAnnoDir != NULL)
1221         return dexGetClassAnnotationSet(pDexFile, pAnnoDir);
1222     else
1223         return NULL;
1224 }
1225
1226 /*
1227  * Return an array of Annotation objects for the class.  Returns an empty
1228  * array if there are no annotations.
1229  *
1230  * Caller must call dvmReleaseTrackedAlloc().
1231  *
1232  * On allocation failure, this returns NULL with an exception raised.
1233  */
1234 ArrayObject* dvmGetClassAnnotations(const ClassObject* clazz)
1235 {
1236     ArrayObject* annoArray;
1237     const DexAnnotationSetItem* pAnnoSet = NULL;
1238
1239     pAnnoSet = findAnnotationSetForClass(clazz);
1240     if (pAnnoSet == NULL) {
1241         /* no annotations for anything in class, or no class annotations */
1242         annoArray = emptyAnnoArray();
1243     } else {
1244         annoArray = processAnnotationSet(clazz, pAnnoSet,
1245                         kDexVisibilityRuntime);
1246     }
1247
1248     return annoArray;
1249 }
1250
1251 /*
1252  * Returns the annotation or NULL if it doesn't exist.
1253  */
1254 Object* dvmGetClassAnnotation(const ClassObject* clazz,
1255         const ClassObject* annotationClazz)
1256 {
1257     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForClass(clazz);
1258     if (pAnnoSet == NULL) {
1259         return NULL;
1260     }
1261     return getAnnotationObjectFromAnnotationSet(clazz, pAnnoSet,
1262             kDexVisibilityRuntime, annotationClazz);
1263 }
1264
1265 /*
1266  * Returns true if the annotation exists.
1267  */
1268 bool dvmIsClassAnnotationPresent(const ClassObject* clazz,
1269         const ClassObject* annotationClazz)
1270 {
1271     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForClass(clazz);
1272     if (pAnnoSet == NULL) {
1273         return NULL;
1274     }
1275     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
1276             clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
1277     return (pAnnoItem != NULL);
1278 }
1279
1280 /*
1281  * Retrieve the Signature annotation, if any.  Returns NULL if no signature
1282  * exists.
1283  *
1284  * Caller must call dvmReleaseTrackedAlloc().
1285  */
1286 ArrayObject* dvmGetClassSignatureAnnotation(const ClassObject* clazz)
1287 {
1288     ArrayObject* signature = NULL;
1289     const DexAnnotationSetItem* pAnnoSet;
1290
1291     pAnnoSet = findAnnotationSetForClass(clazz);
1292     if (pAnnoSet != NULL)
1293         signature = getSignatureValue(clazz, pAnnoSet);
1294
1295     return signature;
1296 }
1297
1298 /*
1299  * Get the EnclosingMethod attribute from an annotation.  Returns a Method
1300  * object, or NULL.
1301  *
1302  * Caller must call dvmReleaseTrackedAlloc().
1303  */
1304 Object* dvmGetEnclosingMethod(const ClassObject* clazz)
1305 {
1306     const DexAnnotationItem* pAnnoItem;
1307     const DexAnnotationSetItem* pAnnoSet;
1308     Object* obj;
1309
1310     pAnnoSet = findAnnotationSetForClass(clazz);
1311     if (pAnnoSet == NULL)
1312         return NULL;
1313
1314     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingMethod,
1315         kDexVisibilitySystem);
1316     if (pAnnoItem == NULL)
1317         return NULL;
1318
1319     /*
1320      * The EnclosingMethod annotation has one member, "Method value".
1321      */
1322     obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationMethod,
1323             "EnclosingMethod");
1324     if (obj == GAV_FAILED)
1325         return NULL;
1326     assert(obj->clazz == gDvm.classJavaLangReflectConstructor ||
1327            obj->clazz == gDvm.classJavaLangReflectMethod);
1328
1329     return obj;
1330 }
1331
1332 /*
1333  * Find a class' enclosing class.  We return what we find in the
1334  * EnclosingClass attribute.
1335  *
1336  * Returns a Class object, or NULL.
1337  *
1338  * Caller must call dvmReleaseTrackedAlloc().
1339  */
1340 ClassObject* dvmGetDeclaringClass(const ClassObject* clazz)
1341 {
1342     const DexAnnotationItem* pAnnoItem;
1343     const DexAnnotationSetItem* pAnnoSet;
1344     Object* obj;
1345
1346     pAnnoSet = findAnnotationSetForClass(clazz);
1347     if (pAnnoSet == NULL)
1348         return NULL;
1349
1350     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingClass,
1351         kDexVisibilitySystem);
1352     if (pAnnoItem == NULL)
1353         return NULL;
1354
1355     /*
1356      * The EnclosingClass annotation has one member, "Class value".
1357      */
1358     obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationType,
1359             "EnclosingClass");
1360     if (obj == GAV_FAILED)
1361         return NULL;
1362
1363     assert(dvmIsClassObject(obj));
1364     return (ClassObject*)obj;
1365 }
1366
1367 /*
1368  * Find a class' enclosing class.  We first search for an EnclosingClass
1369  * attribute, and if that's not found we look for an EnclosingMethod.
1370  *
1371  * Returns a Class object, or NULL.
1372  *
1373  * Caller must call dvmReleaseTrackedAlloc().
1374  */
1375 ClassObject* dvmGetEnclosingClass(const ClassObject* clazz)
1376 {
1377     const DexAnnotationItem* pAnnoItem;
1378     const DexAnnotationSetItem* pAnnoSet;
1379     Object* obj;
1380
1381     pAnnoSet = findAnnotationSetForClass(clazz);
1382     if (pAnnoSet == NULL)
1383         return NULL;
1384
1385     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingClass,
1386         kDexVisibilitySystem);
1387     if (pAnnoItem != NULL) {
1388         /*
1389          * The EnclosingClass annotation has one member, "Class value".
1390          */
1391         obj = getAnnotationValue(clazz, pAnnoItem, "value", kDexAnnotationType,
1392                 "EnclosingClass");
1393         if (obj != GAV_FAILED) {
1394             assert(dvmIsClassObject(obj));
1395             return (ClassObject*)obj;
1396         }
1397     }
1398
1399     /*
1400      * That didn't work.  Look for an EnclosingMethod.
1401      *
1402      * We could create a java.lang.reflect.Method object and extract the
1403      * declaringClass from it, but that's more work than we want to do.
1404      * Instead, we find the "value" item and parse the index out ourselves.
1405      */
1406     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrEnclosingMethod,
1407         kDexVisibilitySystem);
1408     if (pAnnoItem == NULL)
1409         return NULL;
1410
1411     /* find the value member */
1412     const u1* ptr;
1413     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "value");
1414     if (ptr == NULL) {
1415         ALOGW("EnclosingMethod annotation lacks 'value' member");
1416         return NULL;
1417     }
1418
1419     /* parse it, verify the type */
1420     AnnotationValue avalue;
1421     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllRaw)) {
1422         ALOGW("EnclosingMethod parse failed");
1423         return NULL;
1424     }
1425     if (avalue.type != kDexAnnotationMethod) {
1426         ALOGW("EnclosingMethod value has wrong type (0x%02x, expected 0x%02x)",
1427             avalue.type, kDexAnnotationMethod);
1428         return NULL;
1429     }
1430
1431     /* pull out the method index and resolve the method */
1432     Method* meth = resolveAmbiguousMethod(clazz, avalue.value.i);
1433     if (meth == NULL)
1434         return NULL;
1435
1436     ClassObject* methClazz = meth->clazz;
1437     dvmAddTrackedAlloc((Object*) methClazz, NULL);      // balance the Release
1438     return methClazz;
1439 }
1440
1441 /*
1442  * Get the EnclosingClass attribute from an annotation.  If found, returns
1443  * "true".  A String with the original name of the class and the original
1444  * access flags are returned through the arguments.  (The name will be NULL
1445  * for an anonymous inner class.)
1446  *
1447  * Caller must call dvmReleaseTrackedAlloc().
1448  */
1449 bool dvmGetInnerClass(const ClassObject* clazz, StringObject** pName,
1450     int* pAccessFlags)
1451 {
1452     const DexAnnotationItem* pAnnoItem;
1453     const DexAnnotationSetItem* pAnnoSet;
1454
1455     pAnnoSet = findAnnotationSetForClass(clazz);
1456     if (pAnnoSet == NULL)
1457         return false;
1458
1459     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrInnerClass,
1460         kDexVisibilitySystem);
1461     if (pAnnoItem == NULL)
1462         return false;
1463
1464     /*
1465      * The InnerClass annotation has two members, "String name" and
1466      * "int accessFlags".  We don't want to get the access flags as an
1467      * Integer, so we process that as a simple value.
1468      */
1469     const u1* ptr;
1470     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "name");
1471     if (ptr == NULL) {
1472         ALOGW("InnerClass annotation lacks 'name' member");
1473         return false;
1474     }
1475
1476     /* parse it into an Object */
1477     AnnotationValue avalue;
1478     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) {
1479         ALOGD("processAnnotationValue failed on InnerClass member 'name'");
1480         return false;
1481     }
1482
1483     /* make sure it has the expected format */
1484     if (avalue.type != kDexAnnotationNull &&
1485         avalue.type != kDexAnnotationString)
1486     {
1487         ALOGW("InnerClass name has bad type (0x%02x, expected STRING or NULL)",
1488             avalue.type);
1489         return false;
1490     }
1491
1492     *pName = (StringObject*) avalue.value.l;
1493     assert(*pName == NULL || (*pName)->clazz == gDvm.classJavaLangString);
1494
1495     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "accessFlags");
1496     if (ptr == NULL) {
1497         ALOGW("InnerClass annotation lacks 'accessFlags' member");
1498         return false;
1499     }
1500
1501     /* parse it, verify the type */
1502     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllRaw)) {
1503         ALOGW("InnerClass accessFlags parse failed");
1504         return false;
1505     }
1506     if (avalue.type != kDexAnnotationInt) {
1507         ALOGW("InnerClass value has wrong type (0x%02x, expected 0x%02x)",
1508             avalue.type, kDexAnnotationInt);
1509         return false;
1510     }
1511
1512     *pAccessFlags = avalue.value.i;
1513
1514     return true;
1515 }
1516
1517 /*
1518  * Extract an array of Class objects from the MemberClasses annotation
1519  * for this class.
1520  *
1521  * Caller must call dvmReleaseTrackedAlloc().
1522  *
1523  * Returns NULL if we don't find any member classes.
1524  */
1525 ArrayObject* dvmGetDeclaredClasses(const ClassObject* clazz)
1526 {
1527     const DexAnnotationSetItem* pAnnoSet;
1528     const DexAnnotationItem* pAnnoItem;
1529     Object* obj;
1530
1531     pAnnoSet = findAnnotationSetForClass(clazz);
1532     if (pAnnoSet == NULL)
1533         return NULL;
1534
1535     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrMemberClasses,
1536         kDexVisibilitySystem);
1537     if (pAnnoItem == NULL)
1538         return NULL;
1539
1540     /*
1541      * The MemberClasses annotation has one member, "Class[] value".
1542      */
1543     obj = getAnnotationValue(clazz, pAnnoItem, "value",
1544             kDexAnnotationArray, "MemberClasses");
1545     if (obj == GAV_FAILED)
1546         return NULL;
1547     assert(dvmIsArray((ArrayObject*)obj));
1548     obj = convertReturnType(obj, gDvm.classJavaLangClassArray);
1549     return (ArrayObject*)obj;
1550 }
1551
1552
1553 /*
1554  * ===========================================================================
1555  *      Method (and Constructor)
1556  * ===========================================================================
1557  */
1558
1559 /*
1560  * Compare the attributes (class name, method name, method signature) of
1561  * the specified method to "method".
1562  */
1563 static int compareMethodStr(DexFile* pDexFile, u4 methodIdx,
1564     const Method* method)
1565 {
1566     const DexMethodId* pMethodId = dexGetMethodId(pDexFile, methodIdx);
1567     const char* str = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);
1568     int result = strcmp(str, method->clazz->descriptor);
1569
1570     if (result == 0) {
1571         str = dexStringById(pDexFile, pMethodId->nameIdx);
1572         result = strcmp(str, method->name);
1573         if (result == 0) {
1574             DexProto proto;
1575             dexProtoSetFromMethodId(&proto, pDexFile, pMethodId);
1576             result = dexProtoCompare(&proto, &method->prototype);
1577         }
1578     }
1579
1580     return result;
1581 }
1582
1583 /*
1584  * Given a method, determine the method's index.
1585  *
1586  * We could simply store this in the Method*, but that would cost 4 bytes
1587  * per method.  Instead we plow through the DEX data.
1588  *
1589  * We have two choices: look through the class method data, or look through
1590  * the global method_ids table.  The former is awkward because the method
1591  * could have been defined in a superclass or interface.  The latter works
1592  * out reasonably well because it's in sorted order, though we're still left
1593  * doing a fair number of string comparisons.
1594  */
1595 static u4 getMethodIdx(const Method* method)
1596 {
1597     DexFile* pDexFile = method->clazz->pDvmDex->pDexFile;
1598     u4 hi = pDexFile->pHeader->methodIdsSize -1;
1599     u4 lo = 0;
1600     u4 cur;
1601
1602     while (hi >= lo) {
1603         int cmp;
1604         cur = (lo + hi) / 2;
1605
1606         cmp = compareMethodStr(pDexFile, cur, method);
1607         if (cmp < 0) {
1608             lo = cur + 1;
1609         } else if (cmp > 0) {
1610             hi = cur - 1;
1611         } else {
1612             break;
1613         }
1614     }
1615
1616     if (hi < lo) {
1617         /* this should be impossible -- the method came out of this DEX */
1618         char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
1619         ALOGE("Unable to find method %s.%s %s in DEX file!",
1620             method->clazz->descriptor, method->name, desc);
1621         free(desc);
1622         dvmAbort();
1623     }
1624
1625     return cur;
1626 }
1627
1628 /*
1629  * Find the DexAnnotationSetItem for this method.
1630  *
1631  * Returns NULL if none found.
1632  */
1633 static const DexAnnotationSetItem* findAnnotationSetForMethod(
1634     const Method* method)
1635 {
1636     ClassObject* clazz = method->clazz;
1637     DexFile* pDexFile;
1638     const DexAnnotationsDirectoryItem* pAnnoDir;
1639     const DexMethodAnnotationsItem* pMethodList;
1640     const DexAnnotationSetItem* pAnnoSet = NULL;
1641
1642     if (clazz->pDvmDex == NULL)         /* generated class (Proxy, array) */
1643         return NULL;
1644     pDexFile = clazz->pDvmDex->pDexFile;
1645
1646     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1647     if (pAnnoDir != NULL) {
1648         pMethodList = dexGetMethodAnnotations(pDexFile, pAnnoDir);
1649         if (pMethodList != NULL) {
1650             /*
1651              * Run through the list and find a matching method.  We compare the
1652              * method ref indices in the annotation list with the method's DEX
1653              * method_idx value.
1654              *
1655              * TODO: use a binary search for long lists
1656              *
1657              * Alternate approach: for each entry in the annotations list,
1658              * find the method definition in the DEX file and perform string
1659              * comparisons on class name, method name, and signature.
1660              */
1661             u4 methodIdx = getMethodIdx(method);
1662             u4 count = dexGetMethodAnnotationsSize(pDexFile, pAnnoDir);
1663             u4 idx;
1664
1665             for (idx = 0; idx < count; idx++) {
1666                 if (pMethodList[idx].methodIdx == methodIdx) {
1667                     /* found! */
1668                     pAnnoSet = dexGetMethodAnnotationSetItem(pDexFile,
1669                                     &pMethodList[idx]);
1670                     break;
1671                 }
1672             }
1673         }
1674     }
1675
1676     return pAnnoSet;
1677 }
1678
1679 /*
1680  * Return an array of Annotation objects for the method.  Returns an empty
1681  * array if there are no annotations.
1682  *
1683  * Caller must call dvmReleaseTrackedAlloc().
1684  *
1685  * On allocation failure, this returns NULL with an exception raised.
1686  */
1687 ArrayObject* dvmGetMethodAnnotations(const Method* method)
1688 {
1689     ClassObject* clazz = method->clazz;
1690     const DexAnnotationSetItem* pAnnoSet;
1691     ArrayObject* annoArray = NULL;
1692
1693     pAnnoSet = findAnnotationSetForMethod(method);
1694     if (pAnnoSet == NULL) {
1695         /* no matching annotations found */
1696         annoArray = emptyAnnoArray();
1697     } else {
1698         annoArray = processAnnotationSet(clazz, pAnnoSet,kDexVisibilityRuntime);
1699     }
1700
1701     return annoArray;
1702 }
1703
1704 /*
1705  * Returns the annotation or NULL if it doesn't exist.
1706  */
1707 Object* dvmGetMethodAnnotation(const ClassObject* clazz, const Method* method,
1708         const ClassObject* annotationClazz)
1709 {
1710     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForMethod(method);
1711     if (pAnnoSet == NULL) {
1712         return NULL;
1713     }
1714     return getAnnotationObjectFromAnnotationSet(clazz, pAnnoSet,
1715             kDexVisibilityRuntime, annotationClazz);
1716 }
1717
1718 /*
1719  * Returns true if the annotation exists.
1720  */
1721 bool dvmIsMethodAnnotationPresent(const ClassObject* clazz,
1722         const Method* method, const ClassObject* annotationClazz)
1723 {
1724     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForMethod(method);
1725     if (pAnnoSet == NULL) {
1726         return NULL;
1727     }
1728     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
1729             clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
1730     return (pAnnoItem != NULL);
1731 }
1732
1733 /*
1734  * Retrieve the Signature annotation, if any.  Returns NULL if no signature
1735  * exists.
1736  *
1737  * Caller must call dvmReleaseTrackedAlloc().
1738  */
1739 ArrayObject* dvmGetMethodSignatureAnnotation(const Method* method)
1740 {
1741     ClassObject* clazz = method->clazz;
1742     const DexAnnotationSetItem* pAnnoSet;
1743     ArrayObject* signature = NULL;
1744
1745     pAnnoSet = findAnnotationSetForMethod(method);
1746     if (pAnnoSet != NULL)
1747         signature = getSignatureValue(clazz, pAnnoSet);
1748
1749     return signature;
1750 }
1751
1752 /*
1753  * Extract an array of exception classes from the "system" annotation list
1754  * for this method.
1755  *
1756  * Caller must call dvmReleaseTrackedAlloc().
1757  *
1758  * Returns NULL if we don't find any exceptions for this method.
1759  */
1760 ArrayObject* dvmGetMethodThrows(const Method* method)
1761 {
1762     ClassObject* clazz = method->clazz;
1763     const DexAnnotationSetItem* pAnnoSet;
1764     const DexAnnotationItem* pAnnoItem;
1765
1766     /* find the set for this method */
1767     pAnnoSet = findAnnotationSetForMethod(method);
1768     if (pAnnoSet == NULL)
1769         return NULL;        /* nothing for this method */
1770
1771     /* find the "Throws" annotation, if any */
1772     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrThrows,
1773         kDexVisibilitySystem);
1774     if (pAnnoItem == NULL)
1775         return NULL;        /* no Throws */
1776
1777     /*
1778      * The Throws annotation has one member, "Class[] value".
1779      */
1780     Object* obj = getAnnotationValue(clazz, pAnnoItem, "value",
1781         kDexAnnotationArray, "Throws");
1782     if (obj == GAV_FAILED)
1783         return NULL;
1784     assert(dvmIsArray((ArrayObject*)obj));
1785     obj = convertReturnType(obj, gDvm.classJavaLangClassArray);
1786     return (ArrayObject*)obj;
1787 }
1788
1789 /*
1790  * Given an Annotation's method, find the default value, if any.
1791  *
1792  * If this is a CLASS annotation, and we can't find a match for the
1793  * default class value, we need to throw a TypeNotPresentException.
1794  *
1795  * Caller must call dvmReleaseTrackedAlloc().
1796  */
1797 Object* dvmGetAnnotationDefaultValue(const Method* method)
1798 {
1799     const ClassObject* clazz = method->clazz;
1800     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1801     const DexAnnotationsDirectoryItem* pAnnoDir;
1802     const DexAnnotationSetItem* pAnnoSet = NULL;
1803
1804     /*
1805      * The method's declaring class (the annotation) will have an
1806      * AnnotationDefault "system" annotation associated with it if any
1807      * of its methods have default values.  Start by finding the
1808      * DexAnnotationItem associated with the class.
1809      */
1810     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1811     if (pAnnoDir != NULL)
1812         pAnnoSet = dexGetClassAnnotationSet(pDexFile, pAnnoDir);
1813     if (pAnnoSet == NULL) {
1814         /* no annotations for anything in class, or no class annotations */
1815         return NULL;
1816     }
1817
1818     /* find the "AnnotationDefault" annotation, if any */
1819     const DexAnnotationItem* pAnnoItem;
1820     pAnnoItem = searchAnnotationSet(clazz, pAnnoSet, kDescrAnnotationDefault,
1821         kDexVisibilitySystem);
1822     if (pAnnoItem == NULL) {
1823         /* no default values for any member in this annotation */
1824         //printf("##### no default annotations for %s.%s\n",
1825         //    method->clazz->descriptor, method->name);
1826         return NULL;
1827     }
1828
1829     /*
1830      * The AnnotationDefault annotation has one member, "Annotation value".
1831      * We need to pull that out.
1832      */
1833     const u1* ptr;
1834     ptr = searchEncodedAnnotation(clazz, pAnnoItem->annotation, "value");
1835     if (ptr == NULL) {
1836         ALOGW("AnnotationDefault annotation lacks 'value'");
1837         return NULL;
1838     }
1839     if ((*ptr & kDexAnnotationValueTypeMask) != kDexAnnotationAnnotation) {
1840         ALOGW("AnnotationDefault value has wrong type (0x%02x)",
1841             *ptr & kDexAnnotationValueTypeMask);
1842         return NULL;
1843     }
1844
1845     /*
1846      * The value_type byte for VALUE_ANNOTATION is followed by
1847      * encoded_annotation data.  We want to scan through it to find an
1848      * entry whose name matches our method name.
1849      */
1850     ptr++;
1851     ptr = searchEncodedAnnotation(clazz, ptr, method->name);
1852     if (ptr == NULL)
1853         return NULL;        /* no default annotation for this method */
1854
1855     /* got it, pull it out */
1856     AnnotationValue avalue;
1857     if (!processAnnotationValue(clazz, &ptr, &avalue, kAllObjects)) {
1858         ALOGD("processAnnotationValue failed on default for '%s'",
1859             method->name);
1860         return NULL;
1861     }
1862
1863     /* convert the return type, if necessary */
1864     ClassObject* methodReturn = dvmGetBoxedReturnType(method);
1865     Object* obj = (Object*)avalue.value.l;
1866     obj = convertReturnType(obj, methodReturn);
1867
1868     return obj;
1869 }
1870
1871
1872 /*
1873  * ===========================================================================
1874  *      Field
1875  * ===========================================================================
1876  */
1877
1878 /*
1879  * Compare the attributes (class name, field name, field signature) of
1880  * the specified field to "field".
1881  */
1882 static int compareFieldStr(DexFile* pDexFile, u4 idx, const Field* field)
1883 {
1884     const DexFieldId* pFieldId = dexGetFieldId(pDexFile, idx);
1885     const char* str = dexStringByTypeIdx(pDexFile, pFieldId->classIdx);
1886     int result = strcmp(str, field->clazz->descriptor);
1887
1888     if (result == 0) {
1889         str = dexStringById(pDexFile, pFieldId->nameIdx);
1890         result = strcmp(str, field->name);
1891         if (result == 0) {
1892             str = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
1893             result = strcmp(str, field->signature);
1894         }
1895     }
1896
1897     return result;
1898 }
1899
1900 /*
1901  * Given a field, determine the field's index.
1902  *
1903  * This has the same tradeoffs as getMethodIdx.
1904  */
1905 static u4 getFieldIdx(const Field* field)
1906 {
1907     DexFile* pDexFile = field->clazz->pDvmDex->pDexFile;
1908     u4 hi = pDexFile->pHeader->fieldIdsSize -1;
1909     u4 lo = 0;
1910     u4 cur;
1911
1912     while (hi >= lo) {
1913         int cmp;
1914         cur = (lo + hi) / 2;
1915
1916         cmp = compareFieldStr(pDexFile, cur, field);
1917         if (cmp < 0) {
1918             lo = cur + 1;
1919         } else if (cmp > 0) {
1920             hi = cur - 1;
1921         } else {
1922             break;
1923         }
1924     }
1925
1926     if (hi < lo) {
1927         /* this should be impossible -- the field came out of this DEX */
1928         ALOGE("Unable to find field %s.%s %s in DEX file!",
1929             field->clazz->descriptor, field->name, field->signature);
1930         dvmAbort();
1931     }
1932
1933     return cur;
1934 }
1935
1936 /*
1937  * Find the DexAnnotationSetItem for this field.
1938  *
1939  * Returns NULL if none found.
1940  */
1941 static const DexAnnotationSetItem* findAnnotationSetForField(const Field* field)
1942 {
1943     ClassObject* clazz = field->clazz;
1944     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
1945     const DexAnnotationsDirectoryItem* pAnnoDir;
1946     const DexFieldAnnotationsItem* pFieldList;
1947
1948     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
1949     if (pAnnoDir == NULL)
1950         return NULL;
1951
1952     pFieldList = dexGetFieldAnnotations(pDexFile, pAnnoDir);
1953     if (pFieldList == NULL)
1954         return NULL;
1955
1956     /*
1957      * Run through the list and find a matching field.  We compare the
1958      * field ref indices in the annotation list with the field's DEX
1959      * field_idx value.
1960      *
1961      * TODO: use a binary search for long lists
1962      *
1963      * Alternate approach: for each entry in the annotations list,
1964      * find the field definition in the DEX file and perform string
1965      * comparisons on class name, field name, and signature.
1966      */
1967     u4 fieldIdx = getFieldIdx(field);
1968     u4 count = dexGetFieldAnnotationsSize(pDexFile, pAnnoDir);
1969     u4 idx;
1970
1971     for (idx = 0; idx < count; idx++) {
1972         if (pFieldList[idx].fieldIdx == fieldIdx) {
1973             /* found! */
1974             return dexGetFieldAnnotationSetItem(pDexFile, &pFieldList[idx]);
1975         }
1976     }
1977
1978     return NULL;
1979 }
1980
1981 /*
1982  * Return an array of Annotation objects for the field.  Returns an empty
1983  * array if there are no annotations.
1984  *
1985  * Caller must call dvmReleaseTrackedAlloc().
1986  *
1987  * On allocation failure, this returns NULL with an exception raised.
1988  */
1989 ArrayObject* dvmGetFieldAnnotations(const Field* field)
1990 {
1991     ClassObject* clazz = field->clazz;
1992     ArrayObject* annoArray = NULL;
1993     const DexAnnotationSetItem* pAnnoSet = NULL;
1994
1995     pAnnoSet = findAnnotationSetForField(field);
1996     if (pAnnoSet == NULL) {
1997         /* no matching annotations found */
1998         annoArray = emptyAnnoArray();
1999     } else {
2000         annoArray = processAnnotationSet(clazz, pAnnoSet,
2001                         kDexVisibilityRuntime);
2002     }
2003
2004     return annoArray;
2005 }
2006
2007 /*
2008  * Returns the annotation or NULL if it doesn't exist.
2009  */
2010 Object* dvmGetFieldAnnotation(const ClassObject* clazz, const Field* field,
2011         const ClassObject* annotationClazz)
2012 {
2013     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForField(field);
2014     if (pAnnoSet == NULL) {
2015         return NULL;
2016     }
2017     return getAnnotationObjectFromAnnotationSet(clazz, pAnnoSet,
2018             kDexVisibilityRuntime, annotationClazz);
2019 }
2020
2021 /*
2022  * Returns true if the annotation exists.
2023  */
2024 bool dvmIsFieldAnnotationPresent(const ClassObject* clazz,
2025         const Field* field, const ClassObject* annotationClazz)
2026 {
2027     const DexAnnotationSetItem* pAnnoSet = findAnnotationSetForField(field);
2028     if (pAnnoSet == NULL) {
2029         return NULL;
2030     }
2031     const DexAnnotationItem* pAnnoItem = getAnnotationItemFromAnnotationSet(
2032             clazz, pAnnoSet, kDexVisibilityRuntime, annotationClazz);
2033     return (pAnnoItem != NULL);
2034 }
2035
2036 /*
2037  * Retrieve the Signature annotation, if any.  Returns NULL if no signature
2038  * exists.
2039  *
2040  * Caller must call dvmReleaseTrackedAlloc().
2041  */
2042 ArrayObject* dvmGetFieldSignatureAnnotation(const Field* field)
2043 {
2044     ClassObject* clazz = field->clazz;
2045     const DexAnnotationSetItem* pAnnoSet;
2046     ArrayObject* signature = NULL;
2047
2048     pAnnoSet = findAnnotationSetForField(field);
2049     if (pAnnoSet != NULL)
2050         signature = getSignatureValue(clazz, pAnnoSet);
2051
2052     return signature;
2053 }
2054
2055
2056 /*
2057  * ===========================================================================
2058  *      Parameter
2059  * ===========================================================================
2060  */
2061
2062 /*
2063  * We have an annotation_set_ref_list, which is essentially a list of
2064  * entries that we pass to processAnnotationSet().
2065  *
2066  * The returned object must be released with dvmReleaseTrackedAlloc.
2067  */
2068 static ArrayObject* processAnnotationSetRefList(const ClassObject* clazz,
2069     const DexAnnotationSetRefList* pAnnoSetList, u4 count)
2070 {
2071     DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2072     ArrayObject* annoArrayArray = NULL;
2073     u4 idx;
2074
2075     /* allocate an array of Annotation arrays to hold results */
2076     annoArrayArray = dvmAllocArrayByClass(
2077         gDvm.classJavaLangAnnotationAnnotationArrayArray, count, ALLOC_DEFAULT);
2078     if (annoArrayArray == NULL) {
2079         ALOGW("annotation set ref array alloc failed");
2080         goto bail;
2081     }
2082
2083     for (idx = 0; idx < count; idx++) {
2084         Thread* self = dvmThreadSelf();
2085         const DexAnnotationSetRefItem* pItem;
2086         const DexAnnotationSetItem* pAnnoSet;
2087         Object *annoSet;
2088
2089         pItem = dexGetParameterAnnotationSetRef(pAnnoSetList, idx);
2090         pAnnoSet = dexGetSetRefItemItem(pDexFile, pItem);
2091         annoSet = (Object *)processAnnotationSet(clazz,
2092                                                  pAnnoSet,
2093                                                  kDexVisibilityRuntime);
2094         if (annoSet == NULL) {
2095             ALOGW("processAnnotationSet failed");
2096             annoArrayArray = NULL;
2097             goto bail;
2098         }
2099         dvmSetObjectArrayElement(annoArrayArray, idx, annoSet);
2100         dvmReleaseTrackedAlloc((Object*) annoSet, self);
2101     }
2102
2103 bail:
2104     return annoArrayArray;
2105 }
2106
2107 /*
2108  * Find the DexAnnotationSetItem for this parameter.
2109  *
2110  * Returns NULL if none found.
2111  */
2112 static const DexParameterAnnotationsItem* findAnnotationsItemForMethod(
2113     const Method* method)
2114 {
2115     ClassObject* clazz = method->clazz;
2116     DexFile* pDexFile;
2117     const DexAnnotationsDirectoryItem* pAnnoDir;
2118     const DexParameterAnnotationsItem* pParameterList;
2119
2120     if (clazz->pDvmDex == NULL)         /* generated class (Proxy, array) */
2121         return NULL;
2122
2123     pDexFile = clazz->pDvmDex->pDexFile;
2124     pAnnoDir = getAnnoDirectory(pDexFile, clazz);
2125     if (pAnnoDir == NULL)
2126         return NULL;
2127
2128     pParameterList = dexGetParameterAnnotations(pDexFile, pAnnoDir);
2129     if (pParameterList == NULL)
2130         return NULL;
2131
2132     /*
2133      * Run through the list and find a matching method.  We compare the
2134      * method ref indices in the annotation list with the method's DEX
2135      * method_idx value.
2136      *
2137      * TODO: use a binary search for long lists
2138      *
2139      * Alternate approach: for each entry in the annotations list,
2140      * find the method definition in the DEX file and perform string
2141      * comparisons on class name, method name, and signature.
2142      */
2143     u4 methodIdx = getMethodIdx(method);
2144     u4 count = dexGetParameterAnnotationsSize(pDexFile, pAnnoDir);
2145     u4 idx;
2146
2147     for (idx = 0; idx < count; idx++) {
2148         if (pParameterList[idx].methodIdx == methodIdx) {
2149             /* found! */
2150             return &pParameterList[idx];
2151         }
2152     }
2153
2154     return NULL;
2155 }
2156
2157
2158 /*
2159  * Count up the number of arguments the method takes.  The "this" pointer
2160  * doesn't count.
2161  */
2162 static int countMethodArguments(const Method* method)
2163 {
2164     /* method->shorty[0] is the return type */
2165     return strlen(method->shorty + 1);
2166 }
2167
2168 /*
2169  * Return an array of arrays of Annotation objects.  The outer array has
2170  * one entry per method parameter, the inner array has the list of annotations
2171  * associated with that parameter.
2172  *
2173  * If the method has no parameters, we return an array of length zero.  If
2174  * the method has one or more parameters, we return an array whose length
2175  * is equal to the number of parameters; if a given parameter does not have
2176  * an annotation, the corresponding entry will be null.
2177  *
2178  * Caller must call dvmReleaseTrackedAlloc().
2179  */
2180 ArrayObject* dvmGetParameterAnnotations(const Method* method)
2181 {
2182     ClassObject* clazz = method->clazz;
2183     const DexParameterAnnotationsItem* pItem;
2184     ArrayObject* annoArrayArray = NULL;
2185
2186     pItem = findAnnotationsItemForMethod(method);
2187     if (pItem != NULL) {
2188         DexFile* pDexFile = clazz->pDvmDex->pDexFile;
2189         const DexAnnotationSetRefList* pAnnoSetList;
2190         u4 size;
2191
2192         size = dexGetParameterAnnotationSetRefSize(pDexFile, pItem);
2193         pAnnoSetList = dexGetParameterAnnotationSetRefList(pDexFile, pItem);
2194         annoArrayArray = processAnnotationSetRefList(clazz, pAnnoSetList, size);
2195     } else {
2196         /* no matching annotations found */
2197         annoArrayArray = emptyAnnoArrayArray(countMethodArguments(method));
2198     }
2199
2200     return annoArrayArray;
2201 }
2202
2203
2204 /*
2205  * ===========================================================================
2206  *      DexEncodedArray interpretation
2207  * ===========================================================================
2208  */
2209
2210 /**
2211  * Initializes an encoded array iterator.
2212  *
2213  * @param iterator iterator to initialize
2214  * @param encodedArray encoded array to iterate over
2215  * @param clazz class to use when resolving strings and types
2216  */
2217 void dvmEncodedArrayIteratorInitialize(EncodedArrayIterator* iterator,
2218         const DexEncodedArray* encodedArray, const ClassObject* clazz) {
2219     iterator->encodedArray = encodedArray;
2220     iterator->cursor = encodedArray->array;
2221     iterator->size = readUleb128(&iterator->cursor);
2222     iterator->elementsLeft = iterator->size;
2223     iterator->clazz = clazz;
2224 }
2225
2226 /**
2227  * Returns whether there are more elements to be read.
2228  */
2229 bool dvmEncodedArrayIteratorHasNext(const EncodedArrayIterator* iterator) {
2230     return (iterator->elementsLeft != 0);
2231 }
2232
2233 /**
2234  * Returns the next decoded value from the iterator, advancing its
2235  * cursor. This returns primitive values in their corresponding union
2236  * slots, and returns everything else (including nulls) as object
2237  * references in the "l" union slot.
2238  *
2239  * The caller must call dvmReleaseTrackedAlloc() on any returned reference.
2240  *
2241  * @param value pointer to store decoded value into
2242  * @returns true if a value was decoded and the cursor advanced; false if
2243  * the last value had already been decoded or if there was a problem decoding
2244  */
2245 bool dvmEncodedArrayIteratorGetNext(EncodedArrayIterator* iterator,
2246         AnnotationValue* value) {
2247     bool processed;
2248
2249     if (iterator->elementsLeft == 0) {
2250         return false;
2251     }
2252
2253     processed = processAnnotationValue(iterator->clazz, &iterator->cursor,
2254             value, kPrimitivesOrObjects);
2255
2256     if (! processed) {
2257         ALOGE("Failed to process array element %d from %p",
2258                 iterator->size - iterator->elementsLeft,
2259                 iterator->encodedArray);
2260         iterator->elementsLeft = 0;
2261         return false;
2262     }
2263
2264     iterator->elementsLeft--;
2265     return true;
2266 }