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