-/* 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.
Edwin Steiner
Christian Thalinger
- $Id: loader.c 1443 2004-11-05 13:53:13Z twisti $
+ $Id: loader.c 1735 2004-12-07 14:33:27Z 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 "options.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/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
list of classpath entries (either filesystem directories or
ZIP/JAR archives
********************************************************************/
-static classpath_info *classpath_entries=0;
+
+static classpath_info *classpath_entries = NULL;
/******************************************************************************
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;
- if (classpath_entries)
- panic("suck_init should be called only once");
-
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 = (union classpath_info *) NEW(classpath_info);
+ cpi->archive.type = CLASSPATH_ARCHIVE;
+ cpi->archive.uf = uf;
+ cpi->archive.next = NULL;
}
#else
throw_cacao_exception_exit(string_java_lang_InternalError,
#endif
} else {
- tmp = (union classpath_info *) NEW(classpath_info);
- tmp->filepath.type = CLASSPATH_PATH;
- tmp->filepath.next = 0;
+ cpi = (union classpath_info *) NEW(classpath_info);
+ cpi->filepath.type = CLASSPATH_PATH;
+ cpi->filepath.next = NULL;
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->filepath.path = filename;
+ cpi->filepath.pathlen = filenamelen;
}
- if (tmp) {
- if (insertAfter) {
- insertAfter->filepath.next = tmp;
+ /* attach current classpath entry */
+
+ if (cpi) {
+ if (!classpath_entries) {
+ classpath_entries = cpi;
} else {
- classpath_entries = tmp;
+ lastcpi->filepath.next = cpi;
}
- insertAfter = tmp;
+
+ 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;
}
}
}
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;
+#if 0
utf_ptr = c->name->text;
while (utf_ptr < utf_end(c->name)) {
ch = '?';
filename[filenamelen++] = ch;
}
+#endif
+
+ /* initialize return value */
+
+ found = false;
+ cb = NULL;
+
+ filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
+ filename = MNEW(char, filenamelen);
+
+ 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->filepath.next) {
#if defined(USE_ZLIB)
- if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
- if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
+ if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
+ if (cacao_locate(cpi->archive.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->archive.uf, &file_info, filename,
+ sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
+ if (unzOpenCurrentFile(cpi->archive.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;
- } else {
- MFREE(cb->data, u1, cb->size);
- FREE(cb, classbuffer);
+ len = unzReadCurrentFile(cpi->archive.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->archive.uf);
} else {
-#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 */
+#endif /* USE_ZLIB */
+
+ path = MNEW(char, cpi->filepath.pathlen + filenamelen + 1);
+ strcpy(path, cpi->filepath.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);
- return cb;
+ /* read class data */
+ len = fread(cb->data, 1, cb->size, classfile);
+
+ if (len != buffer.st_size) {
+ suck_stop(cb);
+/* if (ferror(classfile)) { */
+/* } */
+
+ } else {
+ found = true;
+ }
}
}
+
+ MFREE(path, char, cpi->filepath.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;
}
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)
return false;
if (opt_verify &&
- !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
+ !is_valid_utf((char *) (cb->pos + 1),
+ (char *) (cb->pos + 1 + length))) {
dolog("Invalid UTF-8 string (constant pool index %d)",idx);
panic("Invalid UTF-8 string");
}
/* insert utf-string into the utf-symboltable */
- cpinfos[idx] = utf_new_intern(cb->pos + 1, length);
+ cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
/* skip bytes of the string (buffer size check above) */
skip_nbytes(cb, length);
return NULL;
if (super->flags & ACC_INTERFACE) {
- // java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class
+ /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
panic("Interface specified as super class");
}
goto notfoundvftblindex;
if (tc->methods[j].flags & ACC_FINAL) {
- // class a overrides final method .
+ /* class a overrides final method . */
*exceptionptr =
new_exception(string_java_lang_VerifyError);
return NULL;