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 8341 2007-08-17 21:32:01Z 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;
87 /* get declaring class */
91 /* allocate a new object */
93 o = builtin_new(class_java_lang_reflect_Constructor);
98 /* initialize instance fields */
100 rc = (java_lang_reflect_Constructor *) o;
102 /* calculate the slot */
104 slot = m - c->methods;
106 #if defined(WITH_CLASSPATH_GNU)
108 LLNI_field_set_cls(rc, clazz , c);
109 LLNI_field_set_val(rc, slot , slot);
110 LLNI_field_set_ref(rc, annotations , method_get_annotations(m));
111 LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
113 #elif defined(WITH_CLASSPATH_SUN)
115 LLNI_field_set_cls(rc, clazz , c);
116 LLNI_field_set_ref(rc, parameterTypes , method_get_parametertypearray(m));
117 LLNI_field_set_ref(rc, exceptionTypes , method_get_exceptionarray(m));
118 LLNI_field_set_val(rc, modifiers , m->flags & ACC_CLASS_REFLECT_MASK);
119 LLNI_field_set_val(rc, slot , slot);
120 LLNI_field_set_ref(rc, signature , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
121 LLNI_field_set_ref(rc, annotations , method_get_annotations(m));
122 LLNI_field_set_ref(rc, parameterAnnotations, method_get_parameterannotations(m));
125 # error unknown classpath configuration
132 /* reflect_field_new ***********************************************************
134 Allocates a new java.lang.reflect.Field object and initializes the
135 fields with the field passed.
137 *******************************************************************************/
139 java_lang_reflect_Field *reflect_field_new(fieldinfo *f)
143 java_lang_reflect_Field *rf;
146 /* get declaring class */
150 /* allocate a new object */
152 o = builtin_new(class_java_lang_reflect_Field);
157 /* initialize instance fields */
159 rf = (java_lang_reflect_Field *) o;
161 /* calculate the slot */
163 slot = f - c->fields;
165 #if defined(WITH_CLASSPATH_GNU)
167 LLNI_field_set_cls(rf, clazz , c);
169 /* The name needs to be interned */
170 /* XXX implement me better! */
172 LLNI_field_set_ref(rf, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name)));
173 LLNI_field_set_val(rf, slot , slot);
174 LLNI_field_set_ref(rf, annotations , field_get_annotations(f));
176 #elif defined(WITH_CLASSPATH_SUN)
178 LLNI_field_set_cls(rf, clazz , c);
180 /* The name needs to be interned */
181 /* XXX implement me better! */
183 LLNI_field_set_ref(rf, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(f->name)));
184 LLNI_field_set_cls(rf, type , (java_lang_Class *) field_get_type(f));
185 LLNI_field_set_val(rf, modifiers , f->flags);
186 LLNI_field_set_val(rf, slot , slot);
187 LLNI_field_set_ref(rf, signature , f->signature ? (java_lang_String *) javastring_new(f->signature) : NULL);
188 LLNI_field_set_ref(rf, annotations , field_get_annotations(f));
191 # error unknown classpath configuration
198 /* reflect_method_new **********************************************************
200 Allocates a new java.lang.reflect.Method object and initializes the
201 fields with the method passed.
203 *******************************************************************************/
205 java_lang_reflect_Method *reflect_method_new(methodinfo *m)
209 java_lang_reflect_Method *rm;
212 /* get declaring class */
216 /* allocate a new object */
218 o = builtin_new(class_java_lang_reflect_Method);
223 /* initialize instance fields */
225 rm = (java_lang_reflect_Method *) o;
227 /* calculate the slot */
229 slot = m - c->methods;
231 #if defined(WITH_CLASSPATH_GNU)
233 LLNI_field_set_cls(rm, clazz , m->class);
235 /* The name needs to be interned */
236 /* XXX implement me better! */
238 LLNI_field_set_ref(rm, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name)));
239 LLNI_field_set_val(rm, slot , slot);
240 LLNI_field_set_ref(rm, annotations , method_get_annotations(m));
241 LLNI_field_set_ref(rm, parameterAnnotations, method_get_parameterannotations(m));
242 LLNI_field_set_ref(rm, annotationDefault , method_get_annotationdefault(m));
244 #elif defined(WITH_CLASSPATH_SUN)
246 LLNI_field_set_cls(rm, clazz , m->class);
248 /* The name needs to be interned */
249 /* XXX implement me better! */
251 LLNI_field_set_ref(rm, name , _Jv_java_lang_String_intern((java_lang_String *) javastring_new(m->name)));
252 LLNI_field_set_ref(rm, parameterTypes , method_get_parametertypearray(m));
253 LLNI_field_set_cls(rm, returnType , (java_lang_Class *) method_returntype_get(m));
254 LLNI_field_set_ref(rm, exceptionTypes , method_get_exceptionarray(m));
255 LLNI_field_set_val(rm, modifiers , m->flags & ACC_CLASS_REFLECT_MASK);
256 LLNI_field_set_val(rm, slot , slot);
257 LLNI_field_set_ref(rm, signature , m->signature ? (java_lang_String *) javastring_new(m->signature) : NULL);
258 LLNI_field_set_ref(rm, annotations , method_get_annotations(m));
259 LLNI_field_set_ref(rm, parameterAnnotations, method_get_parameterannotations(m));
260 LLNI_field_set_ref(rm, annotationDefault , method_get_annotationdefault(m));
263 # error unknown classpath configuration
270 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
271 /* reflect_get_declaredannotatios *********************************************
273 Returns a java.util.Map<Class, Annotation> of the declared
276 *******************************************************************************/
278 struct java_util_Map* reflect_get_declaredannotatios(
279 java_handle_bytearray_t *annotations,
280 java_lang_Class *declaringClass,
283 static methodinfo *m_parseAnnotations = NULL;
284 utf *utf_parseAnnotations = NULL;
285 utf *utf_desc = NULL;
286 sun_reflect_ConstantPool *constantPool = NULL;
287 java_lang_Object *constantPoolOop = (java_lang_Object*)declaringClass;
290 (sun_reflect_ConstantPool*)native_new_and_init(
291 class_sun_reflect_ConstantPool);
293 if(constantPool == NULL) {
298 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
300 /* only resolve the method the first time */
301 if (m_parseAnnotations == NULL) {
302 utf_parseAnnotations = utf_new_char("parseAnnotations");
303 utf_desc = utf_new_char(
304 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
307 if (utf_parseAnnotations == NULL || utf_desc == NULL) {
312 m_parseAnnotations = class_resolveclassmethod(
313 class_sun_reflect_annotation_AnnotationParser,
314 utf_parseAnnotations,
319 if (m_parseAnnotations == NULL) {
320 /* method not found */
325 return (struct java_util_Map*)vm_call_method(
326 m_parseAnnotations, NULL, annotations,
327 constantPool, declaringClass);
331 /* reflect_get_parameterannotations *******************************************
333 Parses and returns the parameter annotations of a method.
335 *******************************************************************************/
337 java_handle_objectarray_t* reflect_get_parameterannotations(
338 java_handle_t *parameterAnnotations,
340 java_lang_Class *declaringClass,
343 /* This method in java would be basically the following.
344 * We don't do it in java because we don't want to make a
345 * public method with wich you can get a ConstantPool, because
346 * with that you could read any kind of constants (even private
349 * ConstantPool constPool = new ConstantPool();
350 * constPool.constantPoolOop = getDeclaringClass();
351 * return sun.reflect.AnnotationParser.parseParameterAnnotations(
352 * parameterAnnotations,
354 * getDeclaringClass(),
355 * getParameterTypes().length);
357 static methodinfo *m_parseParameterAnnotations = NULL;
358 utf *utf_parseParameterAnnotations = NULL;
359 utf *utf_desc = NULL;
360 sun_reflect_ConstantPool *constantPool = NULL;
361 java_lang_Object *constantPoolOop = (java_lang_Object*)declaringClass;
363 methodinfo *m = NULL;
364 int32_t numParameters = -1;
366 /* get parameter count */
368 c = LLNI_classinfo_unwrap(declaringClass);
369 m = &(c->methods[slot]);
371 numParameters = method_get_parametercount(m);
373 if (numParameters < 0) {
374 /* error parsing descriptor */
378 /* get ConstantPool */
381 (sun_reflect_ConstantPool*)native_new_and_init(
382 class_sun_reflect_ConstantPool);
384 if(constantPool == NULL) {
389 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
391 /* only resolve the method the first time */
392 if (m_parseParameterAnnotations == NULL) {
393 utf_parseParameterAnnotations = utf_new_char("parseParameterAnnotations");
394 utf_desc = utf_new_char(
395 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;I)"
396 "[[Ljava/lang/annotation/Annotation;");
398 if (utf_parseParameterAnnotations == NULL || utf_desc == NULL) {
403 /* get parser method */
405 m_parseParameterAnnotations = class_resolveclassmethod(
406 class_sun_reflect_annotation_AnnotationParser,
407 utf_parseParameterAnnotations,
412 if (m_parseParameterAnnotations == NULL)
414 /* method not found */
419 return (java_handle_objectarray_t*)vm_call_method(
420 m_parseParameterAnnotations, NULL, parameterAnnotations,
421 constantPool, declaringClass, numParameters);
427 * These are local overrides for various environment variables in Emacs.
428 * Please do not remove this and leave it at the end of the file, where
429 * Emacs will automagically detect them.
430 * ---------------------------------------------------------------------
433 * indent-tabs-mode: t
437 * vim:noexpandtab:sw=4:ts=4: