Calling convention fixes.
[cacao.git] / src / vm / loader.c
index ce65f7abb4c72e52d090394733774afc6f427a8d..2a4681af59d61a9e554dc78ed3b8a0762f6fb612 100644 (file)
@@ -1,9 +1,9 @@
-/* loader.c - class loader functions
+/* vm/loader.c - class loader functions
 
-   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) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
@@ -32,7 +32,7 @@
             Edwin Steiner
             Christian Thalinger
 
-   $Id: loader.c 1508 2004-11-15 08:34:10Z carolyn $
+   $Id: loader.c 1936 2005-02-10 11:04:10Z twisti $
 
 */
 
 #include <string.h>
 #include <assert.h>
 #include <sys/stat.h>
-#include "exceptions.h"
-#include "global.h"
-#include "loader.h"
-#include "options.h"
-#include "native.h"
-#include "tables.h"
-#include "builtin.h"
-#include "jit/jit.h"
-#include "asmpart.h"
-#include "statistics.h"
-#include "toolbox/memory.h"
+
+#include "mm/memory.h"
+#include "native/native.h"
+#include "native/include/java_lang_Throwable.h"
+
+#if defined(USE_THREADS)
+# if defined(NATIVE_THREADS)
+#  include "threads/native/threads.h"
+# else
+#  include "threads/green/threads.h"
+#  include "threads/green/locks.h"
+# endif
+#endif
+
 #include "toolbox/logging.h"
-#include "threads/thread.h"
-#include "threads/locks.h"
-#include "nat/java_lang_Throwable.h"
+#include "vm/exceptions.h"
+#include "vm/builtin.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+#include "vm/stringlocal.h"
+#include "vm/tables.h"
 
-#ifdef USE_ZLIB
-#include "unzip.h"
+#if defined(USE_ZLIB)
+# include "vm/unzip.h"
 #endif
 
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+
+
 #undef JOWENN_DEBUG
 #undef JOWENN_DEBUG1
 #undef JOWENN_DEBUG2
@@ -71,58 +83,15 @@ static s4 interfaceindex;       /* sequential numbering of interfaces         */
 static s4 classvalue;
 
 
-/* utf-symbols for pointer comparison of frequently used strings */
-
-static utf *utf_innerclasses;          /* InnerClasses                           */
-static utf *utf_constantvalue;                 /* ConstantValue                          */
-static utf *utf_code;                      /* Code                                   */
-static utf *utf_exceptions;         /* Exceptions                             */
-static utf *utf_linenumbertable;    /* LineNumberTable                        */
-static utf *utf_sourcefile;         /* SourceFile                             */
-static utf *utf_finalize;                  /* finalize                               */
-static utf *utf_fidesc;                    /* ()V changed                            */
-static utf *utf_init;                          /* <init>                                 */
-static utf *utf_clinit;                    /* <clinit>                               */
-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;
-static utf *utf_java_lang_Object;   /* java/lang/Object                       */
-
-utf *utf_fillInStackTrace_name;
-utf *utf_fillInStackTrace_desc;
-
-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_Cloneable;
-classinfo *class_java_io_Serializable;
-
-/* Pseudo classes for the typechecker */
-classinfo *pseudo_class_Arraystub = NULL;
-classinfo *pseudo_class_Null = NULL;
-classinfo *pseudo_class_New = NULL;
 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
 
-utf *array_packagename = NULL;
-
 
 /********************************************************************
    list of classpath entries (either filesystem directories or 
    ZIP/JAR archives
 ********************************************************************/
-static classpath_info *classpath_entries=0;
+
+static classpath_info *classpath_entries = NULL;
 
 
 /******************************************************************************
@@ -314,95 +283,97 @@ static double suck_double(classbuffer *cb)
 
 void suck_init(char *classpath)
 {
-       char *filename=0;
        char *start;
        char *end;
-       int isZip;
-       int filenamelen;
-       union classpath_info *tmp;
-       union classpath_info *insertAfter=0;
+       char *filename;
+       s4 filenamelen;
+       bool is_zip;
+       classpath_info *cpi;
+       classpath_info *lastcpi;
 
-       if (!classpath)
-               return;
+       /* search for last classpath entry (only if there already some) */
 
-       if (classpath_entries)
-               panic("suck_init should be called only once");
+       if ((lastcpi = classpath_entries)) {
+               while (lastcpi->next)
+                       lastcpi = lastcpi->next;
+       }
 
        for (start = classpath; (*start) != '\0';) {
+
+               /* search for ':' delimiter to get the end of the current entry */
                for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
 
                if (start != end) {
-                       isZip = 0;
+                       is_zip = false;
                        filenamelen = end - start;
 
                        if (filenamelen > 3) {
                                if (strncasecmp(end - 3, "zip", 3) == 0 ||
                                        strncasecmp(end - 3, "jar", 3) == 0) {
-                                       isZip = 1;
+                                       is_zip = true;
                                }
                        }
 
-                       if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
-                               panic("path length >= MAXFILENAME in suck_init");
-
-                       if (!filename)
-                               filename = MNEW(char, CLASSPATH_MAXFILENAME);
+                       /* allocate memory for filename and fill it */
 
+                       filename = MNEW(char, filenamelen + 2);  /* 2 = "/\0" */
                        strncpy(filename, start, filenamelen);
                        filename[filenamelen + 1] = '\0';
-                       tmp = NULL;
+                       cpi = NULL;
 
-                       if (isZip) {
+                       if (is_zip) {
 #if defined(USE_ZLIB)
                                unzFile uf = unzOpen(filename);
 
                                if (uf) {
-                                       tmp = (union classpath_info *) NEW(classpath_info);
-                                       tmp->archive.type = CLASSPATH_ARCHIVE;
-                                       tmp->archive.uf = uf;
-                                       tmp->archive.next = NULL;
-                                       filename = NULL;
+                                       cpi = NEW(classpath_info);
+                                       cpi->type = CLASSPATH_ARCHIVE;
+                                       cpi->uf = uf;
+                                       cpi->next = NULL;
+                                       cpi->pd = NULL; /* ProtectionDomain not set yet */
+                                       cpi->path = filename;
                                }
+
 #else
                                throw_cacao_exception_exit(string_java_lang_InternalError,
                                                                                   "zip/jar files not supported");
 #endif
                                
                        } else {
-                               tmp = (union classpath_info *) NEW(classpath_info);
-                               tmp->filepath.type = CLASSPATH_PATH;
-                               tmp->filepath.next = 0;
+                               cpi = NEW(classpath_info);
+                               cpi->type = CLASSPATH_PATH;
+                               cpi->next = NULL;
+                               cpi->pd = NULL; /* ProtectionDomain not set yet */
 
                                if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
                                        filename[filenamelen] = '/';
                                        filename[filenamelen + 1] = '\0';
                                        filenamelen++;
                                }
-                       
-                               tmp->filepath.filename = filename;
-                               tmp->filepath.pathlen = filenamelen;                            
-                               filename = NULL;
+
+                               cpi->path = filename;
+                               cpi->pathlen = filenamelen;
                        }
 
-                       if (tmp) {
-                               if (insertAfter) {
-                                       insertAfter->filepath.next = tmp;
+                       /* attach current classpath entry */
 
-                               } else {
-                                       classpath_entries = tmp;
-                               }
-                               insertAfter = tmp;
+                       if (cpi) {
+                               if (!classpath_entries)
+                                       classpath_entries = cpi;
+                               else
+                                       lastcpi->next = cpi;
+
+                               lastcpi = cpi;
                        }
                }
 
-               if ((*end) == ':')
+               /* goto next classpath entry, skip ':' delimiter */
+
+               if ((*end) == ':') {
                        start = end + 1;
-               else
+
+               } else {
                        start = end;
-       
-               if (filename) {
-                       MFREE(filename, char, CLASSPATH_MAXFILENAME);
-                       filename = NULL;
                }
        }
 }
@@ -412,13 +383,13 @@ void create_all_classes()
 {
        classpath_info *cpi;
 
-       for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
+       for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
 #if defined(USE_ZLIB)
-               if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
+               if (cpi->type == CLASSPATH_ARCHIVE) {
                        cacao_entry_s *ce;
                        unz_s *s;
 
-                       s = (unz_s *) cpi->archive.uf;
+                       s = (unz_s *) cpi->uf;
                        ce = s->cacao_dir_list;
                                
                        while (ce) {
@@ -446,100 +417,130 @@ void create_all_classes()
 
 classbuffer *suck_start(classinfo *c)
 {
-       classpath_info *currPos;
-       char *utf_ptr;
-       char ch;
-       char filename[CLASSPATH_MAXFILENAME+10];  /* room for '.class'            */
-       int  filenamelen=0;
+       classpath_info *cpi;
+/*     char *utf_ptr; */
+/*     char ch; */
+       char *filename;
+       s4    filenamelen;
+       char *path;
        FILE *classfile;
-       int  err;
+       bool found;
+       s4 len;
        struct stat buffer;
        classbuffer *cb;
 
-       utf_ptr = c->name->text;
+       /* initialize return value */
 
-       while (utf_ptr < utf_end(c->name)) {
-               if (filenamelen >= CLASSPATH_MAXFILENAME) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_InternalError,
-                                                                         "Filename too long");
+       found = false;
+       cb = NULL;
 
-                       /* XXX should we exit in such a case? */
-                       throw_exception_exit();
-               }
+       filenamelen = utf_strlen(c->name) + 7;  /* 7 = ".class\0" */
+       filename = MNEW(char, filenamelen);
 
-               ch = *utf_ptr++;
-               if ((ch <= ' ' || ch > 'z') && (ch != '/'))     /* invalid character */
-                       ch = '?';
-               filename[filenamelen++] = ch;
-       }
+       utf_sprint(filename, c->name);
+       strcat(filename, ".class");
 
-       strcpy(filename + filenamelen, ".class");
-       filenamelen += 6;
+       /* walk through all classpath entries */
 
-       for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
+       for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
 #if defined(USE_ZLIB)
-               if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
-                       if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
+               if (cpi->type == CLASSPATH_ARCHIVE) {
+
+#if defined(USE_THREADS)
+                       /* enter a monitor on zip/jar archives */
+
+                       builtin_monitorenter((java_objectheader *) cpi);
+#endif
+
+                       if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
                                unz_file_info file_info;
-                               /*log_text("Class found in zip file");*/
-                               if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
-                                               sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
-                                       if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
+
+                               if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
+                                                                                 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
+                                       if (unzOpenCurrentFile(cpi->uf) == UNZ_OK) {
                                                cb = NEW(classbuffer);
                                                cb->class = c;
                                                cb->size = file_info.uncompressed_size;
                                                cb->data = MNEW(u1, cb->size);
                                                cb->pos = cb->data - 1;
-                                               /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
-                                               if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
-                                                       unzCloseCurrentFile(currPos->archive.uf);
-                                                       return cb;
+                                               /* We need this later in use_class_as_object to set a */
+                                               /* correct ProtectionDomain and CodeSource.           */
+                                               c->pd = (struct java_security_ProtectionDomain *) cpi; 
 
-                                               } else {
-                                                       MFREE(cb->data, u1, cb->size);
-                                                       FREE(cb, classbuffer);
+                                               len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
+
+                                               if (len != cb->size) {
+                                                       suck_stop(cb);
                                                        log_text("Error while unzipping");
+
+                                               } else {
+                                                       found = true;
                                                }
-                                       } else log_text("Error while opening file in archive");
-                               } else log_text("Error while retrieving fileinfo");
+
+                                       } else {
+                                               log_text("Error while opening file in archive");
+                                       }
+
+                               } else {
+                                       log_text("Error while retrieving fileinfo");
+                               }
                        }
-                       unzCloseCurrentFile(currPos->archive.uf);
+                       unzCloseCurrentFile(cpi->uf);
 
-               } else {
+#if defined(USE_THREADS)
+                       /* leave the monitor */
+
+                       builtin_monitorexit((java_objectheader *) cpi);
 #endif
-                       if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
-                       strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
-                       classfile = fopen(currPos->filepath.filename, "r");
-                       if (classfile) {                                       /* file exists */
 
-                               /* determine size of classfile */
+               } else {
+#endif /* USE_ZLIB */
+                       
+                       path = MNEW(char, cpi->pathlen + filenamelen + 1);
+                       strcpy(path, cpi->path);
+                       strcat(path, filename);
 
-                               /* dolog("File: %s",filename); */
-                               err = stat(currPos->filepath.filename, &buffer);
+                       classfile = fopen(path, "r");
 
-                               if (!err) {                            /* read classfile data */
+                       if (classfile) {                                   /* file exists */
+                               if (!stat(path, &buffer)) {            /* read classfile data */
                                        cb = NEW(classbuffer);
                                        cb->class = c;
                                        cb->size = buffer.st_size;
                                        cb->data = MNEW(u1, cb->size);
                                        cb->pos = cb->data - 1;
-                                       fread(cb->data, 1, cb->size, classfile);
-                                       fclose(classfile);
+                                       /* We need this later in use_class_as_object to set a     */
+                                       /* correct ProtectionDomain and CodeSource.               */
+                                       c->pd = (struct java_security_ProtectionDomain *) cpi; 
+
+                                       /* read class data */
+                                       len = fread(cb->data, 1, cb->size, classfile);
+
+                                       if (len != buffer.st_size) {
+                                               suck_stop(cb);
+/*                                             if (ferror(classfile)) { */
+/*                                             } */
 
-                                       return cb;
+                                       } else {
+                                               found = true;
+                                       }
                                }
                        }
+
+                       MFREE(path, char, cpi->pathlen + filenamelen + 1);
 #if defined(USE_ZLIB)
                }
 #endif
        }
 
-       if (verbose) {
-               dolog("Warning: Can not open class file '%s'", filename);
+       if (opt_verbose) {
+               if (!found)
+                       dolog("Warning: Can not open class file '%s'", filename);
        }
 
-       return NULL;
+       MFREE(filename, char, filenamelen);
+
+       return cb;
 }
 
 
@@ -735,7 +736,7 @@ static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
                if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
                        return false;
 
-               if (aname == utf_innerclasses) {
+               if (aname == utf_InnerClasses) {
                        /* innerclasses attribute */
                        if (c->innerclass) {
                                *exceptionptr =
@@ -776,7 +777,7 @@ static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
                                info->flags = suck_u2(cb);
                        }
 
-               } else if (aname == utf_sourcefile) {
+               } else if (aname == utf_SourceFile) {
                        if (!check_classbuffer_size(cb, 4 + 2))
                                return false;
 
@@ -1089,7 +1090,7 @@ static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
                if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
                        return false;
 
-               if (u == utf_constantvalue) {
+               if (u == utf_ConstantValue) {
                        if (!check_classbuffer_size(cb, 4 + 2))
                                return false;
 
@@ -1362,7 +1363,7 @@ static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
                if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
                        return false;
 
-               if (aname == utf_code) {
+               if (aname == utf_Code) {
                        if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
                                        *exceptionptr =
                                                new_classformaterror(c,
@@ -1465,7 +1466,7 @@ static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
                                if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
                                        return false;
 
-                               if (caname == utf_linenumbertable) {
+                               if (caname == utf_LineNumberTable) {
                                        u2 lncid;
 
                                        if (!check_classbuffer_size(cb, 4 + 2))
@@ -1497,7 +1498,7 @@ static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
                                }
                        }
 
-               } else if (aname == utf_exceptions) {
+               } else if (aname == utf_Exceptions) {
                        s4 j;
 
                        if (m->thrownexceptions) {
@@ -1536,8 +1537,6 @@ static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
        }
 
        /* everything was ok */
-       /*              utf_display(m->name);
-                       printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
 
        return true;
 }
@@ -1584,6 +1583,24 @@ void method_display(methodinfo *m)
        printf("\n");
 }
 
+/************** Function: method_display_w_class  (debugging only) **************/
+
+void method_display_w_class(methodinfo *m)
+{
+        printflags(m->class->flags);
+        printf(" "); fflush(stdout);
+        utf_display(m->class->name);
+        printf(".");fflush(stdout);
+
+        printf("   ");
+        printflags(m->flags);
+        printf(" "); fflush(stdout);
+        utf_display(m->name);
+        printf(" "); fflush(stdout);
+        utf_display(m->descriptor);
+        printf("\n"); fflush(stdout);
+}
+
 /************** Function: method_display_flags_last  (debugging only) **************/
 
 void method_display_flags_last(methodinfo *m)
@@ -1986,11 +2003,20 @@ static bool class_loadcpool(classbuffer *cb, classinfo *c)
 
                if (opt_verify) {
                        /* check name */
-                       if (!is_valid_name_utf(cn->name))
-                               panic("NameAndType with invalid name");
+                       if (!is_valid_name_utf(cn->name)) {
+                               *exceptionptr =
+                                       new_exception_utfmessage(string_java_lang_InternalError,
+                                                                                        cn->name);
+                               return false;
+                       }
+
                        /* disallow referencing <clinit> among others */
-                       if (cn->name->text[0] == '<' && cn->name != utf_init)
-                               panic("NameAndType with invalid special name");
+                       if (cn->name->text[0] == '<' && cn->name != utf_init) {
+                               *exceptionptr =
+                                       new_exception_utfmessage(string_java_lang_InternalError,
+                                                                                        cn->name);
+                               return false;
+                       }
                }
 
                cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
@@ -2065,13 +2091,17 @@ classinfo *class_load(classinfo *c)
        classbuffer *cb;
        classinfo *r;
 
+#if defined(USE_THREADS)
        /* enter a monitor on the class */
 
        builtin_monitorenter((java_objectheader *) c);
+#endif
 
        /* maybe the class is already loaded */
        if (c->loaded) {
+#if defined(USE_THREADS)
                builtin_monitorexit((java_objectheader *) c);
+#endif
 
                return c;
        }
@@ -2096,7 +2126,9 @@ classinfo *class_load(classinfo *c)
                        new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
                                                                         c->name);
 
+#if defined(USE_THREADS)
                builtin_monitorexit((java_objectheader *) c);
+#endif
 
                return NULL;
        }
@@ -2123,9 +2155,11 @@ classinfo *class_load(classinfo *c)
        if (getcompilingtime)
                compilingtime_start();
 
+#if defined(USE_THREADS)
        /* leave the monitor */
 
        builtin_monitorexit((java_objectheader *) c);
+#endif
 
        return r;
 }
@@ -2780,13 +2814,17 @@ classinfo *class_link(classinfo *c)
 {
        classinfo *r;
 
+#if defined(USE_THREADS)
        /* enter a monitor on the class */
 
        builtin_monitorenter((java_objectheader *) c);
+#endif
 
        /* maybe the class is already linked */
        if (c->linked) {
+#if defined(USE_THREADS)
                builtin_monitorexit((java_objectheader *) c);
+#endif
 
                return c;
        }
@@ -2814,9 +2852,11 @@ classinfo *class_link(classinfo *c)
        if (getcompilingtime)
                compilingtime_start();
 
+#if defined(USE_THREADS)
        /* leave the monitor */
 
        builtin_monitorexit((java_objectheader *) c);
+#endif
 
        return r;
 }
@@ -2864,7 +2904,7 @@ static classinfo *class_link_intern(classinfo *c)
                }
 
                if (!tc->loaded)
-                       if (!class_load(tc))
+                       if (!class_load(tc))
                                return NULL;
 
                if (!(tc->flags & ACC_INTERFACE)) {
@@ -3054,24 +3094,20 @@ static classinfo *class_link_intern(classinfo *c)
        
        /* add interfaces */
        
-       for (tc = c; tc != NULL; tc = tc->super) {
-               for (i = 0; i < tc->interfacescount; i++) {
+       for (tc = c; tc != NULL; tc = tc->super)
+               for (i = 0; i < tc->interfacescount; i++)
                        class_addinterface(c, tc->interfaces[i]);
-               }
-       }
 
        /* add finalizer method (not for java.lang.Object) */
 
        if (super) {
                methodinfo *fi;
 
-               fi = class_findmethod(c, utf_finalize, utf_fidesc);
+               fi = class_findmethod(c, utf_finalize, utf_void__void);
 
-               if (fi) {
-                       if (!(fi->flags & ACC_STATIC)) {
+               if (fi)
+                       if (!(fi->flags & ACC_STATIC))
                                c->finalizer = fi;
-                       }
-               }
        }
 
        /* final tasks */
@@ -3662,15 +3698,24 @@ classinfo *class_init(classinfo *c)
        if (!makeinitializations)
                return c;
 
+#if defined(USE_THREADS)
        /* enter a monitor on the class */
 
        builtin_monitorenter((java_objectheader *) c);
+#endif
 
        /* maybe the class is already initalized or the current thread, which can
           pass the monitor, is currently initalizing this class */
 
+       /* JOWENN: In future we need an additinal flag: initializationfailed,
+               since further access to the class should cause a NoClassDefFound,
+               if the static initializer failed once
+        */
+
        if (c->initialized || c->initializing) {
+#if defined(USE_THREADS)
                builtin_monitorexit((java_objectheader *) c);
+#endif
 
                return c;
        }
@@ -3689,9 +3734,11 @@ classinfo *class_init(classinfo *c)
        /* this initalizing run is done */
        c->initializing = false;
 
+#if defined(USE_THREADS)
        /* leave the monitor */
 
        builtin_monitorexit((java_objectheader *) c);
+#endif
 
        return r;
 }
@@ -3759,7 +3806,7 @@ static classinfo *class_init_intern(classinfo *c)
                }
        }
 
-       m = class_findmethod(c, utf_clinit, utf_fidesc);
+       m = class_findmethod(c, utf_clinit, utf_void__void);
 
        if (!m) {
                if (initverbose) {
@@ -4321,7 +4368,6 @@ static void create_pseudo_classes()
 {
     /* pseudo class for Arraystubs (extends java.lang.Object) */
     
-    pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
        pseudo_class_Arraystub->loaded = true;
     pseudo_class_Arraystub->super = class_java_lang_Object;
     pseudo_class_Arraystub->interfacescount = 2;
@@ -4335,18 +4381,15 @@ static void create_pseudo_classes()
 
     /* pseudo class representing the null type */
     
-       pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
        pseudo_class_Null->loaded = true;
     pseudo_class_Null->super = class_java_lang_Object;
        class_link(pseudo_class_Null);  
 
     /* pseudo class representing new uninitialized objects */
     
-       pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
        pseudo_class_New->loaded = true;
        pseudo_class_New->linked = true;
        pseudo_class_New->super = class_java_lang_Object;
-/*     class_link(pseudo_class_New); */
 }
 
 
@@ -4357,52 +4400,41 @@ static void create_pseudo_classes()
 
 *******************************************************************************/
  
-void loader_init(u1 *stackbottom)
+bool loader_init(u1 *stackbottom)
 {
+       classpath_info *cpi;
+
+       /* reset interface index */
+
        interfaceindex = 0;
        
-       /* create utf-symbols for pointer comparison of frequently used strings */
-       utf_innerclasses    = utf_new_char("InnerClasses");
-       utf_constantvalue   = utf_new_char("ConstantValue");
-       utf_code            = utf_new_char("Code");
-       utf_exceptions      = utf_new_char("Exceptions");
-       utf_linenumbertable = utf_new_char("LineNumberTable");
-       utf_sourcefile      = utf_new_char("SourceFile");
-       utf_finalize        = utf_new_char("finalize");
-       utf_fidesc              = utf_new_char("()V");
-       utf_init                = utf_new_char("<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");
-       utf_java_lang_Object= utf_new_char("java/lang/Object");
-       array_packagename   = utf_new_char("<the array package>");
-       utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
-       utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
-
-       /* 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_intern(utf_java_lang_Object);
-       class_load(class_java_lang_Object);
-       class_link(class_java_lang_Object);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       /* Initialize the monitor pointer for zip/jar file locking.               */
 
-       class_java_lang_String = class_new(utf_new_char("java/lang/String"));
-       class_load(class_java_lang_String);
-       class_link(class_java_lang_String);
+       for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
+               if (cpi->type == CLASSPATH_ARCHIVE) 
+                       initObjectLock(&cpi->header);
+       }
+#endif
 
-       class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
-       class_load(class_java_lang_Cloneable);
-       class_link(class_java_lang_Cloneable);
+       /* Create some important classes. These classes have to be created now    */
+       /* because the classinfo pointers are used in the loading code.           */
 
-       class_java_io_Serializable =
-               class_new(utf_new_char("java/io/Serializable"));
-       class_load(class_java_io_Serializable);
-       class_link(class_java_io_Serializable);
+       if (!class_load(class_java_lang_Object) ||
+               !class_link(class_java_lang_Object))
+               return false;
+
+       if (!class_load(class_java_lang_String) ||
+               !class_link(class_java_lang_String))
+               return false;
+
+       if (!class_load(class_java_lang_Cloneable) ||
+               !class_link(class_java_lang_Cloneable))
+               return false;
+
+       if (!class_load(class_java_io_Serializable) ||
+               !class_link(class_java_io_Serializable))
+               return false;
 
        /* create classes representing primitive types */
        create_primitive_classes();
@@ -4417,6 +4449,8 @@ void loader_init(u1 *stackbottom)
        if (stackbottom != 0)
                initLocks();
 #endif
+
+       return true;
 }