/* 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 1729 2004-12-07 11:18:45Z twisti $
+ $Id: loader.c 1896 2005-02-03 16:15:35Z motse $
*/
classpath_info *cpi;
classpath_info *lastcpi;
- if (!classpath)
- return;
+ /* search for last classpath entry (only if there already some) */
+
+ if ((lastcpi = classpath_entries)) {
+ while (lastcpi->next)
+ lastcpi = lastcpi->next;
+ }
for (start = classpath; (*start) != '\0';) {
unzFile uf = unzOpen(filename);
if (uf) {
- cpi = (union classpath_info *) NEW(classpath_info);
- cpi->archive.type = CLASSPATH_ARCHIVE;
- cpi->archive.uf = uf;
- cpi->archive.next = 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;
+ cpi->lock = NULL; /* we'll be initialized later */
}
+
#else
throw_cacao_exception_exit(string_java_lang_InternalError,
"zip/jar files not supported");
#endif
} else {
- cpi = (union classpath_info *) NEW(classpath_info);
- cpi->filepath.type = CLASSPATH_PATH;
- cpi->filepath.next = NULL;
+ 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] = '/';
filenamelen++;
}
- cpi->filepath.path = filename;
- cpi->filepath.pathlen = filenamelen;
+ cpi->path = filename;
+ cpi->pathlen = filenamelen;
}
/* attach current classpath entry */
classpath_entries = cpi;
} else {
- lastcpi->filepath.next = cpi;
+ lastcpi->next = cpi;
}
lastcpi = cpi;
{
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) {
struct stat buffer;
classbuffer *cb;
-#if 0
- utf_ptr = c->name->text;
-
- while (utf_ptr < utf_end(c->name)) {
- if (filenamelen >= CLASSPATH_MAXFILENAME) {
- *exceptionptr =
- new_exception_message(string_java_lang_InternalError,
- "Filename too long");
-
- /* XXX should we exit in such a case? */
- throw_exception_exit();
- }
-
- ch = *utf_ptr++;
- if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
- ch = '?';
- filename[filenamelen++] = ch;
- }
-#endif
-
/* initialize return value */
found = false;
/* walk through all classpath entries */
- for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->filepath.next) {
+ for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
#if defined(USE_ZLIB)
- if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
- if (cacao_locate(cpi->archive.uf, c->name) == UNZ_OK) {
+ if (cpi->type == CLASSPATH_ARCHIVE) {
+ if (cpi->lock != NULL)
+ builtin_monitorenter(cpi->lock);
+ if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
unz_file_info file_info;
- if (unzGetCurrentFileInfo(cpi->archive.uf, &file_info, filename,
+ if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
- if (unzOpenCurrentFile(cpi->archive.uf) == 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;
+ /* we need this later in use_class_as_object to set a correct
+ ProtectionDomain and CodeSource */
+ c->pd = (struct java_security_ProtectionDomain*) cpi;
- len = unzReadCurrentFile(cpi->archive.uf, cb->data, cb->size);
+ len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
if (len != cb->size) {
suck_stop(cb);
log_text("Error while retrieving fileinfo");
}
}
- unzCloseCurrentFile(cpi->archive.uf);
-
+ unzCloseCurrentFile(cpi->uf);
+ if (cpi->lock != NULL)
+ builtin_monitorexit(cpi->lock);
} else {
#endif /* USE_ZLIB */
- path = MNEW(char, cpi->filepath.pathlen + filenamelen + 1);
- strcpy(path, cpi->filepath.path);
+ path = MNEW(char, cpi->pathlen + filenamelen + 1);
+ strcpy(path, cpi->path);
strcat(path, filename);
classfile = fopen(path, "r");
cb->size = buffer.st_size;
cb->data = MNEW(u1, cb->size);
cb->pos = cb->data - 1;
+ /* 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);
}
}
- MFREE(path, char, cpi->filepath.pathlen + filenamelen + 1);
+ MFREE(path, char, cpi->pathlen + filenamelen + 1);
#if defined(USE_ZLIB)
}
#endif
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;
}
new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
c->name);
+#if defined(USE_THREADS)
builtin_monitorexit((java_objectheader *) c);
+#endif
return NULL;
}
if (getcompilingtime)
compilingtime_start();
+#if defined(USE_THREADS)
/* leave the monitor */
builtin_monitorexit((java_objectheader *) c);
+#endif
return r;
}
{
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;
}
if (getcompilingtime)
compilingtime_start();
+#if defined(USE_THREADS)
/* leave the monitor */
builtin_monitorexit((java_objectheader *) c);
+#endif
return r;
}
}
if (!tc->loaded)
- if (!class_load(tc))
+ if (!class_load(tc))
return NULL;
if (!(tc->flags & ACC_INTERFACE)) {
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;
}
/* this initalizing run is done */
c->initializing = false;
+#if defined(USE_THREADS)
/* leave the monitor */
builtin_monitorexit((java_objectheader *) c);
+#endif
return r;
}
void loader_init(u1 *stackbottom)
{
+ classpath_info *cpi;
interfaceindex = 0;
/* create utf-symbols for pointer comparison of frequently used strings */
/* correct vftbl-entries (retarded loading of class java/lang/String) */
stringtable_update();
+ /* init cpi-locks */
+ for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
+ if (cpi->type == CLASSPATH_ARCHIVE)
+ cpi->lock = builtin_new(class_java_lang_Object);
+ }
#if defined(USE_THREADS)
if (stackbottom != 0)
initLocks();