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