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/jni.h"
31 #include "native/llni.h"
32 #include "native/native.h"
34 #if defined(ENABLE_ANNOTATIONS) && defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
38 #include "native/vm/reflection.hpp"
40 #include "vm/access.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.hpp"
43 #include "vm/global.h"
44 #include "vm/initialize.h"
45 #include "vm/string.hpp"
47 #include "vmcore/globals.hpp"
48 #include "vmcore/javaobjects.hpp"
49 #include "vmcore/method.h"
53 * Invoke a method on the given object with the given arguments.
55 * For instance methods OBJ must be != NULL and the method is looked up
56 * in the vftbl of the object.
58 * For static methods, OBJ is ignored.
60 java_handle_t* Reflection::invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
71 argcount = m->parseddesc->paramcount;
72 paramcount = argcount;
74 /* If method is non-static, remove the `this' pointer. */
76 if (!(m->flags & ACC_STATIC))
79 /* For instance methods the object has to be an instance of the
80 class the method belongs to. For static methods the obj
81 parameter is ignored. */
83 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->clazz))) {
84 exceptions_throw_illegalargumentexception();
88 /* check if we got the right number of arguments */
90 if (((params == NULL) && (paramcount != 0)) ||
91 (params && (LLNI_array_size(params) != paramcount)))
93 exceptions_throw_illegalargumentexception();
97 /* for instance methods we need an object */
99 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
100 /* XXX not sure if that is the correct exception */
101 exceptions_throw_nullpointerexception();
105 /* for static methods, zero object to make subsequent code simpler */
106 if (m->flags & ACC_STATIC)
110 /* for instance methods we must do a vftbl lookup */
111 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
114 /* for static methods, just for convenience */
118 ro = vm_call_method_objectarray(resm, o, params);
124 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
125 /* reflect_get_declaredannotations *********************************************
127 Calls the annotation parser with the unparsed annotations and returnes
128 the parsed annotations as a map.
131 annotations........the unparsed annotations
132 declaringClass.....the class in which the annotated element is declared
133 referer............the calling class (for the 'referer' parameter of
137 The parsed annotations as a
138 java.util.Map<Class<? extends Annotation>, Annotation>.
140 *******************************************************************************/
142 java_handle_t* Reflection::get_declaredannotations(java_handle_bytearray_t *annotations, classinfo* declaringClass, classinfo *referer)
144 static methodinfo* m_parseAnnotations = NULL;
146 java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
151 sun_reflect_ConstantPool cp(h);
152 cp.set_constantPoolOop(declaringClass);
154 /* only resolve the parser method the first time */
155 if (m_parseAnnotations == NULL) {
156 // FIXME Use globals.
157 utf* utf_parseAnnotations = utf_new_char("parseAnnotations");
158 utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/util/Map;");
160 if (utf_parseAnnotations == NULL || utf_desc == NULL)
163 m_parseAnnotations = class_resolveclassmethod(
164 class_sun_reflect_annotation_AnnotationParser,
165 utf_parseAnnotations,
170 if (m_parseAnnotations == NULL)
174 return (java_handle_t*) vm_call_method(m_parseAnnotations, NULL, annotations, cp.get_handle(), declaringClass);
178 /* reflect_get_parameterannotations *******************************************
180 Calls the annotation parser with the unparsed parameter annotations of
181 a method and returnes the parsed parameter annotations in a 2 dimensional
185 parameterAnnotations....the unparsed parameter annotations
186 slot....................the slot of the method
187 declaringClass..........the class in which the annotated element is
189 referer.................the calling class (for the 'referer' parameter
193 The parsed parameter annotations in a 2 dimensional array.
195 *******************************************************************************/
197 java_handle_objectarray_t* Reflection::get_parameterannotations(java_handle_bytearray_t* parameterAnnotations, methodinfo* m, classinfo* referer)
199 /* This method in java would be basically the following.
200 * We don't do it in java because we don't want to make a
201 * public method with wich you can get a ConstantPool, because
202 * with that you could read any kind of constants (even private
205 * ConstantPool constPool = new ConstantPool();
206 * constPool.constantPoolOop = method.getDeclaringClass();
207 * return sun.reflect.AnnotationParser.parseParameterAnnotations(
208 * parameterAnnotations,
210 * method.getDeclaringClass(),
211 * method.getParameterTypes().length);
214 static methodinfo* m_parseParameterAnnotations = NULL;
216 /* get parameter count */
218 int32_t numParameters = method_get_parametercount(m);
220 if (numParameters < 0)
223 /* get ConstantPool */
225 java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
230 sun_reflect_ConstantPool cp(h);
231 cp.set_constantPoolOop(m->clazz);
233 /* only resolve the parser method the first time */
234 if (m_parseParameterAnnotations == NULL) {
235 utf* utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
236 utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;");
238 if (utf_parseParameterAnnotations == NULL || utf_desc == NULL)
241 /* get parser method */
243 m_parseParameterAnnotations = class_resolveclassmethod(
244 class_sun_reflect_annotation_AnnotationParser,
245 utf_parseParameterAnnotations,
250 if (m_parseParameterAnnotations == NULL)
254 return (java_handle_objectarray_t*) vm_call_method(m_parseParameterAnnotations, NULL, parameterAnnotations, cp.get_handle(), m->clazz, numParameters);
260 * These are local overrides for various environment variables in Emacs.
261 * Please do not remove this and leave it at the end of the file, where
262 * Emacs will automagically detect them.
263 * ---------------------------------------------------------------------
266 * indent-tabs-mode: t
270 * vim:noexpandtab:sw=4:ts=4: