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