* src/vmcore/linker.c (build_display): Removed superfluous recursion; return
[cacao.git] / src / vmcore / class.c
index 4100024f36b3ed80560a38b665039b62d6af57aa..983339f99fa1019b599878d4c5edea9f2427d322 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.
 
 #include "vmcore/utf8.h"
 
 
+#if defined(ENABLE_JAVASE)
+/* We need to define some reflection functions here since we cannot
+   include native/vm/reflect.h as it includes generated header
+   files. */
+
+java_object_t *reflect_constructor_new(methodinfo *m);
+java_object_t *reflect_field_new(fieldinfo *f);
+java_object_t *reflect_method_new(methodinfo *m);
+#endif
+
+
 /* global variables ***********************************************************/
 
 /* frequently used classes ****************************************************/
 
-/* important system classes */
+/* Important system classes. */
 
 classinfo *class_java_lang_Object;
 classinfo *class_java_lang_Class;
@@ -81,30 +90,24 @@ 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;
+classinfo *class_java_io_Serializable;
 
-#if defined(WITH_CLASSPATH_GNU)
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+classinfo *class_java_lang_VMSystem;
+classinfo *class_java_lang_VMThread;
 classinfo *class_java_lang_VMThrowable;
 #endif
 
+/* Important system exceptions. */
+
 classinfo *class_java_lang_Exception;
-classinfo *class_java_lang_ClassCastException;
 classinfo *class_java_lang_ClassNotFoundException;
+classinfo *class_java_lang_RuntimeException;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+classinfo *class_sun_reflect_MagicAccessorImpl;
+#endif
 
 #if defined(ENABLE_JAVASE)
 classinfo *class_java_lang_Void;
@@ -118,12 +121,6 @@ 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)
@@ -133,18 +130,24 @@ classinfo *class_java_lang_reflect_Field;
 classinfo *class_java_lang_reflect_Method;
 classinfo *class_java_security_PrivilegedAction;
 classinfo *class_java_util_Vector;
+classinfo *class_java_util_HashMap;
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+classinfo *class_java_lang_reflect_VMConstructor;
+classinfo *class_java_lang_reflect_VMField;
+classinfo *class_java_lang_reflect_VMMethod;
+# endif
 
 classinfo *arrayclass_java_lang_Object;
 
-#if defined(ENABLE_ANNOTATIONS)
+# if defined(ENABLE_ANNOTATIONS)
 classinfo *class_sun_reflect_ConstantPool;
-#if defined(WITH_CLASSPATH_GNU)
+#  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
 classinfo *class_sun_reflect_annotation_AnnotationParser;
-#endif
-#endif
+#  endif
+# endif
 #endif
 
-
 /* pseudo classes for the typechecker */
 
 classinfo *pseudo_class_Arraystub;
@@ -154,36 +157,47 @@ classinfo *pseudo_class_New;
 
 /* class_set_packagename *******************************************************
 
-   Derive the package name from the class name and store it in the struct.
+   Derive the package name from the class name and store it in the
+   struct.
+
+   An internal package name consists of the package name plus the
+   trailing '/', e.g. "java/lang/".
+
+   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,14 +231,15 @@ classinfo *class_create_classinfo(utf *classname)
                log_message_utf("Creating class: ", classname);
 #endif
 
-       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
-
-#if defined(ENABLE_GC_CACAO)
+#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);
-       /*c=NEW(classinfo);*/
+       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
 #endif
+
        c->name = classname;
 
        /* Set the header.vftbl of all loaded classes to the one of
@@ -298,7 +313,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;
@@ -330,7 +345,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;
@@ -365,7 +380,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;
@@ -408,7 +423,7 @@ static bool class_load_attribute_sourcefile(classbuffer *cb)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check buffer size */
 
@@ -470,7 +485,7 @@ static bool class_load_attribute_enclosingmethod(classbuffer *cb)
 
        /* get classinfo */
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* check buffer size */
 
@@ -543,7 +558,7 @@ bool class_load_attributes(classbuffer *cb)
        uint16_t               flags;
        int                    i, j;
 
-       c = cb->class;
+       c = cb->clazz;
 
        /* get attributes count */
 
@@ -654,21 +669,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))
@@ -803,7 +808,7 @@ void class_free(classinfo *c)
 {
        s4 i;
        vftbl_t *v;
-               
+
        class_freecpool(c);
 
        if (c->interfaces != NULL)
@@ -812,9 +817,7 @@ void class_free(classinfo *c)
        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) {
@@ -859,8 +862,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;
        
@@ -900,16 +903,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;
@@ -935,7 +938,7 @@ classinfo *class_array_of(classinfo *component, bool link)
 
        c = get_array_class(u, cl, cl, link);
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return c;
 }
@@ -952,10 +955,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");
@@ -986,7 +989,7 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
                                                element->classloader,
                                                link);
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return c;
 }
@@ -1114,13 +1117,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;
@@ -1143,7 +1146,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;
 }
@@ -1588,145 +1591,72 @@ bool class_isanysubclass(classinfo *sub, classinfo *super)
                if (sub->flags & ACC_INTERFACE)
                        return (super == class_java_lang_Object);
 
-               LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+#if USES_NEW_SUBTYPE
+               result = fast_subtype_check(sub->vftbl, super->vftbl);
+#else
+               LOCK_CLASSRENUMBER_LOCK;
 
                diffval = sub->vftbl->baseval - super->vftbl->baseval;
                result  = diffval <= (uint32_t) super->vftbl->diffval;
 
-               LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+               UNLOCK_CLASSRENUMBER_LOCK;
+#endif
        }
 
        return result;
 }
 
 
-/* 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_anonymousclass *****************************************************
+/* class_is_assignable_from ****************************************************
 
-   Checks if the given class is an anonymous class.
+   Return whether an instance of the "from" class parameter would be
+   an instance of this class "to" as well.
 
-*******************************************************************************/
-
-bool class_is_anonymousclass(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_ANONYMOUS)
-               return true;
-
-       return false;
-}
-
-
-/* class_is_array **************************************************************
+   ARGUMENTS:
+       to ..... class
+          from ... class
 
-   Checks if the given class is an array class.
+   RETURN:
+       true .... is assignable
+          false ... is not assignable
 
 *******************************************************************************/
 
-bool class_is_array(classinfo *c)
+bool class_is_assignable_from(classinfo *to, classinfo *from)
 {
-       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;
-
-       return false;
-}
-
-
-/* class_is_memberclass ********************************************************
-
-   Checks if the given class is a member class.
-
-*******************************************************************************/
-
-bool class_is_memberclass(classinfo *c)
-{
-       if (c->flags & ACC_CLASS_MEMBER)
-               return true;
+       if (!(from->state & CLASS_LINKED))
+               if (!link_class(from))
+                       return false;
 
-       return false;
+       return class_isanysubclass(from, to);
 }
 
 
-/* class_get_classloader *******************************************************
-
-   Return the classloader of the given class.
-
-*******************************************************************************/
-
-classloader *class_get_classloader(classinfo *c)
-{
-       classloader *cl;
+/* class_is_instance ***********************************************************
 
-       cl = c->classloader;
+   Return if the given Java object is an instance of the given class.
 
-       if (cl == NULL)
-               return NULL;
-
-       return cl;
-}
+   ARGUMENTS:
+       c ... class
+          h ... Java object
 
-
-/* class_get_superclass ********************************************************
-
-   Return the super class of the given class.
+   RETURN:
+       true .... is instance
+          false ... is not instance
 
 *******************************************************************************/
 
-classinfo *class_get_superclass(classinfo *c)
+bool class_is_instance(classinfo *c, java_handle_t *h)
 {
-       /* For interfaces we return NULL. */
-
-       if (c->flags & ACC_INTERFACE)
-               return NULL;
-
-       /* For java/lang/Object, primitive-type and Void classes c->super
-          is NULL and we return NULL. */
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
 
-       return c->super;
+       return builtin_instanceof(h, c);
 }
 
 
@@ -1755,7 +1685,7 @@ 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);
                
@@ -1851,6 +1781,210 @@ 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 Constructor object.  This is actualy a
+                          java_lang_reflect_Constructor pointer, but we use a
+                          java_handle_t here, because we don't have the header
+                          available when building vmcore. */
+
+                       rc = reflect_constructor_new(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 Field object.  This is actualy a
+                          java_lang_reflect_Field pointer, but we use a
+                          java_handle_t here, because we don't have the header
+                          available when building vmcore. */
+
+                       h = reflect_field_new(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 method object.  This is actualy a
+                          java_lang_reflect_Method pointer, but we use a
+                          java_handle_t here, because we don't have the header
+                          available when building vmcore. */
+
+                       h = reflect_method_new(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,
@@ -1929,6 +2063,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 Constructor object. */
+
+       rc = reflect_constructor_new(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 java.lang.reflect.Method object */
+
+       rm = reflect_method_new(m);
+
+       return rm;
+}
+#endif
+
+
 /* class_get_interfaces ********************************************************
 
    Return an array of interfaces of the given class.
@@ -1962,21 +2207,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
@@ -2128,11 +2435,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_print(c);
        printf("\n");
 }
+#endif
 
 
 /* class_showconstantpool ******************************************************