1 /* src/native/vm/java_lang_Class.c - java/lang/Class
3 Copyright (C) 1996-2005, 2006, 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
36 #include "mm/memory.h"
38 #include "native/jni.h"
39 #include "native/llni.h"
40 #include "native/native.h"
42 /* keep this order of the native includes */
44 #include "native/include/java_lang_String.h"
46 #if defined(ENABLE_JAVASE)
47 # if defined(WITH_CLASSPATH_SUN)
48 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
50 # include "native/include/java_lang_ClassLoader.h"
53 #include "native/include/java_lang_Object.h"
54 #include "native/include/java_lang_Class.h"
56 #if defined(ENABLE_JAVASE)
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"
62 #include "native/vm/java_lang_Class.h"
64 #if defined(ENABLE_JAVASE)
65 # include "native/vm/reflect.h"
68 #include "toolbox/logging.h"
71 #include "vm/builtin.h"
72 #include "vm/exceptions.h"
73 #include "vm/global.h"
74 #include "vm/initialize.h"
75 #include "vm/primitive.h"
76 #include "vm/resolve.h"
77 #include "vm/stringlocal.h"
79 #include "vmcore/class.h"
80 #include "vmcore/loader.h"
82 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
83 #include "native/include/sun_reflect_ConstantPool.h"
87 #include "vmcore/annotation.h"
91 * Class: java/lang/Class
93 * Signature: ()Ljava/lang/String;
95 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
99 java_handle_chararray_t *ca;
102 c = LLNI_classinfo_unwrap(klass);
104 /* create a java string */
106 s = (java_lang_String *) javastring_new(c->name);
111 /* return string where '/' is replaced by '.' */
113 LLNI_field_get_ref(s, value, ca);
115 for (i = 0; i < LLNI_array_size(ca); i++) {
116 if (LLNI_array_direct(ca, i) == '/')
117 LLNI_array_direct(ca, i) = '.';
125 * Class: java/lang/Class
127 * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
129 #if defined(ENABLE_JAVASE)
130 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
131 #elif defined(ENABLE_JAVAME_CLDC1_1)
132 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
135 #if defined(ENABLE_JAVASE)
144 #if defined(ENABLE_JAVASE)
145 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
148 /* illegal argument */
151 exceptions_throw_nullpointerexception();
155 /* create utf string in which '.' is replaced by '/' */
157 ufile = javastring_toutf((java_handle_t *) name, true);
158 uname = javastring_toutf((java_handle_t *) name, false);
160 /* name must not contain '/' (mauve test) */
162 for (i = 0, pos = LLNI_field_direct(name, value)->data + LLNI_field_direct(name, offset); i < LLNI_field_direct(name, count); i++, pos++) {
164 exceptions_throw_classnotfoundexception(uname);
169 /* try to load, ... */
171 #if defined(ENABLE_JAVASE)
172 c = load_class_from_classloader(ufile, cl);
173 #elif defined(ENABLE_JAVAME_CLDC1_1)
174 c = load_class_bootstrap(ufile);
185 /* ...and initialize it, if required */
187 #if defined(ENABLE_JAVASE)
190 if (!initialize_class(c))
193 return LLNI_classinfo_wrap(c);
198 * Class: java/lang/Class
200 * Signature: (Ljava/lang/Object;)Z
202 s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
207 c = LLNI_classinfo_unwrap(klass);
208 ob = (java_handle_t *) o;
210 if (!(c->state & CLASS_LINKED))
214 return builtin_instanceof(ob, c);
219 * Class: java/lang/Class
220 * Method: isAssignableFrom
221 * Signature: (Ljava/lang/Class;)Z
223 s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
228 kc = LLNI_classinfo_unwrap(klass);
229 cc = LLNI_classinfo_unwrap(c);
232 exceptions_throw_nullpointerexception();
236 if (!(kc->state & CLASS_LINKED))
240 if (!(cc->state & CLASS_LINKED))
244 return class_isanysubclass(cc, kc);
248 #if defined(ENABLE_JAVASE)
251 * Class: java/lang/Class
252 * Method: getDeclaredFields
253 * Signature: (Z)[Ljava/lang/reflect/Field;
255 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
258 java_handle_objectarray_t *oa; /* result: array of field-objects */
260 java_lang_reflect_Field *rf;
261 s4 public_fields; /* number of elements in field-array */
265 c = LLNI_classinfo_unwrap(klass);
267 /* determine number of fields */
269 for (i = 0, public_fields = 0; i < c->fieldscount; i++)
270 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
273 /* create array of fields */
275 oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
280 /* get the fields and store in the array */
282 for (i = 0, pos = 0; i < c->fieldscount; i++) {
285 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
286 /* create Field object */
288 rf = reflect_field_new(f);
290 /* store object into array */
292 array_objectarray_element_set(oa, pos, (java_handle_t *) rf);
302 * Class: java/lang/Class
303 * Method: getDeclaredMethods
304 * Signature: (Z)[Ljava/lang/reflect/Method;
306 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
309 java_lang_reflect_Method *rm;
310 java_handle_objectarray_t *oa; /* result: array of Method-objects */
311 methodinfo *m; /* the current method to be represented */
312 s4 public_methods; /* number of public methods of the class */
316 c = LLNI_classinfo_unwrap(klass);
320 /* JOWENN: array classes do not declare methods according to mauve
321 test. It should be considered, if we should return to my old
322 clone method overriding instead of declaring it as a member
325 if (class_is_array(c))
326 return builtin_anewarray(0, class_java_lang_reflect_Method);
328 /* determine number of methods */
330 for (i = 0; i < c->methodscount; i++) {
333 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
334 ((m->name != utf_init) && (m->name != utf_clinit)) &&
335 !(m->flags & ACC_MIRANDA))
339 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
344 for (i = 0, pos = 0; i < c->methodscount; i++) {
347 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
348 ((m->name != utf_init) && (m->name != utf_clinit)) &&
349 !(m->flags & ACC_MIRANDA)) {
350 /* create Method object */
352 rm = reflect_method_new(m);
354 /* store object into array */
356 array_objectarray_element_set(oa, pos, (java_handle_t *) rm);
366 * Class: java/lang/Class
367 * Method: getDeclaredConstructors
368 * Signature: (Z)[Ljava/lang/reflect/Constructor;
370 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
373 methodinfo *m; /* the current method to be represented */
374 java_handle_objectarray_t *oa; /* result: array of Method-objects */
375 java_lang_reflect_Constructor *rc;
376 s4 public_methods; /* number of public methods of the class */
380 c = LLNI_classinfo_unwrap(klass);
382 /* determine number of constructors */
384 for (i = 0, public_methods = 0; i < c->methodscount; i++) {
387 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
388 (m->name == utf_init))
392 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
397 for (i = 0, pos = 0; i < c->methodscount; i++) {
400 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
401 (m->name == utf_init)) {
402 /* create Constructor object */
404 rc = reflect_constructor_new(m);
406 /* store object into array */
408 array_objectarray_element_set(oa, pos, (java_handle_t *) rc);
417 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
419 * Class: java/lang/Class
420 * Method: getDeclaredAnnotations
421 * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
423 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
425 classinfo *c = NULL; /* classinfo for the java.lang.Class object 'klass' */
426 static methodinfo *m_parseAnnotationsIntoArray = NULL; /* parser method (cached, therefore static) */
427 utf *utf_parseAnnotationsIntoArray = NULL; /* parser method name */
428 utf *utf_desc = NULL; /* parser method descriptor (signature) */
429 java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
430 sun_reflect_ConstantPool *constantPool = NULL; /* constant pool of klass */
431 java_lang_Object *constantPoolOop = (java_lang_Object*)klass; /* constantPoolOop field of */
432 /* sun.reflect.ConstantPool */
435 exceptions_throw_nullpointerexception();
439 c = LLNI_classinfo_unwrap(klass);
441 /* get annotations: */
442 annotations = class_get_annotations(c);
445 (sun_reflect_ConstantPool*)native_new_and_init(
446 class_sun_reflect_ConstantPool);
448 if (constantPool == NULL) {
453 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
455 /* only resolve the parser method the first time */
456 if (m_parseAnnotationsIntoArray == NULL) {
457 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
458 utf_desc = utf_new_char(
459 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
460 "[Ljava/lang/annotation/Annotation;");
462 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
467 m_parseAnnotationsIntoArray = class_resolveclassmethod(
468 class_sun_reflect_annotation_AnnotationParser,
469 utf_parseAnnotationsIntoArray,
471 class_java_lang_Class,
474 if (m_parseAnnotationsIntoArray == NULL) {
475 /* method not found */
480 return (java_handle_objectarray_t*)vm_call_method(
481 m_parseAnnotationsIntoArray, NULL,
482 annotations, constantPool, klass);
487 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
489 Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
490 _Jv_java_lang_Class_getEnclosingMethod.
492 *******************************************************************************/
494 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
496 constant_nameandtype *cn;
500 /* get enclosing class and method */
502 ec = class_get_enclosingclass(c);
503 cn = c->enclosingmethod;
505 /* check for enclosing class and method */
513 /* find method in enclosing class */
515 m = class_findmethod(ec, cn->name, cn->descriptor);
518 exceptions_throw_internalerror("Enclosing method doesn't exist");
527 * Class: java/lang/Class
528 * Method: getEnclosingConstructor
529 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
531 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
535 java_lang_reflect_Constructor *rc;
537 c = LLNI_classinfo_unwrap(klass);
539 /* get enclosing method */
541 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
546 /* check for <init> */
548 if (m->name != utf_init)
551 /* create Constructor object */
553 rc = reflect_constructor_new(m);
560 * Class: java/lang/Class
561 * Method: getEnclosingMethod
562 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
564 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
568 java_lang_reflect_Method *rm;
570 c = LLNI_classinfo_unwrap(klass);
572 /* get enclosing method */
574 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
579 /* check for <init> */
581 if (m->name == utf_init)
584 /* create java.lang.reflect.Method object */
586 rm = reflect_method_new(m);
591 #endif /* ENABLE_JAVASE */
595 * These are local overrides for various environment variables in Emacs.
596 * Please do not remove this and leave it at the end of the file, where
597 * Emacs will automagically detect them.
598 * ---------------------------------------------------------------------
601 * indent-tabs-mode: t
605 * vim:noexpandtab:sw=4:ts=4: