* src/vm/suck.h: Likewise.
* src/vm/suck.cpp: New file.
* src/vm/suck.hpp: Likewise.
* src/native/jvmti/jvmti.c,
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp,
src/vm/Makefile.am,
src/vm/annotation.c,
src/vm/class.c,
src/vm/field.cpp,
src/vm/jit/parse.c,
src/vm/loader.cpp,
src/vm/method.c,
src/vm/stackmap.c,
src/vm/vm.cpp,
src/vm/zip.c,
src/vm/zip.h: Related changes.
--HG--
rename : src/vm/suck.c => src/vm/suck.cpp
rename : src/vm/suck.h => src/vm/suck.hpp
#include "native/include/java_lang_VMObject.h"
#include "native/include/java_lang_VMSystem.h"
#include "native/include/java_lang_VMClass.h"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "boehm-gc/include/gc.h"
#if defined(ENABLE_THREADS)
#include "vm/primitive.hpp"
#include "vm/statistics.h"
#include "vm/string.hpp"
-#include "vm/suck.h"
#include "vm/vm.hpp"
#include "vm/zip.h"
$(STATISTICS_SOURCES) \
string.cpp \
string.hpp \
- suck.c \
- suck.h \
+ suck.cpp \
+ suck.hpp \
utf8.c \
utf8.h \
vm.cpp \
#include "vm/class.h"
#include "vm/loader.hpp"
#include "vm/primitive.hpp"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/types.h"
#if !defined(ENABLE_ANNOTATIONS)
# include "vm/statistics.h"
#endif
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/utf8.h"
#include "vm/jit/asmpart.h"
#include "vm/primitive.hpp"
#include "vm/references.h"
#include "vm/string.hpp"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/utf8.h"
#include "vm/vm.hpp"
#endif
#include "vm/string.hpp"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.hpp"
#include "vm/resolve.h"
#include "vm/rt-timing.h"
#include "vm/string.hpp"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/vm.hpp"
#include "vm/method.h"
#include "vm/options.h"
#include "vm/resolve.h"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/utf8.h"
#include "vm/vm.hpp"
#include "vm/options.h"
#include "vm/stackmap.h"
#include "vm/statistics.h"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
/* stackmap_get_verification_type_info *****************************************
+++ /dev/null
-/* src/vm/suck.c - functions to read LE ordered types from a buffer
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- 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.
-
- 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.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-#include "vm/types.h"
-
-#include "arch.h"
-
-#include "mm/memory.h"
-
-#include "threads/mutex.hpp"
-
-#include "toolbox/list.h"
-#include "toolbox/logging.h"
-#include "toolbox/util.h"
-
-#include "vm/exceptions.hpp"
-#include "vm/loader.hpp"
-#include "vm/options.h"
-#include "vm/os.hpp"
-#include "vm/properties.hpp"
-#include "vm/suck.h"
-#include "vm/vm.hpp"
-#include "vm/zip.h"
-
-
-/* global variables ***********************************************************/
-
-list_t *list_classpath_entries;
-
-
-/* suck_init *******************************************************************
-
- Initializes the suck subsystem like initializing the classpath
- entries list.
-
-*******************************************************************************/
-
-bool suck_init(void)
-{
- TRACESUBSYSTEMINITIALIZATION("suck_init");
-
- list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
-
- /* everything's ok */
-
- return true;
-}
-
-
-/* scandir_filter **************************************************************
-
- Filters for zip/jar files.
-
-*******************************************************************************/
-
-static int scandir_filter(const struct dirent *a)
-{
- s4 namlen;
-
-#if defined(_DIRENT_HAVE_D_NAMLEN)
- namlen = a->d_namlen;
-#else
- namlen = strlen(a->d_name);
-#endif
-
- if ((strncasecmp(a->d_name + namlen - 4, ".zip", 4) == 0) ||
- (strncasecmp(a->d_name + namlen - 4, ".jar", 4) == 0))
- return 1;
-
- return 0;
-}
-
-
-/* suck_add ********************************************************************
-
- Adds a classpath to the global classpath entries list.
-
-*******************************************************************************/
-
-void suck_add(char *classpath)
-{
- list_classpath_entry *lce;
- char *start;
- char *end;
- char *filename;
- s4 filenamelen;
- bool is_zip;
- char *cwd;
- s4 cwdlen;
-#if defined(ENABLE_ZLIB)
- hashtable *ht;
-#endif
-
- /* parse the classpath string */
-
- 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) {
- is_zip = false;
- filenamelen = end - start;
-
- if (filenamelen > 4) {
- if ((strncasecmp(end - 4, ".zip", 4) == 0) ||
- (strncasecmp(end - 4, ".jar", 4) == 0)) {
- is_zip = true;
- }
- }
-
- /* save classpath entries as absolute pathnames */
-
- cwd = NULL;
- cwdlen = 0;
-
- if (*start != '/') { /* XXX fix me for win32 */
- cwd = _Jv_getcwd();
- cwdlen = strlen(cwd) + strlen("/");
- }
-
- /* allocate memory for filename and fill it */
-
- filename = MNEW(char, filenamelen + cwdlen + strlen("/") +
- strlen("0"));
-
- if (cwd) {
- strcpy(filename, cwd);
- strcat(filename, "/");
- strncat(filename, start, filenamelen);
-
- /* add cwd length to file length */
- filenamelen += cwdlen;
-
- } else {
- strncpy(filename, start, filenamelen);
- filename[filenamelen] = '\0';
- }
-
- lce = NULL;
-
- if (is_zip) {
-#if defined(ENABLE_ZLIB)
- ht = zip_open(filename);
-
- if (ht != NULL) {
- lce = NEW(list_classpath_entry);
-
- lce->type = CLASSPATH_ARCHIVE;
- lce->htclasses = ht;
- lce->path = filename;
- lce->pathlen = filenamelen;
-
- /* SUN compatible -verbose:class output */
-
- if (opt_verboseclass)
- printf("[Opened %s]\n", filename);
- }
-
-#else
- vm_abort("suck_add: zip/jar files not supported");
-#endif
- }
- else {
- if (filename[filenamelen - 1] != '/') {/* XXX fixme for win32 */
- filename[filenamelen] = '/';
- filename[filenamelen + 1] = '\0';
- filenamelen++;
- }
-
- lce = NEW(list_classpath_entry);
-
- lce->type = CLASSPATH_PATH;
- lce->path = filename;
- lce->pathlen = filenamelen;
- }
-
- /* add current classpath entry, if no error */
-
- if (lce != NULL)
- list_add_last(list_classpath_entries, lce);
- }
-
- /* goto next classpath entry, skip ':' delimiter */
-
- if ((*end) == ':')
- start = end + 1;
- else
- start = end;
- }
-}
-
-
-/* suck_add_from_property ******************************************************
-
- Adds a classpath form a property entry to the global classpath
- entries list.
-
-*******************************************************************************/
-
-void suck_add_from_property(const char *key)
-{
- const char *value;
- const char *start;
- const char *end;
- char *path;
- s4 pathlen;
- struct dirent **namelist;
- s4 n;
- s4 i;
- s4 namlen;
- char *boot_class_path;
- char *p;
-
- /* get the property value */
-
- value = Properties_get(key);
-
- if (value == NULL)
- return;
-
- /* get the directory entries of the property */
-
- for (start = value; (*start) != '\0'; ) {
-
- /* search for ':' delimiter to get the end of the current entry */
-
- for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
-
- /* found an entry */
-
- if (start != end) {
- /* allocate memory for the path entry */
-
- pathlen = end - start;
- path = MNEW(char, pathlen + strlen("0"));
-
- /* copy and terminate the string */
-
- strncpy(path, start, pathlen);
- path[pathlen] = '\0';
-
- /* Reset namelist to NULL for the freeing in an error case
- (see below). */
-
- namelist = NULL;
-
- /* scan the directory found for zip/jar files */
-
- n = os_scandir(path, &namelist, scandir_filter, alphasort);
-
- /* On error, just continue, this should be ok. */
-
- if (n > 0) {
- for (i = 0; i < n; i++) {
-#if defined(_DIRENT_HAVE_D_NAMLEN)
- namlen = namelist[i]->d_namlen;
-#else
- namlen = strlen(namelist[i]->d_name);
-#endif
-
- /* Allocate memory for bootclasspath. */
-
- // FIXME Make boot_class_path const char*.
- boot_class_path = (char*) Properties_get("sun.boot.class.path");
-
- p = MNEW(char,
- pathlen + strlen("/") + namlen +
- strlen(":") +
- strlen(boot_class_path) +
- strlen("0"));
-
- /* Prepend the file found to the bootclasspath. */
-
- strcpy(p, path);
- strcat(p, "/");
- strcat(p, namelist[i]->d_name);
- strcat(p, ":");
- strcat(p, boot_class_path);
-
- Properties_put("sun.boot.class.path", p);
- Properties_put("java.boot.class.path", p);
-
- MFREE(boot_class_path, char, strlen(boot_class_path));
-
- /* free the memory allocated by scandir */
- /* (We use `free` as the memory came from the C library.) */
-
- free(namelist[i]);
- }
- }
-
- /* On some systems (like Linux) when n == 0, then namelist
- returned from scnadir is NULL, thus we don't have to
- free it.
- (Use `free` as the memory came from the C library.) */
-
- if (namelist != NULL)
- free(namelist);
-
- MFREE(path, char, pathlen + strlen("0"));
- }
-
- /* goto next entry, skip ':' delimiter */
-
- if ((*end) == ':')
- start = end + 1;
- else
- start = end;
- }
-}
-
-
-/* suck_check_classbuffer_size *************************************************
-
- Assert that at least <len> bytes are left to read <len> is limited
- to the range of non-negative s4 values.
-
-*******************************************************************************/
-
-bool suck_check_classbuffer_size(classbuffer *cb, s4 len)
-{
-#ifdef ENABLE_VERIFIER
- if (len < 0 || ((cb->data + cb->size) - cb->pos) < len) {
- exceptions_throw_classformaterror(cb->clazz, "Truncated class file");
- return false;
- }
-#endif /* ENABLE_VERIFIER */
-
- return true;
-}
-
-
-u1 suck_u1(classbuffer *cb)
-{
- u1 a;
-
- a = SUCK_BE_U1(cb->pos);
- cb->pos++;
-
- return a;
-}
-
-
-u2 suck_u2(classbuffer *cb)
-{
- u2 a;
-
- a = SUCK_BE_U2(cb->pos);
- cb->pos += 2;
-
- return a;
-}
-
-
-u4 suck_u4(classbuffer *cb)
-{
- u4 a;
-
- a = SUCK_BE_U4(cb->pos);
- cb->pos += 4;
-
- return a;
-}
-
-
-u8 suck_u8(classbuffer *cb)
-{
-#if U8_AVAILABLE == 1
- u8 a;
-
- a = SUCK_BE_U8(cb->pos);
- cb->pos += 8;
-
- return a;
-#else
- u8 v;
-
- v.high = suck_u4(cb);
- v.low = suck_u4(cb);
-
- return v;
-#endif
-}
-
-
-float suck_float(classbuffer *cb)
-{
- float f;
-
-#if WORDS_BIGENDIAN == 0
- u1 buffer[4];
- u2 i;
-
- for (i = 0; i < 4; i++)
- buffer[3 - i] = suck_u1(cb);
-
- MCOPY((u1 *) (&f), buffer, u1, 4);
-#else
- suck_nbytes((u1*) (&f), cb, 4);
-#endif
-
- assert(sizeof(float) == 4);
-
- return f;
-}
-
-
-double suck_double(classbuffer *cb)
-{
- double d;
-
-#if WORDS_BIGENDIAN == 0
- u1 buffer[8];
- u2 i;
-
-# if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
- /*
- * On little endian ARM processors when using FPA, word order
- * of doubles is still big endian. So take that into account
- * here. When using VFP, word order of doubles follows byte
- * order. (michi 2005/07/24)
- */
- for (i = 0; i < 4; i++)
- buffer[3 - i] = suck_u1(cb);
- for (i = 0; i < 4; i++)
- buffer[7 - i] = suck_u1(cb);
-# else
- for (i = 0; i < 8; i++)
- buffer[7 - i] = suck_u1(cb);
-# endif /* defined(__ARM__) && ... */
-
- MCOPY((u1 *) (&d), buffer, u1, 8);
-#else
- suck_nbytes((u1*) (&d), cb, 8);
-#endif
-
- assert(sizeof(double) == 8);
-
- return d;
-}
-
-
-/* suck_nbytes *****************************************************************
-
- Transfer block of classfile data into a buffer.
-
-*******************************************************************************/
-
-void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
-{
- MCOPY(buffer, cb->pos, u1, len);
- cb->pos += len;
-}
-
-
-/* suck_skip_nbytes ************************************************************
-
- Skip block of classfile data.
-
-*******************************************************************************/
-
-void suck_skip_nbytes(classbuffer *cb, s4 len)
-{
- cb->pos += len;
-}
-
-
-/* suck_start ******************************************************************
-
- Returns true if classbuffer is already loaded or a file for the
- specified class has succussfully been read in. All directories of
- the searchpath are used to find the classfile (<classname>.class).
- Returns NULL if no classfile is found and writes an error message.
-
-*******************************************************************************/
-
-classbuffer *suck_start(classinfo *c)
-{
- list_classpath_entry *lce;
- char *filename;
- s4 filenamelen;
- char *path;
- FILE *classfile;
- s4 len;
- struct stat buffer;
- classbuffer *cb;
-
- /* initialize return value */
-
- cb = NULL;
-
- /* get the classname as char string (do it here for the warning at
- the end of the function) */
-
- filenamelen = utf_bytes(c->name) + strlen(".class") + strlen("0");
- filename = MNEW(char, filenamelen);
-
- utf_copy(filename, c->name);
- strcat(filename, ".class");
-
- /* walk through all classpath entries */
-
- for (lce = list_first(list_classpath_entries); lce != NULL && cb == NULL;
- lce = list_next(list_classpath_entries, lce)) {
-#if defined(ENABLE_ZLIB)
- if (lce->type == CLASSPATH_ARCHIVE) {
-
- /* enter a monitor on zip/jar archives */
-
- Mutex_lock(lce->mutex);
-
- /* try to get the file in current archive */
-
- cb = zip_get(lce, c);
-
- /* leave the monitor */
-
- Mutex_unlock(lce->mutex);
-
- } else {
-#endif /* defined(ENABLE_ZLIB) */
- path = MNEW(char, lce->pathlen + filenamelen);
- strcpy(path, lce->path);
- strcat(path, filename);
-
- classfile = os_fopen(path, "r");
-
- if (classfile) { /* file exists */
- if (!os_stat(path, &buffer)) { /* read classfile data */
- cb = NEW(classbuffer);
- cb->clazz = c;
- cb->size = buffer.st_size;
- cb->data = MNEW(u1, cb->size);
- cb->pos = cb->data;
- cb->path = lce->path;
-
- /* read class data */
-
- len = os_fread((void *) cb->data, 1, cb->size,
- classfile);
-
- if (len != buffer.st_size) {
- suck_stop(cb);
-/* if (ferror(classfile)) { */
-/* } */
- }
-
- /* close the class file */
-
- os_fclose(classfile);
- }
- }
-
- MFREE(path, char, lce->pathlen + filenamelen);
-#if defined(ENABLE_ZLIB)
- }
-#endif
- }
-
- if (opt_verbose)
- if (cb == NULL)
- dolog("Warning: Can not open class file '%s'", filename);
-
- MFREE(filename, char, filenamelen);
-
- return cb;
-}
-
-
-/* suck_stop *******************************************************************
-
- Frees memory for buffer with classfile data.
-
- CAUTION: This function may only be called if buffer has been
- allocated by suck_start with reading a file.
-
-*******************************************************************************/
-
-void suck_stop(classbuffer *cb)
-{
- /* free memory */
-
- MFREE(cb->data, u1, cb->size);
- FREE(cb, classbuffer);
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
--- /dev/null
+/* src/vm/suck.cpp - functions to read LE ordered types from a buffer
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ 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.
+
+ 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.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/memory.h"
+
+#include "threads/mutex.hpp"
+
+#include "toolbox/list.h"
+#include "toolbox/logging.h"
+#include "toolbox/util.h"
+
+#include "vm/exceptions.hpp"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/os.hpp"
+#include "vm/properties.hpp"
+#include "vm/suck.hpp"
+#include "vm/vm.hpp"
+#include "vm/zip.h"
+
+
+/* global variables ***********************************************************/
+
+list_t *list_classpath_entries;
+
+
+/* suck_init *******************************************************************
+
+ Initializes the suck subsystem like initializing the classpath
+ entries list.
+
+*******************************************************************************/
+
+bool suck_init(void)
+{
+ TRACESUBSYSTEMINITIALIZATION("suck_init");
+
+ list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
+
+ /* everything's ok */
+
+ return true;
+}
+
+
+/* scandir_filter **************************************************************
+
+ Filters for zip/jar files.
+
+*******************************************************************************/
+
+static int scandir_filter(const struct dirent *a)
+{
+ s4 namlen;
+
+#if defined(_DIRENT_HAVE_D_NAMLEN)
+ namlen = a->d_namlen;
+#else
+ namlen = strlen(a->d_name);
+#endif
+
+ if ((strncasecmp(a->d_name + namlen - 4, ".zip", 4) == 0) ||
+ (strncasecmp(a->d_name + namlen - 4, ".jar", 4) == 0))
+ return 1;
+
+ return 0;
+}
+
+
+/* suck_add ********************************************************************
+
+ Adds a classpath to the global classpath entries list.
+
+*******************************************************************************/
+
+void suck_add(char *classpath)
+{
+ list_classpath_entry *lce;
+ char *start;
+ char *end;
+ char *filename;
+ s4 filenamelen;
+ bool is_zip;
+ char *cwd;
+ s4 cwdlen;
+#if defined(ENABLE_ZLIB)
+ hashtable *ht;
+#endif
+
+ /* parse the classpath string */
+
+ 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) {
+ is_zip = false;
+ filenamelen = end - start;
+
+ if (filenamelen > 4) {
+ if ((strncasecmp(end - 4, ".zip", 4) == 0) ||
+ (strncasecmp(end - 4, ".jar", 4) == 0)) {
+ is_zip = true;
+ }
+ }
+
+ /* save classpath entries as absolute pathnames */
+
+ cwd = NULL;
+ cwdlen = 0;
+
+ if (*start != '/') { /* XXX fix me for win32 */
+ cwd = _Jv_getcwd();
+ cwdlen = strlen(cwd) + strlen("/");
+ }
+
+ /* allocate memory for filename and fill it */
+
+ filename = MNEW(char, filenamelen + cwdlen + strlen("/") +
+ strlen("0"));
+
+ if (cwd) {
+ strcpy(filename, cwd);
+ strcat(filename, "/");
+ strncat(filename, start, filenamelen);
+
+ /* add cwd length to file length */
+ filenamelen += cwdlen;
+
+ } else {
+ strncpy(filename, start, filenamelen);
+ filename[filenamelen] = '\0';
+ }
+
+ lce = NULL;
+
+ if (is_zip) {
+#if defined(ENABLE_ZLIB)
+ ht = zip_open(filename);
+
+ if (ht != NULL) {
+ lce = NEW(list_classpath_entry);
+
+ lce->type = CLASSPATH_ARCHIVE;
+ lce->htclasses = ht;
+ lce->path = filename;
+ lce->pathlen = filenamelen;
+
+ /* SUN compatible -verbose:class output */
+
+ if (opt_verboseclass)
+ printf("[Opened %s]\n", filename);
+ }
+
+#else
+ VM::get_current()->abort("suck_add: zip/jar files not supported");
+#endif
+ }
+ else {
+ if (filename[filenamelen - 1] != '/') {/* XXX fixme for win32 */
+ filename[filenamelen] = '/';
+ filename[filenamelen + 1] = '\0';
+ filenamelen++;
+ }
+
+ lce = NEW(list_classpath_entry);
+
+ lce->type = CLASSPATH_PATH;
+ lce->path = filename;
+ lce->pathlen = filenamelen;
+ }
+
+ /* add current classpath entry, if no error */
+
+ if (lce != NULL)
+ list_add_last(list_classpath_entries, lce);
+ }
+
+ /* goto next classpath entry, skip ':' delimiter */
+
+ if ((*end) == ':')
+ start = end + 1;
+ else
+ start = end;
+ }
+}
+
+
+/* suck_add_from_property ******************************************************
+
+ Adds a classpath form a property entry to the global classpath
+ entries list.
+
+*******************************************************************************/
+
+void suck_add_from_property(const char *key)
+{
+ const char *value;
+ const char *start;
+ const char *end;
+ s4 pathlen;
+ struct dirent **namelist;
+ s4 n;
+ s4 i;
+ s4 namlen;
+ char *p;
+
+ /* get the property value */
+ Properties properties = VM::get_current()->get_properties();
+ value = properties.get(key);
+
+ if (value == NULL)
+ return;
+
+ /* get the directory entries of the property */
+
+ for (start = value; (*start) != '\0'; ) {
+
+ /* search for ':' delimiter to get the end of the current entry */
+
+ for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
+
+ /* found an entry */
+
+ if (start != end) {
+ /* allocate memory for the path entry */
+
+ pathlen = end - start;
+ char* path = MNEW(char, pathlen + strlen("0"));
+
+ /* copy and terminate the string */
+
+ strncpy(path, start, pathlen);
+ path[pathlen] = '\0';
+
+ /* Reset namelist to NULL for the freeing in an error case
+ (see below). */
+
+ namelist = NULL;
+
+ /* scan the directory found for zip/jar files */
+
+ n = os::scandir((const char*) path, &namelist, &scandir_filter, (int (*)(const void*, const void*)) &alphasort);
+
+ /* On error, just continue, this should be ok. */
+
+ if (n > 0) {
+ for (i = 0; i < n; i++) {
+#if defined(_DIRENT_HAVE_D_NAMLEN)
+ namlen = namelist[i]->d_namlen;
+#else
+ namlen = strlen(namelist[i]->d_name);
+#endif
+
+ /* Allocate memory for bootclasspath. */
+
+ // FIXME Make boot_class_path const char*.
+ char* boot_class_path = (char*) properties.get("sun.boot.class.path");
+
+ p = MNEW(char,
+ pathlen + strlen("/") + namlen +
+ strlen(":") +
+ strlen(boot_class_path) +
+ strlen("0"));
+
+ /* Prepend the file found to the bootclasspath. */
+
+ strcpy(p, path);
+ strcat(p, "/");
+ strcat(p, namelist[i]->d_name);
+ strcat(p, ":");
+ strcat(p, boot_class_path);
+
+ properties.put("sun.boot.class.path", p);
+ properties.put("java.boot.class.path", p);
+
+ MFREE(boot_class_path, char, strlen(boot_class_path));
+
+ /* free the memory allocated by scandir */
+ /* (We use `free` as the memory came from the C library.) */
+
+ free(namelist[i]);
+ }
+ }
+
+ /* On some systems (like Linux) when n == 0, then namelist
+ returned from scnadir is NULL, thus we don't have to
+ free it.
+ (Use `free` as the memory came from the C library.) */
+
+ if (namelist != NULL)
+ free(namelist);
+
+ MFREE(path, char, pathlen + strlen("0"));
+ }
+
+ /* goto next entry, skip ':' delimiter */
+
+ if ((*end) == ':')
+ start = end + 1;
+ else
+ start = end;
+ }
+}
+
+
+/* suck_check_classbuffer_size *************************************************
+
+ Assert that at least <len> bytes are left to read <len> is limited
+ to the range of non-negative s4 values.
+
+*******************************************************************************/
+
+bool suck_check_classbuffer_size(classbuffer *cb, s4 len)
+{
+#ifdef ENABLE_VERIFIER
+ if (len < 0 || ((cb->data + cb->size) - cb->pos) < len) {
+ exceptions_throw_classformaterror(cb->clazz, "Truncated class file");
+ return false;
+ }
+#endif /* ENABLE_VERIFIER */
+
+ return true;
+}
+
+
+u1 suck_u1(classbuffer *cb)
+{
+ u1 a;
+
+ a = SUCK_BE_U1(cb->pos);
+ cb->pos++;
+
+ return a;
+}
+
+
+u2 suck_u2(classbuffer *cb)
+{
+ u2 a;
+
+ a = SUCK_BE_U2(cb->pos);
+ cb->pos += 2;
+
+ return a;
+}
+
+
+u4 suck_u4(classbuffer *cb)
+{
+ u4 a;
+
+ a = SUCK_BE_U4(cb->pos);
+ cb->pos += 4;
+
+ return a;
+}
+
+
+u8 suck_u8(classbuffer *cb)
+{
+#if U8_AVAILABLE == 1
+ u8 a;
+
+ a = SUCK_BE_U8(cb->pos);
+ cb->pos += 8;
+
+ return a;
+#else
+ u8 v;
+
+ v.high = suck_u4(cb);
+ v.low = suck_u4(cb);
+
+ return v;
+#endif
+}
+
+
+float suck_float(classbuffer *cb)
+{
+ float f;
+
+#if WORDS_BIGENDIAN == 0
+ u1 buffer[4];
+ u2 i;
+
+ for (i = 0; i < 4; i++)
+ buffer[3 - i] = suck_u1(cb);
+
+ MCOPY((u1 *) (&f), buffer, u1, 4);
+#else
+ suck_nbytes((u1*) (&f), cb, 4);
+#endif
+
+ assert(sizeof(float) == 4);
+
+ return f;
+}
+
+
+double suck_double(classbuffer *cb)
+{
+ double d;
+
+#if WORDS_BIGENDIAN == 0
+ u1 buffer[8];
+ u2 i;
+
+# if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
+ /*
+ * On little endian ARM processors when using FPA, word order
+ * of doubles is still big endian. So take that into account
+ * here. When using VFP, word order of doubles follows byte
+ * order. (michi 2005/07/24)
+ */
+ for (i = 0; i < 4; i++)
+ buffer[3 - i] = suck_u1(cb);
+ for (i = 0; i < 4; i++)
+ buffer[7 - i] = suck_u1(cb);
+# else
+ for (i = 0; i < 8; i++)
+ buffer[7 - i] = suck_u1(cb);
+# endif /* defined(__ARM__) && ... */
+
+ MCOPY((u1 *) (&d), buffer, u1, 8);
+#else
+ suck_nbytes((u1*) (&d), cb, 8);
+#endif
+
+ assert(sizeof(double) == 8);
+
+ return d;
+}
+
+
+/* suck_nbytes *****************************************************************
+
+ Transfer block of classfile data into a buffer.
+
+*******************************************************************************/
+
+void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
+{
+ MCOPY(buffer, cb->pos, u1, len);
+ cb->pos += len;
+}
+
+
+/* suck_skip_nbytes ************************************************************
+
+ Skip block of classfile data.
+
+*******************************************************************************/
+
+void suck_skip_nbytes(classbuffer *cb, s4 len)
+{
+ cb->pos += len;
+}
+
+
+/* suck_start ******************************************************************
+
+ Returns true if classbuffer is already loaded or a file for the
+ specified class has succussfully been read in. All directories of
+ the searchpath are used to find the classfile (<classname>.class).
+ Returns NULL if no classfile is found and writes an error message.
+
+*******************************************************************************/
+
+classbuffer *suck_start(classinfo *c)
+{
+ list_classpath_entry *lce;
+ char *filename;
+ s4 filenamelen;
+ char *path;
+ FILE *classfile;
+ s4 len;
+ struct stat buffer;
+ classbuffer *cb;
+
+ /* initialize return value */
+
+ cb = NULL;
+
+ /* get the classname as char string (do it here for the warning at
+ the end of the function) */
+
+ filenamelen = utf_bytes(c->name) + strlen(".class") + strlen("0");
+ filename = MNEW(char, filenamelen);
+
+ utf_copy(filename, c->name);
+ strcat(filename, ".class");
+
+ /* walk through all classpath entries */
+
+ for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL && cb == NULL;
+ lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
+#if defined(ENABLE_ZLIB)
+ if (lce->type == CLASSPATH_ARCHIVE) {
+
+ /* enter a monitor on zip/jar archives */
+
+ lce->mutex->lock();
+
+ /* try to get the file in current archive */
+
+ cb = zip_get(lce, c);
+
+ /* leave the monitor */
+
+ lce->mutex->unlock();
+
+ } else {
+#endif /* defined(ENABLE_ZLIB) */
+ path = MNEW(char, lce->pathlen + filenamelen);
+ strcpy(path, lce->path);
+ strcat(path, filename);
+
+ classfile = os::fopen(path, "r");
+
+ if (classfile) { /* file exists */
+ if (!os::stat(path, &buffer)) { /* read classfile data */
+ cb = NEW(classbuffer);
+ cb->clazz = c;
+ cb->size = buffer.st_size;
+ cb->data = MNEW(u1, cb->size);
+ cb->pos = cb->data;
+ cb->path = lce->path;
+
+ /* read class data */
+
+ len = os::fread((void *) cb->data, 1, cb->size,
+ classfile);
+
+ if (len != buffer.st_size) {
+ suck_stop(cb);
+/* if (ferror(classfile)) { */
+/* } */
+ }
+
+ /* close the class file */
+
+ os::fclose(classfile);
+ }
+ }
+
+ MFREE(path, char, lce->pathlen + filenamelen);
+#if defined(ENABLE_ZLIB)
+ }
+#endif
+ }
+
+ if (opt_verbose)
+ if (cb == NULL)
+ dolog("Warning: Can not open class file '%s'", filename);
+
+ MFREE(filename, char, filenamelen);
+
+ return cb;
+}
+
+
+/* suck_stop *******************************************************************
+
+ Frees memory for buffer with classfile data.
+
+ CAUTION: This function may only be called if buffer has been
+ allocated by suck_start with reading a file.
+
+*******************************************************************************/
+
+void suck_stop(classbuffer *cb)
+{
+ /* free memory */
+
+ MFREE(cb->data, u1, cb->size);
+ FREE(cb, classbuffer);
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+++ /dev/null
-/* src/vm/suck.h - functions to read LE ordered types from a buffer
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- 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.
-
- 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.
-
- 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., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#ifndef _SUCK_H
-#define _SUCK_H
-
-#include "config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm/types.h"
-
-#include "threads/mutex.hpp"
-
-#include "toolbox/hashtable.h"
-#include "toolbox/list.h"
-
-#include "vm/class.h"
-#include "vm/global.h"
-#include "vm/loader.hpp"
-
-
-/* list_classpath_entry *******************************************************/
-
-enum {
- CLASSPATH_PATH,
- CLASSPATH_ARCHIVE
-};
-
-typedef struct list_classpath_entry list_classpath_entry;
-
-struct list_classpath_entry {
-#if defined(ENABLE_THREADS)
- Mutex *mutex; /* mutex locking on zip/jar files */
-#endif
- s4 type;
- char *path;
- s4 pathlen;
-#if defined(ENABLE_ZLIB)
- hashtable *htclasses;
-#endif
- listnode_t linkage;
-};
-
-
-/* macros to read LE and BE types from a buffer ********************************
-
- BE macros are for Java class file loading.
- LE macros are for ZIP file loading.
-
-*******************************************************************************/
-
-/* LE macros (for ZIP files ) *************************************************/
-
-#if defined(__I386__) || defined(__X86_64__)
-
-/* we can optimize the LE access on little endian machines without alignment */
-
-#define SUCK_LE_U1(p) *((u1 *) (p))
-#define SUCK_LE_U2(p) *((u2 *) (p))
-#define SUCK_LE_U4(p) *((u4 *) (p))
-
-#if U8_AVAILABLE == 1
-#define SUCK_LE_U8(p) *((u8 *) (p))
-#endif
-
-#else /* defined(__I386__) || defined(__X86_64__) */
-
-#define SUCK_LE_U1(p) \
- ((u1) (p)[0])
-
-#define SUCK_LE_U2(p) \
- ((((u2) (p)[1]) << 8) + \
- ((u2) (p)[0]))
-
-#define SUCK_LE_U4(p) \
- ((((u4) (p)[3]) << 24) + \
- (((u4) (p)[2]) << 16) + \
- (((u4) (p)[1]) << 8) + \
- ((u4) (p)[0]))
-
-#if U8_AVAILABLE == 1
-#define SUCK_LE_U8(p) \
- ((((u8) (p)[7]) << 56) + \
- (((u8) (p)[6]) << 48) + \
- (((u8) (p)[5]) << 40) + \
- (((u8) (p)[4]) << 32) + \
- (((u8) (p)[3]) << 24) + \
- (((u8) (p)[2]) << 16) + \
- (((u8) (p)[1]) << 8) + \
- ((u8) (p)[0]))
-#endif
-
-#endif /* defined(__I386__) || defined(__X86_64__) */
-
-
-/* BE macros (for Java class files ) ******************************************/
-
-#define SUCK_BE_U1(p) \
- ((u1) (p)[0])
-
-#define SUCK_BE_U2(p) \
- ((((u2) (p)[0]) << 8) + \
- ((u2) (p)[1]))
-
-#define SUCK_BE_U4(p) \
- ((((u4) (p)[0]) << 24) + \
- (((u4) (p)[1]) << 16) + \
- (((u4) (p)[2]) << 8) + \
- ((u4) (p)[3]))
-
-#if U8_AVAILABLE == 1
-#define SUCK_BE_U8(p) \
- ((((u8) (p)[0]) << 56) + \
- (((u8) (p)[1]) << 48) + \
- (((u8) (p)[2]) << 40) + \
- (((u8) (p)[3]) << 32) + \
- (((u8) (p)[4]) << 24) + \
- (((u8) (p)[5]) << 16) + \
- (((u8) (p)[6]) << 8) + \
- ((u8) (p)[7]))
-#endif
-
-
-#define SUCK_BE_S1(p) (s1) SUCK_BE_U1(p)
-#define SUCK_BE_S2(p) (s2) SUCK_BE_U2(p)
-#define SUCK_BE_S4(p) (s4) SUCK_BE_U4(p)
-#define SUCK_BE_S8(p) (s8) SUCK_BE_U8(p)
-
-
-/* signed suck defines ********************************************************/
-
-#define suck_s1(a) (s1) suck_u1((a))
-#define suck_s2(a) (s2) suck_u2((a))
-#define suck_s4(a) (s4) suck_u4((a))
-#define suck_s8(a) (s8) suck_u8((a))
-
-
-/* export variables ***********************************************************/
-
-extern list_t *list_classpath_entries;
-
-
-/* function prototypes ********************************************************/
-
-bool suck_init(void);
-
-void suck_add(char *classpath);
-void suck_add_from_property(const char *key);
-
-bool suck_check_classbuffer_size(classbuffer *cb, s4 len);
-
-u1 suck_u1(classbuffer *cb);
-u2 suck_u2(classbuffer *cb);
-u4 suck_u4(classbuffer *cb);
-u8 suck_u8(classbuffer *cb);
-
-float suck_float(classbuffer *cb);
-double suck_double(classbuffer *cb);
-
-void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len);
-void suck_skip_nbytes(classbuffer *cb, s4 len);
-
-classbuffer *suck_start(classinfo *c);
-
-void suck_stop(classbuffer *cb);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SUCK_H */
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
--- /dev/null
+/* src/vm/suck.hpp - functions to read LE ordered types from a buffer
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ 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.
+
+ 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.
+
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _SUCK_HPP
+#define _SUCK_HPP
+
+#include "config.h"
+
+#include "vm/types.h"
+
+#include "threads/mutex.hpp"
+
+#include "toolbox/hashtable.h"
+#include "toolbox/list.h"
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/loader.hpp"
+
+
+/* list_classpath_entry *******************************************************/
+
+enum {
+ CLASSPATH_PATH,
+ CLASSPATH_ARCHIVE
+};
+
+typedef struct list_classpath_entry list_classpath_entry;
+
+struct list_classpath_entry {
+#if defined(ENABLE_THREADS)
+ Mutex *mutex; /* mutex locking on zip/jar files */
+#endif
+ s4 type;
+ char *path;
+ s4 pathlen;
+#if defined(ENABLE_ZLIB)
+ hashtable *htclasses;
+#endif
+ listnode_t linkage;
+};
+
+
+/* macros to read LE and BE types from a buffer ********************************
+
+ BE macros are for Java class file loading.
+ LE macros are for ZIP file loading.
+
+*******************************************************************************/
+
+/* LE macros (for ZIP files ) *************************************************/
+
+#if defined(__I386__) || defined(__X86_64__)
+
+/* we can optimize the LE access on little endian machines without alignment */
+
+#define SUCK_LE_U1(p) *((u1 *) (p))
+#define SUCK_LE_U2(p) *((u2 *) (p))
+#define SUCK_LE_U4(p) *((u4 *) (p))
+
+#if U8_AVAILABLE == 1
+#define SUCK_LE_U8(p) *((u8 *) (p))
+#endif
+
+#else /* defined(__I386__) || defined(__X86_64__) */
+
+#define SUCK_LE_U1(p) \
+ ((u1) (p)[0])
+
+#define SUCK_LE_U2(p) \
+ ((((u2) (p)[1]) << 8) + \
+ ((u2) (p)[0]))
+
+#define SUCK_LE_U4(p) \
+ ((((u4) (p)[3]) << 24) + \
+ (((u4) (p)[2]) << 16) + \
+ (((u4) (p)[1]) << 8) + \
+ ((u4) (p)[0]))
+
+#if U8_AVAILABLE == 1
+#define SUCK_LE_U8(p) \
+ ((((u8) (p)[7]) << 56) + \
+ (((u8) (p)[6]) << 48) + \
+ (((u8) (p)[5]) << 40) + \
+ (((u8) (p)[4]) << 32) + \
+ (((u8) (p)[3]) << 24) + \
+ (((u8) (p)[2]) << 16) + \
+ (((u8) (p)[1]) << 8) + \
+ ((u8) (p)[0]))
+#endif
+
+#endif /* defined(__I386__) || defined(__X86_64__) */
+
+
+/* BE macros (for Java class files ) ******************************************/
+
+#define SUCK_BE_U1(p) \
+ ((u1) (p)[0])
+
+#define SUCK_BE_U2(p) \
+ ((((u2) (p)[0]) << 8) + \
+ ((u2) (p)[1]))
+
+#define SUCK_BE_U4(p) \
+ ((((u4) (p)[0]) << 24) + \
+ (((u4) (p)[1]) << 16) + \
+ (((u4) (p)[2]) << 8) + \
+ ((u4) (p)[3]))
+
+#if U8_AVAILABLE == 1
+#define SUCK_BE_U8(p) \
+ ((((u8) (p)[0]) << 56) + \
+ (((u8) (p)[1]) << 48) + \
+ (((u8) (p)[2]) << 40) + \
+ (((u8) (p)[3]) << 32) + \
+ (((u8) (p)[4]) << 24) + \
+ (((u8) (p)[5]) << 16) + \
+ (((u8) (p)[6]) << 8) + \
+ ((u8) (p)[7]))
+#endif
+
+
+#define SUCK_BE_S1(p) (s1) SUCK_BE_U1(p)
+#define SUCK_BE_S2(p) (s2) SUCK_BE_U2(p)
+#define SUCK_BE_S4(p) (s4) SUCK_BE_U4(p)
+#define SUCK_BE_S8(p) (s8) SUCK_BE_U8(p)
+
+
+/* signed suck defines ********************************************************/
+
+#define suck_s1(a) (s1) suck_u1((a))
+#define suck_s2(a) (s2) suck_u2((a))
+#define suck_s4(a) (s4) suck_u4((a))
+#define suck_s8(a) (s8) suck_u8((a))
+
+
+/* export variables ***********************************************************/
+
+extern list_t *list_classpath_entries;
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool suck_init(void);
+
+void suck_add(char *classpath);
+void suck_add_from_property(const char *key);
+
+bool suck_check_classbuffer_size(classbuffer *cb, s4 len);
+
+u1 suck_u1(classbuffer *cb);
+u2 suck_u2(classbuffer *cb);
+u4 suck_u4(classbuffer *cb);
+u8 suck_u8(classbuffer *cb);
+
+float suck_float(classbuffer *cb);
+double suck_double(classbuffer *cb);
+
+void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len);
+void suck_skip_nbytes(classbuffer *cb, s4 len);
+
+classbuffer *suck_start(classinfo *c);
+
+void suck_stop(classbuffer *cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SUCK_HPP
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/signallocal.h"
#include "vm/statistics.h"
#include "vm/string.hpp"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/vm.hpp"
#include "vm/jit/argument.h"
#include "mm/memory.h"
#include "vm/global.h"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/utf8.h"
#include "vm/vm.hpp"
#include "vm/zip.h"
#ifndef _ZIP_H
#define _ZIP_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "config.h"
#include "vm/types.h"
#include "vm/class.h"
#include "vm/global.h"
#include "vm/loader.hpp"
-#include "vm/suck.h"
+#include "vm/suck.hpp"
#include "vm/utf8.h"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
hashtable *zip_open(char *path);
hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u);
classbuffer *zip_get(list_classpath_entry *lce, classinfo *c);