* src/vm/jit/replace.c (replace_create_replacement_points): Don't use
[cacao.git] / src / vm / linker.c
index 0981baf388c1136be921905ddce28c308cafaac8..bb2a8e13963383db1c0fd9ca036474a019f79c5c 100644 (file)
@@ -1,9 +1,9 @@
 /* src/vm/linker.c - class linker functions
 
-   Copyright (C) 1996-2005 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 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
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Reinhard Grafl
 
             Edwin Steiner
             Christian Thalinger
 
-   $Id: linker.c 3888 2005-12-05 22:08:45Z twisti $
+   $Id: linker.c 4551 2006-03-03 00:00:39Z twisti $
 
 */
 
 
+#include "config.h"
+
 #include <assert.h>
 
-#include "config.h"
 #include "vm/types.h"
 
 #include "mm/memory.h"
@@ -53,7 +54,7 @@
 #include "vm/resolve.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
-#include "vm/jit/codegen.inc.h"
+#include "vm/access.h"
 
 
 /* global variables ***********************************************************/
@@ -300,8 +301,6 @@ static bool link_primitivetype_table(void)
                c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
 
                c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
-               c->classUsed = NOTUSED; /* not used initially CO-RT */
-               c->impldBy = NULL;
                
                /* prevent loader from loading primitive class */
 
@@ -322,8 +321,6 @@ static bool link_primitivetype_table(void)
                        return false;
 
                primitivetype_table[i].class_wrap = c;
-               primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
-               primitivetype_table[i].class_wrap->impldBy = NULL;
 
                /* create the primitive array class */
 
@@ -362,7 +359,7 @@ classinfo *link_class(classinfo *c)
        classinfo *r;
 
        if (!c) {
-               *exceptionptr = new_nullpointerexception();
+               exceptions_throw_nullpointerexception();
                return NULL;
        }
 
@@ -382,7 +379,7 @@ classinfo *link_class(classinfo *c)
                return c;
        }
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        /* measure time */
 
        if (getcompilingtime)
@@ -401,7 +398,7 @@ classinfo *link_class(classinfo *c)
        if (!r)
                c->state &= ~CLASS_LINKING;
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        /* measure time */
 
        if (getloadingtime)
@@ -509,8 +506,6 @@ static classinfo *link_class_intern(classinfo *c)
 
        if (c->super.any == NULL) {                     /* class java.lang.Object */
                c->index = 0;
-        c->classUsed = USED;              /* Object class is always used CO-RT*/
-               c->impldBy = NULL;
                c->instancesize = sizeof(java_objectheader);
                
                vftbllength = supervftbllength = 0;
@@ -590,6 +585,15 @@ static classinfo *link_class_intern(classinfo *c)
                                                if (tc->methods[j].flags & ACC_PRIVATE)
                                                        goto notfoundvftblindex;
 
+                                               /* package-private methods in other packages */
+                                               /* must not be overridden                    */
+                                               /* (see Java Language Specification 8.4.8.1) */
+                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
+                                                        && !SAME_PACKAGE(c,tc) ) 
+                                               {
+                                                   goto notfoundvftblindex;
+                                               }
+
                                                if (tc->methods[j].flags & ACC_FINAL) {
                                                        /* class a overrides final method . */
                                                        *exceptionptr =
@@ -613,7 +617,10 @@ static classinfo *link_class_intern(classinfo *c)
        }       
 
 
-       /* check interfaces of ABSTRACT class for unimplemented methods */
+       /* Check all interfaces of an abtract class (maybe be an interface
+          too) for unimplemented methods.  Such methods are called
+          miranda-methods and are marked with the ACC_MIRANDA flag.
+          VMClass.getDeclaredMethods does not return such methods. */
 
        if (c->flags & ACC_ABSTRACT) {
                classinfo  *ic;
@@ -624,6 +631,8 @@ static classinfo *link_class_intern(classinfo *c)
 
                abstractmethodscount = 0;
 
+               /* check all interfaces of the abtract class */
+
                for (i = 0; i < c->interfacescount; i++) {
                        ic = c->interfaces[i].cls;
 
@@ -632,18 +641,14 @@ static classinfo *link_class_intern(classinfo *c)
 
                                /* skip `<clinit>' and `<init>' */
 
-                               if (im->name == utf_clinit || im->name == utf_init)
+                               if ((im->name == utf_clinit) || (im->name == utf_init))
                                        continue;
 
-                               tc = c;
-
-                               while (tc) {
+                               for (tc = c; tc != NULL; tc = tc->super.cls) {
                                        for (k = 0; k < tc->methodscount; k++) {
                                                if (method_canoverwrite(im, &(tc->methods[k])))
                                                        goto noabstractmethod;
                                        }
-
-                                       tc = tc->super.cls;
                                }
 
                                abstractmethodscount++;
@@ -669,27 +674,27 @@ static classinfo *link_class_intern(classinfo *c)
 
                                        /* skip `<clinit>' and `<init>' */
 
-                                       if (im->name == utf_clinit || im->name == utf_init)
+                                       if ((im->name == utf_clinit) || (im->name == utf_init))
                                                continue;
 
-                                       tc = c;
-
-                                       while (tc) {
+                                       for (tc = c; tc != NULL; tc = tc->super.cls) {
                                                for (k = 0; k < tc->methodscount; k++) {
                                                        if (method_canoverwrite(im, &(tc->methods[k])))
                                                                goto noabstractmethod2;
                                                }
-
-                                               tc = tc->super.cls;
                                        }
 
+                                       /* Copy the method found into the new c->methods
+                                          array and tag it as miranda-method. */
+
                                        am = &(c->methods[c->methodscount]);
                                        c->methodscount++;
 
                                        MCOPY(am, im, methodinfo, 1);
 
-                                       am->vftblindex = (vftbllength++);
-                                       am->class = c;
+                                       am->vftblindex  = (vftbllength++);
+                                       am->class       = c;
+                                       am->flags      |= ACC_MIRANDA;
 
                                noabstractmethod2:
                                        ;
@@ -699,7 +704,7 @@ static classinfo *link_class_intern(classinfo *c)
        }
 
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        if (opt_stat)
                count_vftbl_len +=
                        sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
@@ -746,11 +751,21 @@ static classinfo *link_class_intern(classinfo *c)
        for (i = 0; i < c->methodscount; i++) {
                methodinfo *m = &(c->methods[i]);
 
-               /* Methods in ABSTRACT classes from interfaces maybe already have a   */
-               /* stubroutine.                                                       */
+               /* Methods in ABSTRACT classes from interfaces maybe already
+                  have a stubroutine. */
 
-               if (!m->stubroutine)
-                       m->stubroutine = createcompilerstub(m);
+               if (!m->stubroutine) {
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+                       if (opt_intrp)
+                               m->stubroutine = intrp_createcompilerstub(m);
+                       else
+#endif
+                               m->stubroutine = createcompilerstub(m);
+#else
+                       m->stubroutine = intrp_createcompilerstub(m);
+#endif
+               }
 
                if (!(m->flags & ACC_STATIC))
                        v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
@@ -774,7 +789,7 @@ static classinfo *link_class_intern(classinfo *c)
        
        v->interfacevftbllength = MNEW(s4, interfacetablelength);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        if (opt_stat)
                count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
 #endif
@@ -1080,7 +1095,7 @@ static void linker_addinterface(classinfo *c, classinfo *ic)
                v->interfacevftbllength[i] = ic->methodscount;
                v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                if (opt_stat)
                        count_vftbl_len += sizeof(methodptr) *
                                (ic->methodscount + (ic->methodscount == 0));
@@ -1149,4 +1164,5 @@ static s4 class_highestinterface(classinfo *c)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */