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