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 8339 2007-08-17 21:21:51Z twisti $
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)
102 c = (classinfo *) 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 = (classloader *) 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 (java_lang_Class *) 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 = (classinfo *) 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 = (classinfo *) klass;
229 cc = (classinfo *) 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 = (classinfo *) 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 = (classinfo *) 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 = (classinfo *) klass;
292 super = class_get_superclass(c);
294 return (java_lang_Class *) 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 = (classinfo *) 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 = (classinfo *) 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)
372 c = (classinfo *) klass;
374 return (java_lang_Class *) class_get_declaringclass(c);
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 = (classinfo *) 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 = (classinfo *) 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 = (classinfo *) 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 = (classinfo *) 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 = (classinfo *) 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 = (classinfo *) 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)
620 classinfo *c = (classinfo*)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;
627 java_lang_Object *constantPoolOop = (java_lang_Object*)klass;
630 exceptions_throw_nullpointerexception();
634 /* Return null for arrays and primitives: */
635 if (class_is_primitive(c) || class_is_array(c)) {
639 if (c->annotations != NULL) {
640 size = c->annotations->size;
641 annotations = builtin_newarray_byte(size);
643 if(annotations != NULL) {
644 MCOPY(annotations->data, c->annotations->data, uint8_t, size);
649 (sun_reflect_ConstantPool*)native_new_and_init(
650 class_sun_reflect_ConstantPool);
652 if(constantPool == NULL) {
657 LLNI_field_set_ref(constantPool, constantPoolOop, constantPoolOop);
659 /* only resolve the method the first time */
660 if (m_parseAnnotationsIntoArray == NULL) {
661 utf_parseAnnotationsIntoArray = utf_new_char("parseAnnotationsIntoArray");
662 utf_desc = utf_new_char(
663 "([BLsun/reflect/ConstantPool;Ljava/lang/Class;)"
664 "[Ljava/lang/annotation/Annotation;");
666 if (utf_parseAnnotationsIntoArray == NULL || utf_desc == NULL) {
671 m_parseAnnotationsIntoArray = class_resolveclassmethod(
672 class_sun_reflect_annotation_AnnotationParser,
673 utf_parseAnnotationsIntoArray,
675 class_java_lang_Class,
678 if (m_parseAnnotationsIntoArray == NULL) {
679 /* method not found */
684 return (java_handle_objectarray_t*)vm_call_method(
685 m_parseAnnotationsIntoArray, NULL,
686 annotations, constantPool, klass);
691 /* _Jv_java_lang_Class_getEnclosingMethod_intern *******************************
693 Helper function for _Jv_java_lang_Class_getEnclosingConstructor and
694 _Jv_java_lang_Class_getEnclosingMethod.
696 *******************************************************************************/
698 static methodinfo *_Jv_java_lang_Class_getEnclosingMethod_intern(classinfo *c)
700 constant_nameandtype *cn;
704 /* get enclosing class and method */
706 ec = class_get_enclosingclass(c);
707 cn = c->enclosingmethod;
709 /* check for enclosing class and method */
717 /* find method in enclosing class */
719 m = class_findmethod(ec, cn->name, cn->descriptor);
722 exceptions_throw_internalerror("Enclosing method doesn't exist");
731 * Class: java/lang/Class
732 * Method: getEnclosingConstructor
733 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
735 java_lang_reflect_Constructor *_Jv_java_lang_Class_getEnclosingConstructor(java_lang_Class *klass)
739 java_lang_reflect_Constructor *rc;
741 c = (classinfo *) klass;
743 /* get enclosing method */
745 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
750 /* check for <init> */
752 if (m->name != utf_init)
755 /* create Constructor object */
757 rc = reflect_constructor_new(m);
764 * Class: java/lang/Class
765 * Method: getEnclosingMethod
766 * Signature: (Ljava/lang/Class;)Ljava/lang/reflect/Method;
768 java_lang_reflect_Method *_Jv_java_lang_Class_getEnclosingMethod(java_lang_Class *klass)
772 java_lang_reflect_Method *rm;
774 c = (classinfo *) klass;
776 /* get enclosing method */
778 m = _Jv_java_lang_Class_getEnclosingMethod_intern(c);
783 /* check for <init> */
785 if (m->name == utf_init)
788 /* create java.lang.reflect.Method object */
790 rm = reflect_method_new(m);
797 * Class: java/lang/Class
798 * Method: getClassSignature
799 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
801 java_lang_String *_Jv_java_lang_Class_getClassSignature(java_lang_Class* klass)
806 c = (classinfo *) klass;
808 if (c->signature == NULL)
811 o = javastring_new(c->signature);
813 /* in error case o is NULL */
815 return (java_lang_String *) o;
818 #endif /* ENABLE_JAVASE */
822 * These are local overrides for various environment variables in Emacs.
823 * Please do not remove this and leave it at the end of the file, where
824 * Emacs will automagically detect them.
825 * ---------------------------------------------------------------------
828 * indent-tabs-mode: t
832 * vim:noexpandtab:sw=4:ts=4: