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