* src/vmcore/class.h (classinfo): Changed type of super and interfaces
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Sun, 2 Sep 2007 17:37:50 +0000 (19:37 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Sun, 2 Sep 2007 17:37:50 +0000 (19:37 +0200)
to classinfo*.
* src/cacaoh/headers.c (printfields): Removed .cls for super class
and/or interfaces.
* src/vm/initialize.c (initialize_class_intern): Likewise.
* src/vm/jit/verify/typecheck-invoke.inc: Likewise.
* src/vm/jit/verify/typeinfo.c (interface_extends_interface):
Likewise.
(typeinfo_merge_nonarrays): Likewise.
* src/vm/resolve.c (resolve_method_invokespecial_lookup): Likwise.
* src/vmcore/class.c (class_free): Likewise.
(class_resolvemethod): Likewise.
(class_resolveinterface_intern): Likewise.
(class_resolveclassmethod): Likewise.
(class_findfield): Likewise.
(class_resolvefield_int): Likewise.
(class_get_interfaces): Likewise.
(class_issubclass): Likewise.
(class_get_superclass): Likewise.
(class_showmethods): Likewise.
(class_showmethods): Likewise.
(class_resolve_superclass): Removed.
* src/vmcore/linker.c (linker_init): Removed .cls for super class
and/or interfaces.
(linker_compute_subclasses): Likewise.
(linker_addinterface): Likewise.
(link_class_intern): Moved verifier checks into classfile parsing
stage.
* src/vmcore/loader.c (vm/resolve.h): Added.
(load_class_from_classbuffer_intern): Resolve super class and super
interfaces during loading. This is also done by the RI.
(load_newly_created_array): Removed .cls for super class and/or
interfaces.
* src/vmcore/primitivecore.c (primitive_init): Likewise.

src/cacaoh/headers.c
src/vm/initialize.c
src/vm/jit/verify/typecheck-invoke.inc
src/vm/jit/verify/typeinfo.c
src/vm/resolve.c
src/vmcore/class.c
src/vmcore/class.h
src/vmcore/linker.c
src/vmcore/loader.c
src/vmcore/primitivecore.c

index 0971ba6d2a3a64a244bdd9f8c9e13be846f74f27..d3b080f26ce40db038b70464f1c479bfeaaf0939 100644 (file)
@@ -250,7 +250,7 @@ static void printfields(classinfo *c)
                return;
        }
                
-       printfields(c->super.cls);
+       printfields(c->super);
        
        for (i = 0; i < c->fieldscount; i++) {
                f = &(c->fields[i]);
index cc847933a6c921c2124d993f1508da4bc74dce61..e6313678bf91ab2da53459defe90f2a64604559a 100644 (file)
@@ -142,19 +142,19 @@ static bool initialize_class_intern(classinfo *c)
                count_class_inits++;
 #endif
 
-       /* initialize super class */
+       /* Initialize super class. */
 
-       if (c->super.cls) {
-               if (!(c->super.cls->state & CLASS_INITIALIZED)) {
+       if (c->super != NULL) {
+               if (!(c->super->state & CLASS_INITIALIZED)) {
 #if !defined(NDEBUG)
                        if (initverbose)
                                log_message_class_message_class("Initialize super class ",
-                                                                                               c->super.cls,
+                                                                                               c->super,
                                                                                                " from ",
                                                                                                c);
 #endif
 
-                       if (!initialize_class(c->super.cls))
+                       if (!initialize_class(c->super))
                                return false;
                }
        }
@@ -163,7 +163,7 @@ static bool initialize_class_intern(classinfo *c)
 
        m = class_findmethod(c, utf_clinit, utf_void__void);
 
-       if (!m) {
+       if (m == NULL) {
 #if !defined(NDEBUG)
                if (initverbose)
                        log_message_class("Class has no static class initializer: ", c);
index 0055ff3a8bd7d411848858a3f27751e906b48119..2c30dc67d61708d1554d64db01fbe873c08e0b8a 100644 (file)
 
                        /* if lazy resolving did not succeed, it's not one of the allowed classes */
                        /* otherwise we check it directly                                         */
-                       if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
+                       if (cls == NULL || (cls != state->m->class && cls != state->m->class->super)) {
                                TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
                        }
 
index 3d0a47888fc582644cd9ca2a1e5292a6735a8e8e..b3313cea5bfc6e584994f6a2057bf03309aa2d53 100644 (file)
@@ -418,13 +418,13 @@ interface_extends_interface(classinfo *cls,classinfo *interf)
 
     /* first check direct superinterfaces */
     for (i=0; i<cls->interfacescount; ++i) {
-        if (cls->interfaces[i].cls == interf)
+        if (cls->interfaces[i] == interf)
             return true;
     }
     
     /* check indirect superinterfaces */
     for (i=0; i<cls->interfacescount; ++i) {
-        if (interface_extends_interface(cls->interfaces[i].cls,interf))
+        if (interface_extends_interface(cls->interfaces[i],interf))
             return true;
     }
     
@@ -1852,13 +1852,16 @@ typeinfo_merge_nonarrays(typeinfo *dest,
     /* {We know: y is at least as deep in the hierarchy as x.} */
 
     /* Find nearest common anchestor for the classes. */
+
     common = x.cls;
-    tcls = y.cls;
+    tcls   = y.cls;
+
     while (tcls->index > common->index)
-        tcls = tcls->super.cls;
+        tcls = tcls->super;
+
     while (common != tcls) {
-        common = common->super.cls;
-        tcls = tcls->super.cls;
+        common = common->super;
+        tcls = tcls->super;
     }
 
     /* {common == nearest common anchestor of x and y.} */
index a1235b901100bde201f9ae49dd6e557447405ff8..3f60dbc57be8dff3fd12ff98584f0e51842cd7f3 100644 (file)
@@ -1549,7 +1549,7 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
                /* lookup starting with the direct super class of referer      */
 
                if ((referer->flags & ACC_SUPER) != 0) {
-                       mi = class_resolvemethod(referer->super.cls,
+                       mi = class_resolvemethod(referer->super,
                                                                         mi->name,
                                                                         mi->descriptor);
 
index 31f95208bdcaa991cbfd27bbba73323a6fecf7b1..b836658794fba02dcef0d7c5f0e445524866740a 100644 (file)
@@ -806,7 +806,7 @@ void class_free(classinfo *c)
                
        class_freecpool(c);
 
-       if (c->interfaces)
+       if (c->interfaces != NULL)
                MFREE(c->interfaces, classinfo*, c->interfacescount);
 
        if (c->fields) {
@@ -1240,7 +1240,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;
@@ -1266,11 +1266,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;
@@ -1315,11 +1314,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;
@@ -1400,8 +1398,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;
 }
@@ -1474,18 +1472,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 */
 
@@ -1522,38 +1521,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.
@@ -1562,20 +1529,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;
+
+       for (;;) {
+               /* We reached java/lang/Object and did not find the requested
+                  super class. */
 
-/*             sub = class_resolve_superclass(sub); */
-               if (sub->super.any == NULL)
+               if (c == NULL)
                        return false;
 
-               assert(IS_CLASSREF(sub->super) == 0);
+               /* We found the requested super class. */
+
+               if (c == super)
+                       return true;
 
-               sub = sub->super.cls;
+               c = c->super;
        }
 }
 
@@ -1723,31 +1693,21 @@ bool class_is_memberclass(classinfo *c)
 
 /* 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 the super class of the given class.
 
 *******************************************************************************/
 
 classinfo *class_get_superclass(classinfo *c)
 {
-       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. */
+       /* For interfaces we return NULL. */
 
        if (c->flags & ACC_INTERFACE)
                return NULL;
 
-       /* We may have to resolve the super class reference. */
-
-       super = class_resolve_superclass(c);
+       /* For java/lang/Object, primitive-type and Void classes c->super
+          is NULL and we return NULL. */
 
-       return super;
+       return c->super;
 }
 
 
@@ -1972,7 +1932,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;
        }
@@ -2262,9 +2222,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");
        }
 
@@ -2273,8 +2233,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");
index fddb1279da5cf5b6b9e24b778f23a44402d45119..5ab593cf64935ba655d88a0f6908e61155fc76a9 100644 (file)
@@ -111,17 +111,17 @@ struct classinfo {                /* class structure                          */
        s4          parseddescsize;   /* size of the parsed descriptors block     */
        u1         *parseddescs;      /* parsed descriptors                       */
 
-       classref_or_classinfo super;  /* super class                              */
+       classinfo  *super;            /* super class                              */
        classinfo  *sub;              /* sub class pointer                        */
        classinfo  *nextsub;          /* pointer to next class in sub class list  */
 
-       s4          interfacescount;  /* number of interfaces                     */
-       classref_or_classinfo *interfaces; /* superinterfaces                     */
+       int32_t     interfacescount;  /* number of interfaces                     */
+       classinfo **interfaces;       /* super interfaces                         */
 
-       s4          fieldscount;      /* number of fields                         */
+       int32_t     fieldscount;      /* number of fields                         */
        fieldinfo  *fields;           /* field table                              */
 
-       s4          methodscount;     /* number of methods                        */
+       int32_t     methodscount;     /* number of methods                        */
        methodinfo *methods;          /* method table                             */
 
        s4          state;            /* current class state                      */
index df4911add3b1cb00aeea5c254ecf47f02200fec8..0c9f34af1121b6a16ff003ce24a5cc6e8fdb221f 100644 (file)
@@ -280,22 +280,22 @@ void linker_init(void)
 
     /* pseudo class for Arraystubs (extends java.lang.Object) */
 
-       pseudo_class_Arraystub =
+       pseudo_class_Arraystub                   =
                class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
-       pseudo_class_Arraystub->state            |= CLASS_LOADED;
-       pseudo_class_Arraystub->super.cls         = class_java_lang_Object;
+       pseudo_class_Arraystub->state           |= CLASS_LOADED;
+       pseudo_class_Arraystub->super            = class_java_lang_Object;
 
 #if defined(ENABLE_JAVASE)
 
-       pseudo_class_Arraystub->interfacescount   = 2;
-       pseudo_class_Arraystub->interfaces        = MNEW(classref_or_classinfo, 2);
-       pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
-       pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
+       pseudo_class_Arraystub->interfacescount  = 2;
+       pseudo_class_Arraystub->interfaces       = MNEW(classinfo*, 2);
+       pseudo_class_Arraystub->interfaces[0]    = class_java_lang_Cloneable;
+       pseudo_class_Arraystub->interfaces[1]    = class_java_io_Serializable;
 
 #elif defined(ENABLE_JAVAME_CLDC1_1)
 
-       pseudo_class_Arraystub->interfacescount   = 0;
-       pseudo_class_Arraystub->interfaces        = NULL;
+       pseudo_class_Arraystub->interfacescount    = 0;
+       pseudo_class_Arraystub->interfaces         = NULL;
 
 #else
 # error unknown Java configuration
@@ -309,9 +309,9 @@ void linker_init(void)
 
        /* pseudo class representing the null type */
 
-       pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
+       pseudo_class_Null         = class_create_classinfo(utf_new_char("$NULL$"));
        pseudo_class_Null->state |= CLASS_LOADED;
-       pseudo_class_Null->super.cls = class_java_lang_Object;
+       pseudo_class_Null->super  = class_java_lang_Object;
 
        if (!classcache_store_unique(pseudo_class_Null))
                vm_abort("linker_init: could not cache pseudo_class_Null");
@@ -321,10 +321,10 @@ void linker_init(void)
 
        /* pseudo class representing new uninitialized objects */
     
-       pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
+       pseudo_class_New         = class_create_classinfo(utf_new_char("$NEW$"));
        pseudo_class_New->state |= CLASS_LOADED;
        pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
-       pseudo_class_New->super.cls = class_java_lang_Object;
+       pseudo_class_New->super  = class_java_lang_Object;
 
        if (!classcache_store_unique(pseudo_class_New))
                vm_abort("linker_init: could not cache pseudo_class_New");
@@ -549,30 +549,10 @@ static classinfo *link_class_intern(classinfo *c)
        arraydesc = NULL;
        worklist = NULL;
 
-       /* check interfaces */
+       /* Link the super interfaces. */
 
        for (i = 0; i < c->interfacescount; i++) {
-               /* resolve this super interface */
-
-               if ((tc = resolve_classref_or_classinfo_eager(c->interfaces[i], true)) == NULL)
-                       return NULL;
-
-               c->interfaces[i].cls = tc;
-               
-               /* detect circularity */
-
-               if (tc == c) {
-                       exceptions_throw_classcircularityerror(c);
-                       return NULL;
-               }
-
-               assert(tc->state & CLASS_LOADED);
-
-               if (!(tc->flags & ACC_INTERFACE)) {
-                       exceptions_throw_incompatibleclasschangeerror(tc,
-                                                                                                                 "Implementing class");
-                       return NULL;
-               }
+               tc = c->interfaces[i];
 
                if (!(tc->state & CLASS_LINKED))
                        if (!link_class(tc))
@@ -583,49 +563,22 @@ static classinfo *link_class_intern(classinfo *c)
 
        super = NULL;
 
-       if (c->super.any == NULL) {                     /* class java.lang.Object */
+       /* Check for java/lang/Object. */
+
+       if (c->super == NULL) {
                c->index = 0;
                c->instancesize = sizeof(java_object_t);
                
                vftbllength = supervftbllength = 0;
 
                c->finalizer = NULL;
-
        }
        else {
-               /* Resolve super class. */
-
-               super = resolve_classref_or_classinfo_eager(c->super, true);
+               /* Get super class. */
 
-               if (super == NULL)
-                       return NULL;
-
-               c->super.cls = super;
-               
-               /* Detect circularity. */
-
-               if (super == c) {
-                       exceptions_throw_classcircularityerror(c);
-                       return NULL;
-               }
-
-               assert(super->state & CLASS_LOADED);
-
-               if (super->flags & ACC_INTERFACE) {
-                       /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
-                       log_text("Interface specified as super class");
-                       assert(0);
-               }
-
-               /* Don't allow extending final classes */
-
-               if (super->flags & ACC_FINAL) {
-                       exceptions_throw_verifyerror(NULL,
-                                                                                "Cannot inherit from final class");
-                       return NULL;
-               }
+               super = c->super;
 
-               /* link the superclass if necessary */
+               /* Link the super class if necessary. */
                
                if (!(super->state & CLASS_LINKED))
                        if (!link_class(super))
@@ -689,7 +642,7 @@ static classinfo *link_class_intern(classinfo *c)
                                        }
                                }
 
-                               tc = tc->super.cls;
+                               tc = tc->super;
                        }
 
                notfoundvftblindex:
@@ -719,7 +672,7 @@ static classinfo *link_class_intern(classinfo *c)
                /* check all interfaces of the abstract class */
 
                for (i = 0; i < c->interfacescount; i++) {
-                       ic = c->interfaces[i].cls;
+                       ic = c->interfaces[i];
 
                        for (j = 0; j < ic->methodscount; j++) {
                                im = &(ic->methods[j]);
@@ -729,7 +682,7 @@ static classinfo *link_class_intern(classinfo *c)
                                if ((im->name == utf_clinit) || (im->name == utf_init))
                                        continue;
 
-                               for (tc = c; tc != NULL; tc = tc->super.cls) {
+                               for (tc = c; tc != NULL; tc = tc->super) {
                                        for (k = 0; k < tc->methodscount; k++) {
                                                if (method_canoverwrite(im, &(tc->methods[k])))
                                                        goto noabstractmethod;
@@ -752,7 +705,7 @@ static classinfo *link_class_intern(classinfo *c)
                                                                  c->methodscount + abstractmethodscount);
 
                        for (i = 0; i < c->interfacescount; i++) {
-                               ic = c->interfaces[i].cls;
+                               ic = c->interfaces[i];
 
                                for (j = 0; j < ic->methodscount; j++) {
                                        im = &(ic->methods[j]);
@@ -762,7 +715,7 @@ static classinfo *link_class_intern(classinfo *c)
                                        if ((im->name == utf_clinit) || (im->name == utf_init))
                                                continue;
 
-                                       for (tc = c; tc != NULL; tc = tc->super.cls) {
+                                       for (tc = c; tc != NULL; tc = tc->super) {
                                                for (k = 0; k < tc->methodscount; k++) {
                                                        if (method_canoverwrite(im, &(tc->methods[k])))
                                                                goto noabstractmethod2;
@@ -800,9 +753,9 @@ static classinfo *link_class_intern(classinfo *c)
 
        interfacetablelength = 0;
 
-       for (tc = c; tc != NULL; tc = tc->super.cls) {
+       for (tc = c; tc != NULL; tc = tc->super) {
                for (i = 0; i < tc->interfacescount; i++) {
-                       s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
+                       s4 h = class_highestinterface(tc->interfaces[i]) + 1;
 
                        if (h > interfacetablelength)
                                interfacetablelength = h;
@@ -931,9 +884,9 @@ static classinfo *link_class_intern(classinfo *c)
 
        /* add interfaces */
 
-       for (tc = c; tc != NULL; tc = tc->super.cls)
+       for (tc = c; tc != NULL; tc = tc->super)
                for (i = 0; i < tc->interfacescount; i++)
-                       if (!linker_addinterface(c, tc->interfaces[i].cls))
+                       if (!linker_addinterface(c, tc->interfaces[i]))
                                return NULL;
 
        RT_TIMING_GET_TIME(time_fill_iftbl);
@@ -1172,9 +1125,9 @@ static void linker_compute_subclasses(classinfo *c)
                c->sub     = NULL;
        }
 
-       if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
-               c->nextsub        = c->super.cls->sub;
-               c->super.cls->sub = c;
+       if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
+               c->nextsub    = c->super->sub;
+               c->super->sub = c;
        }
 
        classvalue = 0;
@@ -1261,7 +1214,7 @@ static bool linker_addinterface(classinfo *c, classinfo *ic)
 #endif
 
                for (j = 0; j < ic->methodscount; j++) {
-                       for (sc = c; sc != NULL; sc = sc->super.cls) {
+                       for (sc = c; sc != NULL; sc = sc->super) {
                                for (k = 0; k < sc->methodscount; k++) {
                                        m = &(sc->methods[k]);
 
@@ -1318,7 +1271,7 @@ static bool linker_addinterface(classinfo *c, classinfo *ic)
        /* add superinterfaces of this interface */
 
        for (j = 0; j < ic->interfacescount; j++)
-               if (!linker_addinterface(c, ic->interfaces[j].cls))
+               if (!linker_addinterface(c, ic->interfaces[j]))
                        return false;
 
        /* everything ok */
@@ -1345,7 +1298,7 @@ static s4 class_highestinterface(classinfo *c)
     h = c->index;
 
        for (i = 0; i < c->interfacescount; i++) {
-               h2 = class_highestinterface(c->interfaces[i].cls);
+               h2 = class_highestinterface(c->interfaces[i]);
 
                if (h2 > h)
                        h = h2;
index d7b90d98737ae5b6ea28af05a7aa09be1c043742..047e0d91c94a536acde508cadf482c0dcb0c65f2 100644 (file)
@@ -46,6 +46,7 @@
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/primitive.h"
+#include "vm/resolve.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
@@ -1377,9 +1378,15 @@ classinfo *load_class_bootstrap(utf *name)
 
 static bool load_class_from_classbuffer_intern(classbuffer *cb)
 {
-       classinfo *c;
-       utf *name;
-       utf *supername;
+       classinfo          *c;
+       classinfo          *tc;
+       utf                *name;
+       utf                *supername;
+       utf               **interfacesnames;
+       utf                *u;
+       constant_classref  *cr;
+       int16_t             index;
+
        u4 i,j;
        u4 ma, mi;
        descriptor_pool *descpool;
@@ -1477,11 +1484,13 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
        if (!suck_check_classbuffer_size(cb, 2 + 2))
                return false;
 
-       /* this class */
+       /* This class. */
 
-       i = suck_u2(cb);
+       index = suck_u2(cb);
 
-       if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
+       name = (utf *) class_getconstant(c, index, CONSTANT_Class);
+
+       if (name == NULL)
                return false;
 
        if (c->name == utf_not_named_yet) {
@@ -1494,12 +1503,26 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
                return false;
        }
 
-       /* retrieve superclass */
+       /* Retrieve superclass. */
+
+       c->super = NULL;
+
+       index = suck_u2(cb);
+
+       if (index == 0) {
+               supername = NULL;
+
+               /* This is only allowed for java.lang.Object. */
 
-       c->super.any = NULL;
+               if (c->name != utf_java_lang_Object) {
+                       exceptions_throw_classformaterror(c, "Bad superclass index");
+                       return false;
+               }
+       }
+       else {
+               supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
 
-       if ((i = suck_u2(cb))) {
-               if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
+               if (supername == NULL)
                        return false;
 
                /* java.lang.Object may not have a super class. */
@@ -1509,25 +1532,22 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
                        return false;
                }
 
-               /* Interfaces must have java.lang.Object as super class. */
+               /* Detect circularity. */
 
-               if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
-                       exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
+               if (supername == c->name) {
+                       exceptions_throw_classcircularityerror(c);
                        return false;
                }
-       }
-       else {
-               supername = NULL;
 
-               /* This is only allowed for java.lang.Object. */
+               /* Interfaces must have java.lang.Object as super class. */
 
-               if (c->name != utf_java_lang_Object) {
-                       exceptions_throw_classformaterror(c, "Bad superclass index");
+               if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
+                       exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
                        return false;
                }
        }
 
-       /* retrieve interfaces */
+       /* Parse the super interfaces. */
 
        if (!suck_check_classbuffer_size(cb, 2))
                return false;
@@ -1537,17 +1557,26 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
        if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
                return false;
 
-       c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
+       c->interfaces = MNEW(classinfo*, c->interfacescount);
+
+       /* Get the names of the super interfaces. */
+
+       interfacesnames = DMNEW(utf*, c->interfacescount);
 
        for (i = 0; i < c->interfacescount; i++) {
-               /* the classrefs are created later */
-               if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
+               index = suck_u2(cb);
+
+               u = (utf *) class_getconstant(c, index, CONSTANT_Class);
+
+               if (u == NULL)
                        return false;
+
+               interfacesnames[i] = u;
        }
 
        RT_TIMING_GET_TIME(time_setup);
 
-       /* load fields */
+       /* Parse fields. */
 
        if (!suck_check_classbuffer_size(cb, 2))
                return false;
@@ -1564,7 +1593,7 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
 
        RT_TIMING_GET_TIME(time_fields);
 
-       /* load methods */
+       /* Parse methods. */
 
        if (!suck_check_classbuffer_size(cb, 2))
                return false;
@@ -1605,6 +1634,7 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
        RT_TIMING_GET_TIME(time_descs);
 
        /* put the classrefs in the constant pool */
+
        for (i = 0; i < c->cpcount; i++) {
                if (c->cptags[i] == CONSTANT_Class) {
                        utf *name = (utf *) c->cpinfos[i];
@@ -1612,27 +1642,76 @@ static bool load_class_from_classbuffer_intern(classbuffer *cb)
                }
        }
 
-       /* set the super class reference */
+       /* Resolve the super class. */
+
+       if (supername != NULL) {
+               cr = descriptor_pool_lookup_classref(descpool, supername);
+
+               if (cr == NULL)
+                       return false;
+
+               /* XXX This should be done better. */
+               tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
+
+               if (tc == NULL)
+                       return false;
+
+               /* Interfaces are not allowed as super classes. */
 
-       if (supername) {
-               c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
-               if (!c->super.ref)
+               if (tc->flags & ACC_INTERFACE) {
+                       exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
                        return false;
+               }
+
+               /* Don't allow extending final classes */
+
+               if (tc->flags & ACC_FINAL) {
+                       exceptions_throw_verifyerror(NULL,
+                                                                                "Cannot inherit from final class");
+                       return false;
+               }
+
+               /* Store the super class. */
+
+               c->super = tc;
        }
 
-       /* set the super interfaces references */
+       /* Resolve the super interfaces. */
 
        for (i = 0; i < c->interfacescount; i++) {
-               c->interfaces[i].ref =
-                       descriptor_pool_lookup_classref(descpool,
-                                                                                       (utf *) c->interfaces[i].any);
-               if (!c->interfaces[i].ref)
+               u  = interfacesnames[i];
+               cr = descriptor_pool_lookup_classref(descpool, u);
+
+               if (cr == NULL)
                        return false;
+
+               /* XXX This should be done better. */
+               tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
+
+               if (tc == NULL)
+                       return false;
+
+               /* Detect circularity. */
+
+               if (tc == c) {
+                       exceptions_throw_classcircularityerror(c);
+                       return false;
+               }
+
+               if (!(tc->flags & ACC_INTERFACE)) {
+                       exceptions_throw_incompatibleclasschangeerror(tc,
+                                                                                                                 "Implementing class");
+                       return false;
+               }
+
+               /* Store the super interface. */
+
+               c->interfaces[i] = tc;
        }
 
        RT_TIMING_GET_TIME(time_setrefs);
 
-       /* parse field descriptors */
+       /* Parse the field descriptors. */
 
        for (i = 0; i < c->fieldscount; i++) {
                c->fields[i].parseddesc =
@@ -2036,31 +2115,33 @@ classinfo *load_newly_created_array(classinfo *c, classloader *loader)
        assert(class_java_io_Serializable);
 #endif
 
-       /* setup the array class */
+       /* Setup the array class. */
 
-       c->super.cls = class_java_lang_Object;
+       c->super = class_java_lang_Object;
 
 #if defined(ENABLE_JAVASE)
 
-       c->interfacescount   = 2;
-    c->interfaces        = MNEW(classref_or_classinfo, 2);
-       c->interfaces[0].cls = class_java_lang_Cloneable;
-       c->interfaces[1].cls = class_java_io_Serializable;
+       c->interfacescount = 2;
+    c->interfaces      = MNEW(classinfo*, 2);
+       c->interfaces[0]   = class_java_lang_Cloneable;
+       c->interfaces[1]   = class_java_io_Serializable;
 
 #elif defined(ENABLE_JAVAME_CLDC1_1)
 
-       c->interfacescount   = 0;
-       c->interfaces        = NULL;
+       c->interfacescount = 0;
+       c->interfaces      = NULL;
 
 #else
 # error unknow Java configuration
 #endif
 
        c->methodscount = 1;
-       c->methods = MNEW(methodinfo, c->methodscount);
+       c->methods      = MNEW(methodinfo, c->methodscount);
+
        MZERO(c->methods, methodinfo, c->methodscount);
 
        classrefs = MNEW(constant_classref, 2);
+
        CLASSREF_INIT(classrefs[0], c, c->name);
        CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
 
index a1bb2a76aa08ff0ba2060b45715a89213e1c35d1..1434b5d8ef4fa907dad53c51163a14196d561186 100644 (file)
@@ -69,7 +69,7 @@ primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
 };
 
 
-/* primitive_preinit ***********************************************************
+/* primitive_init **************************************************************
 
    Fill the primitive type table with the primitive-type classes,
    array-classes and wrapper classes.  This is important in the VM
@@ -114,9 +114,9 @@ void primitive_init(void)
 
                c = class_create_classinfo(name);
 
-               /* primitive classes don't have a super class */
+               /* Primitive type classes don't have a super class. */
 
-               c->super.any = NULL;
+               c->super = NULL;
 
                /* set flags and mark it as primitive class */