1 /* src/native/vm/reflection.cpp - helper functions for java/lang/reflect
3 Copyright (C) 1996-2011
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.hpp"
40 #include "vm/array.hpp"
41 #include "vm/jit/builtin.hpp"
42 #include "vm/exceptions.hpp"
43 #include "vm/global.h"
44 #include "vm/globals.hpp"
45 #include "vm/initialize.hpp"
46 #include "vm/javaobjects.hpp"
47 #include "vm/method.hpp"
48 #include "vm/string.hpp"
52 * Invoke a method on the given object with the given arguments.
54 * For instance methods OBJ must be != NULL and the method is looked up
55 * in the vftbl of the object.
57 * For static methods, OBJ is ignored.
59 java_handle_t* Reflection::invoke(methodinfo *m, java_handle_t *o, java_handle_objectarray_t *params)
70 argcount = m->parseddesc->paramcount;
71 paramcount = argcount;
73 /* If method is non-static, remove the `this' pointer. */
75 if (!(m->flags & ACC_STATIC))
78 /* For instance methods the object has to be an instance of the
79 class the method belongs to. For static methods the obj
80 parameter is ignored. */
82 if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->clazz))) {
83 exceptions_throw_illegalargumentexception();
87 /* check if we got the right number of arguments */
89 ObjectArray oa(params);
91 if (((params == NULL) && (paramcount != 0)) ||
92 (params && (oa.get_length() != paramcount)))
94 exceptions_throw_illegalargumentexception();
98 /* for instance methods we need an object */
100 if (!(m->flags & ACC_STATIC) && (o == NULL)) {
101 /* XXX not sure if that is the correct exception */
102 exceptions_throw_nullpointerexception();
106 /* for static methods, zero object to make subsequent code simpler */
107 if (m->flags & ACC_STATIC)
111 /* for instance methods we must do a vftbl lookup */
112 resm = method_vftbl_lookup(LLNI_vftbl_direct(o), m);
115 /* for static methods, just for convenience */
119 ro = vm_call_method_objectarray(resm, o, params);
125 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH) && defined(ENABLE_ANNOTATIONS)
126 /* reflect_get_declaredannotations *********************************************
128 Calls the annotation parser with the unparsed annotations and returnes
129 the parsed annotations as a map.
132 annotations........the unparsed annotations
133 declaringClass.....the class in which the annotated element is declared
134 referer............the calling class (for the 'referer' parameter of
138 The parsed annotations as a
139 java.util.Map<Class<? extends Annotation>, Annotation>.
141 *******************************************************************************/
143 java_handle_t* Reflection::get_declaredannotations(java_handle_bytearray_t *annotations, classinfo* declaringClass, classinfo *referer)
145 static methodinfo* m_parseAnnotations = NULL;
147 java_handle_t* h = native_new_and_init(class_sun_reflect_ConstantPool);
152 sun_reflect_ConstantPool cp(h);
153 cp.set_constantPoolOop(declaringClass);
155 /* only resolve the parser method the first time */
156 if (m_parseAnnotations == NULL) {
157 // FIXME Use globals.
158 utf* utf_parseAnnotations = utf_new_char("parseAnnotations");
159 utf* utf_desc = utf_new_char("([BLsun/reflect/ConstantPool;Ljava/lang/Class;)Ljava/util/Map;");
161 if (utf_parseAnnotations == NULL || utf_desc == NULL)
164 m_parseAnnotations = class_resolveclassmethod(
165 class_sun_reflect_annotation_AnnotationParser,
166 utf_parseAnnotations,
171 if (m_parseAnnotations == NULL)
175 return (java_handle_t*) vm_call_method(m_parseAnnotations, NULL, annotations, cp.get_handle(), declaringClass);
179 /* reflect_get_parameterannotations *******************************************
181 Calls the annotation parser with the unparsed parameter annotations of
182 a method and returnes the parsed parameter annotations in a 2 dimensional
186 parameterAnnotations....the unparsed parameter annotations
187 slot....................the slot of the method
188 declaringClass..........the class in which the annotated element is
190 referer.................the calling class (for the 'referer' parameter
194 The parsed parameter annotations in a 2 dimensional array.
196 *******************************************************************************/
198 java_handle_objectarray_t* Reflection::get_parameterannotations(java_handle_bytearray_t* parameterAnnotations, methodinfo* m, classinfo* referer)
200 /* This method in java would be basically the following.
201 * We don't do it in java because we don't want to make a
202 * public method with wich you can get a ConstantPool, because
203 * with that you could read any kind of constants (even private
206 * ConstantPool constPool = new ConstantPool();
207 * constPool.constantPoolOop = method.getDeclaringClass();
208 * return sun.reflect.AnnotationParser.parseParameterAnnotations(
209 * parameterAnnotations,
211 * method.getDeclaringClass(),
212 * method.getParameterTypes().length);
215 static methodinfo* m_parseParameterAnnotations = NULL;
217 /* get parameter count */
219 int32_t numParameters = method_get_parametercount(m);
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: