1 /* src/native/vm/reflection.cpp - helper functions for java/lang/reflect
3 Copyright (C) 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 #include "native/llni.h"
31 #include "native/native.hpp"
33 #if defined(ENABLE_ANNOTATIONS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
37 #include "native/vm/reflection.hpp"
39 #include "vm/access.h"
40 #include "vm/jit/builtin.hpp"
41 #include "vm/exceptions.hpp"
42 #include "vm/global.h"
43 #include "vm/globals.hpp"
44 #include "vm/initialize.hpp"
45 #include "vm/javaobjects.hpp"
46 #include "vm/method.hpp"
47 #include "vm/string.hpp"
51 * Invoke a method on the given object with the given arguments.
53 * For instance methods OBJ must be != NULL and the method is looked up
54 * in the vftbl of the object.
56 * For static methods, OBJ is ignored.
58 java_handle_t* Reflection::invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
69 argcount = m->parseddesc->paramcount;
70 paramcount = argcount;
72 /* If method is non-static, remove the `this' pointer. */
74 if (!(m->flags & ACC_STATIC))
77 /* For instance methods the object has to be an instance of the
78 class the method belongs to. For static methods the obj
79 parameter is ignored. */
81 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->clazz))) {
82 exceptions_throw_illegalargumentexception();
86 /* check if we got the right number of arguments */
88 if (((params == NULL) && (paramcount != 0)) ||
89 (params && (LLNI_array_size(params) != paramcount)))
91 exceptions_throw_illegalargumentexception();
95 /* for instance methods we need an object */
97 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
98 /* XXX not sure if that is the correct exception */
99 exceptions_throw_nullpointerexception();
103 /* for static methods, zero object to make subsequent code simpler */
104 if (m->flags & ACC_STATIC)
108 /* for instance methods we must do a vftbl lookup */
109 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
112 /* for static methods, just for convenience */
116 ro = vm_call_method_objectarray(resm, o, params);
122 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
123 /* reflect_get_declaredannotations *********************************************
125 Calls the annotation parser with the unparsed annotations and returnes
126 the parsed annotations as a map.
129 annotations........the unparsed annotations
130 declaringClass.....the class in which the annotated element is declared
131 referer............the calling class (for the 'referer' parameter of
135 The parsed annotations as a
136 java.util.Map<Class<? extends Annotation>, Annotation>.
138 *******************************************************************************/
140 java_handle_t* Reflection::get_declaredannotations(java_handle_bytearray_t *annotations, classinfo* declaringClass, classinfo *referer)
142 static methodinfo* m_parseAnnotations = NULL;
144 java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
149 sun_reflect_ConstantPool cp(h);
150 cp.set_constantPoolOop(declaringClass);
152 /* only resolve the parser method the first time */
153 if (m_parseAnnotations == NULL) {
154 // FIXME Use globals.
155 utf* utf_parseAnnotations = utf_new_char("parseAnnotations");
156 utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/util/Map;");
158 if (utf_parseAnnotations == NULL || utf_desc == NULL)
161 m_parseAnnotations = class_resolveclassmethod(
162 class_sun_reflect_annotation_AnnotationParser,
163 utf_parseAnnotations,
168 if (m_parseAnnotations == NULL)
172 return (java_handle_t*) vm_call_method(m_parseAnnotations, NULL, annotations, cp.get_handle(), declaringClass);
176 /* reflect_get_parameterannotations *******************************************
178 Calls the annotation parser with the unparsed parameter annotations of
179 a method and returnes the parsed parameter annotations in a 2 dimensional
183 parameterAnnotations....the unparsed parameter annotations
184 slot....................the slot of the method
185 declaringClass..........the class in which the annotated element is
187 referer.................the calling class (for the 'referer' parameter
191 The parsed parameter annotations in a 2 dimensional array.
193 *******************************************************************************/
195 java_handle_objectarray_t* Reflection::get_parameterannotations(java_handle_bytearray_t* parameterAnnotations, methodinfo* m, classinfo* referer)
197 /* This method in java would be basically the following.
198 * We don't do it in java because we don't want to make a
199 * public method with wich you can get a ConstantPool, because
200 * with that you could read any kind of constants (even private
203 * ConstantPool constPool = new ConstantPool();
204 * constPool.constantPoolOop = method.getDeclaringClass();
205 * return sun.reflect.AnnotationParser.parseParameterAnnotations(
206 * parameterAnnotations,
208 * method.getDeclaringClass(),
209 * method.getParameterTypes().length);
212 static methodinfo* m_parseParameterAnnotations = NULL;
214 /* get parameter count */
216 int32_t numParameters = method_get_parametercount(m);
218 if (numParameters < 0)
221 /* get ConstantPool */
223 java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
228 sun_reflect_ConstantPool cp(h);
229 cp.set_constantPoolOop(m->clazz);
231 /* only resolve the parser method the first time */
232 if (m_parseParameterAnnotations == NULL) {
233 utf* utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
234 utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;");
236 if (utf_parseParameterAnnotations == NULL || utf_desc == NULL)
239 /* get parser method */
241 m_parseParameterAnnotations = class_resolveclassmethod(
242 class_sun_reflect_annotation_AnnotationParser,
243 utf_parseParameterAnnotations,
248 if (m_parseParameterAnnotations == NULL)
252 return (java_handle_objectarray_t*) vm_call_method(m_parseParameterAnnotations, NULL, parameterAnnotations, cp.get_handle(), m->clazz, numParameters);
258 * These are local overrides for various environment variables in Emacs.
259 * Please do not remove this and leave it at the end of the file, where
260 * Emacs will automagically detect them.
261 * ---------------------------------------------------------------------
264 * indent-tabs-mode: t
268 * vim:noexpandtab:sw=4:ts=4: