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 8395 2007-08-22 13:12:46Z panzi $
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"
66 #if defined(ENABLE_JAVASE)
67 # include "native/vm/reflect.h"
70 #include "toolbox/logging.h"
72 #include "vm/builtin.h"
73 #include "vm/exceptions.h"
74 #include "vm/global.h"
75 #include "vm/initialize.h"
76 #include "vm/primitive.h"
77 #include "vm/resolve.h"
78 #include "vm/stringlocal.h"
80 #include "vmcore/class.h"
81 #include "vmcore/loader.h"
83 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
85 #include "vmcore/annotation.h"
86 #include "native/include/sun_reflect_ConstantPool.h"
90 * Class: java/lang/Class
92 * Signature: ()Ljava/lang/String;
94 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
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 = (classloader *) 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)
574 c = LLNI_classinfo_unwrap(klass);
576 return (java_lang_ClassLoader *) c->classloader;
579 #endif /* defined(ENABLE_JAVASE) */
583 * Class: java/lang/Class
587 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isArray(JNIEnv *env, java_lang_Class *this)
591 c = LLNI_classinfo_unwrap(this);
593 return class_is_array(c);
597 #if defined(ENABLE_JAVASE)
600 * Class: java/lang/Class
601 * Method: throwException
602 * Signature: (Ljava/lang/Throwable;)V
604 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
608 o = (java_handle_t *) t;
610 exceptions_set_exception(o);
614 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
616 * Class: java/lang/Class
617 * Method: getDeclaredAnnotations
618 * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
620 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
623 static methodinfo *m_parseAnnotationsIntoArray = NULL;
624 utf *utf_parseAnnotationsIntoArray = NULL;
625 utf *utf_desc = NULL;
626 java_handle_bytearray_t *annotations = NULL;
627 sun_reflect_ConstantPool *constantPool = NULL;
628 java_lang_Object *constantPoolOop = (java_lang_Object*)klass;
631 exceptions_throw_nullpointerexception();
635 c = LLNI_classinfo_unwrap(klass);
637 /* get annotations: */
638 annotations = class_get_annotations(c);
640 if (exceptions_get_exception() != NULL) {
641 /* the only exception possible here should be a out of memory exception
642 * raised by copying the annotations into a java bytearray */
647 (sun_reflect_ConstantPool*)native_new_and_init(
648 class_sun_reflect_ConstantPool);
650 if(constantPool == NULL) {
655 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
657 /* only resolve the method the first time */
658 if (m_parseAnnotationsIntoArray == NULL) {
659 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
660 utf_desc = utf_new_char(
661 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
662 "[Ljava/lang/annotation/Annotation;");
664 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
669 m_parseAnnotationsIntoArray = class_resolveclassmethod(
670 class_sun_reflect_annotation_AnnotationParser,
671 utf_parseAnnotationsIntoArray,
673 class_java_lang_Class,
676 if (m_parseAnnotationsIntoArray == NULL) {
677 /* method not found */
682 return (java_handle_objectarray_t*)vm_call_method(
683 m_parseAnnotationsIntoArray, NULL,
684 annotations, constantPool, klass);
689 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
691 Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
692 _Jv_java_lang_Class_getEnclosingMethod.
694 *******************************************************************************/
696 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
698 constant_nameandtype *cn;
702 /* get enclosing class and method */
704 ec = class_get_enclosingclass(c);
705 cn = c->enclosingmethod;
707 /* check for enclosing class and method */
715 /* find method in enclosing class */
717 m = class_findmethod(ec, cn->name, cn->descriptor);
720 exceptions_throw_internalerror("Enclosing method doesn't exist");
729 * Class: java/lang/Class
730 * Method: getEnclosingConstructor
731 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
733 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
737 java_lang_reflect_Constructor *rc;
739 c = LLNI_classinfo_unwrap(klass);
741 /* get enclosing method */
743 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
748 /* check for <init> */
750 if (m->name != utf_init)
753 /* create Constructor object */
755 rc = reflect_constructor_new(m);
762 * Class: java/lang/Class
763 * Method: getEnclosingMethod
764 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
766 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
770 java_lang_reflect_Method *rm;
772 c = LLNI_classinfo_unwrap(klass);
774 /* get enclosing method */
776 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
781 /* check for <init> */
783 if (m->name == utf_init)
786 /* create java.lang.reflect.Method object */
788 rm = reflect_method_new(m);
795 * Class: java/lang/Class
796 * Method: getClassSignature
797 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
799 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
804 c = LLNI_classinfo_unwrap(klass);
806 if (c->signature == NULL)
809 o = javastring_new(c->signature);
811 /* in error case o is NULL */
813 return (java_lang_String *) o;
816 #endif /* ENABLE_JAVASE */
820 * These are local overrides for various environment variables in Emacs.
821 * Please do not remove this and leave it at the end of the file, where
822 * Emacs will automagically detect them.
823 * ---------------------------------------------------------------------
826 * indent-tabs-mode: t
830 * vim:noexpandtab:sw=4:ts=4: