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
25 $Id: java_lang_Class.c 8343 2007-08-17 21:39:32Z michi $
38 #include "mm/memory.h"
40 #include "native/jni.h"
41 #include "native/llni.h"
42 #include "native/native.h"
44 /* keep this order of the native includes */
46 #include "native/include/java_lang_String.h"
48 #if defined(ENABLE_JAVASE)
49 # if defined(WITH_CLASSPATH_SUN)
50 # include "native/include/java_nio_ByteBuffer.h" /* required by j.l.CL */
52 # include "native/include/java_lang_ClassLoader.h"
55 #include "native/include/java_lang_Object.h"
56 #include "native/include/java_lang_Class.h"
58 #if defined(ENABLE_JAVASE)
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"
64 #include "native/vm/java_lang_Class.h"
65 #include "native/vm/java_lang_String.h"
67 #if defined(ENABLE_JAVASE)
68 # include "native/vm/reflect.h"
71 #include "toolbox/logging.h"
73 #include "vm/builtin.h"
74 #include "vm/exceptions.h"
75 #include "vm/global.h"
76 #include "vm/initialize.h"
77 #include "vm/primitive.h"
78 #include "vm/resolve.h"
79 #include "vm/stringlocal.h"
81 #include "vmcore/class.h"
82 #include "vmcore/loader.h"
84 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
86 #include "vmcore/annotation.h"
87 #include "native/include/sun_reflect_ConstantPool.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);
249 * Class: java/lang/Class
250 * Method: isInterface
253 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isInterface(JNIEnv *env, java_lang_Class *this)
257 c = LLNI_classinfo_unwrap(this);
259 return class_is_interface(c);
263 #if defined(ENABLE_JAVASE)
266 * Class: java/lang/Class
267 * Method: isPrimitive
270 s4 _Jv_java_lang_Class_isPrimitive(java_lang_Class *klass)
274 c = LLNI_classinfo_unwrap(klass);
276 return class_is_primitive(c);
281 * Class: java/lang/Class
282 * Method: getSuperclass
283 * Signature: ()Ljava/lang/Class;
285 java_lang_Class *_Jv_java_lang_Class_getSuperclass(java_lang_Class *klass)
290 c = LLNI_classinfo_unwrap(klass);
292 super = class_get_superclass(c);
294 return LLNI_classinfo_wrap(super);
299 * Class: java/lang/Class
300 * Method: getInterfaces
301 * Signature: ()[Ljava/lang/Class;
303 java_handle_objectarray_t *_Jv_java_lang_Class_getInterfaces(java_lang_Class *klass)
306 java_handle_objectarray_t *oa;
308 c = LLNI_classinfo_unwrap(klass);
310 oa = class_get_interfaces(c);
317 * Class: java/lang/Class
318 * Method: getModifiers
321 s4 _Jv_java_lang_Class_getModifiers(java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
324 classref_or_classinfo inner;
325 classref_or_classinfo outer;
329 c = LLNI_classinfo_unwrap(klass);
331 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
332 /* search for passed class as inner class */
334 for (i = 0; i < c->innerclasscount; i++) {
335 inner = c->innerclass[i].inner_class;
336 outer = c->innerclass[i].outer_class;
338 /* Check if inner is a classref or a real class and get
339 the name of the structure */
341 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
343 /* innerclass is this class */
345 if (innername == c->name) {
346 /* has the class actually an outer class? */
349 /* return flags got from the outer class file */
350 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
352 return c->flags & ACC_CLASS_REFLECT_MASK;
357 /* passed class is no inner class or it was not requested */
359 return c->flags & ACC_CLASS_REFLECT_MASK;
364 * Class: java/lang/Class
365 * Method: getDeclaringClass
366 * Signature: ()Ljava/lang/Class;
368 java_lang_Class *_Jv_java_lang_Class_getDeclaringClass(java_lang_Class *klass)
373 c = LLNI_classinfo_unwrap(klass);
375 dc = class_get_declaringclass(c);
377 return LLNI_classinfo_wrap(dc);
382 * Class: java/lang/Class
383 * Method: getDeclaredClasses
384 * Signature: (Z)[Ljava/lang/Class;
386 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredClasses(java_lang_Class *klass, s4 publicOnly)
389 java_handle_objectarray_t *oa;
391 c = LLNI_classinfo_unwrap(klass);
393 oa = class_get_declaredclasses(c, publicOnly);
400 * Class: java/lang/Class
401 * Method: getDeclaredFields
402 * Signature: (Z)[Ljava/lang/reflect/Field;
404 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
407 java_handle_objectarray_t *oa; /* result: array of field-objects */
409 java_lang_reflect_Field *rf;
410 s4 public_fields; /* number of elements in field-array */
414 c = LLNI_classinfo_unwrap(klass);
416 /* determine number of fields */
418 for (i = 0, public_fields = 0; i < c->fieldscount; i++)
419 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
422 /* create array of fields */
424 oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
429 /* get the fields and store in the array */
431 for (i = 0, pos = 0; i < c->fieldscount; i++) {
434 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
435 /* create Field object */
437 rf = reflect_field_new(f);
439 /* store object into array */
441 LLNI_objectarray_element_set(oa, pos, rf);
451 * Class: java/lang/Class
452 * Method: getDeclaredMethods
453 * Signature: (Z)[Ljava/lang/reflect/Method;
455 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
458 java_lang_reflect_Method *rm;
459 java_handle_objectarray_t *oa; /* result: array of Method-objects */
460 methodinfo *m; /* the current method to be represented */
461 s4 public_methods; /* number of public methods of the class */
465 c = LLNI_classinfo_unwrap(klass);
469 /* JOWENN: array classes do not declare methods according to mauve
470 test. It should be considered, if we should return to my old
471 clone method overriding instead of declaring it as a member
474 if (class_is_array(c))
475 return builtin_anewarray(0, class_java_lang_reflect_Method);
477 /* determine number of methods */
479 for (i = 0; i < c->methodscount; i++) {
482 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
483 ((m->name != utf_init) && (m->name != utf_clinit)) &&
484 !(m->flags & ACC_MIRANDA))
488 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
493 for (i = 0, pos = 0; i < c->methodscount; i++) {
496 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
497 ((m->name != utf_init) && (m->name != utf_clinit)) &&
498 !(m->flags & ACC_MIRANDA)) {
499 /* create Method object */
501 rm = reflect_method_new(m);
503 /* store object into array */
505 LLNI_objectarray_element_set(oa, pos, rm);
515 * Class: java/lang/Class
516 * Method: getDeclaredConstructors
517 * Signature: (Z)[Ljava/lang/reflect/Constructor;
519 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
522 methodinfo *m; /* the current method to be represented */
523 java_handle_objectarray_t *oa; /* result: array of Method-objects */
524 java_lang_reflect_Constructor *rc;
525 s4 public_methods; /* number of public methods of the class */
529 c = LLNI_classinfo_unwrap(klass);
531 /* determine number of constructors */
533 for (i = 0, public_methods = 0; i < c->methodscount; i++) {
536 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
537 (m->name == utf_init))
541 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
546 for (i = 0, pos = 0; i < c->methodscount; i++) {
549 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
550 (m->name == utf_init)) {
551 /* create Constructor object */
553 rc = reflect_constructor_new(m);
555 /* store object into array */
557 LLNI_objectarray_element_set(oa, pos, rc);
567 * Class: java/lang/Class
568 * Method: getClassLoader
569 * Signature: ()Ljava/lang/ClassLoader;
571 java_lang_ClassLoader *_Jv_java_lang_Class_getClassLoader(java_lang_Class *klass)
575 c = LLNI_classinfo_unwrap(klass);
577 if (c->classloader == NULL)
580 return (java_lang_ClassLoader *) c->classloader->object;
583 #endif /* defined(ENABLE_JAVASE) */
587 * Class: java/lang/Class
591 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isArray(JNIEnv *env, java_lang_Class *this)
595 c = LLNI_classinfo_unwrap(this);
597 return class_is_array(c);
601 #if defined(ENABLE_JAVASE)
604 * Class: java/lang/Class
605 * Method: throwException
606 * Signature: (Ljava/lang/Throwable;)V
608 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
612 o = (java_handle_t *) t;
614 exceptions_set_exception(o);
618 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
620 * Class: java/lang/Class
621 * Method: getDeclaredAnnotations
622 * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
624 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
626 classinfo *c = LLNI_classinfo_unwrap(klass);
627 static methodinfo *m_parseAnnotationsIntoArray = NULL;
628 utf *utf_parseAnnotationsIntoArray = NULL;
629 utf *utf_desc = NULL;
630 java_handle_bytearray_t *annotations = NULL;
631 sun_reflect_ConstantPool *constantPool = NULL;
633 java_lang_Object *constantPoolOop = (java_lang_Object*)klass;
636 exceptions_throw_nullpointerexception();
640 /* Return null for arrays and primitives: */
641 if (class_is_primitive(c) || class_is_array(c)) {
645 if (c->annotations != NULL) {
646 size = c->annotations->size;
647 annotations = builtin_newarray_byte(size);
649 if(annotations != NULL) {
650 MCOPY(annotations->data, c->annotations->data, uint8_t, size);
655 (sun_reflect_ConstantPool*)native_new_and_init(
656 class_sun_reflect_ConstantPool);
658 if(constantPool == NULL) {
663 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
665 /* only resolve the method the first time */
666 if (m_parseAnnotationsIntoArray == NULL) {
667 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
668 utf_desc = utf_new_char(
669 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
670 "[Ljava/lang/annotation/Annotation;");
672 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
677 m_parseAnnotationsIntoArray = class_resolveclassmethod(
678 class_sun_reflect_annotation_AnnotationParser,
679 utf_parseAnnotationsIntoArray,
681 class_java_lang_Class,
684 if (m_parseAnnotationsIntoArray == NULL) {
685 /* method not found */
690 return (java_handle_objectarray_t*)vm_call_method(
691 m_parseAnnotationsIntoArray, NULL,
692 annotations, constantPool, klass);
697 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
699 Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
700 _Jv_java_lang_Class_getEnclosingMethod.
702 *******************************************************************************/
704 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
706 constant_nameandtype *cn;
710 /* get enclosing class and method */
712 ec = class_get_enclosingclass(c);
713 cn = c->enclosingmethod;
715 /* check for enclosing class and method */
723 /* find method in enclosing class */
725 m = class_findmethod(ec, cn->name, cn->descriptor);
728 exceptions_throw_internalerror("Enclosing method doesn't exist");
737 * Class: java/lang/Class
738 * Method: getEnclosingConstructor
739 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
741 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
745 java_lang_reflect_Constructor *rc;
747 c = LLNI_classinfo_unwrap(klass);
749 /* get enclosing method */
751 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
756 /* check for <init> */
758 if (m->name != utf_init)
761 /* create Constructor object */
763 rc = reflect_constructor_new(m);
770 * Class: java/lang/Class
771 * Method: getEnclosingMethod
772 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
774 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
778 java_lang_reflect_Method *rm;
780 c = LLNI_classinfo_unwrap(klass);
782 /* get enclosing method */
784 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
789 /* check for <init> */
791 if (m->name == utf_init)
794 /* create java.lang.reflect.Method object */
796 rm = reflect_method_new(m);
803 * Class: java/lang/Class
804 * Method: getClassSignature
805 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
807 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
812 c = LLNI_classinfo_unwrap(klass);
814 if (c->signature == NULL)
817 o = javastring_new(c->signature);
819 /* in error case o is NULL */
821 return (java_lang_String *) o;
824 #endif /* ENABLE_JAVASE */
828 * These are local overrides for various environment variables in Emacs.
829 * Please do not remove this and leave it at the end of the file, where
830 * Emacs will automagically detect them.
831 * ---------------------------------------------------------------------
834 * indent-tabs-mode: t
838 * vim:noexpandtab:sw=4:ts=4: