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"
70 #include "vm/builtin.h"
71 #include "vm/exceptions.h"
72 #include "vm/global.h"
73 #include "vm/initialize.h"
74 #include "vm/primitive.h"
75 #include "vm/resolve.h"
76 #include "vm/stringlocal.h"
78 #include "vmcore/class.h"
79 #include "vmcore/loader.h"
81 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
82 #include "native/include/sun_reflect_ConstantPool.h"
86 #include "vmcore/annotation.h"
90 * Class: java/lang/Class
92 * Signature: ()Ljava/lang/String;
94 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
98 java_handle_chararray_t *ca;
101 c = LLNI_classinfo_unwrap(klass);
103 /* create a java string */
105 s = (java_lang_String *) javastring_new(c->name);
110 /* return string where '/' is replaced by '.' */
112 LLNI_field_get_ref(s, value, ca);
114 for (i = 0; i < LLNI_array_size(ca); i++) {
115 if (LLNI_array_direct(ca, i) == '/')
116 LLNI_array_direct(ca, i) = '.';
124 * Class: java/lang/Class
126 * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
128 #if defined(ENABLE_JAVASE)
129 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
130 #elif defined(ENABLE_JAVAME_CLDC1_1)
131 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
134 #if defined(ENABLE_JAVASE)
143 #if defined(ENABLE_JAVASE)
144 cl = loader_hashtable_classloader_add((java_handle_t *) loader);
147 /* illegal argument */
150 exceptions_throw_nullpointerexception();
154 /* create utf string in which '.' is replaced by '/' */
156 ufile = javastring_toutf((java_handle_t *) name, true);
157 uname = javastring_toutf((java_handle_t *) name, false);
159 /* name must not contain '/' (mauve test) */
161 for (i = 0, pos = LLNI_field_direct(name, value)->data + LLNI_field_direct(name, offset); i < LLNI_field_direct(name, count); i++, pos++) {
163 exceptions_throw_classnotfoundexception(uname);
168 /* try to load, ... */
170 #if defined(ENABLE_JAVASE)
171 c = load_class_from_classloader(ufile, cl);
172 #elif defined(ENABLE_JAVAME_CLDC1_1)
173 c = load_class_bootstrap(ufile);
184 /* ...and initialize it, if required */
186 #if defined(ENABLE_JAVASE)
189 if (!initialize_class(c))
192 return LLNI_classinfo_wrap(c);
197 * Class: java/lang/Class
199 * Signature: (Ljava/lang/Object;)Z
201 s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
206 c = LLNI_classinfo_unwrap(klass);
207 ob = (java_handle_t *) o;
209 if (!(c->state & CLASS_LINKED))
213 return builtin_instanceof(ob, c);
218 * Class: java/lang/Class
219 * Method: isAssignableFrom
220 * Signature: (Ljava/lang/Class;)Z
222 s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
227 kc = LLNI_classinfo_unwrap(klass);
228 cc = LLNI_classinfo_unwrap(c);
231 exceptions_throw_nullpointerexception();
235 if (!(kc->state & CLASS_LINKED))
239 if (!(cc->state & CLASS_LINKED))
243 return class_isanysubclass(cc, kc);
248 * Class: java/lang/Class
249 * Method: isInterface
252 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isInterface(JNIEnv *env, java_lang_Class *this)
256 c = LLNI_classinfo_unwrap(this);
258 return class_is_interface(c);
262 #if defined(ENABLE_JAVASE)
265 * Class: java/lang/Class
266 * Method: isPrimitive
269 s4 _Jv_java_lang_Class_isPrimitive(java_lang_Class *klass)
273 c = LLNI_classinfo_unwrap(klass);
275 return class_is_primitive(c);
280 * Class: java/lang/Class
281 * Method: getSuperclass
282 * Signature: ()Ljava/lang/Class;
284 java_lang_Class *_Jv_java_lang_Class_getSuperclass(java_lang_Class *klass)
289 c = LLNI_classinfo_unwrap(klass);
291 super = class_get_superclass(c);
293 return LLNI_classinfo_wrap(super);
298 * Class: java/lang/Class
299 * Method: getInterfaces
300 * Signature: ()[Ljava/lang/Class;
302 java_handle_objectarray_t *_Jv_java_lang_Class_getInterfaces(java_lang_Class *klass)
305 java_handle_objectarray_t *oa;
307 c = LLNI_classinfo_unwrap(klass);
309 oa = class_get_interfaces(c);
316 * Class: java/lang/Class
317 * Method: getModifiers
320 s4 _Jv_java_lang_Class_getModifiers(java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
323 classref_or_classinfo inner;
324 classref_or_classinfo outer;
328 c = LLNI_classinfo_unwrap(klass);
330 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
331 /* search for passed class as inner class */
333 for (i = 0; i < c->innerclasscount; i++) {
334 inner = c->innerclass[i].inner_class;
335 outer = c->innerclass[i].outer_class;
337 /* Check if inner is a classref or a real class and get
338 the name of the structure */
340 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
342 /* innerclass is this class */
344 if (innername == c->name) {
345 /* has the class actually an outer class? */
348 /* return flags got from the outer class file */
349 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
351 return c->flags & ACC_CLASS_REFLECT_MASK;
356 /* passed class is no inner class or it was not requested */
358 return c->flags & ACC_CLASS_REFLECT_MASK;
363 * Class: java/lang/Class
364 * Method: getDeclaringClass
365 * Signature: ()Ljava/lang/Class;
367 java_lang_Class *_Jv_java_lang_Class_getDeclaringClass(java_lang_Class *klass)
372 c = LLNI_classinfo_unwrap(klass);
374 dc = class_get_declaringclass(c);
376 return LLNI_classinfo_wrap(dc);
381 * Class: java/lang/Class
382 * Method: getDeclaredClasses
383 * Signature: (Z)[Ljava/lang/Class;
385 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredClasses(java_lang_Class *klass, s4 publicOnly)
388 java_handle_objectarray_t *oa;
390 c = LLNI_classinfo_unwrap(klass);
392 oa = class_get_declaredclasses(c, publicOnly);
399 * Class: java/lang/Class
400 * Method: getDeclaredFields
401 * Signature: (Z)[Ljava/lang/reflect/Field;
403 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
406 java_handle_objectarray_t *oa; /* result: array of field-objects */
408 java_lang_reflect_Field *rf;
409 s4 public_fields; /* number of elements in field-array */
413 c = LLNI_classinfo_unwrap(klass);
415 /* determine number of fields */
417 for (i = 0, public_fields = 0; i < c->fieldscount; i++)
418 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
421 /* create array of fields */
423 oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
428 /* get the fields and store in the array */
430 for (i = 0, pos = 0; i < c->fieldscount; i++) {
433 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
434 /* create Field object */
436 rf = reflect_field_new(f);
438 /* store object into array */
440 LLNI_objectarray_element_set(oa, pos, rf);
450 * Class: java/lang/Class
451 * Method: getDeclaredMethods
452 * Signature: (Z)[Ljava/lang/reflect/Method;
454 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
457 java_lang_reflect_Method *rm;
458 java_handle_objectarray_t *oa; /* result: array of Method-objects */
459 methodinfo *m; /* the current method to be represented */
460 s4 public_methods; /* number of public methods of the class */
464 c = LLNI_classinfo_unwrap(klass);
468 /* JOWENN: array classes do not declare methods according to mauve
469 test. It should be considered, if we should return to my old
470 clone method overriding instead of declaring it as a member
473 if (class_is_array(c))
474 return builtin_anewarray(0, class_java_lang_reflect_Method);
476 /* determine number of methods */
478 for (i = 0; i < c->methodscount; i++) {
481 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
482 ((m->name != utf_init) && (m->name != utf_clinit)) &&
483 !(m->flags & ACC_MIRANDA))
487 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
492 for (i = 0, pos = 0; i < c->methodscount; i++) {
495 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
496 ((m->name != utf_init) && (m->name != utf_clinit)) &&
497 !(m->flags & ACC_MIRANDA)) {
498 /* create Method object */
500 rm = reflect_method_new(m);
502 /* store object into array */
504 LLNI_objectarray_element_set(oa, pos, rm);
514 * Class: java/lang/Class
515 * Method: getDeclaredConstructors
516 * Signature: (Z)[Ljava/lang/reflect/Constructor;
518 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
521 methodinfo *m; /* the current method to be represented */
522 java_handle_objectarray_t *oa; /* result: array of Method-objects */
523 java_lang_reflect_Constructor *rc;
524 s4 public_methods; /* number of public methods of the class */
528 c = LLNI_classinfo_unwrap(klass);
530 /* determine number of constructors */
532 for (i = 0, public_methods = 0; i < c->methodscount; i++) {
535 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
536 (m->name == utf_init))
540 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
545 for (i = 0, pos = 0; i < c->methodscount; i++) {
548 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
549 (m->name == utf_init)) {
550 /* create Constructor object */
552 rc = reflect_constructor_new(m);
554 /* store object into array */
556 LLNI_objectarray_element_set(oa, pos, rc);
566 * Class: java/lang/Class
567 * Method: getClassLoader
568 * Signature: ()Ljava/lang/ClassLoader;
570 java_lang_ClassLoader *_Jv_java_lang_Class_getClassLoader(java_lang_Class *klass)
575 c = LLNI_classinfo_unwrap(klass);
581 #if defined(ENABLE_HANDLES)
582 /* the classloader entry itself is the handle */
583 return (java_lang_ClassLoader *) cl;
585 /* get the object out of the classloader entry */
586 return (java_lang_ClassLoader *) cl->object;
590 #endif /* defined(ENABLE_JAVASE) */
594 * Class: java/lang/Class
598 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isArray(JNIEnv *env, java_lang_Class *this)
602 c = LLNI_classinfo_unwrap(this);
604 return class_is_array(c);
608 #if defined(ENABLE_JAVASE)
611 * Class: java/lang/Class
612 * Method: throwException
613 * Signature: (Ljava/lang/Throwable;)V
615 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
619 o = (java_handle_t *) t;
621 exceptions_set_exception(o);
625 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
627 * Class: java/lang/Class
628 * Method: getDeclaredAnnotations
629 * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
631 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
634 static methodinfo *m_parseAnnotationsIntoArray = NULL;
635 utf *utf_parseAnnotationsIntoArray = NULL;
636 utf *utf_desc = NULL;
637 java_handle_bytearray_t *annotations = NULL;
638 sun_reflect_ConstantPool *constantPool = NULL;
639 java_lang_Object *constantPoolOop = (java_lang_Object*)klass;
642 exceptions_throw_nullpointerexception();
646 c = LLNI_classinfo_unwrap(klass);
648 /* get annotations: */
649 annotations = class_get_annotations(c);
652 (sun_reflect_ConstantPool*)native_new_and_init(
653 class_sun_reflect_ConstantPool);
655 if(constantPool == NULL) {
660 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
662 /* only resolve the method the first time */
663 if (m_parseAnnotationsIntoArray == NULL) {
664 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
665 utf_desc = utf_new_char(
666 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
667 "[Ljava/lang/annotation/Annotation;");
669 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
674 m_parseAnnotationsIntoArray = class_resolveclassmethod(
675 class_sun_reflect_annotation_AnnotationParser,
676 utf_parseAnnotationsIntoArray,
678 class_java_lang_Class,
681 if (m_parseAnnotationsIntoArray == NULL) {
682 /* method not found */
687 return (java_handle_objectarray_t*)vm_call_method(
688 m_parseAnnotationsIntoArray, NULL,
689 annotations, constantPool, klass);
694 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
696 Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
697 _Jv_java_lang_Class_getEnclosingMethod.
699 *******************************************************************************/
701 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
703 constant_nameandtype *cn;
707 /* get enclosing class and method */
709 ec = class_get_enclosingclass(c);
710 cn = c->enclosingmethod;
712 /* check for enclosing class and method */
720 /* find method in enclosing class */
722 m = class_findmethod(ec, cn->name, cn->descriptor);
725 exceptions_throw_internalerror("Enclosing method doesn't exist");
734 * Class: java/lang/Class
735 * Method: getEnclosingConstructor
736 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
738 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
742 java_lang_reflect_Constructor *rc;
744 c = LLNI_classinfo_unwrap(klass);
746 /* get enclosing method */
748 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
753 /* check for <init> */
755 if (m->name != utf_init)
758 /* create Constructor object */
760 rc = reflect_constructor_new(m);
767 * Class: java/lang/Class
768 * Method: getEnclosingMethod
769 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
771 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
775 java_lang_reflect_Method *rm;
777 c = LLNI_classinfo_unwrap(klass);
779 /* get enclosing method */
781 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
786 /* check for <init> */
788 if (m->name == utf_init)
791 /* create java.lang.reflect.Method object */
793 rm = reflect_method_new(m);
800 * Class: java/lang/Class
801 * Method: getClassSignature
802 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
804 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
809 c = LLNI_classinfo_unwrap(klass);
811 if (c->signature == NULL)
814 o = javastring_new(c->signature);
816 /* in error case o is NULL */
818 return (java_lang_String *) o;
821 #endif /* ENABLE_JAVASE */
825 * These are local overrides for various environment variables in Emacs.
826 * Please do not remove this and leave it at the end of the file, where
827 * Emacs will automagically detect them.
828 * ---------------------------------------------------------------------
831 * indent-tabs-mode: t
835 * vim:noexpandtab:sw=4:ts=4: