1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/*
17 * Basic reflection calls and utility functions.
18 */
19#ifndef DALVIK_REFLECT_REFLECT_H_
20#define DALVIK_REFLECT_REFLECT_H_
21
22/*
23 * During startup, validate the "box" classes, e.g. java/lang/Integer.
24 */
25bool dvmValidateBoxClasses();
26
27/*
28 * Get all fields declared by a class.
29 *
30 * Includes both class and instance fields.
31 */
32ArrayObject* dvmGetDeclaredFields(ClassObject* clazz, bool publicOnly);
33
34/*
35 * Get the named field.
36 */
37Object* dvmGetDeclaredField(ClassObject* clazz, StringObject* nameObj);
38
39/*
40 * Get all constructors declared by a class.
41 */
42ArrayObject* dvmGetDeclaredConstructors(ClassObject* clazz, bool publicOnly);
43
44/*
45 * Get all methods declared by a class.
46 *
47 * This includes both static and virtual methods, and can include private
48 * members if "publicOnly" is false.  It does not include Miranda methods,
49 * since those weren't declared in the class, or constructors.
50 */
51ArrayObject* dvmGetDeclaredMethods(ClassObject* clazz, bool publicOnly);
52
53/*
54 * Get the named method.
55 */
56Object* dvmGetDeclaredConstructorOrMethod(ClassObject* clazz,
57    StringObject* nameObj, ArrayObject* args);
58
59/*
60 * Get all interfaces a class implements. If this is unable to allocate
61 * the result array, this raises an OutOfMemoryError and returns NULL.
62 */
63ArrayObject* dvmGetInterfaces(ClassObject* clazz);
64
65/*
66 * Convert slot numbers back to objects.
67 */
68Field* dvmSlotToField(ClassObject* clazz, int slot);
69Method* dvmSlotToMethod(ClassObject* clazz, int slot);
70
71/*
72 * Convert a primitive value, performing a widening conversion if necessary.
73 */
74int dvmConvertPrimitiveValue(PrimitiveType srcType,
75    PrimitiveType dstType, const s4* srcPtr, s4* dstPtr);
76
77/*
78 * Convert the argument to the specified type.
79 *
80 * Returns the width of the argument (1 for most types, 2 for J/D, -1 on
81 * error).
82 */
83int dvmConvertArgument(DataObject* arg, ClassObject* type, s4* ins);
84
85/*
86 * Box a primitive value into an object.  If "returnType" is
87 * not primitive, this just returns "value" cast to an object.
88 */
89DataObject* dvmBoxPrimitive(JValue value, ClassObject* returnType);
90
91/*
92 * Unwrap a boxed primitive.  If "returnType" is not primitive, this just
93 * returns "value" cast into a JValue.
94 */
95bool dvmUnboxPrimitive(Object* value, ClassObject* returnType,
96    JValue* pResult);
97
98/*
99 * Return the class object that matches the method's signature.  For
100 * primitive types, returns the box class.
101 */
102ClassObject* dvmGetBoxedReturnType(const Method* meth);
103
104/*
105 * JNI reflection support.
106 */
107Field* dvmGetFieldFromReflectObj(Object* obj);
108Method* dvmGetMethodFromReflectObj(Object* obj);
109Object* dvmCreateReflectObjForField(const ClassObject* clazz, Field* field);
110Object* dvmCreateReflectObjForMethod(const ClassObject* clazz, Method* method);
111
112/*
113 * Quick test to determine if the method in question is a reflection call.
114 * Used for some stack parsing.  Currently defined as "the method's declaring
115 * class is java.lang.reflect.Method".
116 */
117INLINE bool dvmIsReflectionMethod(const Method* method)
118{
119    return (method->clazz == gDvm.classJavaLangReflectMethod);
120}
121
122/*
123 * Proxy class generation.
124 */
125ClassObject* dvmGenerateProxyClass(StringObject* str, ArrayObject* interfaces,
126    Object* loader);
127
128/*
129 * Create a new java.lang.reflect.Method object based on "meth".
130 */
131Object* dvmCreateReflectMethodObject(const Method* meth);
132
133/*
134 * Return an array of Annotation objects for the specified piece.  For method
135 * parameters this is an array of arrays of Annotation objects.
136 *
137 * Method also applies to Constructor.
138 */
139ArrayObject* dvmGetClassAnnotations(const ClassObject* clazz);
140ArrayObject* dvmGetMethodAnnotations(const Method* method);
141ArrayObject* dvmGetFieldAnnotations(const Field* field);
142ArrayObject* dvmGetParameterAnnotations(const Method* method);
143
144/*
145 * Return the annotation if it exists.
146 */
147Object* dvmGetClassAnnotation(const ClassObject* clazz, const ClassObject* annotationClazz);
148Object* dvmGetMethodAnnotation(const ClassObject* clazz, const Method* method,
149        const ClassObject* annotationClazz);
150Object* dvmGetFieldAnnotation(const ClassObject* clazz, const Field* method,
151        const ClassObject* annotationClazz);
152
153/*
154 * Return true if the annotation exists.
155 */
156bool dvmIsClassAnnotationPresent(const ClassObject* clazz, const ClassObject* annotationClazz);
157bool dvmIsMethodAnnotationPresent(const ClassObject* clazz, const Method* method,
158        const ClassObject* annotationClazz);
159bool dvmIsFieldAnnotationPresent(const ClassObject* clazz, const Field* method,
160        const ClassObject* annotationClazz);
161
162/*
163 * Find the default value for an annotation member.
164 */
165Object* dvmGetAnnotationDefaultValue(const Method* method);
166
167/*
168 * Get the list of thrown exceptions for a method.  Returns NULL if there
169 * are no exceptions listed.
170 */
171ArrayObject* dvmGetMethodThrows(const Method* method);
172
173/*
174 * Get the Signature annotation.
175 */
176ArrayObject* dvmGetClassSignatureAnnotation(const ClassObject* clazz);
177ArrayObject* dvmGetMethodSignatureAnnotation(const Method* method);
178ArrayObject* dvmGetFieldSignatureAnnotation(const Field* field);
179
180/*
181 * Get the EnclosingMethod attribute from an annotation.  Returns a Method
182 * object, or NULL.
183 */
184Object* dvmGetEnclosingMethod(const ClassObject* clazz);
185
186/*
187 * Return clazz's declaring class, or NULL if there isn't one.
188 */
189ClassObject* dvmGetDeclaringClass(const ClassObject* clazz);
190
191/*
192 * Return clazz's enclosing class, or NULL if there isn't one.
193 */
194ClassObject* dvmGetEnclosingClass(const ClassObject* clazz);
195
196/*
197 * Get the EnclosingClass attribute from an annotation.  If found, returns
198 * "true".  A String with the original name of the class and the original
199 * access flags are returned through the arguments.  (The name will be NULL
200 * for an anonymous inner class.)
201 */
202bool dvmGetInnerClass(const ClassObject* clazz, StringObject** pName,
203    int* pAccessFlags);
204
205/*
206 * Get an array of class objects from the MemberClasses annotation.  Returns
207 * NULL if none found.
208 */
209ArrayObject* dvmGetDeclaredClasses(const ClassObject* clazz);
210
211/*
212 * Used to pass values out of annotation (and encoded array) processing
213 * functions.
214 */
215struct AnnotationValue {
216    JValue  value;
217    u1      type;
218};
219
220
221/**
222 * Iterator structure for iterating over DexEncodedArray instances. The
223 * structure should be treated as opaque.
224 */
225struct EncodedArrayIterator {
226    const u1* cursor;                    /* current cursor */
227    u4 elementsLeft;                     /* number of elements left to read */
228    const DexEncodedArray* encodedArray; /* instance being iterated over */
229    u4 size;                             /* number of elements in instance */
230    const ClassObject* clazz;            /* class to resolve with respect to */
231};
232
233/**
234 * Initializes an encoded array iterator.
235 *
236 * @param iterator iterator to initialize
237 * @param encodedArray encoded array to iterate over
238 * @param clazz class to use when resolving strings and types
239 */
240void dvmEncodedArrayIteratorInitialize(EncodedArrayIterator* iterator,
241        const DexEncodedArray* encodedArray, const ClassObject* clazz);
242
243/**
244 * Returns whether there are more elements to be read.
245 */
246bool dvmEncodedArrayIteratorHasNext(const EncodedArrayIterator* iterator);
247
248/**
249 * Returns the next decoded value from the iterator, advancing its
250 * cursor. This returns primitive values in their corresponding union
251 * slots, and returns everything else (including nulls) as object
252 * references in the "l" union slot.
253 *
254 * The caller must call dvmReleaseTrackedAlloc() on any returned reference.
255 *
256 * @param value pointer to store decoded value into
257 * @returns true if a value was decoded and the cursor advanced; false if
258 * the last value had already been decoded or if there was a problem decoding
259 */
260bool dvmEncodedArrayIteratorGetNext(EncodedArrayIterator* iterator,
261        AnnotationValue* value);
262
263#endif  // DALVIK_REFLECT_REFLECT_H_
264