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