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