missed a header.c change related to arrayarray
[cacao.git] / loader.c
index ff4e40fa83103af40434c38b9b60ab921f486cd2..cc6a5c5db89c5a5c00681ad375f312d66c00fc23 100644 (file)
--- a/loader.c
+++ b/loader.c
@@ -1,41 +1,67 @@
+/* loader.c - class loader functions
 
-/* loader.c ********************************************************************
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
+   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
+   P. Tomsich, J. Wenninger
 
-       Copyright (c) 1999 A. Krall, R. Grafl, R. Obermaiser, M. Probst
+   This file is part of CACAO.
 
-       See file COPYRIGHT for information on usage and disclaimer of warranties
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
 
-       Contains the functions of the class loader.
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
-       Author:  Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
-       Changes: Andreas Krall       EMAIL: cacao@complang.tuwien.ac.at
-                Roman Obermaiser    EMAIL: cacao@complang.tuwien.ac.at
-                Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
+   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.
 
-       Last Change: 1999/11/08
+   Contact: cacao@complang.tuwien.ac.at
 
-*******************************************************************************/
+   Authors: Reinhard Grafl
+   Changes: Andreas Krall
+            Roman Obermaiser
+            Mark Probst
 
+   $Id: loader.c 664 2003-11-21 18:24:01Z jowenn $
+
+*/
 
-#include <assert.h>
 
+#include <string.h>
+#include <assert.h>
+#include <sys/stat.h>
 #include "global.h"
 #include "loader.h"
 #include "native.h"
 #include "tables.h"
 #include "builtin.h"
 #include "jit.h"
-#ifdef OLD_COMPILER
-#include "compiler.h"
-#endif
 #include "asmpart.h"
-
+#include "toolbox/memory.h"
+#include "toolbox/loging.h"
 #include "threads/thread.h"
 #include <sys/stat.h>
 
+#ifdef USE_ZLIB
+#include "unzip.h"
+#endif
+
+#undef JOWENN_DEBUG
+#undef JOWENN_DEBUG1
+#undef JOWENN_DEBUG2
+
 /* global variables ***********************************************************/
 
-extern bool newcompiler;        /* true if new compiler is used               */               
+bool opt_rt = false;            /* true if RTA parse should be used     RT-CO */
+bool opt_xta = false;           /* true if XTA parse should be used    XTA-CO */
+bool opt_vta = false;           /* true if VTA parse should be used    VTA-CO */
 
 int count_class_infos = 0;      /* variables for measurements                 */
 int count_const_pool_len = 0;
@@ -43,6 +69,8 @@ int count_vftbl_len = 0;
 int count_all_methods = 0;
 int count_vmcode_len = 0;
 int count_extable_len = 0;
+int count_class_loads = 0;
+int count_class_inits = 0;
 
 bool loadverbose = false;       /* switches for debug messages                */
 bool linkverbose = false;
@@ -66,26 +94,50 @@ static utf *utf_innerclasses;               /* InnerClasses                    */
 static utf *utf_constantvalue;                 /* ConstantValue                   */
 static utf *utf_code;                      /* Code                            */
 static utf *utf_finalize;                  /* finalize                            */
-static utf *utf_fidesc;                    /* ()V                                     */
+static utf *utf_fidesc;                    /* ()V changed                                   */
 static utf *utf_clinit;                    /* <clinit>                            */
-static utf *utf_initsystemclass;       /* initializeSystemClass   */
+static utf *utf_initsystemclass;       /* initializeSystemClass */
 static utf *utf_systemclass;           /* java/lang/System        */
+static utf *utf_vmclassloader; /*java/lang/VMClassLoader*/
+static utf *utf_vmclass; /*java/lang/VMClassLoader*/
+static utf *utf_initialize;
+static utf *utf_initializedesc;
 
-
+utf* clinit_desc(){
+       return utf_fidesc;
+}
+utf* clinit_name(){
+       return utf_clinit;
+}
 /* important system classes ***************************************************/
 
 classinfo *class_java_lang_Object;
 classinfo *class_java_lang_String;
-classinfo *class_java_lang_ClassCastException;
-classinfo *class_java_lang_NullPointerException;
-classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
-classinfo *class_java_lang_NegativeArraySizeException;
-classinfo *class_java_lang_OutOfMemoryError;
-classinfo *class_java_lang_ArithmeticException;
-classinfo *class_java_lang_ArrayStoreException;
-classinfo *class_java_lang_ThreadDeath;
-classinfo *class_array = NULL;
 
+classinfo *class_java_lang_Throwable;
+classinfo *class_java_lang_Cloneable;
+classinfo *class_java_io_Serializable;
+
+/* Pseudo classes for the typechecker */
+classinfo *pseudo_class_Arraystub = NULL;
+classinfo *pseudo_class_Null = NULL;
+vftbl *pseudo_class_Arraystub_vftbl = NULL;
+
+/* stefan */
+/* These are made static so they cannot be used for throwing in native */
+/* functions.                                                          */
+static classinfo *class_java_lang_ClassCastException;
+static classinfo *class_java_lang_NullPointerException;
+static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
+static classinfo *class_java_lang_NegativeArraySizeException;
+static classinfo *class_java_lang_OutOfMemoryError;
+static classinfo *class_java_lang_ArithmeticException;
+static classinfo *class_java_lang_ArrayStoreException;
+static classinfo *class_java_lang_ThreadDeath;
+
+static methodinfo method_clone_array;
+
+static int loader_inited = 0;
 
 /******************************************************************************
 
@@ -94,18 +146,20 @@ classinfo *class_array = NULL;
    the one character type signature and the name of the primitive class
  
  ******************************************************************************/
-primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
-               { NULL, NULL, "java/lang/Double",    'D', "double"  },
-               { NULL, NULL, "java/lang/Float",     'F', "float"   },
-               { NULL, NULL, "java/lang/Character", 'C', "char"    },
-               { NULL, NULL, "java/lang/Integer",   'I', "int"     },
-               { NULL, NULL, "java/lang/Long",      'J', "long"    },
-               { NULL, NULL, "java/lang/Byte",      'B', "byte"    },
-               { NULL, NULL, "java/lang/Short",     'S', "short"   },
-               { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" },
-               { NULL, NULL, "java/lang/Void",      'V', "void"    }};
 
+/* CAUTION: Don't change the order of the types. This table is indexed
+ * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
+ */
+primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
+               { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
+               { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
+               { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
+               { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
+               { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
+               { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
+               { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
+               { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
+               { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }};
 
 /* instances of important system classes **************************************/
 
@@ -118,6 +172,50 @@ java_objectheader *proto_java_lang_ArithmeticException;
 java_objectheader *proto_java_lang_ArrayStoreException;
 java_objectheader *proto_java_lang_ThreadDeath;
 
+/* XXX delete */
+#if 0
+void override_array_class(classinfo *c) {
+       int i;
+       classinfo *sup;
+       utf *u=utf_new_char("clone");
+       sup=c->super;
+       class_showmethods(c);
+
+       for (i=0;i<sup->methodscount;i++) {
+               if (sup->methods[i].name==u) {
+                       method_clone_array.class = c;
+                       method_clone_array. flags = ACC_PUBLIC;
+                       method_clone_array.name =  utf_new_char("clone");
+                       method_clone_array.descriptor = utf_new_char("()Ljava/lang/Object;");
+
+                       method_clone_array.jcode = NULL;
+                       method_clone_array.exceptiontable = NULL;
+                       method_clone_array.entrypoint = NULL;
+                       method_clone_array.mcode = NULL;
+                       method_clone_array.stubroutine = NULL;
+                       method_clone_array.methodUsed = NOTUSED;
+                       method_clone_array.monoPoly = MONO;
+                       method_clone_array.subRedefs = 0;
+                       method_clone_array.subRedefsUsed = 0;
+                       method_clone_array.flags=0;
+                       method_clone_array.xta = NULL;
+                        method_clone_array.stubroutine = createnativestub (&builtin_clone_array, &method_clone_array);
+                       c->vftbl->table[sup->methods[i].vftblindex]=method_clone_array.stubroutine;
+                       log_text("Found !!!! :)))))))))))))))))))))))))))))))))))))))))))))))))");
+               }
+       
+
+       }
+}
+#endif
+
+
+
+
+
+
+
+
 
 /************* functions for reading classdata *********************************
 
@@ -140,13 +238,24 @@ static int classbuffer_size;        /* size of classfile-data                 */
 
 #define skip_nbytes(len) classbuf_pos+=len;
 
-#define suck_u1() (*++classbuf_pos)
+inline u1 suck_u1()
+{
+       return *++classbuf_pos;
+}
+inline u2 suck_u2()
+{
+       u1 a=suck_u1(), b=suck_u1();
+       return ((u2)a<<8)+(u2)b;
+}
+inline u4 suck_u4()
+{
+       u1 a=suck_u1(), b=suck_u1(), c=suck_u1(), d=suck_u1();
+       return ((u4)a<<24)+((u4)b<<16)+((u4)c<<8)+(u4)d;
+}
 #define suck_s8() (s8) suck_u8()
 #define suck_s2() (s2) suck_u2()
 #define suck_s4() (s4) suck_u4()
 #define suck_s1() (s1) suck_u1()
-#define suck_u2() (u2) ((suck_u1()<<8)+suck_u1())
-#define suck_u4() (u4) ((((u4)suck_u1())<<24)+(((u4)suck_u1())<<16)+(((u4)suck_u1())<<8)+((u4)suck_u1()))
 
 
 /* get u8 from classfile data */
@@ -238,7 +347,8 @@ bool suck_start (utf *classname) {
        FILE *classfile;
        int  filenamelen, err;
        struct stat buffer;
-       
+       int isZip;
+
        if (classbuffer)                /* classbuffer is already valid */
                return true;
 
@@ -259,43 +369,104 @@ bool suck_start (utf *classname) {
                        filename[filenamelen++] = *(pathpos++);
                        }
 
-               filename[filenamelen++] = '/';  
+               isZip=0;
+               if (filenamelen>4) {
+                       if ( ((filename[filenamelen-1]=='p') || (filename[filenamelen-1]=='P')) &
+                            ((filename[filenamelen-2]=='i') || (filename[filenamelen-1]=='I')) &
+                             ((filename[filenamelen-3]=='z') || (filename[filenamelen-1]=='Z')) ) {
+                               isZip=1;
+                       }
+               }
+
+               if (isZip) {
+#ifdef USE_ZLIB
+
+                       unzFile uf;
+
+                       filename[filenamelen++]='\0';
+                       uf=unzOpen(filename);
+                       if (uf!=0) {
+                               utf_ptr = classname->text;
+                               filenamelen=0;
+                               while (utf_ptr < utf_end(classname)) {
+                                       PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
+                                       c = *utf_ptr++;
+                                       if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
+                                               c = '?'; 
+                                       filename[filenamelen++] = c;    
+                               }
+                               strcpy (filename+filenamelen, ".class");
+                               /*log_text(filename);*/
+                               if (unzLocateFile(uf,filename,1 /*case sensitive*/)==UNZ_OK) {
+                                       unz_file_info file_info;
+                                       log_text("Class found in zip file");
+                                       if (unzGetCurrentFileInfo(uf,&file_info,filename,
+                                               sizeof(filename),NULL,0,NULL,0) ==UNZ_OK) {
+                                               if (unzOpenCurrentFile(uf)==UNZ_OK) {
+                                                       classbuffer_size = file_info.uncompressed_size;                         
+                                                       classbuffer      = MNEW(u1, classbuffer_size);
+                                                       classbuf_pos     = classbuffer-1;
+                                                       /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
+                                                       if (unzReadCurrentFile(uf,classbuffer,classbuffer_size)==classbuffer_size) {
+                                                               unzCloseCurrentFile(uf);
+                                                               return true;
+                                                       } else {
+                                                               MFREE(classbuffer,u1,classbuffer_size);
+                                                               log_text("Error while unzipping");
+                                                       }
+                                               } else log_text("Error while opening file in archive");
+                                       } else log_text("Error while retrieving fileinfo");
+                               }; 
+                               unzCloseCurrentFile(uf);
+
+                       }
+#endif                 
+               } else {
+                       filename[filenamelen++] = '/';  
    
-               /* add classname to filename */
-
-               utf_ptr = classname->text;
-               while (utf_ptr < utf_end(classname)) {
-                       PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
-                       c = *utf_ptr++;
-                       if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
-                               c = '?'; 
-                       filename[filenamelen++] = c;    
+                       /* add classname to filename */
+
+                       utf_ptr = classname->text;
+                       while (utf_ptr < utf_end(classname)) {
+                               PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
+                               c = *utf_ptr++;
+                               if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
+                                       c = '?'; 
+                               filename[filenamelen++] = c;    
                        }
-      
-               /* add suffix */
+       
+                       /* add suffix */
+
+                       strcpy (filename+filenamelen, ".class");
 
-               strcpy (filename+filenamelen, ".class");
+                       classfile = fopen(filename, "r");
+                       if (classfile) {                                       /* file exists */
 
-               classfile = fopen(filename, "r");
-               if (classfile) {                                       /* file exists */
+                               /* XXX remove */
+                               /*
+                                 sprintf(logtext,"Opening file: %s",filename);
+                                 dolog();
+                               */
                        
-                       /* determine size of classfile */
+                               /* determine size of classfile */
 
-                       err = stat (filename, &buffer);
+                               err = stat (filename, &buffer);
 
-                       if (!err) {                                /* read classfile data */                            
-                               classbuffer_size = buffer.st_size;                              
-                               classbuffer      = MNEW(u1, classbuffer_size);
-                               classbuf_pos     = classbuffer-1;
-                               fread(classbuffer, 1, classbuffer_size, classfile);
-                               fclose(classfile);
-                               return true;
+                               if (!err) {                                /* read classfile data */                            
+                                       classbuffer_size = buffer.st_size;                              
+                                       classbuffer      = MNEW(u1, classbuffer_size);
+                                       classbuf_pos     = classbuffer-1;
+                                       fread(classbuffer, 1, classbuffer_size, classfile);
+                                       fclose(classfile);
+                                       return true;
+                               }
                        }
                }
        }
-
-       sprintf (logtext,"Warning: Can not open class file '%s'", filename);
-       dolog();
+       if (verbose) {
+               sprintf (logtext, "Warning: Can not open class file '%s'", filename);
+               dolog();
+       }
 
        return false;
 }
@@ -329,13 +500,28 @@ void suck_stop () {
 }
 
 /******************************************************************************/
-/******************* Einige Support-Funkionen *********************************/
+/******************* Some support functions ***********************************/
 /******************************************************************************/
 
 
-/********** interne Funktion: printflags  (nur zu Debug-Zwecken) **************/
 
-static void printflags (u2 f)
+void fprintflags (FILE *fp, u2 f)
+{
+   if ( f & ACC_PUBLIC )       fprintf (fp," PUBLIC");
+   if ( f & ACC_PRIVATE )      fprintf (fp," PRIVATE");
+   if ( f & ACC_PROTECTED )    fprintf (fp," PROTECTED");
+   if ( f & ACC_STATIC )       fprintf (fp," STATIC");
+   if ( f & ACC_FINAL )        fprintf (fp," FINAL");
+   if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
+   if ( f & ACC_VOLATILE )     fprintf (fp," VOLATILE");
+   if ( f & ACC_TRANSIENT )    fprintf (fp," TRANSIENT");
+   if ( f & ACC_NATIVE )       fprintf (fp," NATIVE");
+   if ( f & ACC_INTERFACE )    fprintf (fp," INTERFACE");
+   if ( f & ACC_ABSTRACT )     fprintf (fp," ABSTRACT");
+}
+
+/********** internal function: printflags  (only for debugging) ***************/
+void printflags (u2 f)
 {
    if ( f & ACC_PUBLIC )       printf (" PUBLIC");
    if ( f & ACC_PRIVATE )      printf (" PRIVATE");
@@ -351,9 +537,9 @@ static void printflags (u2 f)
 }
 
 
-/************************* Funktion: skipattribute *****************************
+/************************* Function: skipattribute *****************************
 
-       "uberliest im ClassFile eine (1) 'attribute'-Struktur 
+       skips a (1) 'attribute' structure in the class file
 
 *******************************************************************************/
 
@@ -363,10 +549,10 @@ static void skipattribute ()
        skip_nbytes(suck_u4()); 
 }
 
-/********************** Funktion: skipattributebody ****************************
+/********************** Function: skipattributebody ****************************
 
-       "uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name - 
-       Referenz schon gelesen worden ist.
+       skips an attribute after the 16 bit reference to attribute_name has already
+       been read
        
 *******************************************************************************/
 
@@ -375,9 +561,9 @@ static void skipattributebody ()
        skip_nbytes(suck_u4());
 }
 
-/************************* Funktion: skipattributes ****************************
+/************************* Function: skipattributes ****************************
 
-       "uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen
+       skips num attribute structures
        
 *******************************************************************************/
 
@@ -406,7 +592,7 @@ voidptr innerclass_getconstant (classinfo *c, u4 pos, u4 ctype)
 
        /* check type of constantpool entry */
        if (c->cptags[pos] != ctype) {
-               sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
+               sprintf (logtext, "Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
                 (int) ctype, (int) c->cptags[pos] );
                error();
                }
@@ -470,73 +656,31 @@ static void checkfielddescriptor (char *utf_ptr, char *end_pos)
 {
        char *tstart;  /* pointer to start of classname */
        char ch;
-       
-       switch (*utf_ptr++) {
-       case 'B':
-       case 'C':
-       case 'I':
-       case 'S':
-       case 'Z':  
-       case 'J':  
-       case 'F':  
-       case 'D':
-               /* primitive type */  
-               break;
-
-       case 'L':
-               /* save start of classname */
-               tstart = utf_ptr;  
-               
-               /* determine length of classname */
-               while ( *utf_ptr++ != ';' )
-                       if (utf_ptr>=end_pos) 
-                               panic ("Missing ';' in objecttype-descriptor");
-
-               /* cause loading of referenced class */                 
-               class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-               break;
-
-       case '[' : 
-               /* array type */
-               while ((ch = *utf_ptr++)=='[') 
-                       /* skip */ ;
-
-               /* component type of array */
-               switch (ch) {
-               case 'B':
-               case 'C':
-               case 'I':
-               case 'S':
-               case 'Z':  
-               case 'J':  
-               case 'F':  
-               case 'D':
-                       /* primitive type */  
-                       break;
-                       
-               case 'L':
-                       /* save start of classname */
-                       tstart = utf_ptr;
-                       
-                       /* determine length of classname */
-                       while ( *utf_ptr++ != ';' )
-                               if (utf_ptr>=end_pos) 
-                                       panic ("Missing ';' in objecttype-descriptor");
+       char *start = utf_ptr; /* XXX remove */
 
-                       /* cause loading of referenced class */                 
-                       class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                       break;
-
-               default:   
-                       panic ("Ill formed methodtype-descriptor");
-               }
-               break;
-                       
-       default:   
-               panic ("Ill formed methodtype-descriptor");
+       switch (*utf_ptr++) {
+         case 'B':
+         case 'C':
+         case 'I':
+         case 'S':
+         case 'Z':  
+         case 'J':  
+         case 'F':  
+         case 'D':
+                 /* primitive type */  
+                 break;
+                 
+         case '[':
+         case 'L':
+                 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
+                         panic ("Ill formed descriptor");
+                 break;
+                 
+         default:   
+                 panic ("Ill formed descriptor");
        }                       
-
-        /* exceeding characters */             
+       
+       /* exceeding characters */              
        if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
 }
 
@@ -554,12 +698,17 @@ static void checkmethoddescriptor (utf *d)
        char *end_pos = utf_end(d);  /* points behind utf string       */
        char *tstart;                /* pointer to start of classname  */
        char c,ch;
+       char *start; /* XXX remove */
 
        /* method descriptor must start with parenthesis */
+       /* XXX check length */
        if (*utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
 
+       /* XXX check length */
        /* check arguments */
        while ((c = *utf_ptr++) != ')') {
+               start = utf_ptr-1; /* XXX remove */
+               
                switch (c) {
                case 'B':
                case 'C':
@@ -572,58 +721,15 @@ static void checkmethoddescriptor (utf *d)
                        /* primitive type */  
                        break;
 
+               case '[':
                case 'L':
-                       /* save start of classname */ 
-                       tstart = utf_ptr;
-                       
-                       /* determine length of classname */
-                       while ( *utf_ptr++ != ';' )
-                               if (utf_ptr>=end_pos) 
-                                       panic ("Missing ';' in objecttype-descriptor");
-                       
-                       /* cause loading of referenced class */
-                       class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                       break;
-          
-               case '[' :
-                       /* array type */ 
-                       while ((ch = *utf_ptr++)=='[') 
-                               /* skip */ ;
-
-                       /* component type of array */
-                       switch (ch) {
-                       case 'B':
-                       case 'C':
-                       case 'I':
-                       case 'S':
-                       case 'Z':  
-                       case 'J':  
-                       case 'F':  
-                       case 'D':
-                               /* primitive type */  
-                               break;
-
-                       case 'L':
-                               /* save start of classname */
-                               tstart = utf_ptr;
-                       
-                               /* determine length of classname */     
-                               while ( *utf_ptr++ != ';' )
-                                       if (utf_ptr>=end_pos) 
-                                               panic ("Missing ';' in objecttype-descriptor");
-
-                               /* cause loading of referenced class */
-                               class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                               break;
-
-                       default:   
-                               panic ("Ill formed methodtype-descriptor");
-                       } 
+                       if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
+                               panic ("Ill formed method descriptor");
                        break;
                        
                default:   
                        panic ("Ill formed methodtype-descriptor");
-               }                       
+               }
        }
 
        /* check returntype */
@@ -637,16 +743,20 @@ static void checkmethoddescriptor (utf *d)
 }
 
 
-/******************** Funktion: buildarraydescriptor ***************************
+/******************** Function: buildarraydescriptor ***************************
 
-       erzeugt zu einem namentlich als utf-String vorliegenden Arraytyp eine
-       entsprechende constant_arraydescriptor - Struktur 
+       creates a constant_arraydescriptor structure for the array type named by an
+       utf string
        
 *******************************************************************************/
 
+/* XXX delete */
+#if 0
 constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
 {
        constant_arraydescriptor *d;
+
+       /* class_new( utf_new(utf_ptr,namelen) ); */ /* XXX remove */
        
        if (*utf_ptr++ != '[') panic ("Attempt to build arraydescriptor for non-array");
 
@@ -675,20 +785,25 @@ constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
                
        case 'L':
                d -> arraytype = ARRAYTYPE_OBJECT;
+
                d -> objectclass = class_new ( utf_new(utf_ptr+1, namelen-3) );
+                d -> objectclass  -> classUsed = NOTUSED; /* not used initially CO-RT */
+               d -> objectclass  -> impldBy = NULL;
                break;
        }
        return d;
 }
+#endif
 
 
-/******************* Funktion: freearraydescriptor *****************************
+/******************* Function: freearraydescriptor *****************************
 
-       entfernt eine mit buildarraydescriptor erzeugte Struktur wieder 
-       aus dem Speicher
+       removes a structure created by buildarraydescriptor from memory
        
 *******************************************************************************/
 
+/* XXX delete */
+#if 0
 static void freearraydescriptor (constant_arraydescriptor *d)
 {
        while (d) {
@@ -697,9 +812,12 @@ static void freearraydescriptor (constant_arraydescriptor *d)
                d = n;
                }
 }
+#endif
 
-/*********************** Funktion: displayarraydescriptor *********************/
+/*********************** Function: displayarraydescriptor *********************/
 
+/* XXX delete */
+#if 0
 static void displayarraydescriptor (constant_arraydescriptor *d)
 {
        switch (d->arraytype) {
@@ -715,20 +833,55 @@ static void displayarraydescriptor (constant_arraydescriptor *d)
        case ARRAYTYPE_OBJECT: utf_display(d->objectclass->name); printf("[]"); break;
        }
 }
+#endif
 
+/***************** Function: print_arraydescriptor ****************************
 
+       Debugging helper for displaying an arraydescriptor
+       
+*******************************************************************************/
+
+void
+print_arraydescriptor(FILE *file,arraydescriptor *desc)
+{
+       if (!desc) {
+               fprintf(file,"<NULL>");
+               return;
+       }
+
+       fprintf(file,"{");
+       if (desc->componentvftbl) {
+               if (desc->componentvftbl->class)
+                       utf_fprint(file,desc->componentvftbl->class->name);
+               else
+                       fprintf(file,"<no classinfo>");
+       }
+       else
+               fprintf(file,"0");
+               
+       fprintf(file,",");
+       if (desc->elementvftbl) {
+               if (desc->elementvftbl->class)
+                       utf_fprint(file,desc->elementvftbl->class->name);
+               else
+                       fprintf(file,"<no classinfo>");
+       }
+       else
+               fprintf(file,"0");
+       fprintf(file,",%d,%d,%d,%d}",desc->arraytype,desc->dimension,
+                       desc->dataoffset,desc->componentsize);
+}
 
 /******************************************************************************/
-/******************** Funktionen fuer Fields **********************************/
+/**************************  Functions for fields  ****************************/
 /******************************************************************************/
 
 
-/************************ Funktion: field_load *********************************
+/************************ Function: field_load *********************************
 
-       l"adt alle Informationen f"ur eine Feld einer Methode aus dem ClassFile,
-       und f"ullt mit diesen Infos eine schon existierende 'fieldinfo'-Struktur.
-       Bei 'static'-Fields wird auch noch ein Platz auf dem Datensegment
-       reserviert.
+       Load everything about a class field from the class file and fill a
+       'fieldinfo' structure. For static fields, space in the data segment is
+       allocated.
 
 *******************************************************************************/
 
@@ -742,6 +895,7 @@ static void field_load (fieldinfo *f, classinfo *c)
        f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor           */
        f -> type = jtype = desc_to_type (f->descriptor);                  /* data type                   */
        f -> offset = 0;                                                   /* offset from start of object */
+       f->xta = NULL;
        
        switch (f->type) {
        case TYPE_INT:        f->value.i = 0; break;
@@ -836,9 +990,9 @@ static void field_free (fieldinfo *f)
 }
 
 
-/************** Funktion: field_display (nur zu Debug-Zwecken) ****************/
+/**************** Function: field_display (debugging only) ********************/
 
-static void field_display (fieldinfo *f)
+void field_display (fieldinfo *f)
 {
        printf ("   ");
        printflags (f -> flags);
@@ -851,17 +1005,16 @@ static void field_display (fieldinfo *f)
 
 
 /******************************************************************************/
-/************************* Funktionen f"ur Methods ****************************/ 
+/************************* Functions for methods ******************************/ 
 /******************************************************************************/
 
 
-/*********************** Funktion: method_load *********************************
+/*********************** Function: method_load *********************************
 
-       l"adt die Infos f"ur eine Methode aus dem ClassFile und f"ullt damit 
-       eine schon existierende 'methodinfo'-Struktur aus.
-       Bei allen native-Methoden wird au"serdem gleich der richtige 
-       Funktionszeiger eingetragen, bei JavaVM-Methoden einstweilen ein
-       Zeiger auf den Compiler 
+       Loads a method from the class file and fills an existing 'methodinfo'
+       structure. For native methods, the function pointer field is set to the
+       real function pointer, for JavaVM methods a pointer to the compiler is used
+       preliminarily.
        
 *******************************************************************************/
 
@@ -884,6 +1037,12 @@ static void method_load (methodinfo *m, classinfo *c)
        m -> entrypoint = NULL;
        m -> mcode = NULL;
        m -> stubroutine = NULL;
+        m -> methodUsed = NOTUSED;    
+        m -> monoPoly = MONO;    
+       m -> subRedefs = 0;
+       m -> subRedefsUsed = 0;
+
+       m->xta = NULL;
        
        if (! (m->flags & ACC_NATIVE) ) {
                m -> stubroutine = createcompilerstub (m);
@@ -893,14 +1052,7 @@ static void method_load (methodinfo *m, classinfo *c)
                functionptr f = native_findfunction 
                       (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
                if (f) {
-#ifdef OLD_COMPILER
-               if (newcompiler)
-#endif
                        m -> stubroutine = createnativestub (f, m);
-#ifdef OLD_COMPILER
-               else
-                       m -> stubroutine = oldcreatenativestub (f, m);
-#endif
                        }
                }
        
@@ -953,10 +1105,9 @@ static void method_load (methodinfo *m, classinfo *c)
 
 }
 
-/********************* Funktion: method_free ***********************************
+/********************* Function: method_free ***********************************
 
-       gibt allen Speicher, der extra f"ur eine Methode angefordert wurde,
-       wieder frei
+       frees all memory that was allocated for this method
 
 *******************************************************************************/
 
@@ -973,7 +1124,7 @@ static void method_free (methodinfo *m)
 }
 
 
-/************** Funktion: method_display  (nur zu Debug-Zwecken) **************/
+/************** Function: method_display  (debugging only) **************/
 
 void method_display (methodinfo *m)
 {
@@ -987,11 +1138,10 @@ void method_display (methodinfo *m)
 }
 
 
-/******************** Funktion: method_canoverwrite ****************************
+/******************** Function: method_canoverwrite ****************************
 
-       "uberpr"ft, ob eine Methode mit einer anderen typ- und namensidentisch 
-       ist (also mit einer Methodendefinition eine andere "uberschrieben 
-       werden kann).
+       Check if m and old are identical with respect to type and name. This means
+       that old can be overwritten with m.
        
 *******************************************************************************/  
 
@@ -1007,11 +1157,11 @@ static bool method_canoverwrite (methodinfo *m, methodinfo *old)
 
 
 /******************************************************************************/
-/************************ Funktionen fuer Class *******************************/
+/************************ Functions for class *********************************/
 /******************************************************************************/
 
 
-/******************** function: class_getconstant ******************************
+/******************** function:: class_getconstant ******************************
 
        retrieves the value at position 'pos' of the constantpool of a class
        if the type of the value is other than 'ctype' the system is stopped
@@ -1025,8 +1175,10 @@ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
                panic ("Attempt to access constant outside range");
 
        /* check type of constantpool entry */
+
        if (c->cptags[pos] != ctype) {
-               sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
+               class_showconstantpool(c);
+               sprintf (logtext, "Type mismatch on constant: %d requested, %d here (class_getconstant)",
                 (int) ctype, (int) c->cptags[pos] );
                error();
                }
@@ -1035,10 +1187,9 @@ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
 }
 
 
-/********************* Funktion: class_constanttype ****************************
+/********************* Function: class_constanttype ****************************
 
-       Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer 
-       Klasse hat.
+       Determines the type of a class entry in the ConstantPool
        
 *******************************************************************************/
 
@@ -1283,21 +1434,11 @@ static void class_loadcpool (classinfo *c)
        while (forward_classes) {
                utf *name =
                  class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
-               
-               if ( (name->blength>0) && (name->text[0]=='[') ) {
-                       /* check validity of descriptor */
-                       checkfielddescriptor (name->text, utf_end(name)); 
 
-                       cptags  [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
-                       cpinfos [forward_classes -> thisindex] = 
-                          buildarraydescriptor(name->text, name->blength);
+               cptags  [forward_classes -> thisindex] = CONSTANT_Class;
+               /* retrieve class from class-table */
+               cpinfos [forward_classes -> thisindex] = class_new (name);
 
-                       }
-               else {                                  
-                       cptags  [forward_classes -> thisindex] = CONSTANT_Class;
-                       /* retrieve class from class-table */
-                       cpinfos [forward_classes -> thisindex] = class_new (name);
-                       }
                forward_classes = forward_classes -> next;
                
                }
@@ -1305,7 +1446,11 @@ static void class_loadcpool (classinfo *c)
        while (forward_strings) {
                utf *text = 
                  class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
-       
+/*
+               log_text("forward_string:");
+               printf( "classpoolid: %d\n",forward_strings -> thisindex);
+               utf_display(text);
+               log_text("\n------------------"); */
                /* resolve utf-string */                
                cptags   [forward_strings -> thisindex] = CONSTANT_String;
                cpinfos  [forward_strings -> thisindex] = text;
@@ -1344,6 +1489,21 @@ static void class_loadcpool (classinfo *c)
                nat = class_getconstant
                        (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
 
+#ifdef JOWENN_DEBUG
+               log_text("trying to resolve:");
+               log_text(nat->name->text);
+               switch(forward_fieldmethints ->tag) {
+               case CONSTANT_Fieldref: 
+                               log_text("CONSTANT_Fieldref");
+                               break;
+               case CONSTANT_InterfaceMethodref: 
+                               log_text("CONSTANT_InterfaceMethodref");
+                               break;
+               case CONSTANT_Methodref: 
+                               log_text("CONSTANT_Methodref");
+                               break;
+               }
+#endif
                fmi -> class = class_getconstant 
                        (c, forward_fieldmethints -> class_index, CONSTANT_Class);
                fmi -> name = nat -> name;
@@ -1366,22 +1526,22 @@ static void class_loadcpool (classinfo *c)
 
                }
 
+/*     class_showconstantpool(c); */
 
        dump_release (dumpsize);
 }
 
 
-/********************** Funktion: class_load ***********************************
-
-       l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
-       'classinfo'-Struktur mu"s bereits angelegt worden sein.
-       
-       Die Superklasse und die Interfaces, die diese Klasse implementiert,
-       m"ussen zu diesem Zeitpunkt noch nicht geladen sein, die 
-       Verbindung dazu wird sp"ater in der Funktion 'class_link' hergestellt.
+/********************** Function: class_load ***********************************
        
-       Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
-       und in die Liste 'unlinkedclasses' eingh"angt.
+       Loads everything interesting about a class from the class file. The
+       'classinfo' structure must have been allocated previously.
+
+       The super class and the interfaces implemented by this class need not be
+       loaded. The link is set later by the function 'class_link'.
+
+       The loaded class is removed from the list 'unloadedclasses' and added to
+       the list 'unlinkedclasses'.
        
 *******************************************************************************/
 
@@ -1390,16 +1550,25 @@ static int class_load (classinfo *c)
        u4 i;
        u4 mi,ma;
 
+#ifdef STATISTICS
+       count_class_loads++;
+#endif
+
+       /* XXX remove */
+       /*      loadverbose = 1; */
+       
        /* output for debugging purposes */
        if (loadverbose) {              
+
                sprintf (logtext, "Loading class: ");
                utf_sprint (logtext+strlen(logtext), c->name );
                dolog();
                }
        
        /* load classdata, throw exception on error */
+
        if (!suck_start (c->name)) {
-               throw_classnotfoundexception();            
+               throw_classnotfoundexception2(c->name);            
                return false;
        }
        
@@ -1408,19 +1577,20 @@ static int class_load (classinfo *c)
        /* check version */
        mi = suck_u2(); 
        ma = suck_u2();
-       if (ma != MAJOR_VERSION) {
-               sprintf (logtext, "Can only support major version %d, but not %d",
-                                MAJOR_VERSION, (int) ma);
+       if (ma != MAJOR_VERSION && (ma != MAJOR_VERSION+1 || mi != 0)) {
+               sprintf (logtext, "File version %d.%d is not supported",
+                                (int) ma, (int) mi);
                error();
                }
-       if (mi > MINOR_VERSION)  {
-               sprintf (logtext, "Minor version %d is not yet supported.", (int) mi);
-               error();
-               }
-
 
        class_loadcpool (c);
-       
+       /*JOWENN*/
+       c->erroneous_state=0;
+       c->initializing_thread=0;       
+       /*JOWENN*/
+        c -> classUsed = NOTUSED; /* not used initially CO-RT */
+       c -> impldBy = NULL;
+
        /* ACC flags */
        c -> flags = suck_u2 (); 
        /* this class */
@@ -1444,7 +1614,10 @@ static int class_load (classinfo *c)
 
        /* load fields */
        c -> fieldscount = suck_u2 ();
-       c -> fields = MNEW (fieldinfo, c -> fieldscount);
+/*     utf_display(c->name);
+       printf(" ,Fieldscount: %d\n",c->fieldscount);*/
+
+       c -> fields = GCNEW (fieldinfo, c -> fieldscount);
        for (i=0; i < c -> fieldscount; i++) {
                field_load (&(c->fields[i]), c);
                }
@@ -1478,10 +1651,10 @@ static int class_load (classinfo *c)
 
 
 
-/************** interne Funktion: class_highestinterface ***********************
+/************** internal Function: class_highestinterface ***********************
 
-       wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
-       die Interfacetable einer Klasse sein mu"s.
+       Used by the function class_link to determine the amount of memory needed
+       for the interface table.
 
 *******************************************************************************/
 
@@ -1507,9 +1680,8 @@ static s4 class_highestinterface (classinfo *c)
 
 /* class_addinterface **********************************************************
 
-       wird von der Funktion class_link ben"otigt, um eine Virtual Function 
-       Table f"ur ein Interface (und alle weiteren von diesem Interface
-       implementierten Interfaces) in eine Klasse einzutragen.
+       Is needed by class_link for adding a VTBL to a class. All interfaces
+       implemented by ic are added as well.
 
 *******************************************************************************/       
 
@@ -1560,26 +1732,223 @@ static void class_addinterface (classinfo *c, classinfo *ic)
 }
 
 
-/********************** Funktion: class_link ***********************************
+/******************* Function: class_new_array *********************************
+
+    This function is called by class_new to setup an array class.
+
+*******************************************************************************/
+
+void
+class_new_array(classinfo *c)
+{
+       classinfo *comp = NULL;
+       methodinfo *clone;
+       int namelen;
+
+       /* XXX remove logging */
+       /*
+       sprintf(logtext,"new array class: ");
+       utf_sprint(logtext+strlen(logtext),c->name);
+       dolog();
+       */
+       
+       /* Array classes are not loaded from classfiles. */
+       list_remove (&unloadedclasses, c);
+
+       /* Check array class name */
+       namelen = c->name->blength;
+       if (namelen < 2 || c->name->text[0] != '[')
+               panic("Invalid array class name.");
+
+       /* Check the component type */
+       switch (c->name->text[1]) {
+         case '[':
+                 /* c is an array of arrays. We have to create the component class. */
+                 comp = class_new(utf_new(c->name->text + 1,namelen - 1));
+                 break;
+
+         case 'L':
+                 /* XXX remove logging */
+                 /*
+                 sprintf(logtext,"Component class: ");
+                 utf_sprint(logtext+strlen(logtext),utf_new(c->name->text + 2,namelen - 3));
+                 dolog();
+                 if (class_get(utf_new(c->name->text + 2,namelen - 3)))
+                         log_text("Already created.");
+                 */
+                 
+                 /* c is an array of objects. */
+                 if (namelen < 4 || c->name->text[namelen-1] != ';')
+                         panic("Invalid array class name.");
+                 comp = class_new(utf_new(c->name->text + 2,namelen - 3));
+                 break;
+       }
+
+       /* Setup the array class */
+       c->super = class_java_lang_Object;
+
+    c->interfacescount = 2;
+    c->interfaces = MNEW(classinfo*,2);
+    c->interfaces[0] = class_java_lang_Cloneable;
+    c->interfaces[1] = class_java_io_Serializable;
+
+       c->methodscount = 1;
+       c->methods = MNEW (methodinfo, c->methodscount);
+
+       clone = c->methods;
+       memset(clone,0,sizeof(methodinfo));
+       clone->flags = ACC_PUBLIC; /* XXX protected? */
+       clone->name = utf_new_char("clone");
+       clone->descriptor = utf_new_char("()Ljava/lang/Object;");
+       clone->class = c;
+       clone->stubroutine = createnativestub(&builtin_clone_array,clone);
+       clone->monoPoly = MONO; /* XXX should be poly? */
+
+       /* XXX: field: length? */
+
+       /* The array class has to be linked */
+       list_addlast(&unlinkedclasses,c);
+       
+       /*
+     * Array classes which are created after the other classes have been
+     * loaded and linked are linked explicitely.
+     */
+       if (loader_inited)
+               loader_load(c->name);
+}
+
+/****************** Function: class_link_array *********************************
+
+    This function is called by class_link to create the
+    arraydescriptor for an array class.
+
+    This function returns NULL if the array cannot be linked because
+    the component type has not been linked yet.
+
+*******************************************************************************/
+
+static
+arraydescriptor *
+class_link_array(classinfo *c)
+{
+       classinfo *comp = NULL;
+       int namelen = c->name->blength;
+       arraydescriptor *desc;
+       vftbl *compvftbl;
+
+       /* XXX remove logging */
+
+       /*
+         sprintf(logtext,"linking array class: ");
+         utf_sprint(logtext+strlen(logtext),c->name);
+         dolog();
+       */
+       
+       
+       /* Check the component type */
+       switch (c->name->text[1]) {
+         case '[':
+                 /* c is an array of arrays. */
+                 comp = class_get(utf_new(c->name->text + 1,namelen - 1));
+                 if (!comp) panic("Could not find component array class.");
+                 break;
+
+         case 'L':
+                 /* c is an array of objects. */
+                 comp = class_get(utf_new(c->name->text + 2,namelen - 3));
+                 if (!comp) panic("Could not find component class.");
+                 break;
+       }
+
+       /* If the component type has not been linked return NULL */
+       if (comp && !comp->linked)
+               return NULL;
+
+       /* Allocate the arraydescriptor */
+       desc = NEW(arraydescriptor);
+
+       if (comp) {
+               /* c is an array of references */
+               desc->arraytype = ARRAYTYPE_OBJECT;
+               desc->componentsize = sizeof(void*);
+               desc->dataoffset = OFFSET(java_objectarray,data);
+               
+               compvftbl = comp->vftbl;
+               if (!compvftbl)
+                       panic("Component class has no vftbl.");
+               desc->componentvftbl = compvftbl;
+               
+               if (compvftbl->arraydesc) {
+                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+                       desc->dimension = compvftbl->arraydesc->dimension + 1;
+               }
+               else {
+                       desc->elementvftbl = compvftbl;
+                       desc->dimension = 1;
+               }
+       }
+       else {
+               /* c is an array of a primitive type */
+               switch (c->name->text[1]) {
+                 case 'Z': desc->arraytype = ARRAYTYPE_BOOLEAN;
+                           desc->dataoffset = OFFSET(java_booleanarray,data);
+                               desc->componentsize = sizeof(u1); break;
+                 case 'B': desc->arraytype = ARRAYTYPE_BYTE;
+                           desc->dataoffset = OFFSET(java_bytearray,data);
+                               desc->componentsize = sizeof(u1); break;
+                 case 'C': desc->arraytype = ARRAYTYPE_CHAR;
+                           desc->dataoffset = OFFSET(java_chararray,data);
+                               desc->componentsize = sizeof(u2); break;
+                 case 'D': desc->arraytype = ARRAYTYPE_DOUBLE;
+                           desc->dataoffset = OFFSET(java_doublearray,data);
+                               desc->componentsize = sizeof(double); break;
+                 case 'F': desc->arraytype = ARRAYTYPE_FLOAT;
+                           desc->dataoffset = OFFSET(java_floatarray,data);
+                               desc->componentsize = sizeof(float); break;
+                 case 'I': desc->arraytype = ARRAYTYPE_INT;
+                           desc->dataoffset = OFFSET(java_intarray,data);
+                               desc->componentsize = sizeof(s4); break;
+                 case 'J': desc->arraytype = ARRAYTYPE_LONG;
+                           desc->dataoffset = OFFSET(java_longarray,data);
+                               desc->componentsize = sizeof(s8); break;
+                 case 'S': desc->arraytype = ARRAYTYPE_SHORT;
+                           desc->dataoffset = OFFSET(java_shortarray,data);
+                               desc->componentsize = sizeof(s2); break;
+                 default:
+                         panic("Invalid array class name");
+               }
+               
+               desc->componentvftbl = NULL;
+               desc->elementvftbl = NULL;
+               desc->dimension = 1;
+       }
+
+       /* XXX remove logging */
+       /*
+         print_arraydescriptor(stdout,desc); 
+         printf("\n");
+       */
+
+       return desc;
+}
+
+/********************** Function: class_link ***********************************
 
-       versucht, eine Klasse in das System voll zu integrieren (linken). Dazu 
-       m"ussen sowol die Superklasse, als auch alle implementierten
-       Interfaces schon gelinkt sein.
-       Diese Funktion berechnet sowohl die L"ange (in Bytes) einer Instanz 
-       dieser Klasse, als auch die Virtual Function Tables f"ur normale
-       Methoden als auch Interface-Methoden.
+       Tries to link a class. The super class and every implemented interface must
+       already have been linked. The function calculates the length in bytes that
+       an instance of this class requires as well as the VTBL for methods and
+       interface methods.
        
-       Wenn die Klasse erfolgreich gelinkt werden kann, dann wird sie aus
-       der Liste 'unlinkedclasses' ausgeh"angt, und in die Klasse 'linkedclasses'
-       eingetragen.
-       Wenn nicht, dann wird sie ans Ende der Liste 'unlinkedclasses' gestellt.
+       If the class can be linked, it is removed from the list 'unlinkedclasses'
+       and added to 'linkedclasses'. Otherwise, it is moved to the end of
+       'unlinkedclasses'.
 
-       Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
-                eine Endlosschleife!!  (Da muss ich mir noch was einfallen lassen)
+       Attention: If cyclical class definitions are encountered, the program gets
+       into an infinite loop (we'll have to work that out)
 
 *******************************************************************************/
 
-static void class_link (classinfo *c)
+void class_link(classinfo *c)
 {
        s4 supervftbllength;          /* vftbllegnth of super class               */
        s4 vftbllength;               /* vftbllength of current class             */
@@ -1587,9 +1956,17 @@ static void class_link (classinfo *c)
        classinfo *super = c->super;  /* super class                              */
        classinfo *ic, *c2;           /* intermediate class variables             */
        vftbl *v;                     /* vftbl of current class                   */
-       s4 i;                         /* interface/method/field counter           */                     
+       s4 i;                         /* interface/method/field counter           */
+       arraydescriptor *arraydesc = NULL;  /* descriptor for array classes       */
 
 
+       /* XXX remove log */
+       /*
+         sprintf(logtext,"trying to link: ");
+         utf_sprint(logtext+strlen(logtext),c->name);
+         dolog();
+       */
+       
        /*  check if all superclasses are already linked, if not put c at end of
            unlinked list and return. Additionally initialize class fields.       */
 
@@ -1601,26 +1978,36 @@ static void class_link (classinfo *c)
                        list_remove(&unlinkedclasses, c);
                        list_addlast(&unlinkedclasses, c);
                        return; 
-                       }
                }
+       }
        
        /*  check super class */
 
        if (super == NULL) {          /* class java.long.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;
 
                c->finalizer = NULL;
-               }
+       }
        else {
                if (!super->linked) {
                        list_remove(&unlinkedclasses, c);
                        list_addlast(&unlinkedclasses, c);
                        return; 
-                       }
+               }
 
+               /* handle array classes */
+               if (c->name->text[0] == '[')
+                       if ((arraydesc = class_link_array(c)) == NULL) {
+                               list_remove(&unlinkedclasses, c);
+                               list_addlast(&unlinkedclasses, c);
+                               return; 
+                       }
+               
                if (c->flags & ACC_INTERFACE)
                        c->index = interfaceindex++;
                else
@@ -1631,14 +2018,14 @@ static void class_link (classinfo *c)
                vftbllength = supervftbllength = super->vftbl->vftbllength;
                
                c->finalizer = super->finalizer;
-               }
+       }
 
 
        if (linkverbose) {
                sprintf (logtext, "Linking Class: ");
                utf_sprint (logtext+strlen(logtext), c->name );
                dolog ();
-               }
+       }
 
        /* compute vftbl length */
 
@@ -1653,14 +2040,14 @@ static void class_link (classinfo *c)
                                        if (method_canoverwrite(m, &(sc->methods[j]))) {
                                                m->vftblindex = sc->methods[j].vftblindex;
                                                goto foundvftblindex;
-                                               }
                                        }
-                               sc = sc->super;
                                }
-                       m->vftblindex = (vftbllength++);
-foundvftblindex: ;
+                               sc = sc->super;
                        }
-               }       
+                       m->vftblindex = (vftbllength++);
+               foundvftblindex: ;
+               }
+       }       
        
 #ifdef STATISTICS
        count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
@@ -1675,26 +2062,31 @@ foundvftblindex: ;
                        s4 h = class_highestinterface (c2->interfaces[i]) + 1;
                        if (h > interfacetablelength)
                                interfacetablelength = h;
-                       }
-               c2 = c2->super;
                }
+               c2 = c2->super;
+       }
 
        /* allocate virtual function table */
 
        v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
-                   (vftbllength - 1) + sizeof(methodptr*) *
-                   (interfacetablelength - (interfacetablelength > 0)));
+                                                  (vftbllength - 1) + sizeof(methodptr*) *
+                                                  (interfacetablelength - (interfacetablelength > 0)));
        v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
-                                        (interfacetablelength > 1));
+                                 (interfacetablelength > 1));
        c->header.vftbl = c->vftbl = v;
        v->class = c;
        v->vftbllength = vftbllength;
        v->interfacetablelength = interfacetablelength;
+       v->arraydesc = arraydesc;
+
+       /* store interface index in vftbl */
+       if (c->flags & ACC_INTERFACE)
+               v->baseval = -(c->index);
 
        /* copy virtual function table of super class */
 
        for (i = 0; i < supervftbllength; i++) 
-          v->table[i] = super->vftbl->table[i];
+               v->table[i] = super->vftbl->table[i];
        
        /* add method stubs into virtual function table */
 
@@ -1702,8 +2094,8 @@ foundvftblindex: ;
                methodinfo *m = &(c->methods[i]);
                if (!(m->flags & ACC_STATIC)) {
                        v->table[m->vftblindex] = m->stubroutine;
-                       }
                }
+       }
 
        /* compute instance size and offset of each field */
        
@@ -1716,8 +2108,8 @@ foundvftblindex: ;
                        c->instancesize = ALIGN (c->instancesize, dsize);
                        f->offset = c->instancesize;
                        c->instancesize += dsize;
-                       }
                }
+       }
 
        /* initialize interfacetable and interfacevftbllength */
        
@@ -1730,14 +2122,14 @@ foundvftblindex: ;
        for (i = 0; i < interfacetablelength; i++) {
                v->interfacevftbllength[i] = 0;
                v->interfacetable[-i] = NULL;
-               }
+       }
        
        /* add interfaces */
        
        for (c2 = c; c2 != NULL; c2 = c2->super)
                for (i = 0; i < c2->interfacescount; i++) {
                        class_addinterface (c, c2->interfaces[i]);
-                       }
+               }
 
        /* add finalizer method (not for java.lang.Object) */
 
@@ -1755,9 +2147,9 @@ foundvftblindex: ;
                if (fi != NULL) {
                        if (!(fi->flags & ACC_STATIC)) {
                                c->finalizer = fi;
-                               }
                        }
                }
+       }
 
        /* final tasks */
 
@@ -1765,13 +2157,13 @@ foundvftblindex: ;
 
        list_remove (&unlinkedclasses, c);
        list_addlast (&linkedclasses, c);
+
 }
 
 
-/******************* Funktion: class_freepool **********************************
+/******************* Function: class_freepool **********************************
 
-       Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
-       wieder frei.
+       Frees all resources used by this classes Constant Pool.
 
 *******************************************************************************/
 
@@ -1807,9 +2199,6 @@ static void class_freecpool (classinfo *c)
                        case CONSTANT_NameAndType:
                                FREE (info, constant_nameandtype);
                                break;
-                       case CONSTANT_Arraydescriptor:
-                               freearraydescriptor (info);
-                               break;
                        }
                        }
                }
@@ -1819,9 +2208,9 @@ static void class_freecpool (classinfo *c)
 }
 
 
-/*********************** Funktion: class_free **********************************
+/*********************** Function: class_free **********************************
 
-       Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
+       Frees all resources used by the class.
 
 *******************************************************************************/
 
@@ -1836,13 +2225,15 @@ static void class_free (classinfo *c)
 
        for (i = 0; i < c->fieldscount; i++)
                field_free(&(c->fields[i]));
-       MFREE (c->fields, fieldinfo, c->fieldscount);
        
        for (i = 0; i < c->methodscount; i++)
                method_free(&(c->methods[i]));
        MFREE (c->methods, methodinfo, c->methodscount);
 
        if ((v = c->vftbl) != NULL) {
+               if (v->arraydesc)
+                       mem_free(v->arraydesc,sizeof(arraydescriptor));
+               
                for (i = 0; i < v->interfacetablelength; i++) {
                        MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
                        }
@@ -1859,13 +2250,16 @@ static void class_free (classinfo *c)
        if (c->innerclasscount)
                MFREE (c->innerclass, innerclassinfo, c->innerclasscount);
 
+       /*      if (c->classvftbl)
+               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
+       
        FREE (c, classinfo);
 }
 
-/************************* Funktion: class_findfield ***************************
+/************************* Function: class_findfield ***************************
        
-       sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
-       Namen und Typ.
+       Searches a 'classinfo' structure for a field having the given name and
+       type.
 
 *******************************************************************************/
 
@@ -1874,6 +2268,7 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 {
        s4 i;
 
+       
        for (i = 0; i < c->fieldscount; i++) { 
                if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) 
                        return &(c->fields[i]);                                                         
@@ -1884,31 +2279,147 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 }
 
 
-/************************* Funktion: class_findmethod **************************
+/************************* Function: class_findmethod **************************
+       
+       Searches a 'classinfo' structure for a method having the given name and
+       type and returns the index in the class info structure.
+       If type is NULL, it is ignored.
+
+*******************************************************************************/
+
+s4 class_findmethodIndex (classinfo *c, utf *name, utf *desc)
+{
+       s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+       char *buffer;                   
+       int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+       buffer_len = 
+         utf_strlen(name) + utf_strlen(desc) +utf_strlen(c->name)+ 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "class_findmethod: method:");
+        utf_sprint(buffer+strlen(buffer), name);
+       strcpy(buffer+strlen(buffer), ", desc: ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), ", classname: ");
+        utf_sprint(buffer+strlen(buffer), c->name);
+       
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif 
+       for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+               buffer_len = 
+                 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+       
+               buffer = MNEW(char, buffer_len);
+
+               strcpy(buffer, "class_findmethod: comparing to method:");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].name);
+               strcpy(buffer+strlen(buffer), ", desc: ");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].descriptor);
+       
+               log_text(buffer);       
+
+               MFREE(buffer, char, buffer_len);
+               #endif  
+               
+               
+               if ((c->methods[i].name == name) && ((desc == NULL) ||
+                                                  (c->methods[i].descriptor == desc)))
+                       return i;
+               }
+#ifdef JOWENN_DEBUG2   
+       class_showconstantpool(c);
+       log_text("class_findmethod: returning NULL");
+#endif
+       return -1;
+}
+
+
+
+/************************* Function: class_findmethod **************************
        
-       sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
-       Namen und Typ.
-       Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
+       Searches a 'classinfo' structure for a method having the given name and
+       type.
+       If type is NULL, it is ignored.
 
 *******************************************************************************/
 
 methodinfo *class_findmethod (classinfo *c, utf *name, utf *desc)
 {
+#if 0
        s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+       char *buffer;                   
+       int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+       buffer_len = 
+         utf_strlen(name) + utf_strlen(desc) +utf_strlen(c->name)+ 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "class_findmethod: method:");
+        utf_sprint(buffer+strlen(buffer), name);
+       strcpy(buffer+strlen(buffer), ", desc: ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), ", classname: ");
+        utf_sprint(buffer+strlen(buffer), c->name);
+       
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif 
        for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+               buffer_len = 
+                 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+       
+               buffer = MNEW(char, buffer_len);
+
+               strcpy(buffer, "class_findmethod: comparing to method:");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].name);
+               strcpy(buffer+strlen(buffer), ", desc: ");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].descriptor);
+       
+               log_text(buffer);       
+
+               MFREE(buffer, char, buffer_len);
+               #endif  
+               
+               
                if ((c->methods[i].name == name) && ((desc == NULL) ||
                                                   (c->methods[i].descriptor == desc)))
                        return &(c->methods[i]);
                }
+#ifdef JOWENN_DEBUG2   
+       class_showconstantpool(c);
+       log_text("class_findmethod: returning NULL");
+#endif
        return NULL;
+#endif
+       s4 idx=class_findmethodIndex(c,name,desc);
+/*     if (idx==-1) log_text("class_findmethod: method not found");*/
+       if (idx==-1) return NULL;
+       return &(c->methods[idx]);
 }
 
-/************************* Funktion: class_findmethod_approx ******************
+
+
+
+
+
+/************************* Function: class_findmethod_approx ******************
        
-       sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
-       Namen und Typ.
-       Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
-       beim Vergleichen des Descriptors wird der R"uckgabewert nicht betrachtet
+       like class_findmethod but ignores the return value when comparing the
+       descriptor.
 
 *******************************************************************************/
 
@@ -1948,10 +2459,10 @@ methodinfo *class_findmethod_approx (classinfo *c, utf *name, utf *desc)
        return NULL;
 }
 
-/***************** Funktion: class_resolvemethod_approx ***********************
+/***************** Function: class_resolvemethod_approx ***********************
        
-       sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
-       (ohne Beachtung des R"uckgabewertes)
+       Searches a class and every super class for a method (without paying
+       attention to the return value)
 
 *******************************************************************************/
 
@@ -1969,49 +2480,47 @@ methodinfo *class_resolvemethod_approx (classinfo *c, utf *name, utf *desc)
 }
 
 
-/************************* Funktion: class_resolvemethod ***********************
+/************************* Function: class_resolvemethod ***********************
        
-       sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
+       Searches a class and every super class for a method.
 
 *******************************************************************************/
 
-
 methodinfo *class_resolvemethod (classinfo *c, utf *name, utf *desc)
 {
        while (c) {
-               methodinfo *m = class_findmethod (c, name, desc);
+               methodinfo *m = class_findmethod(c, name, desc);
                if (m) return m;
                /* search superclass */
                c = c->super;
-               }
+       }
        return NULL;
 }
-       
 
 
-/************************* Funktion: class_issubclass **************************
 
-       "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.            
+/************************* Function: class_issubclass **************************
+
+       Checks if sub is a descendant of super.
        
 *******************************************************************************/
 
-bool class_issubclass (classinfo *sub, classinfo *super)
+bool class_issubclass(classinfo *sub, classinfo *super)
 {
        for (;;) {
                if (!sub) return false;
                if (sub==super) return true;
                sub = sub -> super;
-               }
+       }
 }
 
 
 
-/****************** Initialisierungsfunktion f"ur eine Klasse ******************
+/****************** Initialization function for classes ******************
 
-       In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
-       Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
-       Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
-       wird.
+       In Java, every class can have a static initialization function. This
+       function has to be called BEFORE calling other methods or accessing static
+       variables.
 
 *******************************************************************************/
 
@@ -2019,110 +2528,237 @@ bool class_issubclass (classinfo *sub, classinfo *super)
 extern int blockInts;
 #endif
 
-void class_init (classinfo *c)
+void class_init(classinfo *c)
 {
-       methodinfo *m;
-       java_objectheader *exceptionptr;
-       s4 i;
-       int b;
-
-       if (!makeinitializations) return;
-       if (c->initialized) return;
-       c -> initialized = true;
-       
-       if (c->super) class_init (c->super);
-       for (i=0; i < c->interfacescount; i++) class_init(c->interfaces[i]);
-
-       m = class_findmethod (c, 
-                             utf_clinit, 
-                             utf_fidesc);
-       if (!m) {
-               if (initverbose) {
-                       sprintf (logtext, "Class ");
-                       utf_sprint (logtext+strlen(logtext), c->name);
-                       sprintf (logtext+strlen(logtext), " has no initializer");       
-                       dolog ();
-                       }
-               return;
-               }
-               
-       if (! (m->flags & ACC_STATIC)) panic ("Class initializer is not static!");
-       
-       if (initverbose) {
-               sprintf (logtext, "Starting initializer for class: ");
-               utf_sprint (logtext+strlen(logtext), c->name);
-               dolog ();
-       }
+        methodinfo *m;
+        java_objectheader *exceptionptr;
+        s4 i;
+        int b;
+
+
+        if (!makeinitializations)
+                return;
+        if (c->initialized)
+                return;
+        c -> initialized = true;
+
+
+
+#ifdef STATISTICS
+        count_class_inits++;
+#endif
+
+        if (c->super)
+                class_init (c->super);
+        for (i=0; i < c->interfacescount; i++)
+                class_init(c->interfaces[i]);  /* real */
+
+        m = class_findmethod (c, utf_clinit, utf_fidesc);
+        if (!m) {
+                if (initverbose) {
+                        sprintf (logtext, "Class ");
+                        utf_sprint (logtext+strlen(logtext), c->name);
+                        sprintf (logtext+strlen(logtext), " has no initializer");
+                        dolog ();
+                        }
+/*              goto callinitialize;*/
+                return;
+                }
+
+        if (! (m->flags & ACC_STATIC))
+                panic ("Class initializer is not static!");
+
+        if (initverbose) {
+                sprintf (logtext, "Starting initializer for class: ");
+                utf_sprint (logtext+strlen(logtext), c->name);
+                dolog ();
+        }
 
 #ifdef USE_THREADS
-       b = blockInts;
-       blockInts = 0;
+        b = blockInts;
+        blockInts = 0;
 #endif
 
-       exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
+        exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
 
 #ifdef USE_THREADS
-       assert(blockInts == 0);
-       blockInts = b;
+        assert(blockInts == 0);
+        blockInts = b;
 #endif
 
-       if (exceptionptr) {     
-               printf ("#### Initializer of ");
-               utf_display (c->name);
-               printf (" has thrown: ");
-               utf_display (exceptionptr->vftbl->class->name);
-               printf ("\n");
-               fflush (stdout);
-               }
+        if (exceptionptr) {
+                printf ("#### Initializer of ");
+                utf_display (c->name);
+                printf (" has thrown: ");
+                utf_display (exceptionptr->vftbl->class->name);
+                printf ("\n");
+                fflush (stdout);
+                }
+
+        if (initverbose) {
+                sprintf (logtext, "Finished initializer for class: ");
+                utf_sprint (logtext+strlen(logtext), c->name);
+                dolog ();
+        }
+        if (c->name == utf_systemclass) {
+                /* class java.lang.System requires explicit initialization */
+
+                if (initverbose)
+                        printf ("#### Initializing class System");
+
+                /* find initializing method */
+                m = class_findmethod (c,
+                                        utf_initsystemclass,
+                                        utf_fidesc);
+
+                if (!m) {
+                        /* no method found */
+                        /* printf("initializeSystemClass failed"); */
+                        return;
+                }
+                #ifdef USE_THREADS
+                        b = blockInts;
+                        blockInts = 0;
+                #endif
+
+                exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
+
+                #ifdef USE_THREADS
+                        assert(blockInts == 0);
+                        blockInts = b;
+                #endif
+
+                if (exceptionptr) {
+                        printf ("#### initializeSystemClass has thrown: ");
+                        utf_display (exceptionptr->vftbl->class->name);
+                        printf ("\n");
+                        fflush (stdout);
+                }
+        }
 
-       if (initverbose) {
-               sprintf (logtext, "Finished initializer for class: ");
-               utf_sprint (logtext+strlen(logtext), c->name);
-               dolog ();
-       }
+}
 
-       if (c->name == utf_systemclass) {
-               /* class java.lang.System requires explicit initialization */
-               
-               if (initverbose)
-                       printf ("#### Initializing class System");
-
-               /* find initializing method */     
-               m = class_findmethod (c, 
-                                       utf_initsystemclass,
-                                       utf_fidesc);
-
-               if (!m) {
-                       /* no method found */
-                       log("initializeSystemClass failed");
-                       return;
-               }
 
-               #ifdef USE_THREADS
-                       b = blockInts;
-                       blockInts = 0;
-               #endif
 
-               exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
 
-               #ifdef USE_THREADS
-                       assert(blockInts == 0);
-                       blockInts = b;
-               #endif
+/********* Function: find_class_method_constant *********/
+int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)  
+{
+       u4 i;
+       voidptr e;
 
-               if (exceptionptr) {                     
-                       printf ("#### initializeSystemClass has thrown: ");
-                       utf_display (exceptionptr->vftbl->class->name);
-                       printf ("\n");
-                       fflush (stdout);                  
+       for (i=0; i<c->cpcount; i++) {
+               
+               e = c -> cpinfos [i];
+               if (e) {
+                       
+                       switch (c -> cptags [i]) {
+                       case CONSTANT_Methodref:
+                               {
+                                       constant_FMIref *fmi = e;
+                                       if (       (fmi->class->name == c1)  
+                                                          && (fmi->name == m1)
+                                                          && (fmi->descriptor == d1)) {
+                                       
+                                               return i;
+                                       }
+                               }
+                               break;
+
+                       case CONSTANT_InterfaceMethodref:
+                               {
+                                       constant_FMIref *fmi = e;
+                                       if (       (fmi->class->name == c1)  
+                                                          && (fmi->name == m1)
+                                                          && (fmi->descriptor == d1)) {
+
+                                               return i;
+                                       }
+                               }
+                               break;
+                       }
                }
        }
+
+       return -1;
 }
 
 
+void class_showconstanti(classinfo *c, int ii) 
+{
+       u4 i = ii;
+       voidptr e;
+               
+       e = c->cpinfos [i];
+       printf ("#%d:  ", (int) i);
+       if (e) {
+               switch (c->cptags [i]) {
+               case CONSTANT_Class:
+                       printf("Classreference -> ");
+                       utf_display(((classinfo*)e)->name);
+                       break;
+                               
+               case CONSTANT_Fieldref:
+                       printf("Fieldref -> "); goto displayFMIi;
+               case CONSTANT_Methodref:
+                       printf("Methodref -> "); goto displayFMIi;
+               case CONSTANT_InterfaceMethodref:
+                       printf("InterfaceMethod -> "); goto displayFMIi;
+               displayFMIi:
+                       {
+                               constant_FMIref *fmi = e;
+                               utf_display(fmi->class->name);
+                               printf(".");
+                               utf_display(fmi->name);
+                               printf(" ");
+                               utf_display(fmi->descriptor);
+                       }
+                       break;
 
+               case CONSTANT_String:
+                       printf("String -> ");
+                       utf_display(e);
+                       break;
+               case CONSTANT_Integer:
+                       printf("Integer -> %d", (int) (((constant_integer*)e)->value));
+                       break;
+               case CONSTANT_Float:
+                       printf("Float -> %f", ((constant_float*)e)->value);
+                       break;
+               case CONSTANT_Double:
+                       printf("Double -> %f", ((constant_double*)e)->value);
+                       break;
+               case CONSTANT_Long:
+                       {
+                               u8 v = ((constant_long*)e)->value;
+#if U8_AVAILABLE
+                               printf("Long -> %ld", (long int) v);
+#else
+                               printf("Long -> HI: %ld, LO: %ld\n", 
+                                           (long int) v.high, (long int) v.low);
+#endif 
+                       }
+                       break;
+               case CONSTANT_NameAndType:
+                       { 
+                               constant_nameandtype *cnt = e;
+                               printf("NameAndType: ");
+                               utf_display(cnt->name);
+                               printf(" ");
+                               utf_display(cnt->descriptor);
+                       }
+                       break;
+               case CONSTANT_Utf8:
+                       printf("Utf8 -> ");
+                       utf_display(e);
+                       break;
+               default: 
+                       panic("Invalid type of ConstantPool-Entry");
+               }
+       }
+       printf("\n");
+}
 
-/********* Funktion: class_showconstantpool   (nur f"ur Debug-Zwecke) *********/
 
 void class_showconstantpool (classinfo *c) 
 {
@@ -2138,83 +2774,77 @@ void class_showconstantpool (classinfo *c)
                if (e) {
                        
                        switch (c -> cptags [i]) {
-                               case CONSTANT_Class:
-                                       printf ("Classreference -> ");
-                                       utf_display ( ((classinfo*)e) -> name );
-                                       break;
+                       case CONSTANT_Class:
+                               printf ("Classreference -> ");
+                               utf_display ( ((classinfo*)e) -> name );
+                               break;
                                
-                               case CONSTANT_Fieldref:
-                                       printf ("Fieldref -> "); goto displayFMI;
-                               case CONSTANT_Methodref:
-                                       printf ("Methodref -> "); goto displayFMI;
-                               case CONSTANT_InterfaceMethodref:
-                                       printf ("InterfaceMethod -> "); goto displayFMI;
-                                 displayFMI:
-                                       {
+                       case CONSTANT_Fieldref:
+                               printf ("Fieldref -> "); goto displayFMI;
+                       case CONSTANT_Methodref:
+                               printf ("Methodref -> "); goto displayFMI;
+                       case CONSTANT_InterfaceMethodref:
+                               printf ("InterfaceMethod -> "); goto displayFMI;
+                       displayFMI:
+                               {
                                        constant_FMIref *fmi = e;
                                        utf_display ( fmi->class->name );
                                        printf (".");
                                        utf_display ( fmi->name);
                                        printf (" ");
                                        utf_display ( fmi->descriptor );
-                                   }
-                                       break;
+                               }
+                               break;
 
-                               case CONSTANT_String:
-                                       printf ("String -> ");
-                                       utf_display (e);
-                                       break;
-                               case CONSTANT_Integer:
-                                       printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
-                                       break;
-                               case CONSTANT_Float:
-                                       printf ("Float -> %f", ((constant_float*)e) -> value);
-                                       break;
-                               case CONSTANT_Double:
-                                       printf ("Double -> %f", ((constant_double*)e) -> value);
-                                       break;
-                               case CONSTANT_Long:
-                                       {
+                       case CONSTANT_String:
+                               printf ("String -> ");
+                               utf_display (e);
+                               break;
+                       case CONSTANT_Integer:
+                               printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
+                               break;
+                       case CONSTANT_Float:
+                               printf ("Float -> %f", ((constant_float*)e) -> value);
+                               break;
+                       case CONSTANT_Double:
+                               printf ("Double -> %f", ((constant_double*)e) -> value);
+                               break;
+                       case CONSTANT_Long:
+                               {
                                        u8 v = ((constant_long*)e) -> value;
 #if U8_AVAILABLE
                                        printf ("Long -> %ld", (long int) v);
 #else
                                        printf ("Long -> HI: %ld, LO: %ld\n", 
-                                           (long int) v.high, (long int) v.low);
+                                                       (long int) v.high, (long int) v.low);
 #endif 
-                                       }
-                                       break;
-                               case CONSTANT_NameAndType:
-                                       { constant_nameandtype *cnt = e;
-                                         printf ("NameAndType: ");
-                                         utf_display (cnt->name);
-                                         printf (" ");
-                                         utf_display (cnt->descriptor);
-                                       }
-                                       break;
-                               case CONSTANT_Utf8:
-                                       printf ("Utf8 -> ");
-                                       utf_display (e);
-                                       break;
-                               case CONSTANT_Arraydescriptor:  {
-                                       printf ("Arraydescriptor: ");
-                                       displayarraydescriptor (e);
-                                       }
-                                       break;
-                               default: 
-                                       panic ("Invalid type of ConstantPool-Entry");
                                }
-                               
+                               break;
+                       case CONSTANT_NameAndType:
+                               {
+                                       constant_nameandtype *cnt = e;
+                                       printf ("NameAndType: ");
+                                       utf_display (cnt->name);
+                                       printf (" ");
+                                       utf_display (cnt->descriptor);
+                               }
+                               break;
+                       case CONSTANT_Utf8:
+                               printf ("Utf8 -> ");
+                               utf_display (e);
+                               break;
+                       default: 
+                               panic ("Invalid type of ConstantPool-Entry");
                        }
+               }
 
                printf ("\n");
-               }
-       
+       }
 }
 
 
 
-/********** Funktion: class_showmethods   (nur f"ur Debug-Zwecke) *************/
+/********** Function: class_showmethods   (debugging only) *************/
 
 void class_showmethods (classinfo *c)
 {
@@ -2261,28 +2891,34 @@ void class_showmethods (classinfo *c)
 
 
 /******************************************************************************/
-/******************* Funktionen fuer den Class-loader generell ****************/
+/******************* General functions for the class loader *******************/
 /******************************************************************************/
 
-static int loader_inited = 0;
-
-/********************* Funktion: loader_load ***********************************
+/********************* Function: loader_load ***********************************
 
-       l"adt und linkt die ge"unschte Klasse und alle davon 
-       referenzierten Klassen und Interfaces
-       Return: Einen Zeiger auf diese Klasse
+       Loads and links the class desired class and each class and interface
+       referenced by it.
+       Returns: a pointer to this class
 
 *******************************************************************************/
 
+static int loader_load_running = 0;
+
 classinfo *loader_load (utf *topname)
 {
        classinfo *top;
        classinfo *c;
        long int starttime=0,stoptime=0;
+
+       /* avoid recursive calls */
+       if (loader_load_running)
+               return class_new(topname);
+       loader_load_running++;
        
        intsDisable();                           /* schani */
 
-       if (getloadingtime) starttime = getcputime();
+       if (getloadingtime)
+               starttime = getcputime();
 
        top = class_new (topname);
 
@@ -2299,17 +2935,19 @@ classinfo *loader_load (utf *topname)
                class_link (c);
                }
 
+       if (loader_inited)
+               loader_compute_subclasses();
+
        /* measure time */
        if (getloadingtime) {
                stoptime = getcputime();
                loadingtime += (stoptime-starttime);
                }
 
-       if (loader_inited)
-               loader_compute_subclasses();
-
        intsRestore();                          /* schani */
 
+       loader_load_running--;
+       
        return top; 
 }
 
@@ -2328,7 +2966,9 @@ void create_primitive_classes()
        for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
                /* create primitive class */
                classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
-               
+                c -> classUsed = NOTUSED; /* not used initially CO-RT */               
+               c -> impldBy = NULL;
+
                /* prevent loader from loading primitive class */
                list_remove (&unloadedclasses, c);
                /* add to unlinked classes */
@@ -2341,6 +2981,82 @@ void create_primitive_classes()
                /* create class for wrapping the primitive type */
                primitivetype_table[i].class_wrap =
                        class_new( utf_new_char(primitivetype_table[i].wrapname) );
+                primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
+               primitivetype_table[i].class_wrap  -> impldBy = NULL;
+
+               /* create the primitive array class */
+               if (primitivetype_table[i].arrayname) {
+                       c = class_new( utf_new_char(primitivetype_table[i].arrayname) );
+                       primitivetype_table[i].arrayclass = c;
+                       if (!c->linked) class_link(c);
+                       primitivetype_table[i].arrayvftbl = c->vftbl;
+               }
+       }
+}
+
+/**************** function: class_primitive_from_sig ***************************
+
+       return the primitive class indicated by the given signature character
+
+    If the descriptor does not indicate a valid primitive type the
+    return value is NULL.
+
+********************************************************************************/
+
+classinfo *class_primitive_from_sig(char sig)
+{
+       switch (sig) {
+         case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
+         case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
+         case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
+         case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
+         case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
+         case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
+         case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
+         case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
+         case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
+       }
+       return NULL;
+}
+
+/****************** function: class_from_descriptor ****************************
+
+    return the class indicated by the given descriptor
+
+    utf_ptr....first character of descriptor
+    end_ptr....first character after the end of the string
+    next.......if non-NULL, *next is set to the first character after
+               the descriptor
+    mode.......what to do if a class descriptor is parsed successfully:
+                   CLASSLOAD_SKIP...skip it and return something != NULL
+                   CLASSLOAD_NEW....get classinfo * via class_new
+                   CLASSLOAD_LOAD...get classinfo * via loader_load
+
+    If the descriptor is invalid the return value is NULL
+
+********************************************************************************/
+
+classinfo *class_from_descriptor(char *utf_ptr,char *end_ptr,char **next,int mode)
+{
+       char *start = utf_ptr;
+       bool error = false;
+       utf *name;
+       
+       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,error);
+       if (error) return NULL;
+       if (next) *next = utf_ptr;
+
+       switch (*start) {
+         case 'L':
+                 start++;
+                 utf_ptr--;
+                 /* fallthrough */
+         case '[':
+                 if (mode == CLASSLOAD_SKIP) return class_java_lang_Object;
+                 name = utf_new(start,utf_ptr-start);
+                 return (mode == CLASSLOAD_LOAD) ? loader_load(name) : class_new(name);
+         default:
+                 return class_primitive_from_sig(*start);
        }
 }
 
@@ -2350,7 +3066,8 @@ void create_primitive_classes()
 
 ********************************************************************************/
 
-
+/* XXX delete */
+#if 0
 classinfo *create_array_class(utf *u)
 {  
        classinfo *c = class_new (u);
@@ -2360,22 +3077,63 @@ classinfo *create_array_class(utf *u)
        list_addlast (&unlinkedclasses, c);
        c -> super = class_java_lang_Object;
        class_link(c);
-
        return c;
 }
+#endif
 
-/********************** Funktion: loader_init **********************************
+/*************** function: create_pseudo_classes *******************************
 
-       Initialisiert alle Listen und l"adt alle Klassen, die vom System
-       und vom Compiler direkt ben"otigt werden.
+       create pseudo classes used by the typechecker
+
+********************************************************************************/
+
+static void
+create_pseudo_classes()
+{
+    /* pseudo class for Arraystubs (extends java.lang.Object) */
+    
+    pseudo_class_Arraystub = class_new( utf_new_char(";Arraystub;") );
+    list_remove(&unloadedclasses,pseudo_class_Arraystub);
+
+    pseudo_class_Arraystub->super = class_java_lang_Object;
+    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;
+
+    list_addlast(&unlinkedclasses,pseudo_class_Arraystub);
+    class_link(pseudo_class_Arraystub);
+
+       pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
+
+    /* pseudo class representing the null type */
+    
+    pseudo_class_Null = class_new( utf_new_char(";Null;") );
+    list_remove(&unloadedclasses,pseudo_class_Null);
+
+    pseudo_class_Null->super = class_java_lang_Object;
+
+    list_addlast(&unlinkedclasses,pseudo_class_Null);
+    class_link(pseudo_class_Null);     
+}
+
+/********************** Function: loader_init **********************************
+
+       Initializes all lists and loads all classes required for the system or the
+       compiler.
 
 *******************************************************************************/
  
-void loader_init ()
+void loader_init (u1 * stackbottom)
 {
-       utf *string_class;
        interfaceindex = 0;
        
+       
+       log_text("Entering loader_init");
+                               
+       
        list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
        list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
        list_init (&linkedclasses, OFFSET(classinfo, listnode) );
@@ -2389,92 +3147,108 @@ void loader_init ()
        utf_clinit              = utf_new_char("<clinit>");
        utf_initsystemclass = utf_new_char("initializeSystemClass");
        utf_systemclass     = utf_new_char("java/lang/System");
+       utf_vmclassloader =utf_new_char("java/lang/VMClassLoader");
+       utf_initialize =utf_new_char("initialize");
+       utf_initializedesc =utf_new_char("(I)V");
+
+       utf_vmclass =utf_new_char("java/lang/VMClass");
+
+        /* create some important classes */
+        /* These classes have to be created now because the classinfo
+         * pointers are used in the loading code.
+         */
+        class_java_lang_Object = class_new( utf_new_char ("java/lang/Object") );
+        class_java_lang_String = class_new( utf_new_char("java/lang/String") );
+        class_java_lang_Cloneable = class_new( utf_new_char ("java/lang/Cloneable") );
+        class_java_io_Serializable = class_new( utf_new_char ("java/io/Serializable") );
+
+        log_text("loader_init: java/lang/Object");
+        /* load the classes which were created above */
+        loader_load (class_java_lang_Object->name);
+
+        loader_inited=1; /*JOWENN*/
+
+        class_java_lang_Throwable =
+                loader_load( utf_new_char("java/lang/Throwable") );
+
+        log_text("loader_init:  loader_load: java/lang/ClassCastException");
+        class_java_lang_ClassCastException =
+                loader_load ( utf_new_char ("java/lang/ClassCastException") );
+        class_java_lang_NullPointerException =
+                loader_load ( utf_new_char ("java/lang/NullPointerException") );
+        class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
+             utf_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
+        class_java_lang_NegativeArraySizeException = loader_load (
+             utf_new_char ("java/lang/NegativeArraySizeException") );
+        class_java_lang_OutOfMemoryError = loader_load (
+             utf_new_char ("java/lang/OutOfMemoryError") );
+        class_java_lang_ArrayStoreException =
+                loader_load ( utf_new_char ("java/lang/ArrayStoreException") );
+        class_java_lang_ArithmeticException =
+                loader_load ( utf_new_char ("java/lang/ArithmeticException") );
+        class_java_lang_ThreadDeath =                             /* schani */
+                loader_load ( utf_new_char ("java/lang/ThreadDeath") );
+        /* create classes representing primitive types */
+        create_primitive_classes();
+
+        /* create classes used by the typechecker */
+        create_pseudo_classes();
+
+        /* correct vftbl-entries (retarded loading of class java/lang/String) */
+        stringtable_update();
+#ifdef USE_THREADS
+        if (stackbottom!=0)
+                initLocks();
+#endif
 
-       /* create class for arrays */
-       class_array = class_new ( utf_new_char ("The_Array_Class") );
-       list_remove (&unloadedclasses, class_array);
-
-       /* create class for strings, load it after class Object was loaded */
-       string_class = utf_new_char ("java/lang/String");
-       class_java_lang_String = class_new(string_class);
-       list_remove (&unloadedclasses, class_java_lang_String);
-
-       class_java_lang_Object = 
-               loader_load ( utf_new_char ("java/lang/Object") );
-
-       list_addlast(&unloadedclasses, class_java_lang_String);
-
-       class_java_lang_String = 
-               loader_load ( string_class );
-       class_java_lang_ClassCastException = 
-               loader_load ( utf_new_char ("java/lang/ClassCastException") );
-       class_java_lang_NullPointerException = 
-               loader_load ( utf_new_char ("java/lang/NullPointerException") );
-       class_java_lang_ArrayIndexOutOfBoundsException = loader_load ( 
-            utf_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
-       class_java_lang_NegativeArraySizeException = loader_load ( 
-            utf_new_char ("java/lang/NegativeArraySizeException") );
-       class_java_lang_OutOfMemoryError = loader_load ( 
-            utf_new_char ("java/lang/OutOfMemoryError") );
-       class_java_lang_ArrayStoreException =
-               loader_load ( utf_new_char ("java/lang/ArrayStoreException") );
-       class_java_lang_ArithmeticException = 
-               loader_load ( utf_new_char ("java/lang/ArithmeticException") );
-       class_java_lang_ThreadDeath =                             /* schani */
-               loader_load ( utf_new_char ("java/lang/ThreadDeath") );
-
-       /* link class for arrays */
-       list_addlast (&unlinkedclasses, class_array);
-       class_array -> super = class_java_lang_Object;
-       class_link (class_array);
-
-       /* correct vftbl-entries (retarded loading of class java/lang/String) */
-       stringtable_update(); 
-
-       /* create classes representing primitive types */
-       create_primitive_classes();
-               
-       proto_java_lang_ClassCastException = 
-               builtin_new(class_java_lang_ClassCastException);
-       heap_addreference ( (void**) &proto_java_lang_ClassCastException);
 
-       proto_java_lang_NullPointerException = 
-               builtin_new(class_java_lang_NullPointerException);
-       heap_addreference ( (void**) &proto_java_lang_NullPointerException);
 
-       proto_java_lang_ArrayIndexOutOfBoundsException = 
-               builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
-       heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
+        log_text("loader_init: creating global proto_java_lang_ClassCastException");
+        proto_java_lang_ClassCastException =
+                builtin_new(class_java_lang_ClassCastException);
+        heap_addreference ( (void**) &proto_java_lang_ClassCastException);
+
+        log_text("loader_init: proto_java_lang_ClassCastException has been initialized");
+
+        proto_java_lang_NullPointerException =
+               builtin_new(class_java_lang_NullPointerException);
+        heap_addreference ( (void**) &proto_java_lang_NullPointerException);
+        log_text("loader_init: proto_java_lang_NullPointerException has been initialized");
+
+        proto_java_lang_ArrayIndexOutOfBoundsException =
+                builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
+        heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
+
+        proto_java_lang_NegativeArraySizeException =
+                builtin_new(class_java_lang_NegativeArraySizeException);
+        heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
 
-       proto_java_lang_NegativeArraySizeException = 
-               builtin_new(class_java_lang_NegativeArraySizeException);
-       heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
+        proto_java_lang_OutOfMemoryError =
+                builtin_new(class_java_lang_OutOfMemoryError);
+        heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
 
-       proto_java_lang_OutOfMemoryError = 
-               builtin_new(class_java_lang_OutOfMemoryError);
-       heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
+        proto_java_lang_ArithmeticException =
+               builtin_new(class_java_lang_ArithmeticException);
+        heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
 
-       proto_java_lang_ArithmeticException = 
-               builtin_new(class_java_lang_ArithmeticException);
-       heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
+        proto_java_lang_ArrayStoreException =
+                builtin_new(class_java_lang_ArrayStoreException);
+        heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
 
-       proto_java_lang_ArrayStoreException = 
-               builtin_new(class_java_lang_ArrayStoreException);
-       heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
+        proto_java_lang_ThreadDeath =                             /* schani */
+                builtin_new(class_java_lang_ThreadDeath);
+        heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
 
-       proto_java_lang_ThreadDeath =                             /* schani */
-               builtin_new(class_java_lang_ThreadDeath);
-       heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
+        loader_inited = 1;
 
-       loader_inited = 1;
 }
 
 
 
 
-/********************* Funktion: loader_initclasses ****************************
+/********************* Function: loader_initclasses ****************************
 
-       initialisiert alle geladenen aber noch nicht initialisierten Klassen
+       Initializes all loaded but uninitialized classes
 
 *******************************************************************************/
 
@@ -2502,13 +3276,15 @@ static void loader_compute_class_values (classinfo *c)
        classinfo *subs;
 
        c->vftbl->baseval = ++classvalue;
+
        subs = c->sub;
        while (subs != NULL) {
                loader_compute_class_values(subs);
                subs = subs->nextsub;
                }
        c->vftbl->diffval = classvalue - c->vftbl->baseval;
-/*
+       
+       /*
        {
        int i;
        for (i = 0; i < c->index; i++)
@@ -2517,7 +3293,8 @@ static void loader_compute_class_values (classinfo *c)
        utf_display(c->name);
        printf("\n");
        }
-*/
+       */
+       
 }
 
 
@@ -2544,7 +3321,6 @@ void loader_compute_subclasses ()
                        }
                c = list_next (&linkedclasses, c);
                }
-
        classvalue = 0;
        loader_compute_class_values(class_java_lang_Object);
 
@@ -2567,9 +3343,9 @@ void classload_buffer(u1 *buf, int len)
 }
 
 
-/******************** Funktion: loader_close ***********************************
+/******************** Function: loader_close ***********************************
 
-       gibt alle Resourcen wieder frei
+       Frees all resources
        
 *******************************************************************************/
 
@@ -2604,4 +3380,3 @@ void loader_close ()
  * tab-width: 4
  * End:
  */
-