1 /* src/native/vm/reflect.c - helper functions for java/lang/reflect
3 Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 #if defined(ENABLE_ANNOTATIONS)
33 #include "mm/memory.h"
35 #if defined(WITH_CLASSPATH_GNU)
38 #include "native/include/sun_reflect_ConstantPool.h"
42 #include "native/jni.h"
43 #include "native/llni.h"
44 #include "native/native.h"
46 /* keep this order of the native includes */
48 #include "native/include/java_lang_String.h"
50 #if defined(WITH_CLASSPATH_SUN)
51 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
53 #include "native/include/java_lang_ClassLoader.h"
55 #include "native/include/java_lang_Object.h"
56 #include "native/include/java_lang_Class.h"
57 #include "native/include/java_lang_reflect_Constructor.h"
58 #include "native/include/java_lang_reflect_Field.h"
59 #include "native/include/java_lang_reflect_Method.h"
61 #include "native/vm/reflect.h"
63 #include "vm/builtin.h"
64 #include "vm/global.h"
65 #include "vm/stringlocal.h"
67 #include "vmcore/method.h"
70 /* reflect_constructor_new *****************************************************
72 Allocates a new java.lang.reflect.Constructor object and
73 initializes the fields with the method passed.
75 *******************************************************************************/
77 java_lang_reflect_Constructor *reflect_constructor_new(methodinfo *m)
81 java_lang_reflect_Constructor *rc;
84 /* get declaring class */
88 /* allocate a new object */
90 o = builtin_new(class_java_lang_reflect_Constructor);
95 /* initialize instance fields */
97 rc = (java_lang_reflect_Constructor *) o;
99 /* calculate the slot */
101 slot = m - c->methods;
103 #if defined(WITH_CLASSPATH_GNU)
105 LLNI_field_set_cls(rc, clazz , c);
106 LLNI_field_set_val(rc, slot , slot);
107 LLNI_field_set_ref(rc, annotations , method_get_annotations(m));
108 LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
110 #elif defined(WITH_CLASSPATH_SUN)
112 LLNI_field_set_cls(rc, clazz , c);
113 LLNI_field_set_ref(rc, parameterTypes , method_get_parametertypearray(m));
114 LLNI_field_set_ref(rc, exceptionTypes , method_get_exceptionarray(m));
115 LLNI_field_set_val(rc, modifiers , m->flags & ACC_CLASS_REFLECT_MASK);
116 LLNI_field_set_val(rc, slot , slot);
117 LLNI_field_set_ref(rc, signature , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
118 LLNI_field_set_ref(rc, annotations , method_get_annotations(m));
119 LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
122 # error unknown classpath configuration
129 /* reflect_field_new ***********************************************************
131 Allocates a new java.lang.reflect.Field object and initializes the
132 fields with the field passed.
134 *******************************************************************************/
136 java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
140 java_lang_reflect_Field *rf;
143 /* get declaring class */
147 /* allocate a new object */
149 o = builtin_new(class_java_lang_reflect_Field);
154 /* initialize instance fields */
156 rf = (java_lang_reflect_Field *) o;
158 /* calculate the slot */
160 slot = f - c->fields;
162 #if defined(WITH_CLASSPATH_GNU)
164 LLNI_field_set_cls(rf, clazz , c);
166 /* The name needs to be interned */
167 /* XXX implement me better! */
169 LLNI_field_set_ref(rf, name , javastring_intern((java_lang_String *) javastring_new(f->name)));
170 LLNI_field_set_val(rf, slot , slot);
171 LLNI_field_set_ref(rf, annotations , field_get_annotations(f));
173 #elif defined(WITH_CLASSPATH_SUN)
175 LLNI_field_set_cls(rf, clazz , c);
177 /* The name needs to be interned */
178 /* XXX implement me better! */
180 LLNI_field_set_ref(rf, name , javastring_intern((java_lang_String *) javastring_new(f->name)));
181 LLNI_field_set_cls(rf, type , (java_lang_Class *) field_get_type(f));
182 LLNI_field_set_val(rf, modifiers , f->flags);
183 LLNI_field_set_val(rf, slot , slot);
184 LLNI_field_set_ref(rf, signature , f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL);
185 LLNI_field_set_ref(rf, annotations , field_get_annotations(f));
188 # error unknown classpath configuration
195 /* reflect_method_new **********************************************************
197 Allocates a new java.lang.reflect.Method object and initializes the
198 fields with the method passed.
200 *******************************************************************************/
202 java_lang_reflect_Method *reflect_method_new(methodinfo *m)
206 java_lang_reflect_Method *rm;
209 /* get declaring class */
213 /* allocate a new object */
215 o = builtin_new(class_java_lang_reflect_Method);
220 /* initialize instance fields */
222 rm = (java_lang_reflect_Method *) o;
224 /* calculate the slot */
226 slot = m - c->methods;
228 #if defined(WITH_CLASSPATH_GNU)
230 LLNI_field_set_cls(rm, clazz , m->class);
232 /* The name needs to be interned */
233 /* XXX implement me better! */
235 LLNI_field_set_ref(rm, name , javastring_intern((java_lang_String *) javastring_new(m->name)));
236 LLNI_field_set_val(rm, slot , slot);
237 LLNI_field_set_ref(rm, annotations , method_get_annotations(m));
238 LLNI_field_set_ref(rm, parameterAnnotations, method_get_parameterannotations(m));
239 LLNI_field_set_ref(rm, annotationDefault , method_get_annotationdefault(m));
241 #elif defined(WITH_CLASSPATH_SUN)
243 LLNI_field_set_cls(rm, clazz , m->class);
245 /* The name needs to be interned */
246 /* XXX implement me better! */
248 LLNI_field_set_ref(rm, name , javastring_intern((java_lang_String *) javastring_new(m->name)));
249 LLNI_field_set_ref(rm, parameterTypes , method_get_parametertypearray(m));
250 LLNI_field_set_cls(rm, returnType , (java_lang_Class *) method_returntype_get(m));
251 LLNI_field_set_ref(rm, exceptionTypes , method_get_exceptionarray(m));
252 LLNI_field_set_val(rm, modifiers , m->flags & ACC_CLASS_REFLECT_MASK);
253 LLNI_field_set_val(rm, slot , slot);
254 LLNI_field_set_ref(rm, signature , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
255 LLNI_field_set_ref(rm, annotations , method_get_annotations(m));
256 LLNI_field_set_ref(rm, parameterAnnotations, method_get_parameterannotations(m));
257 LLNI_field_set_ref(rm, annotationDefault , method_get_annotationdefault(m));
260 # error unknown classpath configuration
267 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
268 /* reflect_get_declaredannotatios *********************************************
270 Returns a java.util.Map<Class<? extends Annotation>, Annotation>
271 of the declared annotations.
273 *******************************************************************************/
275 struct java_util_Map* reflect_get_declaredannotatios(
276 java_handle_bytearray_t *annotations,
277 java_lang_Class *declaringClass,
280 static methodinfo *m_parseAnnotations = NULL;
281 utf *utf_parseAnnotations = NULL;
282 utf *utf_desc = NULL;
283 sun_reflect_ConstantPool *constantPool = NULL;
284 java_lang_Object *constantPoolOop = (java_lang_Object*)declaringClass;
287 (sun_reflect_ConstantPool*)native_new_and_init(
288 class_sun_reflect_ConstantPool);
290 if(constantPool == NULL) {
295 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
297 /* only resolve the method the first time */
298 if (m_parseAnnotations == NULL) {
299 utf_parseAnnotations = utf_new_char("parseAnnotations");
300 utf_desc = utf_new_char(
301 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
304 if (utf_parseAnnotations == NULL || utf_desc == NULL) {
309 m_parseAnnotations = class_resolveclassmethod(
310 class_sun_reflect_annotation_AnnotationParser,
311 utf_parseAnnotations,
316 if (m_parseAnnotations == NULL) {
317 /* method not found */
322 return (struct java_util_Map*)vm_call_method(
323 m_parseAnnotations, NULL, annotations,
324 constantPool, declaringClass);
328 /* reflect_get_parameterannotations *******************************************
330 Parses and returns the parameter annotations of a method.
332 *******************************************************************************/
334 java_handle_objectarray_t* reflect_get_parameterannotations(
335 java_handle_t *parameterAnnotations,
337 java_lang_Class *declaringClass,
340 /* This method in java would be basically the following.
341 * We don't do it in java because we don't want to make a
342 * public method with wich you can get a ConstantPool, because
343 * with that you could read any kind of constants (even private
346 * ConstantPool constPool = new ConstantPool();
347 * constPool.constantPoolOop = getDeclaringClass();
348 * return sun.reflect.AnnotationParser.parseParameterAnnotations(
349 * parameterAnnotations,
351 * getDeclaringClass(),
352 * getParameterTypes().length);
354 static methodinfo *m_parseParameterAnnotations = NULL;
355 utf *utf_parseParameterAnnotations = NULL;
356 utf *utf_desc = NULL;
357 sun_reflect_ConstantPool *constantPool = NULL;
358 java_lang_Object *constantPoolOop = (java_lang_Object*)declaringClass;
360 methodinfo *m = NULL;
361 int32_t numParameters = -1;
363 /* get parameter count */
365 c = LLNI_classinfo_unwrap(declaringClass);
366 m = &(c->methods[slot]);
368 numParameters = method_get_parametercount(m);
370 if (numParameters < 0) {
371 /* error parsing descriptor */
375 /* get ConstantPool */
378 (sun_reflect_ConstantPool*)native_new_and_init(
379 class_sun_reflect_ConstantPool);
381 if(constantPool == NULL) {
386 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
388 /* only resolve the method the first time */
389 if (m_parseParameterAnnotations == NULL) {
390 utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
391 utf_desc = utf_new_char(
392 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)"
393 "[[Ljava/lang/annotation/Annotation;");
395 if (utf_parseParameterAnnotations == NULL || utf_desc == NULL) {
400 /* get parser method */
402 m_parseParameterAnnotations = class_resolveclassmethod(
403 class_sun_reflect_annotation_AnnotationParser,
404 utf_parseParameterAnnotations,
409 if (m_parseParameterAnnotations == NULL)
411 /* method not found */
416 return (java_handle_objectarray_t*)vm_call_method(
417 m_parseParameterAnnotations, NULL, parameterAnnotations,
418 constantPool, declaringClass, numParameters);
424 * These are local overrides for various environment variables in Emacs.
425 * Please do not remove this and leave it at the end of the file, where
426 * Emacs will automagically detect them.
427 * ---------------------------------------------------------------------
430 * indent-tabs-mode: t
434 * vim:noexpandtab:sw=4:ts=4: