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