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
25 $Id: reflect.c 8318 2007-08-16 10:05:34Z michi $
34 #if defined(ENABLE_ANNOTATIONS)
35 #include "mm/memory.h"
37 #if defined(WITH_CLASSPATH_GNU)
40 #include "native/include/sun_reflect_ConstantPool.h"
44 #include "native/jni.h"
45 #include "native/llni.h"
46 #include "native/native.h"
48 /* keep this order of the native includes */
50 #include "native/include/java_lang_String.h"
52 #if defined(WITH_CLASSPATH_SUN)
53 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
55 #include "native/include/java_lang_ClassLoader.h"
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_Class.h"
59 #include "native/include/java_lang_reflect_Constructor.h"
60 #include "native/include/java_lang_reflect_Field.h"
61 #include "native/include/java_lang_reflect_Method.h"
63 #include "native/vm/java_lang_String.h"
64 #include "native/vm/reflect.h"
66 #include "vm/builtin.h"
67 #include "vm/global.h"
68 #include "vm/stringlocal.h"
70 #include "vmcore/method.h"
73 /* reflect_constructor_new *****************************************************
75 Allocates a new java.lang.reflect.Constructor object and
76 initializes the fields with the method passed.
78 *******************************************************************************/
80 java_lang_reflect_Constructor *reflect_constructor_new(methodinfo *m)
84 java_lang_reflect_Constructor *rc;
86 java_handle_bytearray_t *annotations = NULL;
87 java_handle_bytearray_t *parameterAnnotations = NULL;
89 /* get declaring class */
91 c = (classinfo *) m->class;
93 /* allocate a new object */
95 o = builtin_new(class_java_lang_reflect_Constructor);
100 /* initialize instance fields */
102 rc = (java_lang_reflect_Constructor *) o;
104 /* calculate the slot */
106 slot = m - c->methods;
108 #if defined(ENABLE_ANNOTATIONS)
109 /* get annotations */
111 annotations = method_get_annotations(m);
113 /* get parameter annotations */
115 parameterAnnotations = method_get_parameterannotations(m);
118 #if defined(WITH_CLASSPATH_GNU)
120 LLNI_field_set_cls(rc, clazz , c);
121 LLNI_field_set_val(rc, slot , slot);
122 LLNI_field_set_ref(rc, annotations , annotations);
123 LLNI_field_set_ref(rc, parameterAnnotations, parameterAnnotations);
125 #elif defined(WITH_CLASSPATH_SUN)
127 LLNI_field_set_cls(rc, clazz , c);
128 LLNI_field_set_ref(rc, parameterTypes , method_get_parametertypearray(m));
129 LLNI_field_set_ref(rc, exceptionTypes , method_get_exceptionarray(m));
130 LLNI_field_set_val(rc, modifiers , m->flags & ACC_CLASS_REFLECT_MASK);
131 LLNI_field_set_val(rc, slot , slot);
132 LLNI_field_set_ref(rc, signature , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
133 LLNI_field_set_ref(rc, annotations , annotations);
134 LLNI_field_set_ref(rc, parameterAnnotations, parameterAnnotations);
137 # error unknown classpath configuration
144 /* reflect_field_new ***********************************************************
146 Allocates a new java.lang.reflect.Field object and initializes the
147 fields with the field passed.
149 *******************************************************************************/
151 java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
155 java_lang_reflect_Field *rf;
157 java_handle_bytearray_t *annotations = NULL;
159 /* get declaring class */
161 c = (classinfo *) f->class;
163 /* allocate a new object */
165 o = builtin_new(class_java_lang_reflect_Field);
170 /* initialize instance fields */
172 rf = (java_lang_reflect_Field *) o;
174 /* calculate the slot */
176 slot = f - c->fields;
178 #if defined(ENABLE_ANNOTATIONS)
179 /* get annotations */
181 annotations = field_get_annotations(f);
184 #if defined(WITH_CLASSPATH_GNU)
186 LLNI_field_set_cls(rf, clazz , c);
188 /* The name needs to be interned */
189 /* XXX implement me better! */
191 LLNI_field_set_ref(rf, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name)));
192 LLNI_field_set_val(rf, slot , slot);
193 LLNI_field_set_ref(rf, annotations , annotations);
195 #elif defined(WITH_CLASSPATH_SUN)
197 LLNI_field_set_cls(rf, clazz , c);
199 /* The name needs to be interned */
200 /* XXX implement me better! */
202 LLNI_field_set_ref(rf, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name)));
203 LLNI_field_set_cls(rf, type , (java_lang_Class *) field_get_type(f));
204 LLNI_field_set_val(rf, modifiers , f->flags);
205 LLNI_field_set_val(rf, slot , slot);
206 LLNI_field_set_ref(rf, signature , f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL);
207 LLNI_field_set_ref(rf, annotations , annotations);
210 # error unknown classpath configuration
217 /* reflect_method_new **********************************************************
219 Allocates a new java.lang.reflect.Method object and initializes the
220 fields with the method passed.
222 *******************************************************************************/
224 java_lang_reflect_Method *reflect_method_new(methodinfo *m)
228 java_lang_reflect_Method *rm;
230 java_handle_bytearray_t *annotations = NULL;
231 java_handle_bytearray_t *parameterAnnotations = NULL;
232 java_handle_bytearray_t *annotationDefault = NULL;
234 /* get declaring class */
236 c = (classinfo *) m->class;
238 /* allocate a new object */
240 o = builtin_new(class_java_lang_reflect_Method);
245 /* initialize instance fields */
247 rm = (java_lang_reflect_Method *) o;
249 /* calculate the slot */
251 slot = m - c->methods;
253 #if defined(ENABLE_ANNOTATIONS)
254 /* get annotations */
256 annotations = method_get_annotations(m);
258 /* get parameter annotations */
260 parameterAnnotations = method_get_parameterannotations(m);
262 /* get annotation default value */
264 annotationDefault = method_get_annotationdefault(m);
267 #if defined(WITH_CLASSPATH_GNU)
269 LLNI_field_set_cls(rm, clazz , m->class);
271 /* The name needs to be interned */
272 /* XXX implement me better! */
274 LLNI_field_set_ref(rm, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name)));
275 LLNI_field_set_val(rm, slot , slot);
276 LLNI_field_set_ref(rm, annotations , annotations);
277 LLNI_field_set_ref(rm, parameterAnnotations, parameterAnnotations);
278 LLNI_field_set_ref(rm, annotationDefault , annotationDefault);
280 #elif defined(WITH_CLASSPATH_SUN)
282 LLNI_field_set_cls(rm, clazz , m->class);
284 /* The name needs to be interned */
285 /* XXX implement me better! */
287 LLNI_field_set_ref(rm, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name)));
288 LLNI_field_set_ref(rm, parameterTypes , method_get_parametertypearray(m));
289 LLNI_field_set_cls(rm, returnType , (java_lang_Class *) method_returntype_get(m));
290 LLNI_field_set_ref(rm, exceptionTypes , method_get_exceptionarray(m));
291 LLNI_field_set_val(rm, modifiers , m->flags & ACC_CLASS_REFLECT_MASK);
292 LLNI_field_set_val(rm, slot , slot);
293 LLNI_field_set_ref(rm, signature , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
294 LLNI_field_set_ref(rm, annotations , annotations);
295 LLNI_field_set_ref(rm, parameterAnnotations, parameterAnnotations);
296 LLNI_field_set_ref(rm, annotationDefault , annotationDefault);
299 # error unknown classpath configuration
306 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
307 /* reflect_get_declaredannotatios *********************************************
309 Returns a java.util.Map<Class, Annotation> of the declared
312 *******************************************************************************/
314 struct java_util_Map* reflect_get_declaredannotatios(
315 java_handle_bytearray_t *annotations,
316 java_lang_Class *declaringClass,
319 static methodinfo *m_parseAnnotations = NULL;
320 utf *utf_parseAnnotations = NULL;
321 utf *utf_desc = NULL;
322 sun_reflect_ConstantPool *constantPool = NULL;
323 java_lang_Object *constantPoolOop = (java_lang_Object*)declaringClass;
326 (sun_reflect_ConstantPool*)native_new_and_init(
327 class_sun_reflect_ConstantPool);
329 if(constantPool == NULL) {
334 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
336 /* only resolve the method the first time */
337 if (m_parseAnnotations == NULL) {
338 utf_parseAnnotations = utf_new_char("parseAnnotations");
339 utf_desc = utf_new_char(
340 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
343 if (utf_parseAnnotations == NULL || utf_desc == NULL) {
348 m_parseAnnotations = class_resolveclassmethod(
349 class_sun_reflect_annotation_AnnotationParser,
350 utf_parseAnnotations,
355 if (m_parseAnnotations == NULL) {
356 /* method not found */
361 return (struct java_util_Map*)vm_call_method(
362 m_parseAnnotations, NULL, annotations,
363 constantPool, declaringClass);
367 /* reflect_get_parameterannotations *******************************************
369 Parses and returns the parameter annotations of a method.
371 *******************************************************************************/
373 java_handle_objectarray_t* reflect_get_parameterannotations(
374 java_handle_t *parameterAnnotations,
376 java_lang_Class *declaringClass,
379 /* This method in java would be basically the following.
380 * We don't do it in java because we don't want to make a
381 * public method with wich you can get a ConstantPool, because
382 * with that you could read any kind of constants (even private
385 * ConstantPool constPool = new ConstantPool();
386 * constPool.constantPoolOop = getDeclaringClass();
387 * return sun.reflect.AnnotationParser.parseParameterAnnotations(
388 * parameterAnnotations,
390 * getDeclaringClass(),
391 * getParameterTypes().length);
393 static methodinfo *m_parseParameterAnnotations = NULL;
394 utf *utf_parseParameterAnnotations = NULL;
395 utf *utf_desc = NULL;
396 sun_reflect_ConstantPool *constantPool = NULL;
397 java_lang_Object *constantPoolOop = (java_lang_Object*)declaringClass;
399 methodinfo *m = NULL;
400 int32_t numParameters = -1;
402 /* get parameter count */
404 c = (classinfo *)declaringClass;
405 m = &(c->methods[slot]);
407 numParameters = method_get_parametercount(m);
409 if (numParameters < 0) {
410 /* error parsing descriptor */
414 /* get ConstantPool */
417 (sun_reflect_ConstantPool*)native_new_and_init(
418 class_sun_reflect_ConstantPool);
420 if(constantPool == NULL) {
425 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
427 /* only resolve the method the first time */
428 if (m_parseParameterAnnotations == NULL) {
429 utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
430 utf_desc = utf_new_char(
431 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)"
432 "[[Ljava/lang/annotation/Annotation;");
434 if (utf_parseParameterAnnotations == NULL || utf_desc == NULL) {
439 /* get parser method */
441 m_parseParameterAnnotations = class_resolveclassmethod(
442 class_sun_reflect_annotation_AnnotationParser,
443 utf_parseParameterAnnotations,
448 if (m_parseParameterAnnotations == NULL)
450 /* method not found */
455 return (java_handle_objectarray_t*)vm_call_method(
456 m_parseParameterAnnotations, NULL, parameterAnnotations,
457 constantPool, declaringClass, numParameters);
463 * These are local overrides for various environment variables in Emacs.
464 * Please do not remove this and leave it at the end of the file, where
465 * Emacs will automagically detect them.
466 * ---------------------------------------------------------------------
469 * indent-tabs-mode: t
473 * vim:noexpandtab:sw=4:ts=4: