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