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)
83 #include "vmcore/annotation.h"
84 #include "native/include/sun_reflect_ConstantPool.h"
88 * Class: java/lang/Class
90 * Signature: ()Ljava/lang/String;
92 java_lang_String *_Jv_java_lang_Class_getName(java_lang_Class *klass)
99 c = LLNI_classinfo_unwrap(klass);
101 /* create a java string */
103 s = (java_lang_String *) javastring_new(c->name);
108 /* return string where '/' is replaced by '.' */
110 LLNI_field_get_ref(s, value, ca);
112 for (i = 0; i < LLNI_array_size(ca); i++) {
113 if (LLNI_array_direct(ca, i) == '/')
114 LLNI_array_direct(ca, i) = '.';
122 * Class: java/lang/Class
124 * Signature: (Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
126 #if defined(ENABLE_JAVASE)
127 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initialize, java_lang_ClassLoader *loader)
128 #elif defined(ENABLE_JAVAME_CLDC1_1)
129 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
132 #if defined(ENABLE_JAVASE)
141 #if defined(ENABLE_JAVASE)
142 cl = (classloader *) loader;
145 /* illegal argument */
148 exceptions_throw_nullpointerexception();
152 /* create utf string in which '.' is replaced by '/' */
154 ufile = javastring_toutf((java_handle_t *) name, true);
155 uname = javastring_toutf((java_handle_t *) name, false);
157 /* name must not contain '/' (mauve test) */
159 for (i = 0, pos = LLNI_field_direct(name, value)->data + LLNI_field_direct(name, offset); i < LLNI_field_direct(name, count); i++, pos++) {
161 exceptions_throw_classnotfoundexception(uname);
166 /* try to load, ... */
168 #if defined(ENABLE_JAVASE)
169 c = load_class_from_classloader(ufile, cl);
170 #elif defined(ENABLE_JAVAME_CLDC1_1)
171 c = load_class_bootstrap(ufile);
182 /* ...and initialize it, if required */
184 #if defined(ENABLE_JAVASE)
187 if (!initialize_class(c))
190 return LLNI_classinfo_wrap(c);
195 * Class: java/lang/Class
197 * Signature: (Ljava/lang/Object;)Z
199 s4 _Jv_java_lang_Class_isInstance(java_lang_Class *klass, java_lang_Object *o)
204 c = LLNI_classinfo_unwrap(klass);
205 ob = (java_handle_t *) o;
207 if (!(c->state & CLASS_LINKED))
211 return builtin_instanceof(ob, c);
216 * Class: java/lang/Class
217 * Method: isAssignableFrom
218 * Signature: (Ljava/lang/Class;)Z
220 s4 _Jv_java_lang_Class_isAssignableFrom(java_lang_Class *klass, java_lang_Class *c)
225 kc = LLNI_classinfo_unwrap(klass);
226 cc = LLNI_classinfo_unwrap(c);
229 exceptions_throw_nullpointerexception();
233 if (!(kc->state & CLASS_LINKED))
237 if (!(cc->state & CLASS_LINKED))
241 return class_isanysubclass(cc, kc);
246 * Class: java/lang/Class
247 * Method: isInterface
250 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isInterface(JNIEnv *env, java_lang_Class *this)
254 c = LLNI_classinfo_unwrap(this);
256 return class_is_interface(c);
260 #if defined(ENABLE_JAVASE)
263 * Class: java/lang/Class
264 * Method: isPrimitive
267 s4 _Jv_java_lang_Class_isPrimitive(java_lang_Class *klass)
271 c = LLNI_classinfo_unwrap(klass);
273 return class_is_primitive(c);
278 * Class: java/lang/Class
279 * Method: getSuperclass
280 * Signature: ()Ljava/lang/Class;
282 java_lang_Class *_Jv_java_lang_Class_getSuperclass(java_lang_Class *klass)
287 c = LLNI_classinfo_unwrap(klass);
289 super = class_get_superclass(c);
291 return LLNI_classinfo_wrap(super);
296 * Class: java/lang/Class
297 * Method: getInterfaces
298 * Signature: ()[Ljava/lang/Class;
300 java_handle_objectarray_t *_Jv_java_lang_Class_getInterfaces(java_lang_Class *klass)
303 java_handle_objectarray_t *oa;
305 c = LLNI_classinfo_unwrap(klass);
307 oa = class_get_interfaces(c);
314 * Class: java/lang/Class
315 * Method: getModifiers
318 s4 _Jv_java_lang_Class_getModifiers(java_lang_Class *klass, s4 ignoreInnerClassesAttrib)
321 classref_or_classinfo inner;
322 classref_or_classinfo outer;
326 c = LLNI_classinfo_unwrap(klass);
328 if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
329 /* search for passed class as inner class */
331 for (i = 0; i < c->innerclasscount; i++) {
332 inner = c->innerclass[i].inner_class;
333 outer = c->innerclass[i].outer_class;
335 /* Check if inner is a classref or a real class and get
336 the name of the structure */
338 innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
340 /* innerclass is this class */
342 if (innername == c->name) {
343 /* has the class actually an outer class? */
346 /* return flags got from the outer class file */
347 return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
349 return c->flags & ACC_CLASS_REFLECT_MASK;
354 /* passed class is no inner class or it was not requested */
356 return c->flags & ACC_CLASS_REFLECT_MASK;
361 * Class: java/lang/Class
362 * Method: getDeclaringClass
363 * Signature: ()Ljava/lang/Class;
365 java_lang_Class *_Jv_java_lang_Class_getDeclaringClass(java_lang_Class *klass)
370 c = LLNI_classinfo_unwrap(klass);
372 dc = class_get_declaringclass(c);
374 return LLNI_classinfo_wrap(dc);
379 * Class: java/lang/Class
380 * Method: getDeclaredClasses
381 * Signature: (Z)[Ljava/lang/Class;
383 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredClasses(java_lang_Class *klass, s4 publicOnly)
386 java_handle_objectarray_t *oa;
388 c = LLNI_classinfo_unwrap(klass);
390 oa = class_get_declaredclasses(c, publicOnly);
397 * Class: java/lang/Class
398 * Method: getDeclaredFields
399 * Signature: (Z)[Ljava/lang/reflect/Field;
401 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredFields(java_lang_Class *klass, s4 publicOnly)
404 java_handle_objectarray_t *oa; /* result: array of field-objects */
406 java_lang_reflect_Field *rf;
407 s4 public_fields; /* number of elements in field-array */
411 c = LLNI_classinfo_unwrap(klass);
413 /* determine number of fields */
415 for (i = 0, public_fields = 0; i < c->fieldscount; i++)
416 if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
419 /* create array of fields */
421 oa = builtin_anewarray(public_fields, class_java_lang_reflect_Field);
426 /* get the fields and store in the array */
428 for (i = 0, pos = 0; i < c->fieldscount; i++) {
431 if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
432 /* create Field object */
434 rf = reflect_field_new(f);
436 /* store object into array */
438 LLNI_objectarray_element_set(oa, pos, rf);
448 * Class: java/lang/Class
449 * Method: getDeclaredMethods
450 * Signature: (Z)[Ljava/lang/reflect/Method;
452 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredMethods(java_lang_Class *klass, s4 publicOnly)
455 java_lang_reflect_Method *rm;
456 java_handle_objectarray_t *oa; /* result: array of Method-objects */
457 methodinfo *m; /* the current method to be represented */
458 s4 public_methods; /* number of public methods of the class */
462 c = LLNI_classinfo_unwrap(klass);
466 /* JOWENN: array classes do not declare methods according to mauve
467 test. It should be considered, if we should return to my old
468 clone method overriding instead of declaring it as a member
471 if (class_is_array(c))
472 return builtin_anewarray(0, class_java_lang_reflect_Method);
474 /* determine number of methods */
476 for (i = 0; i < c->methodscount; i++) {
479 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
480 ((m->name != utf_init) && (m->name != utf_clinit)) &&
481 !(m->flags & ACC_MIRANDA))
485 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Method);
490 for (i = 0, pos = 0; i < c->methodscount; i++) {
493 if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
494 ((m->name != utf_init) && (m->name != utf_clinit)) &&
495 !(m->flags & ACC_MIRANDA)) {
496 /* create Method object */
498 rm = reflect_method_new(m);
500 /* store object into array */
502 LLNI_objectarray_element_set(oa, pos, rm);
512 * Class: java/lang/Class
513 * Method: getDeclaredConstructors
514 * Signature: (Z)[Ljava/lang/reflect/Constructor;
516 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredConstructors(java_lang_Class *klass, s4 publicOnly)
519 methodinfo *m; /* the current method to be represented */
520 java_handle_objectarray_t *oa; /* result: array of Method-objects */
521 java_lang_reflect_Constructor *rc;
522 s4 public_methods; /* number of public methods of the class */
526 c = LLNI_classinfo_unwrap(klass);
528 /* determine number of constructors */
530 for (i = 0, public_methods = 0; i < c->methodscount; i++) {
533 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
534 (m->name == utf_init))
538 oa = builtin_anewarray(public_methods, class_java_lang_reflect_Constructor);
543 for (i = 0, pos = 0; i < c->methodscount; i++) {
546 if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
547 (m->name == utf_init)) {
548 /* create Constructor object */
550 rc = reflect_constructor_new(m);
552 /* store object into array */
554 LLNI_objectarray_element_set(oa, pos, rc);
564 * Class: java/lang/Class
565 * Method: getClassLoader
566 * Signature: ()Ljava/lang/ClassLoader;
568 java_lang_ClassLoader *_Jv_java_lang_Class_getClassLoader(java_lang_Class *klass)
572 c = LLNI_classinfo_unwrap(klass);
574 return (java_lang_ClassLoader *) c->classloader;
577 #endif /* defined(ENABLE_JAVASE) */
581 * Class: java/lang/Class
585 JNIEXPORT int32_t JNICALL _Jv_java_lang_Class_isArray(JNIEnv *env, java_lang_Class *this)
589 c = LLNI_classinfo_unwrap(this);
591 return class_is_array(c);
595 #if defined(ENABLE_JAVASE)
598 * Class: java/lang/Class
599 * Method: throwException
600 * Signature: (Ljava/lang/Throwable;)V
602 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
606 o = (java_handle_t *) t;
608 exceptions_set_exception(o);
612 #if defined(WITH_CLASSPATH_GNU) && defined(ENABLE_ANNOTATIONS)
614 * Class: java/lang/Class
615 * Method: getDeclaredAnnotations
616 * Signature: (Ljava/lang/Class;)[Ljava/lang/annotation/Annotation;
618 java_handle_objectarray_t *_Jv_java_lang_Class_getDeclaredAnnotations(java_lang_Class* klass)
621 static methodinfo *m_parseAnnotationsIntoArray = NULL;
622 utf *utf_parseAnnotationsIntoArray = NULL;
623 utf *utf_desc = NULL;
624 java_handle_bytearray_t *annotations = NULL;
625 sun_reflect_ConstantPool *constantPool = NULL;
626 java_lang_Object *constantPoolOop = (java_lang_Object*)klass;
629 exceptions_throw_nullpointerexception();
633 c = LLNI_classinfo_unwrap(klass);
635 /* get annotations: */
636 annotations = class_get_annotations(c);
638 if (exceptions_get_exception() != NULL) {
639 /* the only exception possible here should be a out of memory exception
640 * raised by copying the annotations into a java bytearray */
645 (sun_reflect_ConstantPool*)native_new_and_init(
646 class_sun_reflect_ConstantPool);
648 if(constantPool == NULL) {
653 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
655 /* only resolve the method the first time */
656 if (m_parseAnnotationsIntoArray == NULL) {
657 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
658 utf_desc = utf_new_char(
659 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
660 "[Ljava/lang/annotation/Annotation;");
662 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
667 m_parseAnnotationsIntoArray = class_resolveclassmethod(
668 class_sun_reflect_annotation_AnnotationParser,
669 utf_parseAnnotationsIntoArray,
671 class_java_lang_Class,
674 if (m_parseAnnotationsIntoArray == NULL) {
675 /* method not found */
680 return (java_handle_objectarray_t*)vm_call_method(
681 m_parseAnnotationsIntoArray, NULL,
682 annotations, constantPool, klass);
687 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
689 Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
690 _Jv_java_lang_Class_getEnclosingMethod.
692 *******************************************************************************/
694 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
696 constant_nameandtype *cn;
700 /* get enclosing class and method */
702 ec = class_get_enclosingclass(c);
703 cn = c->enclosingmethod;
705 /* check for enclosing class and method */
713 /* find method in enclosing class */
715 m = class_findmethod(ec, cn->name, cn->descriptor);
718 exceptions_throw_internalerror("Enclosing method doesn't exist");
727 * Class: java/lang/Class
728 * Method: getEnclosingConstructor
729 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
731 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
735 java_lang_reflect_Constructor *rc;
737 c = LLNI_classinfo_unwrap(klass);
739 /* get enclosing method */
741 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
746 /* check for <init> */
748 if (m->name != utf_init)
751 /* create Constructor object */
753 rc = reflect_constructor_new(m);
760 * Class: java/lang/Class
761 * Method: getEnclosingMethod
762 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
764 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
768 java_lang_reflect_Method *rm;
770 c = LLNI_classinfo_unwrap(klass);
772 /* get enclosing method */
774 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
779 /* check for <init> */
781 if (m->name == utf_init)
784 /* create java.lang.reflect.Method object */
786 rm = reflect_method_new(m);
793 * Class: java/lang/Class
794 * Method: getClassSignature
795 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
797 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
802 c = LLNI_classinfo_unwrap(klass);
804 if (c->signature == NULL)
807 o = javastring_new(c->signature);
809 /* in error case o is NULL */
811 return (java_lang_String *) o;
814 #endif /* ENABLE_JAVASE */
818 * These are local overrides for various environment variables in Emacs.
819 * Please do not remove this and leave it at the end of the file, where
820 * Emacs will automagically detect them.
821 * ---------------------------------------------------------------------
824 * indent-tabs-mode: t
828 * vim:noexpandtab:sw=4:ts=4: