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