This commit introduces C++ wrapper classes for Java heap objects.
[cacao.git] / src / vmcore / class.c
index 51ddc07bb38667c4ebf0ac5e40cc0a8110baea98..bdbdb21a75f8ab275cdbcfac09f0ae373e91a763 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/class.c - class related functions
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -46,7 +44,7 @@
 
 #include "vm/array.h"
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/resolve.h"
 
@@ -54,6 +52,8 @@
 
 #include "vmcore/class.h"
 #include "vmcore/classcache.h"
+#include "vmcore/globals.hpp"
+#include "vmcore/javaobjects.hpp"
 #include "vmcore/linker.h"
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
 #include "vmcore/utf8.h"
 
 
-/* global variables ***********************************************************/
-
-/* frequently used classes ****************************************************/
-
-/* important system classes */
-
-classinfo *class_java_lang_Object;
-classinfo *class_java_lang_Class;
-classinfo *class_java_lang_ClassLoader;
-classinfo *class_java_lang_Cloneable;
-classinfo *class_java_lang_SecurityManager;
-classinfo *class_java_lang_String;
-classinfo *class_java_lang_System;
-classinfo *class_java_lang_Thread;
-classinfo *class_java_lang_ThreadGroup;
-classinfo *class_java_lang_VMSystem;
-classinfo *class_java_lang_VMThread;
-classinfo *class_java_io_Serializable;
-
-#if defined(WITH_CLASSPATH_SUN)
-classinfo *class_sun_reflect_MagicAccessorImpl;
-#endif
-
-/* system exception classes required in cacao */
-
-classinfo *class_java_lang_Throwable;
-classinfo *class_java_lang_Error;
-classinfo *class_java_lang_LinkageError;
-classinfo *class_java_lang_NoClassDefFoundError;
-classinfo *class_java_lang_OutOfMemoryError;
-classinfo *class_java_lang_VirtualMachineError;
-
-#if defined(WITH_CLASSPATH_GNU)
-classinfo *class_java_lang_VMThrowable;
-#endif
-
-classinfo *class_java_lang_Exception;
-classinfo *class_java_lang_ClassCastException;
-classinfo *class_java_lang_ClassNotFoundException;
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_Void;
-#endif
-classinfo *class_java_lang_Boolean;
-classinfo *class_java_lang_Byte;
-classinfo *class_java_lang_Character;
-classinfo *class_java_lang_Short;
-classinfo *class_java_lang_Integer;
-classinfo *class_java_lang_Long;
-classinfo *class_java_lang_Float;
-classinfo *class_java_lang_Double;
-
-
-/* some runtime exception */
-
-classinfo *class_java_lang_NullPointerException;
-
-
-/* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_StackTraceElement;
-classinfo *class_java_lang_reflect_Constructor;
-classinfo *class_java_lang_reflect_Field;
-classinfo *class_java_lang_reflect_Method;
-classinfo *class_java_security_PrivilegedAction;
-classinfo *class_java_util_Vector;
-
-classinfo *arrayclass_java_lang_Object;
-
-#if defined(ENABLE_ANNOTATIONS)
-classinfo *class_sun_reflect_ConstantPool;
-#if defined(WITH_CLASSPATH_GNU)
-classinfo *class_sun_reflect_annotation_AnnotationParser;
-#endif
-#endif
-#endif
-
-
-/* pseudo classes for the typechecker */
-
-classinfo *pseudo_class_Arraystub;
-classinfo *pseudo_class_Null;
-classinfo *pseudo_class_New;
+/* class_set_packagename *******************************************************
 
+   Derive the package name from the class name and store it in the
+   struct.
 
-/* class_set_packagename *******************************************************
+   An internal package name consists of the package name plus the
+   trailing '/', e.g. "java/lang/".
 
-   Derive the package name from the class name and store it in the struct.
+   For classes in the unnamed package, the package name is set to
+   NULL.
 
 *******************************************************************************/
 
 void class_set_packagename(classinfo *c)
 {
-       char *p = UTF_END(c->name) - 1;
-       char *start = c->name->text;
+       char *p;
+       char *start;
 
-       /* set the package name */
-       /* classes in the unnamed package keep packagename == NULL */
+       p     = UTF_END(c->name) - 1;
+       start = c->name->text;
 
        if (c->name->text[0] == '[') {
-               /* set packagename of arrays to the element's package */
+               /* Set packagename of arrays to the element's package. */
 
                for (; *start == '['; start++);
 
-               /* skip the 'L' in arrays of references */
+               /* Skip the 'L' in arrays of references. */
+
                if (*start == 'L')
                        start++;
+       }
 
-               for (; (p > start) && (*p != '/'); --p);
+       /* Search for last '/'. */
 
-               c->packagename = utf_new(start, p - start);
+       for (; (p > start) && (*p != '/'); --p);
 
-       } else {
-               for (; (p > start) && (*p != '/'); --p);
+       /* If we found a '/' we set the package name plus the trailing
+          '/'.  Otherwise we set the packagename to NULL. */
 
-               c->packagename = utf_new(start, p - start);
-       }
+       if (p > start)
+               c->packagename = utf_new(start, p - start + 1);
+       else
+               c->packagename = NULL;
 }
 
 
@@ -217,10 +142,15 @@ classinfo *class_create_classinfo(utf *classname)
                log_message_utf("Creating class: ", classname);
 #endif
 
+#if !defined(ENABLE_GC_BOEHM)
+       c = (classinfo *) heap_alloc_uncollectable(sizeof(classinfo));
+       /*c = NEW(classinfo);
+       MZERO(c, classinfo, 1);*/
+#else
+       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
        /* GCNEW_UNCOLLECTABLE clears the allocated memory */
+#endif
 
-       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
-       /*c=NEW(classinfo);*/
        c->name = classname;
 
        /* Set the header.vftbl of all loaded classes to the one of
@@ -294,7 +224,7 @@ void class_postset_header_vftbl(void)
 
 *******************************************************************************/
 
-classinfo *class_define(utf *name, classloader *cl, int32_t length, const uint8_t *data, java_handle_t *pd)
+classinfo *class_define(utf *name, classloader_t *cl, int32_t length, uint8_t *data, java_handle_t *pd)
 {
        classinfo   *c;
        classinfo   *r;
@@ -326,7 +256,7 @@ classinfo *class_define(utf *name, classloader *cl, int32_t length, const uint8_
 
        cb = NEW(classbuffer);
 
-       cb->class = c;
+       cb->clazz = c;
        cb->size  = length;
        cb->data  = data;
        cb->pos   = cb->data;
@@ -361,7 +291,7 @@ classinfo *class_define(utf *name, classloader *cl, int32_t length, const uint8_
        }
 
 #if defined(ENABLE_JAVASE)
-# if defined(WITH_CLASSPATH_SUN)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
        /* Store the protection domain. */
 
        c->protectiondomain = pd;
@@ -404,7 +334,7 @@ static bool class_load_attribute_sourcefile(classbuffer *cb)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check buffer size */
 
@@ -466,7 +396,7 @@ static bool class_load_attribute_enclosingmethod(classbuffer *cb)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check buffer size */
 
@@ -539,7 +469,7 @@ bool class_load_attributes(classbuffer *cb)
        uint16_t               flags;
        int                    i, j;
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* get attributes count */
 
@@ -650,21 +580,11 @@ bool class_load_attributes(classbuffer *cb)
 #endif
 
 #if defined(ENABLE_ANNOTATIONS)
-               /* XXX We can't do a release with that enabled */
-
                else if (attribute_name == utf_RuntimeVisibleAnnotations) {
                        /* RuntimeVisibleAnnotations */
                        if (!annotation_load_class_attribute_runtimevisibleannotations(cb))
                                return false;
                }
-               /* XXX RuntimeInvisibleAnnotations should only be loaded
-                * (or returned to Java) if some commandline options says so.
-                * Currently there is no such option available in cacao,
-                * therefore I load them allways (for testing purpose).
-                * Anyway, bytecode for RuntimeInvisibleAnnotations is only
-                * generated if you tell javac to do so. So in most cases
-                * there won't be any.
-                */
                else if (attribute_name == utf_RuntimeInvisibleAnnotations) {
                        /* RuntimeInvisibleAnnotations */
                        if (!annotation_load_class_attribute_runtimeinvisibleannotations(cb))
@@ -694,7 +614,7 @@ static void class_freecpool(classinfo *c)
 {
        u4 idx;
        u4 tag;
-       voidptr info;
+       void* info;
        
        if (c->cptags && c->cpinfos) {
                for (idx = 0; idx < c->cpcount; idx++) {
@@ -732,7 +652,7 @@ static void class_freecpool(classinfo *c)
                MFREE(c->cptags, u1, c->cpcount);
 
        if (c->cpinfos)
-               MFREE(c->cpinfos, voidptr, c->cpcount);
+               MFREE(c->cpinfos, void*, c->cpcount);
 }
 
 
@@ -744,7 +664,7 @@ static void class_freecpool(classinfo *c)
 
 *******************************************************************************/
 
-voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
+void* class_getconstant(classinfo *c, u4 pos, u4 ctype)
 {
        /* check index and type of constantpool entry */
        /* (pos == 0 is caught by type comparison) */
@@ -764,7 +684,7 @@ voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
        
 *******************************************************************************/
 
-voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
+void* innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
 {
        /* invalid position in constantpool */
 
@@ -799,18 +719,16 @@ void class_free(classinfo *c)
 {
        s4 i;
        vftbl_t *v;
-               
+
        class_freecpool(c);
 
-       if (c->interfaces)
+       if (c->interfaces != NULL)
                MFREE(c->interfaces, classinfo*, c->interfacescount);
 
        if (c->fields) {
                for (i = 0; i < c->fieldscount; i++)
                        field_free(&(c->fields[i]));
-#if defined(ENABLE_CACAO_GC)
                MFREE(c->fields, fieldinfo, c->fieldscount);
-#endif
        }
        
        if (c->methods) {
@@ -855,8 +773,8 @@ void class_free(classinfo *c)
 
 *******************************************************************************/
 
-static classinfo *get_array_class(utf *name,classloader *initloader,
-                                                                                       classloader *defloader,bool link)
+static classinfo *get_array_class(utf *name,classloader_t *initloader,
+                                                                                       classloader_t *defloader,bool link)
 {
        classinfo *c;
        
@@ -896,16 +814,16 @@ static classinfo *get_array_class(utf *name,classloader *initloader,
 
 classinfo *class_array_of(classinfo *component, bool link)
 {
-       classloader       *cl;
+       classloader_t     *cl;
     s4                 namelen;
     char              *namebuf;
        utf               *u;
        classinfo         *c;
-       s4                 dumpsize;
+       int32_t            dumpmarker;
 
        cl = component->classloader;
 
-       dumpsize = dump_size();
+       DMARKER;
 
     /* Assemble the array class name */
     namelen = component->name->blength;
@@ -931,7 +849,7 @@ classinfo *class_array_of(classinfo *component, bool link)
 
        c = get_array_class(u, cl, cl, link);
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return c;
 }
@@ -948,10 +866,10 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
 {
     s4 namelen;
     char *namebuf;
-       s4 dumpsize;
        classinfo *c;
+       int32_t    dumpmarker;
 
-       dumpsize = dump_size();
+       DMARKER;
 
        if (dim < 1) {
                log_text("Invalid array dimension requested");
@@ -982,7 +900,7 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
                                                element->classloader,
                                                link);
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return c;
 }
@@ -1110,13 +1028,13 @@ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *r
 {
     s4 namelen;
     char *namebuf;
-       s4 dumpsize;
        constant_classref *cr;
+       int32_t            dumpmarker;
 
        assert(ref);
        assert(dim >= 1 && dim <= 255);
 
-       dumpsize = dump_size();
+       DMARKER;
 
     /* Assemble the array class name */
     namelen = ref->name->blength;
@@ -1139,7 +1057,7 @@ constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *r
 
     cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return cr;
 }
@@ -1236,7 +1154,7 @@ methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
                if (name == utf_init || name == utf_clinit)
                        return NULL;
 
-               c = c->super.cls;
+               c = c->super;
        }
 
        return NULL;
@@ -1262,11 +1180,10 @@ static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
        if (m != NULL)
                return m;
 
-       /* no method found? try the superinterfaces */
+       /* No method found?  Try the super interfaces. */
 
        for (i = 0; i < c->interfacescount; i++) {
-               m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
-                                                                                                       name, desc);
+               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
 
                if (m != NULL)
                        return m;
@@ -1311,11 +1228,10 @@ methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
        if (m != NULL)
                goto found;
 
-       /* try the superinterfaces */
+       /* Try the super interfaces. */
 
        for (i = 0; i < c->interfacescount; i++) {
-               m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
-                                                                                               name, desc);
+               m = class_resolveinterfacemethod_intern(c->interfaces[i], name, desc);
 
                if (m != NULL)
                        goto found;
@@ -1396,8 +1312,8 @@ fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
                if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
                        return &(c->fields[i]);
 
-       if (c->super.cls)
-               return class_findfield(c->super.cls, name, desc);
+       if (c->super != NULL)
+               return class_findfield(c->super, name, desc);
 
        return NULL;
 }
@@ -1410,41 +1326,18 @@ fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
 
 *******************************************************************************/
  
-fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
-{
-       s4 i;
-
-       /* get field index */
-
-       i = class_findfield_index_by_name(c, name);
-
-       /* field was not found, return */
-
-       if (i == -1)
-               return NULL;
-
-       /* return field address */
-
-       return &(c->fields[i]);
-}
-
-
-s4 class_findfield_index_by_name(classinfo *c, utf *name)
+fieldinfo *class_findfield_by_name(classinfo* c, utf* name)
 {
-       s4 i;
+       for (int32_t i = 0; i < c->fieldscount; i++) {
+               fieldinfo* f = &(c->fields[i]);
 
-       for (i = 0; i < c->fieldscount; i++) {
-               /* compare field names */
-
-               if ((c->fields[i].name == name))
-                       return i;
+               if (f->name == name)
+                       return f;
        }
 
-       /* field was not found, raise exception */      
-
+       // Field not found.
        exceptions_throw_nosuchfielderror(c, name);
-
-       return -1;
+       return NULL;
 }
 
 
@@ -1470,18 +1363,19 @@ static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
                }
     }
 
-       /* try superinterfaces recursively */
+       /* Try super interfaces recursively. */
 
        for (i = 0; i < c->interfacescount; i++) {
-               fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
-               if (fi)
+               fi = class_resolvefield_int(c->interfaces[i], name, desc);
+
+               if (fi != NULL)
                        return fi;
        }
 
-       /* try superclass */
+       /* Try super class. */
 
-       if (c->super.cls)
-               return class_resolvefield_int(c->super.cls, name, desc);
+       if (c->super != NULL)
+               return class_resolvefield_int(c->super, name, desc);
 
        /* not found */
 
@@ -1493,22 +1387,19 @@ static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
        
        Resolves a reference from REFERER to a field with NAME and DESC in class C.
 
-    If the field cannot be resolved the return value is NULL. If EXCEPT is
-    true *exceptionptr is set, too.
+    If the field cannot be resolved, an exception is thrown and the
+    return value is NULL.
 
 *******************************************************************************/
 
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
-                                                         classinfo *referer, bool throwexception)
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer)
 {
        fieldinfo *fi;
 
        fi = class_resolvefield_int(c, name, desc);
 
        if (!fi) {
-               if (throwexception)
-                       exceptions_throw_nosuchfielderror(c, name);
-
+               exceptions_throw_nosuchfielderror(c, name);
                return NULL;
        }
 
@@ -1518,38 +1409,6 @@ fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
 }
 
 
-/* class_resolve_superclass ****************************************************
-
-   Resolves the super class reference of the given class if necessary.
-
-*******************************************************************************/
-
-static classinfo *class_resolve_superclass(classinfo *c)
-{
-       classinfo *super;
-
-       if (c->super.any == NULL)
-               return NULL;
-
-       /* Check if the super class is a reference. */
-
-       if (IS_CLASSREF(c->super)) {
-               /* XXX I'm very sure this is not correct. */
-               super = resolve_classref_or_classinfo_eager(c->super, true);
-/*             super = resolve_classref_or_classinfo_eager(c->super, false); */
-
-               if (super == NULL)
-                       return NULL;
-
-               /* Store the resolved super class in the class structure. */
-
-               c->super.cls = super;
-       }
-
-       return c->super.cls;
-}
-
-
 /* class_issubclass ************************************************************
 
    Checks if sub is a descendant of super.
@@ -1558,20 +1417,23 @@ static classinfo *class_resolve_superclass(classinfo *c)
 
 bool class_issubclass(classinfo *sub, classinfo *super)
 {
-       for (;;) {
-               if (sub == NULL)
-                       return false;
+       classinfo *c;
 
-               if (sub == super)
-                       return true;
+       c = sub;
 
-/*             sub = class_resolve_superclass(sub); */
-               if (sub->super.any == NULL)
+       for (;;) {
+               /* We reached java/lang/Object and did not find the requested
+                  super class. */
+
+               if (c == NULL)
                        return false;
 
-               assert(IS_CLASSREF(sub->super) == 0);
+               /* We found the requested super class. */
 
-               sub = sub->super.cls;
+               if (c == super)
+                       return true;
+
+               c = c->super;
        }
 }
 
@@ -1626,124 +1488,56 @@ bool class_isanysubclass(classinfo *sub, classinfo *super)
 }
 
 
-/* class_is_primitive **********************************************************
-
-   Checks if the given class is a primitive class.
-
-*******************************************************************************/
-
-bool class_is_primitive(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_PRIMITIVE)
-               return true;
-
-       return false;
-}
+/* class_is_assignable_from ****************************************************
 
+   Return whether an instance of the "from" class parameter would be
+   an instance of this class "to" as well.
 
-/* class_is_anonymousclass *****************************************************
+   ARGUMENTS:
+       to ..... class
+          from ... class
 
-   Checks if the given class is an anonymous class.
+   RETURN:
+       true .... is assignable
+          false ... is not assignable
 
 *******************************************************************************/
 
-bool class_is_anonymousclass(classinfo *c)
+bool class_is_assignable_from(classinfo *to, classinfo *from)
 {
-       if (c->flags & ACC_CLASS_ANONYMOUS)
-               return true;
-
-       return false;
-}
-
-
-/* class_is_array **************************************************************
-
-   Checks if the given class is an array class.
-
-*******************************************************************************/
-
-bool class_is_array(classinfo *c)
-{
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
+       if (!(to->state & CLASS_LINKED))
+               if (!link_class(to))
                        return false;
 
-       return (c->vftbl->arraydesc != NULL);
-}
-
-
-/* class_is_interface **********************************************************
-
-   Checks if the given class is an interface.
-
-*******************************************************************************/
-
-bool class_is_interface(classinfo *c)
-{
-       if (c->flags & ACC_INTERFACE)
-               return true;
-
-       return false;
-}
-
-
-/* class_is_localclass *********************************************************
-
-   Checks if the given class is a local class.
-
-*******************************************************************************/
-
-bool class_is_localclass(classinfo *c)
-{
-       if ((c->enclosingmethod != NULL) && !class_is_anonymousclass(c))
-               return true;
+       if (!(from->state & CLASS_LINKED))
+               if (!link_class(from))
+                       return false;
 
-       return false;
+       return class_isanysubclass(from, to);
 }
 
 
-/* class_is_memberclass ********************************************************
+/* class_is_instance ***********************************************************
 
-   Checks if the given class is a member class.
+   Return if the given Java object is an instance of the given class.
 
-*******************************************************************************/
+   ARGUMENTS:
+       c ... class
+          h ... Java object
 
-bool class_is_memberclass(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_MEMBER)
-               return true;
-
-       return false;
-}
-
-
-/* class_get_superclass ********************************************************
-
-   Return the super class of the given class.  If the super-field is a
-   class-reference, resolve it and store it in the classinfo.
+   RETURN:
+       true .... is instance
+          false ... is not instance
 
 *******************************************************************************/
 
-classinfo *class_get_superclass(classinfo *c)
+bool class_is_instance(classinfo *c, java_handle_t *h)
 {
-       classinfo *super;
-
-       /* For java.lang.Object, primitive and Void classes we return
-          NULL. */
-
-       if (c->super.any == NULL)
-               return NULL;
-
-       /* For interfaces we also return NULL. */
-
-       if (c->flags & ACC_INTERFACE)
-               return NULL;
-
-       /* We may have to resolve the super class reference. */
-
-       super = class_resolve_superclass(c);
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
 
-       return super;
+       return builtin_instanceof(h, c);
 }
 
 
@@ -1772,9 +1566,9 @@ classinfo *class_get_componenttype(classinfo *c)
                return NULL;
        
        if (ad->arraytype == ARRAYTYPE_OBJECT)
-               component = ad->componentvftbl->class;
+               component = ad->componentvftbl->clazz;
        else
-               component = primitive_class_get_by_type(ad->arraytype);
+               component = Primitive_get_class_by_type(ad->arraytype);
                
        return component;
 }
@@ -1868,6 +1662,201 @@ java_handle_objectarray_t *class_get_declaredclasses(classinfo *c, bool publicOn
 }
 
 
+/**
+ * Return an array of declared constructors of the given class.
+ *
+ * @param c          class to get the constructors of
+ * @param publicOnly show only public fields
+ *
+ * @return array of java.lang.reflect.Constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredconstructors(classinfo *c, bool publicOnly)
+{
+       methodinfo*                m;
+       java_handle_objectarray_t* oa;
+       java_handle_t*             rc;
+       int                        count;
+       int                        index;
+       int                        i;
+
+       /* Determine number of constructors. */
+
+       count = 0;
+
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+                       (m->name == utf_init))
+                       count++;
+       }
+
+       /* Create array of constructors. */
+
+       oa = builtin_anewarray(count, class_java_lang_reflect_Constructor);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* Get the constructors and store them in the array. */
+
+       for (i = 0, index = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == 0)) &&
+                       (m->name == utf_init)) {
+                       // Create a java.lang.reflect.Constructor object.
+
+                       rc = java_lang_reflect_Constructor_create(m);
+
+                       /* Store object into array. */
+
+                       array_objectarray_element_set(oa, index, rc);
+                       index++;
+               }
+       }
+
+       return oa;
+}
+#endif
+
+
+/* class_get_declaredfields ****************************************************
+
+   Return an array of declared fields of the given class.
+
+   ARGUMENTS:
+       c ............ class to get the fields of
+          publicOnly ... show only public fields
+
+   RETURN:
+       array of java.lang.reflect.Field
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredfields(classinfo *c, bool publicOnly)
+{
+       java_handle_objectarray_t *oa;
+       fieldinfo                 *f;
+       java_handle_t             *h;
+       int                        count;
+       int                        index;
+       int                        i;
+
+       /* Determine number of fields. */
+
+       count = 0;
+
+       for (i = 0; i < c->fieldscount; i++)
+               if ((c->fields[i].flags & ACC_PUBLIC) || (publicOnly == 0))
+                       count++;
+
+       /* Create array of fields. */
+
+       oa = builtin_anewarray(count, class_java_lang_reflect_Field);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* Get the fields and store them in the array. */
+
+       for (i = 0, index = 0; i < c->fieldscount; i++) {
+               f = &(c->fields[i]);
+
+               if ((f->flags & ACC_PUBLIC) || (publicOnly == 0)) {
+                       // Create a java.lang.reflect.Field object.
+
+                       h = java_lang_reflect_Field_create(f);
+
+                       /* Store object into array. */
+
+                       array_objectarray_element_set(oa, index, h);
+                       index++;
+               }
+       }
+
+       return oa;
+}
+#endif
+
+
+/* class_get_declaredmethods ***************************************************
+
+   Return an array of declared methods of the given class.
+
+   ARGUMENTS:
+       c ............ class to get the methods of
+          publicOnly ... show only public methods
+
+   RETURN:
+       array of java.lang.reflect.Method
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *class_get_declaredmethods(classinfo *c, bool publicOnly)
+{
+       java_handle_objectarray_t *oa;         /* result: array of Method-objects */
+       methodinfo                *m;     /* the current method to be represented */
+       java_handle_t             *h;
+       int                        count;
+       int                        index;
+       int                        i;
+
+       /* JOWENN: array classes do not declare methods according to mauve
+          test.  It should be considered, if we should return to my old
+          clone method overriding instead of declaring it as a member
+          function. */
+
+       if (class_is_array(c))
+               return builtin_anewarray(0, class_java_lang_reflect_Method);
+
+       /* Determine number of methods. */
+
+       count = 0;
+
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) &&
+                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
+                       !(m->flags & ACC_MIRANDA))
+                       count++;
+       }
+
+       /* Create array of methods. */
+
+       oa = builtin_anewarray(count, class_java_lang_reflect_Method);
+
+       if (oa == NULL)
+               return NULL;
+
+       /* Get the methods and store them in the array. */
+
+       for (i = 0, index = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if (((m->flags & ACC_PUBLIC) || (publicOnly == false)) && 
+                       ((m->name != utf_init) && (m->name != utf_clinit)) &&
+                       !(m->flags & ACC_MIRANDA)) {
+                       // Create java.lang.reflect.Method object.
+
+                       h = java_lang_reflect_Method_create(m);
+
+                       /* Store object into array. */
+
+                       array_objectarray_element_set(oa, index, h);
+                       index++;
+               }
+       }
+
+       return oa;
+}
+#endif
+
+
 /* class_get_declaringclass ****************************************************
 
    If the class or interface given is a member of another class,
@@ -1946,6 +1935,117 @@ classinfo *class_get_enclosingclass(classinfo *c)
 }
 
 
+/**
+ * Return the enclosing constructor as java.lang.reflect.Constructor
+ * object for the given class.
+ *
+ * @param c class to return the enclosing constructor for
+ *
+ * @return java.lang.reflect.Constructor object of the enclosing
+ * constructor
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* class_get_enclosingconstructor(classinfo *c)
+{
+       methodinfo*    m;
+       java_handle_t* rc;
+
+       m = class_get_enclosingmethod_raw(c);
+
+       if (m == NULL)
+               return NULL;
+
+       /* Check for <init>. */
+
+       if (m->name != utf_init)
+               return NULL;
+
+       // Create a java.lang.reflect.Constructor object.
+
+       rc = java_lang_reflect_Constructor_create(m);
+
+       return rc;
+}
+#endif
+
+
+/* class_get_enclosingmethod ***************************************************
+
+   Return the enclosing method for the given class.
+
+   IN:
+       c ... class to return the enclosing method for
+
+   RETURN:
+       methodinfo of the enclosing method
+
+*******************************************************************************/
+
+methodinfo *class_get_enclosingmethod_raw(classinfo *c)
+{
+       constant_nameandtype *cn;
+       classinfo            *ec;
+       methodinfo           *m;
+
+       /* get enclosing class and method */
+
+       ec = class_get_enclosingclass(c);
+       cn = c->enclosingmethod;
+
+       /* check for enclosing class and method */
+
+       if (ec == NULL)
+               return NULL;
+
+       if (cn == NULL)
+               return NULL;
+
+       /* find method in enclosing class */
+
+       m = class_findmethod(ec, cn->name, cn->descriptor);
+
+       if (m == NULL) {
+               exceptions_throw_internalerror("Enclosing method doesn't exist");
+               return NULL;
+       }
+
+       return m;
+}
+
+
+/**
+ * Return the enclosing method as java.lang.reflect.Method object for
+ * the given class.
+ *
+ * @param c class to return the enclosing method for
+ *
+ * @return java.lang.reflect.Method object of the enclosing method
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* class_get_enclosingmethod(classinfo *c)
+{
+       methodinfo*    m;
+       java_handle_t* rm;
+
+       m = class_get_enclosingmethod_raw(c);
+
+       if (m == NULL)
+               return NULL;
+
+       /* check for <init> */
+
+       if (m->name == utf_init)
+               return NULL;
+
+       // Create a java.lang.reflect.Method object.
+
+       rm = java_lang_reflect_Method_create(m);
+
+       return rm;
+}
+#endif
+
+
 /* class_get_interfaces ********************************************************
 
    Return an array of interfaces of the given class.
@@ -1968,7 +2068,7 @@ java_handle_objectarray_t *class_get_interfaces(classinfo *c)
                return NULL;
 
        for (i = 0; i < c->interfacescount; i++) {
-               ic = c->interfaces[i].cls;
+               ic = c->interfaces[i];
 
                LLNI_array_direct(oa, i) = (java_object_t *) ic;
        }
@@ -1979,21 +2079,83 @@ java_handle_objectarray_t *class_get_interfaces(classinfo *c)
 
 /* class_get_annotations *******************************************************
 
-   Return the unparsed declared annotations in an byte array
-   of the given class (or NULL if there aren't any).
+   Get the unparsed declared annotations in a byte array
+   of the given class.
+
+   IN:
+       c........the class of which the annotations should be returned
+
+   RETURN VALUE:
+       The unparsed declared annotations in a byte array
+       (or NULL if there aren't any).
 
 *******************************************************************************/
 
 java_handle_bytearray_t *class_get_annotations(classinfo *c)
 {
 #if defined(ENABLE_ANNOTATIONS)
-       return c->annotations;
+       java_handle_t *annotations; /* unparsed annotations */
+
+       LLNI_classinfo_field_get(c, annotations, annotations);
+
+       return (java_handle_bytearray_t*)annotations;
 #else
        return NULL;
 #endif
 }
 
 
+/* class_get_modifiers *********************************************************
+
+   Get the modifier flags of the given class.
+
+   IN:
+       c....the class of which the modifier flags should be returned
+          ignoreInnerClassesAttrib
+   RETURN VALUE:
+       modifier flags
+
+*******************************************************************************/
+
+int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
+{
+       classref_or_classinfo  inner;
+       classref_or_classinfo  outer;
+       utf                   *innername;
+       int                    i;
+
+       if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
+               /* search for passed class as inner class */
+
+               for (i = 0; i < c->innerclasscount; i++) {
+                       inner = c->innerclass[i].inner_class;
+                       outer = c->innerclass[i].outer_class;
+
+                       /* Check if inner is a classref or a real class and get
+               the name of the structure */
+
+                       innername = IS_CLASSREF(inner) ? inner.ref->name : inner.cls->name;
+
+                       /* innerclass is this class */
+
+                       if (innername == c->name) {
+                               /* has the class actually an outer class? */
+
+                               if (outer.any)
+                                       /* return flags got from the outer class file */
+                                       return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
+                               else
+                                       return c->flags & ACC_CLASS_REFLECT_MASK;
+                       }
+               }
+       }
+
+       /* passed class is no inner class or it was not requested */
+
+       return c->flags & ACC_CLASS_REFLECT_MASK;
+}
+
+
 /* class_get_signature *********************************************************
 
    Return the signature of the given class.  For array and primitive
@@ -2145,11 +2307,13 @@ void class_classref_or_classinfo_print(classref_or_classinfo c)
 
 *******************************************************************************/
 
+#if !defined(NDEBUG)
 void class_classref_or_classinfo_println(classref_or_classinfo c)
 {
-       class_classref_or_classinfo_println(c);
+       class_classref_or_classinfo_print(c);
        printf("\n");
 }
+#endif
 
 
 /* class_showconstantpool ******************************************************
@@ -2162,7 +2326,7 @@ void class_classref_or_classinfo_println(classref_or_classinfo c)
 void class_showconstantpool (classinfo *c) 
 {
        u4 i;
-       voidptr e;
+       void* e;
 
        printf ("---- dump of constant pool ----\n");
 
@@ -2258,9 +2422,9 @@ void class_showmethods (classinfo *c)
        utf_display_printable_ascii(c->name);
        printf("\n");
 
-       if (c->super.cls) {
+       if (c->super) {
                printf("Super: ");
-               utf_display_printable_ascii(c->super.cls->name);
+               utf_display_printable_ascii(c->super->name);
                printf ("\n");
        }
 
@@ -2269,8 +2433,8 @@ void class_showmethods (classinfo *c)
        printf("Interfaces:\n");        
        for (i = 0; i < c->interfacescount; i++) {
                printf("   ");
-               utf_display_printable_ascii(c->interfaces[i].cls->name);
-               printf (" (%d)\n", c->interfaces[i].cls->index);
+               utf_display_printable_ascii(c->interfaces[i]->name);
+               printf (" (%d)\n", c->interfaces[i]->index);
        }
 
        printf("Fields:\n");