* This is a rather huge commit, which changes the build order of
authortwisti <none@none>
Mon, 29 Jan 2007 18:49:05 +0000 (18:49 +0000)
committertwisti <none@none>
Mon, 29 Jan 2007 18:49:05 +0000 (18:49 +0000)
various parts to be able to bootstrap cacaoh without any dependencies
on a generated header file.  I include the file list from SVN, so we
can see what happened to the files.

Here we go (D-files were mostly moved to src/vmcore):

D    src/vm/hashtable.h
D    src/vm/options.h
M    src/vm/properties.h
D    src/vm/zip.c
D    src/vm/class.c
D    src/vm/suck.c
D    src/vm/loader.c
M    src/vm/builtin.c
M    src/vm/string.c
D    src/vm/zip.h
D    src/vm/class.h
D    src/vm/rt-timing.c
D    src/vm/suck.h
D    src/vm/annotation.c
M    src/vm/builtin.h
D    src/vm/loader.h
D    src/vm/descriptor.c
D    src/vm/annotation.h
D    src/vm/rt-timing.h
D    src/vm/resolve.c
D    src/vm/method.c
D    src/vm/descriptor.h
M    src/vm/finalizer.c
D    src/vm/resolve.h
D    src/vm/method.h
D    src/vm/references.h
D    src/vm/classcache.c
D    src/vm/statistics.c
D    src/vm/classcache.h
D    src/vm/statistics.h
M    src/vm/initialize.c
M    src/vm/access.c
D    src/vm/stackmap.c
M    src/vm/jit/powerpc/linux/md-abi.c
M    src/vm/jit/powerpc/emit.c
M    src/vm/jit/powerpc/md.c
M    src/vm/jit/powerpc/codegen.c
M    src/vm/jit/powerpc/patcher.c
M    src/vm/jit/codegen-common.h
M    src/vm/jit/abi.h
M    src/vm/jit/stack.c
M    src/vm/jit/optimizing/profile.c
M    src/vm/jit/optimizing/recompile.c
M    src/vm/jit/optimizing/ifconv.c
M    src/vm/jit/optimizing/ifconv.h
M    src/vm/jit/code.c
M    src/vm/jit/tools/genoffsets.c
M    src/vm/jit/code.h
M    src/vm/jit/show.c
M    src/vm/jit/dseg.c
M    src/vm/jit/verify/typeinfo.h
M    src/vm/jit/verify/typecheck-typeinferer.c
M    src/vm/jit/verify/typecheck.c
M    src/vm/jit/verify/typecheck-stackbased.c
M    src/vm/jit/verify/typeinfo.c
M    src/vm/jit/dseg.h
M    src/vm/jit/loop/loop.h
M    src/vm/jit/loop/graph.h
M    src/vm/jit/allocator/simplereg.c
M    src/vm/jit/parse.c
M    src/vm/jit/asmpart.h
M    src/vm/jit/stacktrace.c
M    src/vm/jit/emit-common.c
M    src/vm/jit/jit.c
M    src/vm/jit/stacktrace.h
M    src/vm/jit/codegen-common.c
M    src/vm/jit/jit.h
M    src/vm/initialize.h
M    src/vm/access.h
D    src/vm/stackmap.h
M    src/vm/signal.c
M    src/vm/exceptions.c
M    src/vm/vm.c
D    src/vm/field.c
D    src/vm/linker.c
M    src/vm/exceptions.h
M    src/vm/stringlocal.h
D    src/vm/utf8.c
D    src/vm/field.h
M    src/vm/Makefile.am
D    src/vm/linker.h
D    src/vm/hashtable.c
D    src/vm/options.c
D    src/vm/utf8.h
M    src/vm/properties.c
M    src/vm/signallocal.h
M    src/cacao/Makefile.am
M    src/native/jni.c
M    src/native/vm/java_lang_Class.c
M    src/native/vm/gnu/gnu_java_lang_management_VMThreadMXBeanImpl.c
M    src/native/vm/gnu/gnu_java_lang_management_VMMemoryMXBeanImpl.c
M    src/native/vm/gnu/java_security_VMAccessController.c
M    src/native/vm/gnu/java_lang_VMClassLoader.c
M    src/native/vm/gnu/java_lang_management_VMManagementFactory.c
M    src/native/vm/gnu/gnu_java_lang_management_VMRuntimeMXBeanImpl.c
M    src/native/vm/gnu/java_lang_VMClass.c
M    src/native/vm/gnu/java_lang_VMThread.c
M    src/native/vm/gnu/gnu_classpath_VMSystemProperties.c
M    src/native/vm/gnu/java_lang_reflect_Method.c
M    src/native/vm/gnu/java_lang_VMRuntime.c
M    src/native/vm/gnu/java_lang_reflect_Field.c
M    src/native/vm/gnu/gnu_classpath_VMStackWalker.c
M    src/native/vm/gnu/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c
M    src/native/vm/gnu/java_lang_reflect_Constructor.c
M    src/native/vm/gnu/java_lang_VMThrowable.c
M    src/native/vm/java_lang_Object.c
M    src/native/vm/java_lang_Thread.c
D    src/native/include/java_lang_Thread.h
D    src/native/include/java_lang_Throwable.h
D    src/native/include/java_util_Properties.h
D    src/native/include/java_lang_VMThread.h
D    src/native/include/java_lang_VMThrowable.h
D    src/native/include/java_lang_ClassLoader.h
M    src/native/include/Makefile.am
D    src/native/include/java_lang_Cloneable.h
D    src/native/include/java_lang_ThreadGroup.h
D    src/native/include/java_lang_Class.h
D    src/native/include/java_lang_Object.h
D    src/native/include/java_lang_String.h
M    src/native/jni.h
M    src/native/native.c
M    src/native/native.h
A    src/toolbox/hashtable.h
M    src/toolbox/list.c
M    src/toolbox/avl.c
M    src/toolbox/logging.c
M    src/toolbox/Makefile.am
M    src/toolbox/logging.h
A    src/toolbox/hashtable.c
M    src/mm/gc-common.h
M    src/mm/Makefile.am
M    src/mm/memory.c
M    src/mm/boehm.c
M    src/Makefile.am
M    src/threads/none/threads.h
M    src/threads/none/lock.h
M    src/threads/native/threads.h
M    src/threads/native/lock.c
M    src/threads/native/threads.c
AM   src/vmcore
A    src/vmcore/options.h
A    src/vmcore/zip.c
A    src/vmcore/suck.c
A    src/vmcore/class.c
A    src/vmcore/loader.c
A    src/vmcore/zip.h
A    src/vmcore/annotation.c
A    src/vmcore/suck.h
A    src/vmcore/class.h
A    src/vmcore/rt-timing.c
A    src/vmcore/loader.h
A    src/vmcore/descriptor.c
A    src/vmcore/resolve.c
A    src/vmcore/annotation.h
A    src/vmcore/rt-timing.h
A    src/vmcore/method.c
A    src/vmcore/descriptor.h
A    src/vmcore/resolve.h
A    src/vmcore/method.h
A    src/vmcore/references.h
A    src/vmcore/classcache.c
A    src/vmcore/statistics.c
A    src/vmcore/.cvsignore
A    src/vmcore/classcache.h
A    src/vmcore/statistics.h
A    src/vmcore/stackmap.c
A    src/vmcore/stackmap.h
A    src/vmcore/field.c
A    src/vmcore/linker.c
A    src/vmcore/utf8.c
A    src/vmcore/field.h
A    src/vmcore/Makefile.am
A    src/vmcore/linker.h
A    src/vmcore/options.c
A    src/vmcore/utf8.h
M    src/cacaoh/cacaoh.c
M    src/cacaoh/headers.h
M    src/cacaoh/Makefile.am
M    src/cacaoh/headers.c
A    src/cacaoh/dummy.c
M    configure.ac

--HG--
rename : src/vm/hashtable.c => src/toolbox/hashtable.c
rename : src/vm/hashtable.h => src/toolbox/hashtable.h
rename : src/vm/annotation.c => src/vmcore/annotation.c
rename : src/vm/annotation.h => src/vmcore/annotation.h
rename : src/vm/class.c => src/vmcore/class.c
rename : src/vm/class.h => src/vmcore/class.h
rename : src/vm/classcache.c => src/vmcore/classcache.c
rename : src/vm/classcache.h => src/vmcore/classcache.h
rename : src/vm/descriptor.c => src/vmcore/descriptor.c
rename : src/vm/descriptor.h => src/vmcore/descriptor.h
rename : src/vm/field.c => src/vmcore/field.c
rename : src/vm/field.h => src/vmcore/field.h
rename : src/vm/linker.c => src/vmcore/linker.c
rename : src/vm/linker.h => src/vmcore/linker.h
rename : src/vm/loader.c => src/vmcore/loader.c
rename : src/vm/loader.h => src/vmcore/loader.h
rename : src/vm/method.c => src/vmcore/method.c
rename : src/vm/method.h => src/vmcore/method.h
rename : src/vm/options.c => src/vmcore/options.c
rename : src/vm/options.h => src/vmcore/options.h
rename : src/vm/references.h => src/vmcore/references.h
rename : src/vm/resolve.c => src/vmcore/resolve.c
rename : src/vm/resolve.h => src/vmcore/resolve.h
rename : src/vm/rt-timing.c => src/vmcore/rt-timing.c
rename : src/vm/rt-timing.h => src/vmcore/rt-timing.h
rename : src/vm/stackmap.c => src/vmcore/stackmap.c
rename : src/vm/stackmap.h => src/vmcore/stackmap.h
rename : src/vm/statistics.c => src/vmcore/statistics.c
rename : src/vm/statistics.h => src/vmcore/statistics.h
rename : src/vm/suck.c => src/vmcore/suck.c
rename : src/vm/suck.h => src/vmcore/suck.h
rename : src/vm/utf8.c => src/vmcore/utf8.c
rename : src/vm/utf8.h => src/vmcore/utf8.h
rename : src/vm/zip.c => src/vmcore/zip.c
rename : src/vm/zip.h => src/vmcore/zip.h

180 files changed:
configure.ac
src/Makefile.am
src/cacao/Makefile.am
src/cacaoh/Makefile.am
src/cacaoh/cacaoh.c
src/cacaoh/dummy.c [new file with mode: 0644]
src/cacaoh/headers.c
src/cacaoh/headers.h
src/mm/Makefile.am
src/mm/boehm.c
src/mm/gc-common.h
src/mm/memory.c
src/native/include/Makefile.am
src/native/include/java_lang_Class.h [deleted file]
src/native/include/java_lang_ClassLoader.h [deleted file]
src/native/include/java_lang_Cloneable.h [deleted file]
src/native/include/java_lang_Object.h [deleted file]
src/native/include/java_lang_String.h [deleted file]
src/native/include/java_lang_Thread.h [deleted file]
src/native/include/java_lang_ThreadGroup.h [deleted file]
src/native/include/java_lang_Throwable.h [deleted file]
src/native/include/java_lang_VMThread.h [deleted file]
src/native/include/java_lang_VMThrowable.h [deleted file]
src/native/include/java_util_Properties.h [deleted file]
src/native/jni.c
src/native/jni.h
src/native/native.c
src/native/native.h
src/native/vm/gnu/gnu_classpath_VMStackWalker.c
src/native/vm/gnu/gnu_classpath_VMSystemProperties.c
src/native/vm/gnu/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c
src/native/vm/gnu/gnu_java_lang_management_VMMemoryMXBeanImpl.c
src/native/vm/gnu/gnu_java_lang_management_VMRuntimeMXBeanImpl.c
src/native/vm/gnu/gnu_java_lang_management_VMThreadMXBeanImpl.c
src/native/vm/gnu/java_lang_VMClass.c
src/native/vm/gnu/java_lang_VMClassLoader.c
src/native/vm/gnu/java_lang_VMRuntime.c
src/native/vm/gnu/java_lang_VMThread.c
src/native/vm/gnu/java_lang_VMThrowable.c
src/native/vm/gnu/java_lang_management_VMManagementFactory.c
src/native/vm/gnu/java_lang_reflect_Constructor.c
src/native/vm/gnu/java_lang_reflect_Field.c
src/native/vm/gnu/java_lang_reflect_Method.c
src/native/vm/gnu/java_security_VMAccessController.c
src/native/vm/java_lang_Class.c
src/native/vm/java_lang_Object.c
src/native/vm/java_lang_Thread.c
src/threads/native/lock.c
src/threads/native/threads.c
src/threads/native/threads.h
src/threads/none/lock.h
src/threads/none/threads.h
src/toolbox/Makefile.am
src/toolbox/avl.c
src/toolbox/hashtable.c [new file with mode: 0644]
src/toolbox/hashtable.h [new file with mode: 0644]
src/toolbox/list.c
src/toolbox/logging.c
src/toolbox/logging.h
src/vm/Makefile.am
src/vm/access.c
src/vm/access.h
src/vm/annotation.c [deleted file]
src/vm/annotation.h [deleted file]
src/vm/builtin.c
src/vm/builtin.h
src/vm/class.c [deleted file]
src/vm/class.h [deleted file]
src/vm/classcache.c [deleted file]
src/vm/classcache.h [deleted file]
src/vm/descriptor.c [deleted file]
src/vm/descriptor.h [deleted file]
src/vm/exceptions.c
src/vm/exceptions.h
src/vm/field.c [deleted file]
src/vm/field.h [deleted file]
src/vm/finalizer.c
src/vm/hashtable.c [deleted file]
src/vm/hashtable.h [deleted file]
src/vm/initialize.c
src/vm/initialize.h
src/vm/jit/abi.h
src/vm/jit/allocator/simplereg.c
src/vm/jit/asmpart.h
src/vm/jit/code.c
src/vm/jit/code.h
src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/dseg.c
src/vm/jit/dseg.h
src/vm/jit/emit-common.c
src/vm/jit/jit.c
src/vm/jit/jit.h
src/vm/jit/loop/graph.h
src/vm/jit/loop/loop.h
src/vm/jit/optimizing/ifconv.c
src/vm/jit/optimizing/ifconv.h
src/vm/jit/optimizing/profile.c
src/vm/jit/optimizing/recompile.c
src/vm/jit/parse.c
src/vm/jit/powerpc/codegen.c
src/vm/jit/powerpc/emit.c
src/vm/jit/powerpc/linux/md-abi.c
src/vm/jit/powerpc/md.c
src/vm/jit/powerpc/patcher.c
src/vm/jit/show.c
src/vm/jit/stack.c
src/vm/jit/stacktrace.c
src/vm/jit/stacktrace.h
src/vm/jit/tools/genoffsets.c
src/vm/jit/verify/typecheck-stackbased.c
src/vm/jit/verify/typecheck-typeinferer.c
src/vm/jit/verify/typecheck.c
src/vm/jit/verify/typeinfo.c
src/vm/jit/verify/typeinfo.h
src/vm/linker.c [deleted file]
src/vm/linker.h [deleted file]
src/vm/loader.c [deleted file]
src/vm/loader.h [deleted file]
src/vm/method.c [deleted file]
src/vm/method.h [deleted file]
src/vm/options.c [deleted file]
src/vm/options.h [deleted file]
src/vm/properties.c
src/vm/properties.h
src/vm/references.h [deleted file]
src/vm/resolve.c [deleted file]
src/vm/resolve.h [deleted file]
src/vm/rt-timing.c [deleted file]
src/vm/rt-timing.h [deleted file]
src/vm/signal.c
src/vm/signallocal.h
src/vm/stackmap.c [deleted file]
src/vm/stackmap.h [deleted file]
src/vm/statistics.c [deleted file]
src/vm/statistics.h [deleted file]
src/vm/string.c
src/vm/stringlocal.h
src/vm/suck.c [deleted file]
src/vm/suck.h [deleted file]
src/vm/utf8.c [deleted file]
src/vm/utf8.h [deleted file]
src/vm/vm.c
src/vm/zip.c [deleted file]
src/vm/zip.h [deleted file]
src/vmcore/.cvsignore [new file with mode: 0644]
src/vmcore/Makefile.am [new file with mode: 0644]
src/vmcore/annotation.c [new file with mode: 0644]
src/vmcore/annotation.h [new file with mode: 0644]
src/vmcore/class.c [new file with mode: 0644]
src/vmcore/class.h [new file with mode: 0644]
src/vmcore/classcache.c [new file with mode: 0644]
src/vmcore/classcache.h [new file with mode: 0644]
src/vmcore/descriptor.c [new file with mode: 0644]
src/vmcore/descriptor.h [new file with mode: 0644]
src/vmcore/field.c [new file with mode: 0644]
src/vmcore/field.h [new file with mode: 0644]
src/vmcore/linker.c [new file with mode: 0644]
src/vmcore/linker.h [new file with mode: 0644]
src/vmcore/loader.c [new file with mode: 0644]
src/vmcore/loader.h [new file with mode: 0644]
src/vmcore/method.c [new file with mode: 0644]
src/vmcore/method.h [new file with mode: 0644]
src/vmcore/options.c [new file with mode: 0644]
src/vmcore/options.h [new file with mode: 0644]
src/vmcore/references.h [new file with mode: 0644]
src/vmcore/resolve.c [new file with mode: 0644]
src/vmcore/resolve.h [new file with mode: 0644]
src/vmcore/rt-timing.c [new file with mode: 0644]
src/vmcore/rt-timing.h [new file with mode: 0644]
src/vmcore/stackmap.c [new file with mode: 0644]
src/vmcore/stackmap.h [new file with mode: 0644]
src/vmcore/statistics.c [new file with mode: 0644]
src/vmcore/statistics.h [new file with mode: 0644]
src/vmcore/suck.c [new file with mode: 0644]
src/vmcore/suck.h [new file with mode: 0644]
src/vmcore/utf8.c [new file with mode: 0644]
src/vmcore/utf8.h [new file with mode: 0644]
src/vmcore/zip.c [new file with mode: 0644]
src/vmcore/zip.h [new file with mode: 0644]

index d40e88b9b8e22a2778202737e95b9160bab1248e..b7568ab3a19946f2194790c54daa6a4ed3d442d7 100644 (file)
@@ -22,7 +22,7 @@ dnl along with this program; if not, write to the Free Software
 dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 dnl 02110-1301, USA.
 dnl 
-dnl $Id: configure.ac 7241 2007-01-27 15:52:01Z twisti $
+dnl $Id: configure.ac 7246 2007-01-29 18:49:05Z twisti $
 
 dnl Process this file with autoconf to produce a configure script.
 
@@ -1066,13 +1066,14 @@ AC_CONFIG_FILES([Makefile]
                [src/vm/jit/powerpc/netbsd/Makefile]
                [src/vm/jit/powerpc64/Makefile]
                [src/vm/jit/powerpc64/linux/Makefile]
+               [src/vm/jit/s390/Makefile]
                [src/vm/jit/schedule/Makefile]
                [src/vm/jit/sparc64/Makefile]
                [src/vm/jit/sparc64/linux/Makefile]
                [src/vm/jit/tools/Makefile]
                [src/vm/jit/verify/Makefile]
                [src/vm/jit/x86_64/Makefile]
-               [src/vm/jit/s390/Makefile]
+               [src/vmcore/Makefile]
                [tests/Makefile]
                [tests/regression/Makefile]
                [tests/regression/codepatching/Makefile]
index d64def12fc745168d8fa3bf9336afad7b4a76e6c..a2f02acc172ac5a68bb9c1eea16fd0ed9e35c25e 100644 (file)
@@ -1,6 +1,6 @@
 ## src/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+## Copyright (C) 1996-2005, 2006, 2007 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
 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 ## 02110-1301, USA.
 ##
-## Contact: cacao@cacaojvm.org
-##
-## Authors: Christian Thalinger
-##
-## $Id: Makefile.am 6243 2006-12-27 13:56:31Z twisti $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
 DIST_SUBDIRS = \
-       mm \
-       lib \
+       cacao \
+       cacaoh \
        fdlibm \
+       lib \
+       mm \
+       native \
+       scripts \
+       threads \
        toolbox \
        vm \
-       threads \
-       cacaoh \
-       native \
-       cacao \
-       scripts
+       vmcore
 
 if WITH_CLASSPATH_GNU
 VM_DIR = \
        lib
 endif
 
-# Keep this order!!!
+# DON'T CHANGE THIS ORDER!!!
 
 SUBDIRS = \
-       mm \
-       $(VM_DIR) \
-       fdlibm \
        toolbox \
-       vm \
-       threads \
+       vmcore \
        cacaoh \
+       \
+       $(VM_DIR) \
        native \
+       fdlibm \
+       mm \
+       threads \
+       vm \
        cacao \
        scripts
 
index 51c3f728ae7c648a6960a8b98bebe9576fa2b945..8b0c55f270ecb4ce6d1ef0fcc8fca26c88f385a9 100644 (file)
@@ -1,6 +1,6 @@
 ## src/cacao/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+## Copyright (C) 1996-2005, 2006, 2007 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
 ##
 ## Contact: cacao@cacaojvm.org
 ##
-## Authors: Christian Thalinger
-##
-## Changes:
-##
-## $Id: Makefile.am 5884 2006-10-31 20:11:28Z twisti $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -109,6 +105,7 @@ libjvm_la_LIBADD = \
        $(top_builddir)/src/native/libnative.la \
        $(top_builddir)/src/toolbox/libtoolbox.la \
        $(top_builddir)/src/vm/libvm.la \
+       $(top_builddir)/src/vmcore/libvmcore.la \
        $(GC_LIB) \
        $(THREAD_LIB)
 
index 85b18f932c9c4e596363465d32553fffc8ac7df9..5e2e8136ff684ed5405dacd2fd0a168cd78ca67c 100644 (file)
@@ -1,6 +1,6 @@
 ## src/cacaoh/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+## Copyright (C) 1996-2005, 2006, 2007 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
 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 ## 02110-1301, USA.
 ##
-## Contact: cacao@cacaojvm.org
-##
-## Authors: Christian Thalinger
-##
-## Changes:
-##
-## $Id: Makefile.am 5884 2006-10-31 20:11:28Z twisti $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
 AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR)
 
-if ENABLE_THREADS
-THREAD_LIB = \
-       $(top_builddir)/src/threads/native/libthreads.la
-endif
-
 if ENABLE_RT_TIMING
 cacaoh_LDFLAGS = -lrt
 endif
@@ -47,24 +36,22 @@ noinst_LTLIBRARIES = \
        libcacaoh.la
 
 libcacaoh_la_SOURCES = \
+       dummy.c \
        headers.c \
        headers.h
 
 libcacaoh_la_LIBADD = \
-       $(top_builddir)/src/mm/libmm.la \
-       $(THREAD_LIB) \
        $(top_builddir)/src/toolbox/libtoolbox.la \
-       $(top_builddir)/src/vm/libvmcore.la
+       $(top_builddir)/src/vmcore/libvmcore.la
 
-noinst_PROGRAMS = cacaoh
+noinst_PROGRAMS = \
+       cacaoh
 
 cacaoh_SOURCES = \
        cacaoh.c
 
 cacaoh_LDADD = \
-       libcacaoh.la \
-       $(top_builddir)/src/fdlibm/libfdlibm.la \
-       $(GC_LIB)
+       libcacaoh.la
 
 cacaoh_DEPENDENCIES = \
        $(cacaoh_LDADD)
index 5a64b73fb8ae2c315536444d477c26273f32c0e3..757c14450ef2dc7de59387212c36688aa4d0b21a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/cacaoh/cacaoh.c - main for header generation (cacaoh)
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Mark Probst
-            Philipp Tomsich
-            Christian Thalinger
-
-   $Id: cacaoh.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: cacaoh.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "cacaoh/headers.h"
+
 #include "mm/gc-common.h"
 #include "mm/memory.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
-
+#include "toolbox/hashtable.h"
 #include "toolbox/logging.h"
-#include "vm/classcache.h"
+
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
-#include "vm/suck.h"
+#include "vm/vm.h"
+
+#include "vmcore/classcache.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+#include "vmcore/suck.h"
 
 
 /* define heap sizes **********************************************************/
@@ -99,7 +92,7 @@ opt_struct opts[] = {
 
 *******************************************************************************/
 
-static void usage(void)
+void usage(void)
 {
        printf("Usage: cacaoh [options] <classes>\n"
                   "\n"
@@ -126,7 +119,7 @@ static void usage(void)
 static void version(void)
 {
        printf("cacaoh version "VERSION"\n");
-       printf("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,\n");
+       printf("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,\n");
        printf("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,\n");
        printf("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,\n");
        printf("J. Wenninger, Institut f. Computersprachen - TU Wien\n\n");
@@ -148,7 +141,6 @@ static void version(void)
 /* forward declarations *******************************************************/
 
 static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv);
-static void cacaoh_abort(const char *text, ...);
 
 
 /* main ************************************************************************
@@ -282,41 +274,24 @@ int main(int argc, char **argv)
                log_init(NULL);
                log_println("Java - header-generator started"); 
        }
-       
-#if defined(ENABLE_THREADS)
-       /* pre-initialize some core thread stuff, like the stopworldlock,
-          thus this has to happen _before_ gc_init()!!! */
-
-       threads_preinit();
-#endif
-
-       /* initialize the garbage collector */
-
-       gc_init(heapmaxsize, heapstartsize);
-
-       /* initialize the string hashtable stuff: lock (must be done
-          _after_ threads_preinit) */
-
-       if (!string_init())
-               cacaoh_abort("string_init failed\n");
 
        /* initialize the utf8 hashtable stuff: lock, often used utf8 strings
           (must be done _after_ threads_preinit) */
 
        if (!utf8_init())
-               cacaoh_abort("utf8_init failed\n");
+               vm_abort("utf8_init failed\n");
 
        /* initialize the classcache hashtable stuff: lock, hashtable
           (must be done _after_ threads_preinit) */
 
        if (!classcache_init())
-               cacaoh_abort("classcache_init failed\n");
+               vm_abort("classcache_init failed\n");
 
        /* initialize the loader with bootclasspath (must be done _after_
           thread_preinit) */
 
        if (!suck_init())
-               cacaoh_abort("suck_init failed\n");
+               vm_abort("suck_init failed\n");
 
        suck_add(bootclasspath);
 
@@ -329,7 +304,7 @@ int main(int argc, char **argv)
        classcache_init) */
 
        if (!loader_init())
-               cacaoh_abort("loader_init failed\n");
+               vm_abort("loader_init failed\n");
 
 
        /* load Java classes ******************************************************/
@@ -353,10 +328,10 @@ int main(int argc, char **argv)
                /* exceptions are catched with new_exception call */
 
                if (!(c = load_class_bootstrap(utf_new_char(cp))))
-                       cacaoh_abort("java.lang.NoClassDefFoundError: %s\n", cp);
+                       vm_abort("java.lang.NoClassDefFoundError: %s\n", cp);
 
                if (!link_class(c))
-                       cacaoh_abort("java.lang.LinkageError: %s\n", cp);
+                       vm_abort("java.lang.LinkageError: %s\n", cp);
 
                headerfile_generate(c, opt_directory);
        }
@@ -368,7 +343,7 @@ int main(int argc, char **argv)
        if (opt_verbose) {
                log_println("Java - header-generator stopped");
 #if defined(ENABLE_STATISTICS)
-               mem_usagelog(true);
+               statistics_print_memory_usage();
 #endif
        }
        
@@ -399,32 +374,6 @@ static JavaVMInitArgs *cacaoh_options_prepare(int argc, char **argv)
 }
 
 
-/* cacaoh_abort ****************************************************************
-
-   Prints an error message and aborts the VM.
-
-*******************************************************************************/
-
-static void cacaoh_abort(const char *text, ...)
-{
-       va_list ap;
-
-       /* print the log message */
-
-       log_start();
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-
-       log_finish();
-
-       /* now abort the VM */
-
-       abort();
-}
-
-
 /*
  * 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
diff --git a/src/cacaoh/dummy.c b/src/cacaoh/dummy.c
new file mode 100644 (file)
index 0000000..bd5b34c
--- /dev/null
@@ -0,0 +1,497 @@
+/* src/cacaoh/dummy.c - dummy functions for cacaoh
+
+   Copyright (C) 2007 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.
+
+   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.
+
+   $Id: headers.c 6286 2007-01-10 10:03:38Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "toolbox/logging.h"
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vm/vm.h"
+
+#include "vm/jit/code.h"
+
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/utf8.h"
+
+
+/* global variables ***********************************************************/
+
+char *_Jv_bootclasspath;
+
+
+void compiler_lock()
+{
+}
+
+void compiler_unlock()
+{
+}
+
+java_objectheader *javastring_new_slash_to_dot(utf *u)
+{
+       vm_abort("javastring_new_slash_to_dot");
+
+       return NULL;
+}
+
+
+/* access *********************************************************************/
+
+bool access_is_accessible_class(classinfo *referer, classinfo *cls)
+{
+       return true;
+}
+
+bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
+                                                                s4 memberflags)
+{
+       vm_abort("access_is_accessible_member");
+
+       return true;
+}
+
+
+/* asm ************************************************************************/
+
+void asm_abstractmethoderror(void)
+{
+       abort();
+}
+
+
+/* builtin ********************************************************************/
+
+java_objectheader *builtin_clone(void *env, java_objectheader *o)
+{
+       abort();
+}
+
+s4 builtin_isanysubclass(classinfo *sub, classinfo *super)
+{
+       abort();
+}
+
+java_objectheader *builtin_new(classinfo *c)
+{
+       abort();
+}
+
+
+/* code ***********************************************************************/
+
+void code_free_code_of_method(methodinfo *m)
+{
+}
+
+
+/* codegen ********************************************************************/
+
+codeinfo *codegen_createnativestub(functionptr f, methodinfo *m)
+{
+       return NULL;
+}
+
+u1 *createcompilerstub(methodinfo *m)
+{
+       return NULL;
+}
+
+#if defined(ENABLE_INTRP)
+u1 *intrp_createcompilerstub(methodinfo *m)
+{
+       return NULL;
+}
+#endif
+
+void removecompilerstub(u1 *stub)
+{
+}
+
+void removenativestub(u1 *stub)
+{
+}
+
+
+/* exceptions *****************************************************************/
+
+void exceptions_clear_exception(void)
+{
+}
+
+void exceptions_print_current_exception(void)
+{
+}
+
+void exceptions_throw_abstractmethoderror(void)
+{
+       fprintf(stderr, "java.lang.AbstractMethodError\n");
+
+       abort();
+}
+
+void exceptions_throw_classcircularityerror(classinfo *c)
+{
+       fprintf(stderr, "java.lang.ClassCircularityError: ");
+
+       utf_display_printable_ascii(c->name);
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "java.lang.ClassFormatError: ");
+
+       utf_display_printable_ascii(c->name);
+       fprintf(stderr, ": ");
+
+       va_start(ap, message);
+       vfprintf(stderr, message, ap);
+       va_end(ap);
+
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c)
+{
+       fprintf(stderr, "java.lang.IncompatibleClassChangeError: ");
+
+       if (c != NULL)
+               utf_fprint_printable_ascii_classname(stderr, c->name);
+
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_internalerror(const char *message, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "java.lang.InternalError: ");
+
+       va_start(ap, message);
+       vfprintf(stderr, message, ap);
+       va_end(ap);
+
+       abort();
+}
+
+void exceptions_throw_linkageerror(const char *message, classinfo *c)
+{
+       fprintf(stderr, "java.lang.LinkageError: %s", message);
+
+       if (c != NULL)
+               utf_fprint_printable_ascii_classname(stderr, c->name);
+
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_noclassdeffounderror(utf *name)
+{
+       fprintf(stderr, "java.lang.NoClassDefFoundError: ");
+       utf_fprint_printable_ascii(stderr, name);
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_outofmemoryerror(void)
+{
+       fprintf(stderr, "java.lang.OutOfMemoryError\n");
+
+       abort();
+}
+
+void exceptions_throw_verifyerror(methodinfo *m, const char *message)
+{
+       fprintf(stderr, "java.lang.VerifyError: ");
+       utf_fprint_printable_ascii(stderr, m->name);
+       fprintf(stderr, ": %s", message);
+
+       abort();
+}
+
+void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
+{
+       fprintf(stderr, "java.lang.NoSuchFieldError: ");
+       utf_fprint_printable_ascii(stderr, c->name);
+       fprintf(stderr, ".");
+       utf_fprint_printable_ascii(stderr, name);
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
+{
+       fprintf(stderr, "java.lang.NoSuchMethodError: ");
+       utf_fprint_printable_ascii(stderr, c->name);
+       fprintf(stderr, ".");
+       utf_fprint_printable_ascii(stderr, name);
+       utf_fprint_printable_ascii(stderr, desc);
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_unsupportedclassversionerror(classinfo *c,
+                                                                                                  const char *message, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "java.lang.UnsupportedClassVersionError: " );
+
+       utf_display_printable_ascii(c->name);
+       fprintf(stderr, ": ");
+
+       va_start(ap, message);
+       vfprintf(stderr, message, ap);
+       va_end(ap);
+
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_illegalaccessexception(classinfo *c)
+{
+       fprintf(stderr, "java.lang.IllegalAccessException: ");
+
+       if (c != NULL)
+               utf_fprint_printable_ascii_classname(stderr, c->name);
+
+       fputc('\n', stderr);
+
+       abort();
+}
+
+void exceptions_throw_nullpointerexception(void)
+{
+       fprintf(stderr, "java.lang.NullPointerException\n");
+
+       abort();
+}
+
+void classnotfoundexception_to_noclassdeffounderror(void)
+{
+       /* Can that one happen? */
+
+       abort();
+}
+
+
+/* finalizer ******************************************************************/
+
+void finalizer_notify(void)
+{
+       vm_abort("finalizer_notify");
+}
+
+void finalizer_run(void *o, void *p)
+{
+       vm_abort("finalizer_run");
+}
+
+
+/* heap ***********************************************************************/
+
+void *heap_alloc_uncollectable(u4 bytelength)
+{
+       return calloc(bytelength, 1);
+}
+
+
+/* jit ************************************************************************/
+
+void jit_invalidate_code(methodinfo *m)
+{
+       vm_abort("jit_invalidate_code");
+}
+
+
+/* lock ***********************************************************************/
+
+void lock_init_object_lock(java_objectheader *o)
+{
+}
+
+bool lock_monitor_enter(java_objectheader *o)
+{
+       return true;
+}
+
+bool lock_monitor_exit(java_objectheader *o)
+{
+       return true;
+}
+
+
+/* md *************************************************************************/
+
+void md_param_alloc(methoddesc *md)
+{
+}
+
+
+/* memory *********************************************************************/
+
+void *mem_alloc(s4 size)
+{
+       return malloc(size);
+}
+
+void *mem_realloc(void *src, s4 len1, s4 len2)
+{
+       return realloc(src, len2);
+}
+
+void mem_free(void *m, s4 size)
+{
+       free(m);
+}
+
+void *dump_alloc(s4 size)
+{
+       return malloc(size);
+}
+
+void dump_release(s4 size)
+{
+}
+
+s4 dump_size(void)
+{
+       return 0;
+}
+
+
+/* properties *****************************************************************/
+
+char *properties_get(char *key)
+{
+       return NULL;
+}
+
+
+/* stacktrace *****************************************************************/
+
+java_objectarray *stacktrace_getClassContext()
+{
+       return NULL;
+}
+
+
+/* threads ********************************************************************/
+
+pthread_key_t threads_current_threadobject_key;
+
+
+/* typeinfo *******************************************************************/
+
+bool typeinfo_init_class(typeinfo *info, classref_or_classinfo c)
+{
+       return true;
+}
+
+void typeinfo_init_classinfo(typeinfo *info, classinfo *c)
+{
+}
+
+typecheck_result typeinfo_is_assignable_to_class(typeinfo *value, classref_or_classinfo dest)
+{
+       return typecheck_TRUE;
+}
+
+
+/* vm *************************************************************************/
+
+void vm_abort(const char *text, ...)
+{
+       va_list ap;
+
+       /* print the log message */
+
+       va_start(ap, text);
+       vfprintf(stderr, text, ap);
+       va_end(ap);
+
+       /* now abort the VM */
+
+       abort();
+}
+
+java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
+{
+       return NULL;
+}
+
+
+/* XXX */
+
+void stringtable_update(void)
+{
+       log_println("stringtable_update: REMOVE ME!");
+}
+
+java_objectheader *literalstring_new(utf *u)
+{
+       log_println("literalstring_new: REMOVE ME!");
+
+       return NULL;
+}
+
+
+/*
+ * 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:
+ */
index 1aee589588388ef0b07b8c7f7be9bf38e44a8b6d..4d779ed437340d3cc53bff0869210e338498724f 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: headers.c 7228 2007-01-19 01:13:48Z edwin $
+   $Id: headers.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "mm/gc-common.h"
 #include "mm/memory.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
+
 #include "toolbox/chain.h"
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/global.h"
-#include "vm/method.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
-#include "vm/jit/asmpart.h"
-
-
-/* Invocation API variables ***************************************************/
-
-_Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
-char       *_Jv_bootclasspath;
-
-char       *cacao_prefix;
-char       *classpath_libdir;
-
-char       *_Jv_classpath;
-char       *_Jv_java_library_path;
-
-#if defined(ENABLE_INTRP)
-/* dummy interpreter stack to keep the compiler happy */
-
-u1 *intrp_main_stack;
-#endif
-
-
-/* for raising exceptions from native methods *********************************/
-
-#if !defined(ENABLE_THREADS)
-java_objectheader *_no_threads_exceptionptr = NULL;
-#endif
-
-
-/* replace some non-vmcore functions ******************************************/
-
-functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
-                                                               bool isstatic)
-{
-       /* return something different than NULL, otherwise we get an exception */
-
-       return (functionptr) 1;
-}
-
-java_objectheader *native_new_and_init(classinfo *c) { return NULL; }
-java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) { return NULL; }
-java_objectheader *native_new_and_init_int(classinfo *c, s4 i) { return NULL; }
-java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t) { return NULL; }
-
-
-java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
-{ return NULL; }
-
-void vm_abort(const char *text, ...)
-{
-       va_list ap;
-
-       /* print the log message */
-
-       va_start(ap, text);
-       vfprintf(stderr, text, ap);
-       va_end(ap);
-
-       /* now abort the VM */
-
-       abort();
-}
-
-/* code patching functions */
-void patcher_builtin_arraycheckcast(u1 *sp) {}
-
-
-long compare_and_swap(volatile long *p, long oldval, long newval)
-{
-       if (*p == oldval) {
-        *p = newval;
-        return oldval;
-       }
-       else
-        return *p;
-
-       return oldval;
-}
-
-long asm_compare_and_swap(volatile long *p, long oldval, long newval)
-{
-       if (*p == oldval) {
-        *p = newval;
-        return oldval;
-       }
-       else
-        return *p;
-
-       return oldval;
-}
-
-void asm_memory_barrier(void)
-{
-}
-
-
-u1 *createcompilerstub(methodinfo *m) { return NULL; }
-#if defined(ENABLE_INTRP)
-u1 *intrp_createcompilerstub(methodinfo *m) { return NULL; }
-#endif
-
-codeinfo *codegen_createnativestub(functionptr f, methodinfo *m) { return NULL; }
-
-void removecompilerstub(u1 *stub) {}
-void removenativestub(u1 *stub) {}
-
-void asm_perform_threadswitch(u1 **from, u1 **to, u1 **stackTop) {}
-u1* asm_initialize_thread_stack(void *func, u1 *stack) { return NULL; }
-
-void *asm_switchstackandcall(void *stack, void *func, void **stacktopsave, void * p) { return NULL; }
-
-void asm_handle_builtin_exception(classinfo *c) {}
-
-#if defined(ENABLE_JIT)
-void asm_abstractmethoderror(void) {}
-void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out) {}
-#endif
-
-#if defined(ENABLE_INTRP)
-void intrp_asm_abstractmethoderror(void) {}
-void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out) {}
-#endif
-
-u8 asm_get_cycle_count(void)
-{
-       return 0;
-}
-
-
-void *Java_java_lang_VMObject_clone(void *env, void *clazz, void * this)
-{
-       return NULL;
-}
-
-typecheck_result typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
-{
-       return typecheck_TRUE;
-}
-
-void typeinfo_init_classinfo(typeinfo *info,classinfo *c)
-{
-}
-
-bool typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
-{
-       return true;
-}
-
-void typeinfo_print(FILE *file,typeinfo *info,int indent) {}
-void typeinfo_print_short(FILE *file,typeinfo *info) {}
-
-void exceptions_print_exception(java_objectheader *xptr) {}
-void stacktrace_dump_trace(threadobject *thread) {}
-void stacktrace_print_trace(java_objectheader *xptr) {}
-java_objectarray *stacktrace_getClassContext() { return NULL; }
-void code_free_code_of_method(methodinfo *m) {}
-
-void jit_invalidate_code(methodinfo *m) {}
-
-
-/* exception functions ********************************************************/
-
-/* these should not be called */
-
-void throw_main_exception_exit(void) { assert(0); }
-void throw_exception(void) { assert(0); }
-void throw_exception_exit(void) { assert(0); }
-
-void exceptions_throw_verifyerror(methodinfo *m, const char *message)
-{
-       assert(0);
-}
-
-java_objectheader *new_exception_throwable(const char *classname, java_lang_Throwable *throwable)
-{
-       assert(0);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *new_exception(const char *classname)
-{
-       fprintf(stderr, "%s\n", classname);
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *new_exception_message(const char *classname, const char *message)
-{
-       fprintf(stderr, "%s: %s\n", classname, message);
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
-{
-       fprintf(stderr, "%s: ", classname);
-       utf_display_printable_ascii(message);
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *new_exception_javastring(const char *classname,
-                                                                                       java_lang_String *message)
-{
-       fprintf(stderr, "%s: ", classname);
-       /* TODO print message */
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_abstractmethoderror(void)
-{
-       fprintf(stderr, "java.lang.AbstractMethodError\n");
-
-       exit(1);
-}
-
-
-java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
-{
-       va_list ap;
-
-       utf_display_printable_ascii(c->name);
-       fprintf(stderr, ": ");
-
-       va_start(ap, message);
-       vfprintf(stderr, message, ap);
-       va_end(ap);
-
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
-{
-       va_list ap;
-
-       va_start(ap, message);
-       (void) new_classformaterror(c, message, ap);
-       va_end(ap);
-}
-
-
-java_objectheader *new_classnotfoundexception(utf *name)
-{
-       fprintf(stderr, "java.lang.ClassNotFoundException: ");
-       utf_fprint_printable_ascii(stderr, name);
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *new_noclassdeffounderror(utf *name)
-{
-       fprintf(stderr, "java.lang.NoClassDefFoundError: ");
-       utf_fprint_printable_ascii(stderr, name);
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *exceptions_new_linkageerror(const char *message,
-                                                                                          classinfo *c)
-{
-       fprintf(stderr, "java.lang.LinkageError: %s",message);
-       if (c) {
-               utf_fprint_printable_ascii_classname(stderr, c->name);
-       }
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
-                                                                                                       utf *name, utf *desc)
-{
-       fprintf(stderr, "java.lang.NoSuchMethodError: ");
-       utf_fprint_printable_ascii(stderr, c->name);
-       fprintf(stderr, ".");
-       utf_fprint_printable_ascii(stderr, name);
-       utf_fprint_printable_ascii(stderr, desc);
-       fputc('\n', stderr);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
-{
-       (void) exceptions_new_nosuchmethoderror(c, name, desc);
-}
-
-
-void exceptions_throw_internalerror(const char *message, ...)
-{
-       va_list ap;
-
-       fprintf(stderr, "%s: ", string_java_lang_InternalError);
-
-       va_start(ap, message);
-       vfprintf(stderr, message, ap);
-       va_end(ap);
-
-       exit(1);
-}
-
-
-void exceptions_throw_outofmemoryerror(void)
-{
-       fprintf(stderr, "%s", string_java_lang_OutOfMemoryError);
-       exit(1);
-}
-
-
-java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
-{
-       va_list ap;
-
-       fprintf(stderr, "%s: ", string_java_lang_UnsupportedClassVersionError);
-
-       utf_display_printable_ascii(c->name);
-       fprintf(stderr, ": ");
-
-       va_start(ap, message);
-       vfprintf(stderr, message, ap);
-       va_end(ap);
-
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_virtualmachineerror(void)
-{
-       fprintf(stderr, "%s", string_java_lang_VirtualMachineError);
-       exit(1);
-}
-
-
-void exceptions_throw_arrayindexoutofboundsexception(void)
-{
-       fprintf(stderr, "%s", string_java_lang_ArrayIndexOutOfBoundsException);
-       exit(1);
-}
-
-
-java_objectheader *exceptions_new_arraystoreexception(void)
-{
-       fprintf(stderr, "%s", string_java_lang_ArrayStoreException);
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_arraystoreexception(void)
-{
-       (void) exceptions_new_arraystoreexception();
-}
-
-
-java_objectheader *exceptions_throw_illegalmonitorstateexception(void)
-{
-       fprintf(stderr, "%s", string_java_lang_IllegalMonitorStateException);
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-java_objectheader *new_negativearraysizeexception(void)
-{
-       fprintf(stderr, "%s", string_java_lang_NegativeArraySizeException);
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_negativearraysizeexception(void)
-{
-       (void) new_negativearraysizeexception();
-}
-
-
-java_objectheader *exceptions_new_nullpointerexception(void)
-{
-       fprintf(stderr, "%s", string_java_lang_NullPointerException);
-       exit(1);
-
-       /* keep compiler happy */
-
-       return NULL;
-}
-
-
-void exceptions_throw_nullpointerexception(void)
-{
-       (void) exceptions_new_nullpointerexception();
-}
-
-
-void classnotfoundexception_to_noclassdeffounderror(void)
-{
-}
-
-/* machine dependent stuff ****************************************************/
-
-#if defined(ENABLE_THREADS)
-critical_section_node_t asm_criticalsections;
-void thread_restartcriticalsection(ucontext_t *uc) {}
-#endif
-
-void md_param_alloc(methoddesc *md) {}
 
+#include "vm/jit/asmpart.h"
 
-#if defined(ENABLE_INTRP)
-void print_dynamic_super_statistics(void) {}
-#endif
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
 
 
 /************************ global variables **********************/
@@ -942,15 +470,6 @@ void print_classname(classinfo *clazz)
        }
 } 
 
-/* jvmti releated functions ************************************************/
-
-#if defined(ENABLE_JVMTI)
-void jvmti_ThreadStartEnd(int ev) {;}
-void jvmti_ClassLoadPrepare(bool prepared, classinfo *c) {;}
-void jvmti_MonitorContendedEntering(bool entered, jobject obj) {;}
-#endif
-
-
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 7bb7c6c9ec7036801692e56ac9d3d86b7d52862b..e12c74de128d032cb29f8096cac2baa6366f253b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/cacaoh/headers.h - export functions for header generation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: headers.h 5123 2006-07-12 21:45:34Z twisti $
+   $Id: headers.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "config.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
-
 #include "toolbox/chain.h"
-#include "vm/class.h"
+
 #include "vm/global.h"
-#include "vm/method.h"
-#include "vm/utf8.h"
+
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/utf8.h"
 
 
 /* export variables ***********************************************************/
 
-extern THREADSPECIFIC java_objectheader *_exceptionptr;
+extern java_objectheader *_exceptionptr;
 extern chain *nativemethod_chain;
 extern chain *nativeclass_chain;
 extern chain *ident_chain;
index 8ef863bb26602046df61e2f37c444f9b374e17d7..ab39ff1eed9963b03ae5f0d62e347a126883d14a 100644 (file)
@@ -1,6 +1,6 @@
 ## src/mm/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+## Copyright (C) 1996-2005, 2006, 2007 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
 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 ## 02110-1301, USA.
 ##
-## Contact: cacao@cacaojvm.org
-##
-## Authors: Christian Thalinger
-##
-## Changes:
-##
-## $Id: Makefile.am 5900 2006-11-04 17:30:44Z michi $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
index c85a539506e1c2706567754c0656dc1fc42df6dd..7201aa2bad9e98a27a21ed033fdbb0cd0ec10cef 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Stefan Ring
-            Christian Thalinger
-
-   $Id: boehm.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: boehm.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #endif
 
 #include "toolbox/logging.h"
-#include "vm/options.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/finalizer.h"
 #include "vm/global.h"
-#include "vm/loader.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
 
 /* global variables ***********************************************************/
 
index 732a98a7a4eed941e1d9a8fb926f938cfa892531..431f58d7b78dd7fd259b9ed58e1632cee44aafb4 100644 (file)
@@ -1,6 +1,6 @@
 /* src/mm/gc-common.h - gc independant interface for heap managment
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: gc-common.h 6054 2006-11-27 14:37:57Z michi $
+   $Id: gc-common.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -37,7 +33,9 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "vm/method.h"
+#include "vm/global.h"
+
+#include "vmcore/method.h"
 
 
 /* function prototypes ********************************************************/
index 29ccae17949fb13f16c3d22d185e62e9243cf829..1f61736368a85fc9a4da2b7c345d642db93dc704 100644 (file)
@@ -1,6 +1,6 @@
-/* src/mm/memory.c - 
+/* src/mm/memory.c - memory management
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: memory.c 7205 2007-01-11 22:36:29Z twisti $
+   $Id: memory.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "toolbox/logging.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
 
 
 /* constants for ENABLE_MEMCHECK **********************************************/
index 585de125a1d34843c65ded4afdc4d36f9fff2e34..4da573e9a64972bb9a88512419ea324bb299c1ca 100644 (file)
 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 ## 02110-1301, USA.
 ##
-## $Id: Makefile.am 7235 2007-01-22 17:22:28Z twisti $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
-NO_GEN_HEADER_FILES = \
+COMMON_HEADER_FILES = \
        java_lang_Class.h \
        java_lang_Object.h \
        java_lang_String.h \
        java_lang_Thread.h \
-       java_lang_Throwable.h
-
-NO_GEN_JAVASE_HEADER_FILES = \
-       java_lang_ClassLoader.h \
-       java_lang_Cloneable.h \
-       java_lang_ThreadGroup.h \
-       java_lang_VMThread.h \
-       java_lang_VMThrowable.h \
-       java_util_Properties.h
-
-COMMON_HEADER_FILES = \
+       java_lang_Throwable.h \
+       \
        java_io_InputStream.h \
        java_io_PrintStream.h \
        \
@@ -56,6 +47,13 @@ COMMON_HEADER_FILES = \
        java_util_Vector.h
 
 JAVASE_HEADER_FILES = \
+       java_lang_ClassLoader.h \
+       java_lang_Cloneable.h \
+       java_lang_ThreadGroup.h \
+       java_lang_VMThread.h \
+       java_lang_VMThrowable.h \
+       java_util_Properties.h \
+       \
        gnu_classpath_Pointer.h \
        gnu_classpath_Pointer32.h \
        gnu_classpath_Pointer64.h \
@@ -126,16 +124,10 @@ CLEANFILES = \
        $(ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES) \
        $(ADDITIONAL_STATIC_CLASSPATH_HEADER_FILES)
 
-noinst_HEADERS = \
-       $(NO_GEN_HEADER_FILES)
-
 DO_HEADER_FILES = \
        $(COMMON_HEADER_FILES)
 
 if ENABLE_JAVASE
-noinst_HEADERS += \
-       $(NO_GEN_JAVASE_HEADER_FILES)
-
 DO_HEADER_FILES += \
        $(JAVASE_HEADER_FILES) \
        $(ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES)
@@ -167,22 +159,11 @@ endif
 
 noinst_DATA = $(DO_HEADER_FILES)
 
-genall: $(NO_GEN_HEADER_FILES)
-
-$(NO_GEN_HEADER_FILES):
-       @class=`echo $@ | sed -e 's/\.h$$//' -e 's/_/\./g'`; \
-       echo "$(CACAOH) -bootclasspath $(CLASSPATH) -d . $$class"; \
-       $(CACAOH) -bootclasspath $(CLASSPATH) -d . $$class
-
 $(DO_HEADER_FILES): $(CACAOH) $(VM_ZIP) $(CLASSPATH_CLASSES)
        @class=`echo $@ | sed -e 's/\.h$$//' -e 's/_/\./g'`; \
        echo "$(CACAOH) -bootclasspath $(CLASSPATH) -d . $$class"; \
        $(CACAOH) -bootclasspath $(CLASSPATH) -d . $$class
 
-cleanall: clean
-       -rm -rf $(NO_GEN_HEADER_FILES)
-       -rm -rf $(NO_GEN_JAVASE_HEADER_FILES)
-
 
 ## Local variables:
 ## mode: Makefile
diff --git a/src/native/include/java_lang_Class.h b/src/native/include/java_lang_Class.h
deleted file mode 100644 (file)
index 653868a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_CLASS_H
-#define _JAVA_LANG_CLASS_H
-
-/* Structure information for class: java/lang/Class */
-
-typedef struct java_lang_Class {
-   java_objectheader header;
-   java_objectarray* signers;
-   struct java_security_ProtectionDomain* pd;
-   struct java_lang_Object* vmdata;
-   struct java_lang_reflect_Constructor* constructor;
-} java_lang_Class;
-
-#endif
-
diff --git a/src/native/include/java_lang_ClassLoader.h b/src/native/include/java_lang_ClassLoader.h
deleted file mode 100644 (file)
index 13cd74e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_CLASSLOADER_H
-#define _JAVA_LANG_CLASSLOADER_H
-
-/* Structure information for class: java/lang/ClassLoader */
-
-typedef struct java_lang_ClassLoader {
-   java_objectheader header;
-   struct java_util_HashMap* definedPackages;
-   struct java_lang_ClassLoader* parent;
-   s4 initialized;
-   s4 defaultAssertionStatus;
-   struct java_util_Map* packageAssertionStatus;
-   struct java_util_Map* classAssertionStatus;
-   struct java_lang_Object* vmdata;
-} java_lang_ClassLoader;
-
-#endif
-
diff --git a/src/native/include/java_lang_Cloneable.h b/src/native/include/java_lang_Cloneable.h
deleted file mode 100644 (file)
index b428f12..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_CLONEABLE_H
-#define _JAVA_LANG_CLONEABLE_H
-
-/* Structure information for class: java/lang/Cloneable */
-
-typedef struct java_lang_Cloneable {
-   java_objectheader header;
-} java_lang_Cloneable;
-
-#endif
-
diff --git a/src/native/include/java_lang_Object.h b/src/native/include/java_lang_Object.h
deleted file mode 100644 (file)
index d21904d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_OBJECT_H
-#define _JAVA_LANG_OBJECT_H
-
-/* Structure information for class: java/lang/Object */
-
-typedef struct java_lang_Object {
-   java_objectheader header;
-} java_lang_Object;
-
-#endif
-
diff --git a/src/native/include/java_lang_String.h b/src/native/include/java_lang_String.h
deleted file mode 100644 (file)
index cffb3da..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_STRING_H
-#define _JAVA_LANG_STRING_H
-
-/* Structure information for class: java/lang/String */
-
-typedef struct java_lang_String {
-   java_objectheader header;
-   java_chararray* value;
-   s4 count;
-   s4 cachedHashCode;
-   s4 offset;
-} java_lang_String;
-
-#endif
-
diff --git a/src/native/include/java_lang_Thread.h b/src/native/include/java_lang_Thread.h
deleted file mode 100644 (file)
index 1ad04c9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_THREAD_H
-#define _JAVA_LANG_THREAD_H
-
-/* Structure information for class: java/lang/Thread */
-
-typedef struct java_lang_Thread {
-   java_objectheader header;
-   struct java_lang_VMThread* vmThread;
-   struct java_lang_ThreadGroup* group;
-   struct java_lang_Runnable* runnable;
-   struct java_lang_String* name;
-   s4 daemon;
-   s4 priority;
-   s8 stacksize;
-   struct java_lang_Throwable* stillborn;
-   struct java_lang_ClassLoader* contextClassLoader;
-   s4 contextClassLoaderIsSystemClassLoader;
-   s8 threadId;
-   struct java_lang_Object* parkBlocker;
-   struct gnu_java_util_WeakIdentityHashMap* locals;
-   struct java_lang_Thread_UncaughtExceptionHandler* exceptionHandler;
-} java_lang_Thread;
-
-#endif
-
diff --git a/src/native/include/java_lang_ThreadGroup.h b/src/native/include/java_lang_ThreadGroup.h
deleted file mode 100644 (file)
index 6b419a1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_THREADGROUP_H
-#define _JAVA_LANG_THREADGROUP_H
-
-/* Structure information for class: java/lang/ThreadGroup */
-
-typedef struct java_lang_ThreadGroup {
-   java_objectheader header;
-   struct java_lang_ThreadGroup* parent;
-   struct java_lang_String* name;
-   struct java_util_Vector* threads;
-   struct java_util_Vector* groups;
-   s4 daemon_flag;
-   s4 maxpri;
-} java_lang_ThreadGroup;
-
-#endif
-
diff --git a/src/native/include/java_lang_Throwable.h b/src/native/include/java_lang_Throwable.h
deleted file mode 100644 (file)
index ad4b511..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_THROWABLE_H
-#define _JAVA_LANG_THROWABLE_H
-
-/* Structure information for class: java/lang/Throwable */
-
-typedef struct java_lang_Throwable {
-   java_objectheader header;
-   struct java_lang_String* detailMessage;
-   struct java_lang_Throwable* cause;
-   java_objectarray* stackTrace;
-   struct java_lang_VMThrowable* vmState;
-} java_lang_Throwable;
-
-#endif
-
diff --git a/src/native/include/java_lang_VMThread.h b/src/native/include/java_lang_VMThread.h
deleted file mode 100644 (file)
index 423f9c2..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_VMTHREAD_H
-#define _JAVA_LANG_VMTHREAD_H
-
-/* Structure information for class: java/lang/VMThread */
-
-typedef struct java_lang_VMThread {
-   java_objectheader header;
-   struct java_lang_Thread* thread;
-   s4 running;
-   struct java_lang_Object* vmdata;
-} java_lang_VMThread;
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    countStackFrames
- * Signature: ()I
- */
-JNIEXPORT s4 JNICALL Java_java_lang_VMThread_countStackFrames(JNIEnv *env, struct java_lang_VMThread* this);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    start
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_start(JNIEnv *env, struct java_lang_VMThread* this, s8 par1);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    interrupt
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, struct java_lang_VMThread* this);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    isInterrupted
- * Signature: ()Z
- */
-JNIEXPORT s4 JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, struct java_lang_VMThread* this);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    suspend
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_suspend(JNIEnv *env, struct java_lang_VMThread* this);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    resume
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_resume(JNIEnv *env, struct java_lang_VMThread* this);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    nativeSetPriority
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, struct java_lang_VMThread* this, s4 par1);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    nativeStop
- * Signature: (Ljava/lang/Throwable;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(JNIEnv *env, struct java_lang_VMThread* this, struct java_lang_Throwable* par1);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    currentThread
- * Signature: ()Ljava/lang/Thread;
- */
-JNIEXPORT struct java_lang_Thread* JNICALL Java_java_lang_VMThread_currentThread(JNIEnv *env, jclass clazz);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    yield
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(JNIEnv *env, jclass clazz);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    interrupted
- * Signature: ()Z
- */
-JNIEXPORT s4 JNICALL Java_java_lang_VMThread_interrupted(JNIEnv *env, jclass clazz);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    holdsLock
- * Signature: (Ljava/lang/Object;)Z
- */
-JNIEXPORT s4 JNICALL Java_java_lang_VMThread_holdsLock(JNIEnv *env, jclass clazz, struct java_lang_Object* par1);
-
-
-/*
- * Class:     java/lang/VMThread
- * Method:    getState
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT struct java_lang_String* JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, struct java_lang_VMThread* this);
-
-#endif
-
diff --git a/src/native/include/java_lang_VMThrowable.h b/src/native/include/java_lang_VMThrowable.h
deleted file mode 100644 (file)
index 49999fa..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_LANG_VMTHROWABLE_H
-#define _JAVA_LANG_VMTHROWABLE_H
-
-/* Structure information for class: java/lang/VMThrowable */
-
-typedef struct java_lang_VMThrowable {
-   java_objectheader header;
-   struct gnu_classpath_Pointer* vmData;
-   struct java_lang_Object* vmdata;
-} java_lang_VMThrowable;
-
-
-/*
- * Class:     java/lang/VMThrowable
- * Method:    fillInStackTrace
- * Signature: (Ljava/lang/Throwable;)Ljava/lang/VMThrowable;
- */
-JNIEXPORT struct java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackTrace(JNIEnv *env, jclass clazz, struct java_lang_Throwable* par1);
-
-
-/*
- * Class:     java/lang/VMThrowable
- * Method:    getStackTrace
- * Signature: (Ljava/lang/Throwable;)[Ljava/lang/StackTraceElement;
- */
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, struct java_lang_VMThrowable* this, struct java_lang_Throwable* par1);
-
-#endif
-
diff --git a/src/native/include/java_util_Properties.h b/src/native/include/java_util_Properties.h
deleted file mode 100644 (file)
index e71afc9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This file is machine generated, don't edit it! */
-
-#ifndef _JAVA_UTIL_PROPERTIES_H
-#define _JAVA_UTIL_PROPERTIES_H
-
-/* Structure information for class: java/util/Properties */
-
-typedef struct java_util_Properties {
-   java_objectheader header;
-   s4 threshold;
-   float loadFactor;
-   java_objectarray* buckets;
-   s4 modCount;
-   s4 size;
-   struct java_util_Set* keys;
-   struct java_util_Collection* values;
-   struct java_util_Set* entries;
-   struct java_util_Properties* defaults;
-} java_util_Properties;
-
-#endif
-
index 7d7864e50e42a43b8cb1bd0fd4a8c4f6f2d57d0b..742e0458906c68061339010803fd75b8c20d79c6 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/jni.c - implementation of the Java Native Interface functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Rainhard Grafl
-            Roman Obermaisser
-            Joseph Wenninger
-            Martin Platter
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: jni.c 6252 2006-12-27 23:42:37Z twisti $
+   $Id: jni.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -65,6 +56,7 @@
 #include "native/include/java_lang_Long.h"
 #include "native/include/java_lang_Float.h"
 #include "native/include/java_lang_Double.h"
+#include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
 #include "native/include/java_lang_reflect_Method.h"
 #include "native/include/java_lang_reflect_Constructor.h"
 #endif
 
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
+#include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
-#include "vm/statistics.h"
-#include "vm/vm.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+#include "vmcore/statistics.h"
 
 
 /* global variables ***********************************************************/
@@ -843,9 +837,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
           parameter is ignored. */
 
        if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -854,17 +846,15 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
        if (((params == NULL) && (paramcount != 0)) ||
                (params && (params->header.size != paramcount))) 
        {
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalArgumentException);
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
        /* for instance methods we need an object */
 
        if (!(m->flags & ACC_STATIC) && (o == NULL)) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NullPointerException,
-                                                                 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
+               /* XXX not sure if that is the correct exception */
+               exceptions_throw_nullpointerexception();
                return NULL;
        }
 
@@ -875,8 +865,8 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
        if (o != NULL) {
                /* for instance methods we must do a vftbl lookup */
                resm = method_vftbl_lookup(o->vftbl, m);
-
-       else {
+       }
+       else {
                /* for static methods, just for convenience */
                resm = m;
        }
@@ -1031,15 +1021,11 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
        if (*exceptionptr) {
                java_objectheader *cause;
 
-               cause = *exceptionptr;
-
                /* clear exception pointer, we are calling JIT code again */
 
-               *exceptionptr = NULL;
+               cause = exceptions_get_and_clear_exception();
 
-               *exceptionptr =
-                       new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
-                                                                       (java_lang_Throwable *) cause);
+               exceptions_throw_invocationtargetexception(cause);
        }
 
        return ro;
@@ -1225,7 +1211,7 @@ jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
        if (o == NULL)
                return -1;
 
-       *exceptionptr = (java_objectheader *) o;
+       exceptions_set_exception(o);
 
        return 0;
 }
@@ -1318,7 +1304,9 @@ void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
 {
        STATISTICS(jniinvokation());
 
-       throw_cacao_exception_exit(string_java_lang_InternalError, msg);
+       /* this seems to be the best way */
+
+       vm_abort(msg);
 }
 
 
@@ -1590,9 +1578,7 @@ jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
        c = (classinfo *) clazz;
 
        if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_InstantiationException,
-                                                                        c->name);
+               exceptions_throw_instantiationexception(c);
                return NULL;
        }
                
@@ -2876,19 +2862,22 @@ void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
 jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
                                                        const char *sig) 
 {
+       classinfo *c;
        fieldinfo *f;
        utf       *uname;
        utf       *udesc;
 
        STATISTICS(jniinvokation());
 
+       c = (classinfo *) clazz;
+
        uname = utf_new_char((char *) name);
        udesc = utf_new_char((char *) sig);
 
        f = class_findfield(clazz, uname, udesc); 
        
-       if (!f)
-               *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);  
 
        return (jfieldID) f;
 }
@@ -3567,19 +3556,22 @@ void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
 jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
                                                                  const char *sig)
 {
+       classinfo *c;
        fieldinfo *f;
        utf       *uname;
        utf       *usig;
 
        STATISTICS(jniinvokation());
 
+       c = (classinfo *) clazz;
+
        uname = utf_new_char((char *) name);
        usig  = utf_new_char((char *) sig);
 
        f = class_findfield(clazz, uname, usig);
        
        if (f == NULL)
-               *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
+               exceptions_throw_nosuchfielderror(c, uname);
 
        return (jfieldID) f;
 }
@@ -4245,8 +4237,7 @@ void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
           of the array */
 
        if (!builtin_canstore(oa, o)) {
-               *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
-
+               exceptions_throw_arraystoreexception();
                return;
        }
 
index 9a05c7334c8f318ff9d5464f55b46dee84fa9f84..0c14db8e229fe28cfd053a14fea185daf68beb05 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/jni.h - JNI types and data structures
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Roman Obermaisser
-            Christian Thalinger
-
-   $Id: jni.h 6171 2006-12-11 11:47:42Z twisti $
+   $Id: jni.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -63,7 +57,8 @@ typedef struct localref_table localref_table;
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vm/method.h"
+
+#include "vmcore/method.h"
 
 
 /* _Jv_JNIEnv *****************************************************************/
index a4486b9f75850489f3b21a008f463571aeb04bdf..179609eab40db61b0698d9c5b8e5589eabe8190d 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/native.c - table of native functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Roman Obermaisser
-            Andreas Krall
-            Christian Thalinger
-
-   $Id: native.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: native.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -48,6 +41,7 @@
 #include "mm/memory.h"
 #include "native/jni.h"
 #include "native/native.h"
+#include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
 
 #if defined(ENABLE_THREADS)
 # include "threads/none/lock.h"
 #endif
 
+#include "toolbox/hashtable.h"
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
 #if defined(ENABLE_JVMTI)
 #include "native/jvmti/cacaodbg.h"
 #endif
@@ -92,6 +89,7 @@
 #include "native/include/gnu_java_lang_management_VMMemoryMXBeanImpl.h"
 #include "native/include/gnu_java_lang_management_VMRuntimeMXBeanImpl.h"
 #include "native/include/java_lang_VMClass.h"
+#include "native/include/java_security_ProtectionDomain.h"  /* required by... */
 #include "native/include/java_lang_VMClassLoader.h"
 #include "native/include/java_lang_VMObject.h"
 #include "native/include/java_lang_VMRuntime.h"
@@ -922,17 +920,7 @@ functionptr native_resolve_function(methodinfo *m)
                if (opt_verbosejni)
                        printf("failed ]\n");
 
-#if defined(ENABLE_JAVASE)
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_UnsatisfiedLinkError,
-                                                                        m->name);
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_VirtualMachineError,
-                                                                        m->name);
-#else
-#error IMPLEMENT ME!
-#endif
+               exceptions_throw_unsatisfiedlinkerror(m->name);
        }
 
        /* release memory */
@@ -956,14 +944,14 @@ java_objectheader *native_new_and_init(classinfo *c)
        methodinfo *m;
        java_objectheader *o;
 
-       if (!c)
-               return *exceptionptr;
+       if (c == NULL)
+               vm_abort("native_new_and_init: c == NULL");
 
        /* create object */
 
        o = builtin_new(c);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* try to find the initializer */
@@ -973,7 +961,7 @@ java_objectheader *native_new_and_init(classinfo *c)
        /* ATTENTION: returning the object here is ok, since the class may
        not have an initializer */
 
-       if (!m)
+       if (m == NULL)
                return o;
 
        /* call initializer */
@@ -984,19 +972,19 @@ java_objectheader *native_new_and_init(classinfo *c)
 }
 
 
-java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
+java_objectheader *native_new_and_init_string(classinfo *c, java_objectheader *s)
 {
-       methodinfo *m;
+       methodinfo        *m;
        java_objectheader *o;
 
-       if (!c)
-               return *exceptionptr;
+       if (c == NULL)
+               vm_abort("native_new_and_init_string: c == NULL");
 
        /* create object */
 
        o = builtin_new(c);
 
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* find initializer */
@@ -1009,7 +997,7 @@ java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
 
        /* initializer not found */
 
-       if (!m)
+       if (m == NULL)
                return NULL;
 
        /* call initializer */
@@ -1025,14 +1013,14 @@ java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
        methodinfo *m;
        java_objectheader *o;
 
-       if (!c)
-               return *exceptionptr;
+       if (c == NULL)
+               vm_abort("native_new_and_init_int: c == NULL");
 
        /* create object */
 
        o = builtin_new(c);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* find initializer */
@@ -1041,7 +1029,7 @@ java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
 
        /* initializer not found  */
 
-       if (!m)
+       if (m == NULL)
                return NULL;
 
        /* call initializer */
@@ -1052,19 +1040,19 @@ java_objectheader *native_new_and_init_int(classinfo *c, s4 i)
 }
 
 
-java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
+java_objectheader *native_new_and_init_throwable(classinfo *c, java_objectheader *t)
 {
-       methodinfo *m;
        java_objectheader *o;
+       methodinfo        *m;
 
-       if (!c)
-               return *exceptionptr;
+       if (c == NULL)
+               vm_abort("native_new_and_init_throwable: c == NULL");
 
        /* create object */
 
        o = builtin_new(c);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* find initializer */
@@ -1073,7 +1061,7 @@ java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwab
                                                      
        /* initializer not found */
 
-       if (!m)
+       if (m == NULL)
                return NULL;
 
        /* call initializer */
index c05429957fc95c1411b0f93648b49fd93a872577..1cffac9bf5fc5dc81518d0cd3f101e5556df9bd4 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/native.h - table of native functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Christian Thalinger
-
-   $Id: native.h 6251 2006-12-27 23:15:56Z twisti $
+   $Id: native.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 # include <ltdl.h>
 #endif
 
-#include "native/jni.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
-#include "vm/class.h"
 #include "vm/global.h"
-#include "vm/method.h"
-#include "vm/utf8.h"
+
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/utf8.h"
 
 
 /* table for locating native methods */
@@ -128,7 +121,8 @@ java_objectheader *native_new_and_init(classinfo *c);
 
 /* create new object on the heap and call the initializer 
    mainly used for exceptions with a message */
-java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s);
+java_objectheader *native_new_and_init_string(classinfo *c,
+                                                                                         java_objectheader *s);
 
 /* create new object on the heap and call the initializer 
    mainly used for exceptions with an index */
@@ -136,7 +130,8 @@ java_objectheader *native_new_and_init_int(classinfo *c, s4 i);
 
 /* create new object on the heap and call the initializer 
    mainly used for exceptions with cause */
-java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t);
+java_objectheader *native_new_and_init_throwable(classinfo *c,
+                                                                                                java_objectheader *t);
 
 java_objectarray *native_get_parametertypes(methodinfo *m);
 java_objectarray *native_get_exceptiontypes(methodinfo *m);
index 1e0c941c7b2f9d1a8b4abddb6ead964a8df329c1..93ccbe1cebb8b628b1f04345c4ae3ac793c03dc1 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/gnu_classpath_VMStackWalker.c - gnu/classpath/VMStackWalker
+/* src/native/vm/gnu/gnu_classpath_VMStackWalker.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Edwin Steiner
-
-   $Id: gnu_classpath_VMStackWalker.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: gnu_classpath_VMStackWalker.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "native/native.h"
 #include "native/include/java_lang_Class.h"
 #include "native/include/java_lang_ClassLoader.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/global.h"
-#include "vm/options.h"
+
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/class.h"
+#include "vmcore/options.h"
 
 
 /*
index d0e27f35cecb26c1d32468b063c0f1abded514b4..ae531fe7a47860ec7e5874b3f6c3327cf0f2503e 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Christian Thalinger
 
-   $Id: gnu_classpath_VMSystemProperties.c 7237 2007-01-22 20:16:22Z twisti $
+   $Id: gnu_classpath_VMSystemProperties.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
  */
 JNIEXPORT void JNICALL Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jclass clazz, java_util_Properties *properties)
 {
-       if (properties == NULL) {
+       java_objectheader *p;
+
+       p = (java_objectheader *) properties;
+
+       if (p == NULL) {
                exceptions_throw_nullpointerexception();
                return;
        }
 
        /* fill the java.util.Properties object */
 
-       properties_system_add_all(properties);
+       properties_system_add_all(p);
 }
 
 
index 7ee69bfe485510c669b37b2642752501060a2638..8be4825a1a486e7dc60b318c627f3439a4c128d6 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c
+/* src/native/vm/gnu/gnu_java_lang_management_VMClassLoadingMXBeanImpl.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: VMFrame.c 4996 2006-05-31 13:53:16Z motse $
 
 */
 #include "native/jni.h"
 
 #include "toolbox/logging.h"
-#include "vm/classcache.h"
+
 #include "vm/vm.h"
 
+#include "vmcore/classcache.h"
+
 
 /*
  * Class:     gnu/java/lang/management/VMClassLoadingMXBeanImpl
index 4dc96e5ccc03fd9c7eef3ce581a18ad26926ec2d..37741ec71cf76ef92b7972183662a7a17a4a4e40 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/gnu_java_lang_management_VMMemoryMXBeanImpl.c
+/* src/native/vm/gnu/gnu_java_lang_management_VMMemoryMXBeanImpl.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: VMFrame.c 4996 2006-05-31 13:53:16Z motse $
 
 */
 #include "native/include/java_lang_management_MemoryUsage.h"
 
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/global.h"
-#include "vm/loader.h"                   /* XXX only for load_class_bootstrap */
-#include "vm/options.h"
 #include "vm/vm.h"
 
+#include "vmcore/class.h"
+#include "vmcore/loader.h"               /* XXX only for load_class_bootstrap */
+#include "vmcore/options.h"
+
 
 /*
  * Class:     gnu/java/lang/management/VMMemoryMXBeanImpl
index 68e8784c81152444d27b4a19808e55324ee590a2..adeef5faa8a425025de90adefd38f6f2b6fcdc5f 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/gnu_java_lang_management_VMRuntimeMXBeanImpl.c
+/* src/native/vm/gnu/gnu_java_lang_management_VMRuntimeMXBeanImpl.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: VMFrame.c 4996 2006-05-31 13:53:16Z motse $
 
 */
 #include "vm/types.h"
 
 #include "native/jni.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/global.h"
 #include "vm/vm.h"
 
+#include "vmcore/class.h"
+
 
 /*
  * Class:     gnu/java/lang/management/VMRuntimeMXBeanImpl
index 8bde3431e30ee62801315325a2d8445680575695..483e5e1d97f8ecb80d0cf5751543053d2eb144e1 100644 (file)
@@ -1,4 +1,4 @@
-/* src/native/vm/gnu_java_lang_management_VMThreadMXBeanImpl.c
+/* src/native/vm/gnu/gnu_java_lang_management_VMThreadMXBeanImpl.c
 
    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: VMFrame.c 4996 2006-05-31 13:53:16Z motse $
 
 */
 #include "mm/gc-common.h"
 
 #include "native/jni.h"
+#include "native/include/java_lang_Throwable.h"
 #include "native/include/java_lang_management_ThreadInfo.h"
 
 #include "toolbox/logging.h"
-#include "vm/classcache.h"
+
 #include "vm/vm.h"
 
+#include "vmcore/classcache.h"
+
 
 /*
  * Class:     gnu/java/lang/management/VMThreadMXBeanImpl
index 20660790271e090fde1f0f06bb7f6276e61518f1..dfd4c155f722189c77166f0e23bc6bbb6d6905e2 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/java_lang_VMClass.c - java/lang/VMClass
+/* src/native/vm/gnu/java_lang_VMClass.c
 
-   Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   Copyright (C) 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: java_lang_VMClass.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_VMClass.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "native/include/java_lang_Class.h"
 #include "native/include/java_lang_ClassLoader.h"
 #include "native/include/java_lang_Object.h"
+#include "native/include/java_lang_Throwable.h"
 #include "native/include/java_lang_VMClass.h"
 #include "native/include/java_lang_reflect_Constructor.h"
 #include "native/include/java_lang_reflect_Method.h"
+
 #include "native/vm/java_lang_Class.h"
 
 
index 282414ac3d56498bfadcef54bf9c6fd645c2e5ea..23f01d6d1f22d1f4590c8a7ae966c9bf607a7702 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/VMClassLoader.c - java/lang/VMClassLoader
+/* src/native/vm/gnu/VMClassLoader.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-
-   Changes: Joseph Wenninger
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: java_lang_VMClassLoader.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_VMClassLoader.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_Class.h"
 #include "native/include/java_lang_String.h"
+#include "native/include/java_security_ProtectionDomain.h"  /* required by... */
 #include "native/include/java_lang_ClassLoader.h"
-#include "native/include/java_security_ProtectionDomain.h"
 #include "native/include/java_util_Vector.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/classcache.h"
 #include "vm/exceptions.h"
 #include "vm/initialize.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
-#include "vm/suck.h"
 #include "vm/vm.h"
-#include "vm/zip.h"
+
 #include "vm/jit/asmpart.h"
 
+#include "vmcore/class.h"
+#include "vmcore/classcache.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+#include "vmcore/suck.h"
+#include "vmcore/zip.h"
+
 #if defined(ENABLE_JVMTI)
 #include "native/jvmti/cacaodbg.h"
 #endif
  */
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
 {
-       classinfo   *c;
-       classinfo   *r;
-       classbuffer *cb;
-       utf         *utfname;
+       classinfo       *c;
+       classinfo       *r;
+       classbuffer     *cb;
+       utf             *utfname;
+       java_lang_Class *co;
 #if defined(ENABLE_JVMTI)
        jint new_class_data_len = 0;
        unsigned char* new_class_data = NULL;
@@ -100,7 +98,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
                return NULL;
        }
 
-       if (name) {
+       if (name != NULL) {
                /* convert '.' to '/' in java string */
 
                utfname = javastring_toutf(name, true);
@@ -108,9 +106,8 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
                /* check if this class has already been defined */
 
                c = classcache_lookup_defined_or_initiated((java_objectheader *) cl, utfname);
-               if (c) {
-                       *exceptionptr =
-                               exceptions_new_linkageerror("duplicate class definition: ",c);
+               if (c != NULL) {
+                       exceptions_throw_linkageerror("duplicate class definition: ", c);
                        return NULL;
                }
        } 
@@ -175,10 +172,10 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
                loadingtime_stop();
 #endif
 
-       if (!r) {
-               /* If return value is NULL, we had a problem and the class is not   */
-               /* loaded. */
-               /* now free the allocated memory, otherwise we could run into a DOS */
+       if (r == NULL) {
+               /* If return value is NULL, we had a problem and the class is
+                  not loaded.  Now free the allocated memory, otherwise we
+                  could run into a DOS. */
 
                class_free(c);
 
@@ -187,7 +184,9 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
 
        /* set ProtectionDomain */
 
-       c->object.pd = pd;
+       co = (java_lang_Class *) c;
+
+       co->pd = pd;
 
        /* Store the newly defined class in the class cache. This call also       */
        /* checks whether a class of the same name has already been defined by    */
@@ -198,7 +197,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
        /*            pointer after the lookup at to top of this function         */
        /*            directly after the class cache lock has been released.      */
 
-       c = classcache_store((java_objectheader *)cl,c,true);
+       c = classcache_store((java_objectheader *) cl, c, true);
 
        return (java_lang_Class *) c;
 }
@@ -212,42 +211,45 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, s4 type)
 {
        classinfo *c;
+       s4         index;
 
        /* get primitive class */
 
        switch (type) {
        case 'I':
-               c = primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
+               index = PRIMITIVETYPE_INT;
                break;
        case 'J':
-               c = primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
+               index = PRIMITIVETYPE_LONG;
                break;
        case 'F':
-               c = primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
+               index = PRIMITIVETYPE_FLOAT;
                break;
        case 'D':
-               c = primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
+               index = PRIMITIVETYPE_DOUBLE;
                break;
        case 'B':
-               c = primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
+               index = PRIMITIVETYPE_BYTE;
                break;
        case 'C':
-               c = primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
+               index = PRIMITIVETYPE_CHAR;
                break;
        case 'S':
-               c = primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
+               index = PRIMITIVETYPE_SHORT;
                break;
        case 'Z':
-               c = primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
+               index = PRIMITIVETYPE_BOOLEAN;
                break;
        case 'V':
-               c = primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
+               index = PRIMITIVETYPE_VOID;
                break;
        default:
-               *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
+               exceptions_throw_noclassdeffounderror(utf_null);
                c = NULL;
        }
 
+       c = primitivetype_table[index].class_primitive;
+
        return (java_lang_Class *) c;
 }
 
@@ -284,8 +286,9 @@ JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jc
  */
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, jboolean resolve)
 {
-       classinfo *c;
-       utf *u;
+       classinfo         *c;
+       utf               *u;
+       java_objectheader *xptr;
 
        if (name == NULL) {
                exceptions_throw_nullpointerexception();
@@ -298,7 +301,9 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv
 
        /* load class */
 
-       if (!(c = load_class_bootstrap(u)))
+       c = load_class_bootstrap(u);
+
+       if (c == NULL)
                goto exception;
 
        /* resolve class -- if requested */
@@ -310,7 +315,9 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv
        return (java_lang_Class *) c;
 
  exception:
-       c = (*exceptionptr)->vftbl->class;
+       xptr = exceptions_get_exception();
+
+       c = xptr->vftbl->class;
        
        /* if the exception is a NoClassDefFoundError, we replace it with a
           ClassNotFoundException, otherwise return the exception */
@@ -318,10 +325,9 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv
        if (c == class_java_lang_NoClassDefFoundError) {
                /* clear exceptionptr, because builtin_new checks for 
                   ExceptionInInitializerError */
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
 
-               *exceptionptr =
-                       new_exception_javastring(string_java_lang_ClassNotFoundException, name);
+               exceptions_throw_classnotfoundexception(u);
        }
 
        return NULL;
@@ -452,7 +458,7 @@ JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResour
                if (path) {
                        ret = vm_call_method_int(m, o, path);
 
-                       if (*exceptionptr)
+                       if (exceptions_get_exception() != NULL)
                                goto return_NULL;
 
                        if (ret == 0) 
index edb5b36344d254083db85d353be45ae992a12c95..e5975ec4611fbf2d2359dd1826653322951cf0fa 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/VMRuntime.c - java/lang/VMRuntime
+/* src/native/vm/gnu/java_lang_VMRuntime.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-
-   Changes: Joseph Wenninger
-            Christian Thalinger
-                       Edwin Steiner
-
-   $Id: java_lang_VMRuntime.c 6252 2006-12-27 23:42:37Z twisti $
+   $Id: java_lang_VMRuntime.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "mm/gc-common.h"
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_io_File.h"
 #include "native/include/java_lang_ClassLoader.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Process.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
+#include "vmcore/options.h"
+
 
 /* this should work on BSD */
 /*
index 97a2da00f59209ca385af5f3c8f5532dcde25e1f..765960d92c233ae5be0d9dacbf1c96d46005a7e9 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/gnu/java_lang_VMThread.c - java/lang/VMThread
+/* src/native/vm/gnu/java_lang_VMThread.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: java_lang_VMThread.c 6228 2006-12-26 19:56:58Z twisti $
+   $Id: java_lang_VMThread.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
index 47ceaaa31570253cbd292856ec3c62792f223bc4..90633386126c2a334350c6e933a63335caaa1fca 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/java_lang_VMThrowable.c - java/lang/VMThrowable
+/* src/native/vm/gnu/java_lang_VMThrowable.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Joseph Wenninger
-            Christian Thalinger
-
-   $Id: java_lang_VMThrowable.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_VMThrowable.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "native/include/java_lang_StackTraceElement.h"
 #include "native/include/java_lang_Throwable.h"
 #include "native/include/java_lang_VMThrowable.h"
+
 #include "native/vm/java_lang_Class.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
-#include "vm/loader.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/stacktrace.h"
 
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+
 
 /*
  * Class:     java/lang/VMThrowable
index 8abcd629ca8bb7c3584aca48e5a069d40262f2d9..54b902447d0239bb43bb9908f3d48e1edebe17b7 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/java_lang_management_VMManagementFactory.c
+/* src/native/vm/gnu/java_lang_management_VMManagementFactory.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: VMFrame.c 4996 2006-05-31 13:53:16Z motse $
 
 */
 #include "native/jni.h"
 
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
+
+#include "vmcore/class.h"
 
 
 /*
index e507a1fa97da0bca5d8844a7c1b123c5391719dd..cbeeb4cda28a6ad27026467f534c158dd5144532 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/java_lang_reflect_Constructor.c
+/* src/native/vm/gnu/java_lang_reflect_Constructor.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: java_lang_reflect_Constructor.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_reflect_Constructor.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "native/include/java_lang_Object.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_reflect_Constructor.h"
+
 #include "toolbox/logging.h"
-#include "vm/class.h"
+
+#include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "vm/method.h"
 #include "vm/access.h"
 #include "vm/stringlocal.h"
 
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+
 
 /*
  * Class:     java/lang/reflect/Constructor
index dd60bfcd1f1dbab6857c0da8c1100f4837f435ad..796e3607a9c3ca2ac6a9b04f499fd213ff50c95c 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/java_lang_reflect_Field.c - java/lang/reflect/Field
+/* src/native/vm/gnu/java_lang_reflect_Field.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: java_lang_reflect_Field.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_reflect_Field.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "native/include/java_lang_Double.h"
 #include "native/include/java_lang_Object.h"
 #include "native/include/java_lang_Class.h"
+#include "native/include/java_lang_String.h"
 #include "native/include/java_lang_reflect_Field.h"
+
 #include "vm/access.h"
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/resolve.h"
 #include "vm/stringlocal.h"
-#include "vm/utf8.h"
+
 #include "vm/jit/stacktrace.h"
 
+#include "vmcore/loader.h"
+#include "vmcore/resolve.h"
+#include "vmcore/utf8.h"
+
 
 #define CHECKFIELDACCESS(this,fi,c,doret)
 
index d7560e699f963afb925307991968d63b013ff1a3..cfc0ef871c99f6616f787a419c12710351c04a08 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/Method.c - java/lang/reflect/Method
+/* src/native/vm/gnu/java_lang_reflect_Method.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: java_lang_reflect_Method.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_reflect_Method.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -43,7 +37,9 @@
 #include "native/native.h"
 #include "native/include/java_lang_Object.h"
 #include "native/include/java_lang_Class.h"
+#include "native/include/java_lang_String.h"
 #include "native/include/java_lang_reflect_Method.h"
+
 #include "vm/access.h"
 #include "vm/global.h"
 #include "vm/builtin.h"
index 36d1d1e517bbb5047816538601f334df7903deb4..43f6bd55bb48363f31708a276be33f50f0550eff 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/VMAccessController.c - java/security/VMAccessController
+/* src/native/vm/gnu/java_security_VMAccessController.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Joseph Wenninger
-
-   Changes: Christian Thalinger
-
-   $Id: java_security_VMAccessController.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_security_VMAccessController.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "native/jni.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/options.h"
+
 #include "vm/jit/stacktrace.h"
 
+#include "vmcore/class.h"
+#include "vmcore/options.h"
+
 
 /*
  * Class:     java/security/VMAccessController
index 05b370892c09562d12c9f9dc2049407b440b9384..d04c4d5fbbaef5378957d9f41f0fa6ff1ab6b69a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/vm/java_lang_Class.c - java/lang/Class
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-            Edwin Steiner
-
    $Id: java_lang_VMClass.c 6131 2006-12-06 22:15:57Z twisti $
 
 */
@@ -42,6 +35,7 @@
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_Class.h"
 #endif
 
 #include "native/vm/java_lang_Class.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/resolve.h"
 #include "vm/stringlocal.h"
 
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/resolve.h"
+
 
 /*
  * Class:     java/lang/Class
@@ -108,10 +105,16 @@ java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name, s4 initiali
 java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
 #endif
 {
-       classinfo *c;
-       utf       *u;
-       u2        *pos;
-       s4         i;
+       java_objectheader *cl;
+       utf               *ufile;
+       utf               *uname;
+       classinfo         *c;
+       java_objectheader *xptr;
+       classinfo         *xclass;
+       u2                *pos;
+       s4                 i;
+
+       cl = (java_objectheader *) loader;
 
        /* illegal argument */
 
@@ -120,30 +123,32 @@ java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
                return NULL;
        }
 
+       /* create utf string in which '.' is replaced by '/' */
+
+       ufile = javastring_toutf(name, true);
+       uname = javastring_toutf(name, false);
+
        /* name must not contain '/' (mauve test) */
 
        for (i = 0, pos = name->value->data + name->offset; i < name->count; i++, pos++) {
                if (*pos == '/') {
-                       *exceptionptr =
-                               new_exception_javastring(string_java_lang_ClassNotFoundException, name);
+                       exceptions_throw_classnotfoundexception(uname);
                        return NULL;
                }
        }
 
-       /* create utf string in which '.' is replaced by '/' */
-
-       u = javastring_toutf(name, true);
-
        /* try to load, ... */
 
 #if defined(ENABLE_JAVASE)
-       if (!(c = load_class_from_classloader(u, (java_objectheader *) loader))) {
+       c = load_class_from_classloader(ufile, cl);
 #elif defined(ENABLE_JAVAME_CLDC1_1)
-       if (!(c = load_class_bootstrap(u))) {
+       c = load_class_bootstrap(ufile);
 #endif
-               classinfo *xclass;
 
-               xclass = (*exceptionptr)->vftbl->class;
+       if (c == NULL) {
+               xptr = exceptions_get_exception();
+
+               xclass = xptr->vftbl->class;
 
                /* if the exception is a NoClassDefFoundError, we replace it with a
                   ClassNotFoundException, otherwise return the exception */
@@ -151,10 +156,9 @@ java_lang_Class *_Jv_java_lang_Class_forName(java_lang_String *name)
                if (xclass == class_java_lang_NoClassDefFoundError) {
                        /* clear exceptionptr, because builtin_new checks for 
                           ExceptionInInitializerError */
-                       *exceptionptr = NULL;
+                       exceptions_clear_exception();
 
-                       *exceptionptr =
-                               new_exception_javastring(string_java_lang_ClassNotFoundException, name);
+                       exceptions_throw_classnotfoundexception(uname);
                }
 
            return NULL;
@@ -792,7 +796,11 @@ s4 _Jv_java_lang_Class_isArray(java_lang_Class *klass)
  */
 void _Jv_java_lang_Class_throwException(java_lang_Throwable *t)
 {
-       *exceptionptr = (java_objectheader *) t;
+       java_objectheader *o;
+
+       o = (java_objectheader *) t;
+
+       exceptions_set_exception(o);
 }
 
 
index 8f4ec57a865be47a25379fcd6324fa9db69bee5f..463c43a89a9a816788bcb71a190adb9c2752595f 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/vm/java_lang_Object.c - java/lang/Object functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-
    $Id: java_lang_VMObject.c 6213 2006-12-18 17:36:06Z twisti $
 
 */
@@ -54,7 +48,8 @@
 #endif
 
 #include "vm/builtin.h"
-#include "vm/options.h"
+
+#include "vmcore/options.h"
 
 #if defined(ENABLE_JVMTI)
 #include "native/jvmti/cacaodbg.h"
index c2e2fe1e5ef0153c869530857533511c6d7e8d56..50e7fb37c6a55925e6a0f6dc49ecd38cfa5dc4af 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/vm/java_lang_Thread.c - java/lang/Thread functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-            Joseph Wenninger
-            Christian Thalinger
-
    $Id: java_lang_VMThread.c 6213 2006-12-18 17:36:06Z twisti $
 
 */
@@ -43,6 +37,7 @@
 # include "native/include/java_lang_ThreadGroup.h"
 #endif
 
+#include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Object.h"            /* java_lang_Thread.h */
 #include "native/include/java_lang_Throwable.h"         /* java_lang_Thread.h */
 #include "native/include/java_lang_Thread.h"
 #endif
 
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "vm/options.h"
+
+#include "vmcore/options.h"
+
+/* XXX REMOVE ME only for vm_abort */
+#include "vm/vm.h"
 
 
 /*
index ed7d795f85a7e2f720140eb5c6f80e743c4eecf4..9bc692e5a7b5a8e1145ab24bd8e0c340867296cf 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/native/lock.c - lock implementation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Stefan Ring
-                       Edwin Steiner
-
-   Changes: Christian Thalinger
-
    $Id: threads.c 4903 2006-05-11 12:48:43Z edwin $
 
 */
 #include <sys/time.h>
 #include <pthread.h>
 
-#include "mm/memory.h"
 #include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "threads/native/lock.h"
+#include "threads/native/threads.h"
+
 #include "vm/global.h"
 #include "vm/exceptions.h"
 #include "vm/stringlocal.h"
@@ -1141,7 +1139,7 @@ static void lock_record_wait(threadobject *t, lock_record_t *lr, s8 millis, s4 n
        /* if we have been interrupted, throw the appropriate exception */
 
        if (wasinterrupted)
-               *exceptionptr = new_exception(string_java_lang_InterruptedException);
+               exceptions_throw_interruptedexception();
 }
 
 
index 0ab9ead32a36dbccd2f76fd5ae8c3ceb1e74ea16..b7ab5a4fafc04cf344fa8d60b8b8643762882e78 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/native/threads.c - native threads support
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Stefan Ring
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: threads.c 6254 2006-12-28 00:19:16Z twisti $
+   $Id: threads.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "mm/gc-common.h"
 #include "mm/memory.h"
+
+#include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_Object.h"
+#include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
 #include "native/include/java_lang_Thread.h"
 
 #endif
 
 #include "threads/native/threads.h"
+
 #include "toolbox/avl.h"
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 
+#include "vmcore/options.h"
+
 #if !defined(__DARWIN__)
 # if defined(__LINUX__)
 #  define GC_LINUX_THREADS
@@ -1802,7 +1802,7 @@ void threads_sleep(s8 millis, s4 nanos)
        wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
 
        if (wasinterrupted)
-               *exceptionptr = new_exception(string_java_lang_InterruptedException);
+               exceptions_throw_interruptedexception();
 }
 
 
index e1b8f038437bbf278ac3d4f057324eb13150e374..38bca07e8db41be78ca08a2a65cbe8020165f765 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/native/threads.h - native threads header
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Stefan Ring
-            Edwin Steiner
-            Christian Thalinger
-
-   $Id: threads.h 6251 2006-12-27 23:15:56Z twisti $
+   $Id: threads.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -53,10 +47,13 @@ typedef struct threads_table_t       threads_table_t;
 #include "mm/memory.h"
 #include "native/jni.h"
 #include "native/include/java_lang_Thread.h"
-#include "vm/global.h"
 
 #include "threads/native/lock.h"
 
+#include "vm/global.h"
+
+#include "vm/jit/stacktrace.h"
+
 #if defined(ENABLE_INTRP)
 #include "vm/jit/intrp/intrp.h"
 #endif
@@ -184,6 +181,16 @@ struct threadobject {
 };
 
 
+/* exception pointer **********************************************************/
+
+#define exceptionptr      (&(THREADOBJECT->_exceptionptr))
+
+
+/* stackframeinfo *************************************************************/
+
+#define STACKFRAMEINFO    (&(THREADOBJECT->_stackframeinfo))
+
+
 /* variables ******************************************************************/
 
 extern threadobject *mainthreadobj;
index 9dbc9c0ce1c4c0052bd012e9d488b0659bbb975d..b671bd7e6d4ae8a5444e9a7bb27ff320f315371a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/none/lock.h - fake lock implementation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: Christian Thalinger
-
    $Id: threads.h 4866 2006-05-01 21:40:38Z edwin $
 
 */
index c6a9d3e28d215b2caca92cd947d3d3b11e2f7af6..fcdfdc3576e5087f7bd3314a54e9527db089aea7 100644 (file)
@@ -1,6 +1,6 @@
 /* src/threads/none/threads.h - fake threads header
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: threads.h 4405 2006-02-03 12:46:22Z twisti $
 
 */
 
 #define threadobject      void
 
+
+/* exception pointer **********************************************************/
+
+extern java_objectheader    *_no_threads_exceptionptr;
+
+#define exceptionptr        (&_no_threads_exceptionptr)
+
+
+/* stackframeinfo *************************************************************/
+
+extern stackframeinfo       *_no_threads_stackframeinfo;
+
+#define STACKFRAMEINFO      (&_no_threads_stackframeinfo)
+
 #endif /* _THREADS_H */
 
 
index 566797ff89c0122168e189b3d1b613dfba2ca388..58b5da3356f201cd9a9f0161d2cf754033a1029a 100644 (file)
@@ -1,6 +1,6 @@
 ## src/toolbox/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+## Copyright (C) 1996-2005, 2006, 2007 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
@@ -26,9 +26,7 @@
 ##
 ## Authors: Christian Thalinger
 ##
-## Changes:
-##
-## $Id: Makefile.am 5234 2006-08-14 17:50:12Z christian $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -36,13 +34,18 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top
 
 LIBS =
 
-noinst_LTLIBRARIES = libtoolbox.la
+noinst_LTLIBRARIES = \
+       libtoolbox.la
 
 libtoolbox_la_SOURCES = \
        avl.c \
        avl.h \
+       bitvector.c \
+       bitvector.h \
        chain.c \
        chain.h \
+       hashtable.c \
+       hashtable.h \
        list.c \
        list.h \
        logging.c \
@@ -51,8 +54,6 @@ libtoolbox_la_SOURCES = \
        tree.h \
        util.c \
        util.h \
-       bitvector.c \
-       bitvector.h \
        worklist.c \
        worklist.h
 
index 24981f51c0ed556687a368d3f21b2cac21c0731c..15337fa4398528d9485680043c039dfd4610e306 100644 (file)
@@ -1,6 +1,6 @@
 /* src/toolbox/avl.c - AVL tree implementation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: avl.c 5123 2006-07-12 21:45:34Z twisti $
+   $Id: avl.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -44,7 +38,6 @@
 
 #if defined(ENABLE_THREADS)
 # include "threads/native/lock.h"
-# include "threads/native/threads.h"
 #else
 # include "threads/none/lock.h"
 #endif
diff --git a/src/toolbox/hashtable.c b/src/toolbox/hashtable.c
new file mode 100644 (file)
index 0000000..d6d7bf1
--- /dev/null
@@ -0,0 +1,141 @@
+/* src/vm/hashtable.c - functions for internal hashtables
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Reinhard Grafl
+            Mark Probst
+            Andreas Krall
+            Christian Thalinger
+
+   $Id: hashtable.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
+#include "toolbox/hashtable.h"
+#include "vm/global.h"
+
+
+/* hashtable_create ************************************************************
+
+   Initializes a hashtable structure and allocates memory. The
+   parameter size specifies the initial size of the hashtable.
+       
+*******************************************************************************/
+
+void hashtable_create(hashtable *hash, u4 size)
+{
+       /* initialize locking pointer */
+
+#if defined(ENABLE_THREADS)
+       /* We need to seperately allocate a java_objectheader here, as we
+          need to store the lock object in the new hashtable if it's
+          resized.  Otherwise we get an IllegalMonitorStateException. */
+
+       hash->header = NEW(java_objectheader);
+
+       lock_init_object_lock(hash->header);
+#endif
+
+       /* set initial hash values */
+
+       hash->size    = size;
+       hash->entries = 0;
+       hash->ptr     = MNEW(void*, size);
+
+       /* MNEW always allocates memory zeroed out, no need to clear the table */
+}
+
+
+/* hashtable_resize ************************************************************
+
+   Creates a new hashtable with specified size and moves the important
+   stuff from the old hashtable.
+
+*******************************************************************************/
+
+hashtable *hashtable_resize(hashtable *hash, u4 size)
+{
+       hashtable *newhash;
+
+       /* create new hashtable with specified size */
+
+       newhash = NEW(hashtable);
+
+       hashtable_create(newhash, size);
+
+#if defined(ENABLE_THREADS)
+       /* We need to store the old lock object in the new hashtable.
+          Otherwise we get an IllegalMonitorStateException. */
+
+       FREE(newhash->header, java_objectheader);
+
+       newhash->header  = hash->header;
+#endif
+
+       /* store the number of entries in the new hashtable */
+
+       newhash->entries = hash->entries;
+
+       return newhash;
+}
+
+
+/* hashtable_free **************************************************************
+
+   Simply frees the hashtable.
+
+   ATTENTION: It does NOT free the lock object!
+
+*******************************************************************************/
+
+void hashtable_free(hashtable *hash)
+{
+       MFREE(hash->ptr, void*, hash->size);
+       FREE(hash, hashtable);
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/toolbox/hashtable.h b/src/toolbox/hashtable.h
new file mode 100644 (file)
index 0000000..056dbc1
--- /dev/null
@@ -0,0 +1,138 @@
+/* src/toolbox/hashtable.h - functions for internal hashtables
+
+   Copyright (C) 1996-2005, 2006 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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Reinhard Grafl
+            Christian Thalinger
+
+   $Id: hashtable.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _HASHTABLE_H
+#define _HASHTABLE_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct hashtable hashtable;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vmcore/utf8.h"
+
+
+/* data structures for hashtables ********************************************
+
+   All utf-symbols, javastrings and classes are stored in global
+   hashtables, so every symbol exists only once. Equal symbols have
+   identical pointers.  The functions for adding hashtable elements
+   search the table for the element with the specified name/text and
+   return it on success. Otherwise a new hashtable element is created.
+
+   The hashtables use external linking for handling collisions. The
+   hashtable structure contains a pointer <ptr> to the array of
+   hashtable slots. The number of hashtable slots and therefore the
+   size of this array is specified by the element <size> of hashtable
+   structure. <entries> contains the number of all hashtable elements
+   stored in the table, including those in the external chains.  The
+   hashtable element structures (utf, literalstring, classinfo)
+   contain both a pointer to the next hashtable element as a link for
+   the external hash chain and the key of the element. The key is
+   computed from the text of the string or the classname by using up
+   to 8 characters.
+       
+   If the number of entries in the hashtable exceeds twice the size of
+   the hashtableslot-array it is supposed that the average length of
+   the external chains has reached a value beyond 2. Therefore the
+   functions for adding hashtable elements (utf_new, class_new,
+   literalstring_new) double the hashtableslot-array. In this
+   restructuring process all elements have to be inserted into the new
+   hashtable and new external chains must be built.
+
+   Example for the layout of a hashtable:
+
+hashtable.ptr-->+-------------------+
+                |                   |
+                         ...
+                |                   |
+                +-------------------+   +-------------------+   +-------------------+
+                | hashtable element |-->| hashtable element |-->| hashtable element |-->NULL
+                +-------------------+   +-------------------+   +-------------------+
+                | hashtable element |
+                +-------------------+   +-------------------+   
+                | hashtable element |-->| hashtable element |-->NULL
+                +-------------------+   +-------------------+   
+                | hashtable element |-->NULL
+                +-------------------+
+                |                   |
+                         ...
+                |                   |
+                +-------------------+
+
+*/
+
+
+/* hashtable ******************************************************************/
+
+struct hashtable {            
+#if defined(ENABLE_THREADS)
+       java_objectheader  *header;         /* required for locking               */
+#endif
+       u4                  size;           /* current size of the hashtable      */
+       u4                  entries;        /* number of entries in the table     */
+       void              **ptr;            /* pointer to hashtable               */
+};
+
+
+/* function prototypes ********************************************************/
+
+/* create hashtable */
+void hashtable_create(hashtable *hash, u4 size);
+
+/* creates and resizes a hashtable */
+hashtable *hashtable_resize(hashtable *hash, u4 size);
+
+/* frees a hashtable */
+void hashtable_free(hashtable *hash);
+
+#endif /* _HASHTABLE_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:
+ */
index f9569ae7a04af420fb0f1cfbdc9455e7a21b7492..e277eb572a6c21b43f4270fec8458a173e2a2644 100644 (file)
@@ -1,6 +1,6 @@
 /* src/toolbox/list.c - double linked list
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   $Id: list.c 5894 2006-11-02 12:54:15Z twisti $
+   $Id: list.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -41,7 +37,6 @@
 
 #if defined(ENABLE_THREADS)
 # include "threads/native/lock.h"
-# include "threads/native/threads.h"
 #else
 # include "threads/none/lock.h"
 #endif
index 3e4218abc5c3c48785e11c5f1c3ab858ca659166..0d21c1a8e74300d205fcfbbcab22a570178eca0b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/toolbox/logging.c - contains logging functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Christian Thalinger
-                       Edwin Steiner
-
-   $Id: logging.c 4967 2006-05-26 16:24:58Z edwin $
+   $Id: logging.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
 #include "vm/global.h"
-#include "vm/statistics.h"
 
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#if 0
 #if defined(ENABLE_THREADS)
 # include "threads/native/threads.h"
 #endif
+#endif
 
 
 /***************************************************************************
@@ -81,12 +79,14 @@ void log_start(void)
 {
        if (logfile) {
 #if defined(ENABLE_THREADS)
-               fprintf(logfile, "[%p] ", (void *) THREADOBJECT);
+#warning FIX ME!
+/*             fprintf(logfile, "[%p] ", (void *) threads_get_current_threadobject()); */
 #endif
 
        } else {
 #if defined(ENABLE_THREADS)
-               fprintf(stdout, "LOG: [%p] ", (void *) THREADOBJECT);
+#warning FIX ME!
+/*             fprintf(stdout, "LOG: [%p] ", (void *) threads_get_current_threadobject()); */
 #else
                fputs("LOG: ", stdout);
 #endif
index cc8b7a136056a091f509fdfc8c9004d1e43e104d..3af0a0df971404b2f67b3966481cc0b0e501df79 100644 (file)
@@ -1,6 +1,6 @@
 /* src/toolbox/logging.h - contains logging functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Christan Thalinger
-
-   $Id: logging.h 5464 2006-09-11 14:45:13Z edwin $
+   $Id: logging.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -41,9 +35,9 @@
 #include <stdio.h>
 #include <stdarg.h>
 
-#include "vm/class.h"
-#include "vm/method.h"
-#include "vm/utf8.h"
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/utf8.h"
 
 
 /*500 is to small for eclipse traces, (builtin_trace_args, perhaps the
index 9c6da3a59246899f6df1cfbc2ec0770feb30ba49..50db1ba231d284e0d353e3b3b4f87098f6a291c6 100644 (file)
@@ -1,6 +1,6 @@
 ## src/vm/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+## Copyright (C) 1996-2005, 2006, 2007 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
 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 ## 02110-1301, USA.
 ##
-## Contact: cacao@cacaojvm.org
-##
-## Authors: Christian Thalinger
-##
-## $Id: Makefile.am 6216 2006-12-18 18:21:37Z twisti $
+## $Id: Makefile.am 7246 2007-01-29 18:49:05Z twisti $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -36,104 +32,42 @@ LIBS =
 
 SUBDIRS = jit
 
-if ENABLE_JAVASE
-ANNOTATION_SOURCES = \
-       annotation.c \
-       annotation.h
-
-STACKMAP_SOURCES = \
-       stackmap.c \
-       stackmap.h
-endif
-
-if ENABLE_STATISTICS
-STATISTICS_SOURCES = \
-       statistics.c \
-       statistics.h
-endif
-
-if ENABLE_RT_TIMING
-RT_TIMING_OBJ = \
-       rt-timing.c
-endif
-
 if ENABLE_CYCLES_STATS
-CYCLES_STATS_SOURCE = \
+CYCLES_STATS_SOURCES = \
        cycles-stats.c \
        cycles-stats.h
 endif
 
-if ENABLE_ZLIB
-ZLIB_OBJ = \
-       zip.c \
-       zip.h
-endif
-
 noinst_HEADERS = \
        global.h \
        types.h
 
 noinst_LTLIBRARIES = \
-       libvmcore.la \
        libvm.la
 
-libvmcore_la_SOURCES = \
+libvm_la_SOURCES = \
        access.c \
        access.h \
-       $(ANNOTATION_SOURCES) \
        builtin.c \
        builtin.h \
        builtintable.inc \
-       class.c \
-       class.h \
-       classcache.c \
-       classcache.h \
-       $(CYCLES_STATS_SOURCE) \
-       descriptor.c \
-       descriptor.h \
-       field.c \
-       field.h \
+       $(CYCLES_STATS_SOURCES) \
+       exceptions.c \
+       exceptions.h \
        finalizer.c \
        finalizer.h \
-       hashtable.c \
-       hashtable.h \
        initialize.c \
        initialize.h \
-       linker.c \
-       linker.h \
-       loader.c \
-       loader.h \
-       method.c \
-       method.h \
-       options.c \
-       options.h \
        properties.c \
        properties.h \
-       references.h \
-       resolve.c \
-       resolve.h \
-       $(RT_TIMING_OBJ) \
-       rt-timing.h \
-       $(STATISTICS_SOURCES) \
        signal.c \
        signallocal.h \
-       $(STACKMAP_SOURCES) \
        string.c \
        stringlocal.h \
-       suck.c \
-       suck.h \
-       utf8.c \
-       utf8.h \
-       $(ZLIB_OBJ)
-
-libvm_la_SOURCES = \
-       exceptions.c \
-       exceptions.h \
        vm.c \
        vm.h
 
 libvm_la_LIBADD = \
-       libvmcore.la \
        jit/libjit.la
 
 
index fa36e0fd9205a6531799f8e25a8285fb4a346f11..66c9db65afdb749831b9599a4714837829ee7169 100644 (file)
@@ -1,6 +1,6 @@
-/* vm/access.c - checking access rights
+/* src/vmcore/access.c - checking access rights
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id: access.c 5846 2006-10-28 13:02:19Z edwin $
+   $Id: access.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "vm/access.h"
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
-#include "vm/stringlocal.h"
+
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/class.h"
 
 
 /****************************************************************************/
@@ -186,7 +182,8 @@ bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth)
        /* get the caller's class */
 
        oa = stacktrace_getClassContext();
-       if (!oa)
+
+       if (oa == NULL)
                return false;
 
        assert(calldepth >= 0 && calldepth < oa->header.size);
@@ -198,8 +195,7 @@ bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth)
        if (!access_is_accessible_class(callerclass, declarer)
                || !access_is_accessible_member(callerclass, declarer, memberflags))
        {
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalAccessException);
+               exceptions_throw_illegalaccessexception(callerclass);
                return false;
        }
 
@@ -208,6 +204,7 @@ bool access_check_caller(classinfo *declarer, s4 memberflags, s4 calldepth)
        return true;
 }
 
+
 /*
  * 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
index 61e47ee8847a46dc5393c3013e04423767ca675f..d46cd4f161a7cbc905862744edb0827795491f94 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/access.h - checking access rights
+/* src/vmcore/access.h - checking access rights
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id: access.h 5223 2006-08-08 16:21:22Z edwin $
+   $Id: access.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #ifndef _ACCESS_H
 #define _ACCESS_H
 
+#include "config.h"
 #include "vm/types.h"
 
-#include "vm/references.h"
-#include "vm/class.h"
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+
 
 /* macros *********************************************************************/
 
diff --git a/src/vm/annotation.c b/src/vm/annotation.c
deleted file mode 100644 (file)
index 98aeef2..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* src/vm/annotation.c - class annotations
-
-   Copyright (C) 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
-
-*/
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "vm/annotation.h"
-#include "vm/class.h"
-#include "vm/suck.h"
-
-
-/* annotation_load_attribute_runtimevisibleannotations *************************
-
-   RuntimeVisibleAnnotations_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u2 num_annotations;
-       annotation annotations[num_annotations];
-   }
-
-   annotation {
-       u2 type_index;
-       u2 num_element_value_pairs;
-       {
-            u2            element_name_index;
-            element_value element;
-       } element_value_pairs[num_element_value_pairs];
-   }
-
-   element_value {
-       u1 tag;
-       union {
-           u2 const_value_index;
-           {
-               u2 type_name_index;
-               u2 const_name_index;
-           } enum_const_value;
-           u2 class_info_index;
-           annotation annotation_value;
-           {
-               u2 num_values;
-               element_value values[num_values];
-           } array_value;
-       } value;
-   }
-
-*******************************************************************************/
-
-bool annotation_load_attribute_runtimevisibleannotations(classbuffer *cb)
-{
-       classinfo       *c;
-       u4               attribute_length;
-       u2               num_annotations;
-       annotation_t    *aa;
-       element_value_t *element_value;
-       u2               type_index;
-       u2               num_element_value_pairs;
-       u2               element_name_index;
-       u4               i, j;
-
-       /* get classinfo */
-
-       c = cb->class;
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* attribute_length */
-
-       attribute_length = suck_u4(cb);
-
-       if (!suck_check_classbuffer_size(cb, attribute_length))
-               return false;
-
-       /* get number of annotations */
-
-       num_annotations = suck_u2(cb);
-
-       printf("num_annotations: %d\n", num_annotations);
-
-       /* allocate annotations-array */
-
-       aa = MNEW(annotation_t, num_annotations);
-
-       /* parse all annotations */
-
-       for (i = 0; i < num_annotations; i++) {
-               /* get annotation type */
-
-               type_index = suck_u2(cb);
-
-               if (!(aa[i].type = class_getconstant(c, type_index, CONSTANT_Utf8)))
-                       return false;
-
-               printf("type: ");
-               utf_display_printable_ascii(aa[i].type);
-               printf("\n");
-
-               /* get number of element values */
-
-               num_element_value_pairs = suck_u2(cb);
-
-               printf("num_element_value_pairs: %d\n", num_element_value_pairs);
-
-               element_value = MNEW(element_value_t, num_element_value_pairs);
-
-               /* parse all element values */
-
-               for (j = 0; j < num_element_value_pairs; j++) {
-                       /* get element name */
-
-                       element_name_index = suck_u2(cb);
-
-                       if (!(element_value[j].name =
-                                 class_getconstant(c, element_name_index, CONSTANT_Utf8)))
-                               return false;
-
-                       /* get element tag */
-
-                       element_value[i].tag = suck_u1(cb);
-               }
-
-               /* store element value data */
-
-               aa[i].element_valuescount = num_element_value_pairs;
-               aa[i].element_values      = element_value;
-       }
-
-       /* store annotation variables */
-
-       c->runtimevisibleannotationscount = num_annotations;
-       c->runtimevisibleannotations      = aa;
-
-       return true;
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/annotation.h b/src/vm/annotation.h
deleted file mode 100644 (file)
index fd3f5c9..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* src/vm/annotation.h - class annotations
-
-   Copyright (C) 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
-
-*/
-
-
-#ifndef _ANNOTATION_H
-#define _ANNOTATION_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct annotation_t    annotation_t;
-typedef struct element_value_t element_value_t;
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/utf8.h"
-
-
-/* annotation *****************************************************************/
-
-struct annotation_t {
-       utf             *type;
-       s4               element_valuescount;
-       element_value_t *element_values;
-};
-
-
-/* element_value **************************************************************/
-
-struct element_value_t {
-       utf *name;
-       u1   tag;
-};
-
-
-/* function prototypes ********************************************************/
-
-bool annotation_load_attribute_runtimevisibleannotations(classbuffer *cb);
-
-#endif /* _ANNOTATION_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
index ee42646aa0f276dc804ea5f4b1583ab2b30781d0..269a559cc674bbdd2ffc1c6337a8ce28f8accae3 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Andreas Krall
-            Mark Probst
-            Christian Thalinger
-            Edwin Steiner
-
    Contains C functions for JavaVM Instructions that cannot be
    translated to machine language directly. Consequently, the
    generated machine code for these instructions contains function
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 7241 2007-01-27 15:52:01Z twisti $
+   $Id: builtin.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "mm/gc-common.h"
 #include "mm/memory.h"
 
+#include "native/jni.h"
+#include "native/include/java_lang_String.h"
+#include "native/include/java_lang_Throwable.h"
+
 #if defined(ENABLE_THREADS)
 # include "threads/native/threads.h"
 #endif
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
+#include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
-#include "vm/rt-timing.h"
-#include "vm/cycles-stats.h"
+
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/rt-timing.h"
 
 
 /* include builtin tables *****************************************************/
@@ -811,9 +810,7 @@ java_objectheader *builtin_new(classinfo *c)
        /* check if we can instantiate this class */
 
        if (c->flags & ACC_ABSTRACT) {
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_InstantiationError,
-                                                                        c->name);
+               exceptions_throw_instantiationerror(c);
                return NULL;
        }
 
@@ -2710,8 +2707,7 @@ java_objectheader *builtin_clone(void *env, java_objectheader *o)
     /* we are cloning a non-array */
 
     if (!builtin_instanceof(o, class_java_lang_Cloneable)) {
-        *exceptionptr =
-                       new_exception(string_java_lang_CloneNotSupportedException);
+        exceptions_throw_clonenotsupportedexception();
         return NULL;
     }
 
index 3886016e983b5129ca80e8c0684e7c04d1b728e7..c41ca6bd13cef4be47fac0646390cc6a74d16ece 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/builtin.h - prototypes of builtin functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Edwin Steiner
-            Christian Thalinger
-
-   $Id: builtin.h 6013 2006-11-16 22:14:10Z twisti $
+   $Id: builtin.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #define _BUILTIN_H
 
 #include "config.h"
+#include "vm/types.h"
 
 #include "arch.h"
-#include "toolbox/logging.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
+#include "toolbox/logging.h"
 
-#include "vm/jit/stacktrace.h"
+#include "vmcore/utf8.h"
 
 
 /* define infinity for floating point numbers */
diff --git a/src/vm/class.c b/src/vm/class.c
deleted file mode 100644 (file)
index 1e50710..0000000
+++ /dev/null
@@ -1,1689 +0,0 @@
-/* src/vm/class.c - class related functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Mark Probst
-            Andreas Krall
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: class.c 6251 2006-12-27 23:15:56Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
-
-#include "toolbox/logging.h"
-#include "vm/class.h"
-#include "vm/classcache.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/suck.h"
-#include "vm/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-list unlinkedclasses;                   /* this is only used for eager class  */
-                                        /* loading                            */
-
-
-/* frequently used classes ****************************************************/
-
-/* important system classes */
-
-classinfo *class_java_lang_Object;
-classinfo *class_java_lang_Class;
-classinfo *class_java_lang_ClassLoader;
-classinfo *class_java_lang_Cloneable;
-classinfo *class_java_lang_SecurityManager;
-classinfo *class_java_lang_String;
-classinfo *class_java_lang_System;
-classinfo *class_java_lang_Thread;
-classinfo *class_java_lang_ThreadGroup;
-classinfo *class_java_lang_VMSystem;
-classinfo *class_java_lang_VMThread;
-classinfo *class_java_io_Serializable;
-
-
-/* system exception classes required in cacao */
-
-classinfo *class_java_lang_Throwable;
-classinfo *class_java_lang_Error;
-classinfo *class_java_lang_LinkageError;
-classinfo *class_java_lang_NoClassDefFoundError;
-classinfo *class_java_lang_OutOfMemoryError;
-classinfo *class_java_lang_VirtualMachineError;
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_AbstractMethodError;
-classinfo *class_java_lang_NoSuchMethodError;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-classinfo *class_java_lang_VMThrowable;
-#endif
-
-classinfo *class_java_lang_Exception;
-classinfo *class_java_lang_ClassCastException;
-classinfo *class_java_lang_ClassNotFoundException;
-classinfo *class_java_lang_IllegalArgumentException;
-classinfo *class_java_lang_IllegalMonitorStateException;
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_Void;
-#endif
-classinfo *class_java_lang_Boolean;
-classinfo *class_java_lang_Byte;
-classinfo *class_java_lang_Character;
-classinfo *class_java_lang_Short;
-classinfo *class_java_lang_Integer;
-classinfo *class_java_lang_Long;
-classinfo *class_java_lang_Float;
-classinfo *class_java_lang_Double;
-
-
-/* some runtime exception */
-
-classinfo *class_java_lang_NullPointerException;
-
-
-/* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-classinfo *class_java_lang_StackTraceElement;
-classinfo *class_java_lang_reflect_Constructor;
-classinfo *class_java_lang_reflect_Field;
-classinfo *class_java_lang_reflect_Method;
-classinfo *class_java_security_PrivilegedAction;
-classinfo *class_java_util_Vector;
-
-classinfo *arrayclass_java_lang_Object;
-#endif
-
-
-/* pseudo classes for the typechecker */
-
-classinfo *pseudo_class_Arraystub;
-classinfo *pseudo_class_Null;
-classinfo *pseudo_class_New;
-
-
-/* class_set_packagename *******************************************************
-
-   Derive the package name from the class name and store it in the struct.
-
-*******************************************************************************/
-
-void class_set_packagename(classinfo *c)
-{
-       char *p = UTF_END(c->name) - 1;
-       char *start = c->name->text;
-
-       /* set the package name */
-       /* classes in the unnamed package keep packagename == NULL */
-
-       if (c->name->text[0] == '[') {
-               /* set packagename of arrays to the element's package */
-
-               for (; *start == '['; start++);
-
-               /* skip the 'L' in arrays of references */
-               if (*start == 'L')
-                       start++;
-
-               for (; (p > start) && (*p != '/'); --p);
-
-               c->packagename = utf_new(start, p - start);
-
-       } else {
-               for (; (p > start) && (*p != '/'); --p);
-
-               c->packagename = utf_new(start, p - start);
-       }
-}
-
-
-/* class_create_classinfo ******************************************************
-
-   Create a new classinfo struct. The class name is set to the given utf *,
-   most other fields are initialized to zero.
-
-   Note: classname may be NULL. In this case a not-yet-named classinfo is
-         created. The name must be filled in later and class_set_packagename
-                must be called after that.
-
-*******************************************************************************/
-
-classinfo *class_create_classinfo(utf *classname)
-{
-       classinfo *c;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_classinfo += sizeof(classinfo);
-#endif
-
-       /* we use a safe name for temporarily unnamed classes */
-       if (!classname)
-               classname = utf_not_named_yet;
-
-#if !defined(NDEBUG)
-       if (initverbose)
-               log_message_utf("Creating class: ", classname);
-#endif
-
-       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
-
-       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
-       /*c=NEW(classinfo);*/
-       c->name = classname;
-
-       /* set the header.vftbl of all loaded classes to the one of
-       java.lang.Class, so Java code can use a class as object */
-
-       if (class_java_lang_Class)
-               if (class_java_lang_Class->vftbl)
-                       c->object.header.vftbl = class_java_lang_Class->vftbl;
-       
-       if (classname != utf_not_named_yet)
-               class_set_packagename(c);
-
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&c->object.header);
-#endif
-
-       return c;
-}
-
-
-/* class_postset_header_vftbl **************************************************
-
-   Set the header.vftbl of all classes created before java.lang.Class
-   was linked.  This is necessary that Java code can use a class as
-   object.
-
-*******************************************************************************/
-
-void class_postset_header_vftbl(void)
-{
-       classinfo *c;
-       u4 slot;
-       classcache_name_entry *nmen;
-       classcache_class_entry *clsen;
-
-       assert(class_java_lang_Class);
-
-       for (slot = 0; slot < hashtable_classcache.size; slot++) {
-               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
-               for (; nmen; nmen = nmen->hashlink) {
-                       /* iterate over all class entries */
-
-                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
-                               c = clsen->classobj;
-
-                               /* now set the the vftbl */
-
-                               if (c->object.header.vftbl == NULL)
-                                       c->object.header.vftbl = class_java_lang_Class->vftbl;
-                       }
-               }
-       }
-}
-
-
-/* class_load_attribute_sourcefile *********************************************
-
-   SourceFile_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-          u2 sourcefile_index;
-   }
-
-*******************************************************************************/
-
-static bool class_load_attribute_sourcefile(classbuffer *cb)
-{
-       classinfo *c;
-       u4         attribute_length;
-       u2         sourcefile_index;
-       utf       *sourcefile;
-
-       /* get classinfo */
-
-       c = cb->class;
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* check attribute length */
-
-       attribute_length = suck_u4(cb);
-
-       if (attribute_length != 2) {
-               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-               return false;
-       }
-
-       /* there can be no more than one SourceFile attribute */
-
-       if (c->sourcefile != NULL) {
-               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
-               return false;
-       }
-
-       /* get sourcefile */
-
-       sourcefile_index = suck_u2(cb);
-       sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
-
-       if (sourcefile == NULL)
-               return false;
-
-       /* store sourcefile */
-
-       c->sourcefile = sourcefile;
-
-       return true;
-}
-
-
-/* class_load_attribute_enclosingmethod ****************************************
-
-   EnclosingMethod_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-          u2 class_index;
-          u2 method_index;
-   }
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-static bool class_load_attribute_enclosingmethod(classbuffer *cb)
-{
-       classinfo             *c;
-       u4                     attribute_length;
-       u2                     class_index;
-       u2                     method_index;
-       classref_or_classinfo  cr;
-       constant_nameandtype  *cn;
-
-       /* get classinfo */
-
-       c = cb->class;
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
-               return false;
-
-       /* check attribute length */
-
-       attribute_length = suck_u4(cb);
-
-       if (attribute_length != 4) {
-               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-               return false;
-       }
-
-       /* there can be no more than one EnclosingMethod attribute */
-
-       if (c->enclosingmethod != NULL) {
-               exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
-               return false;
-       }
-
-       /* get class index */
-
-       class_index = suck_u2(cb);
-       cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
-
-       /* get method index */
-
-       method_index = suck_u2(cb);
-       cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
-
-       /* store info in classinfo */
-
-       c->enclosingclass.any = cr.any;
-       c->enclosingmethod    = cn;
-
-       return true;
-}
-#endif /* defined(ENABLE_JAVASE) */
-
-
-/* class_load_attributes *******************************************************
-
-   Read attributes from ClassFile.
-
-   attribute_info {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 info[attribute_length];
-   }
-
-   InnerClasses_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-   }
-
-*******************************************************************************/
-
-bool class_load_attributes(classbuffer *cb)
-{
-       classinfo *c;
-       u4         i, j;
-       u2         attributes_count;
-       u2         attribute_name_index;
-       utf       *attribute_name;
-
-       c = cb->class;
-
-       /* get attributes count */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       attributes_count = suck_u2(cb);
-
-       for (i = 0; i < attributes_count; i++) {
-               /* get attribute name */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               attribute_name_index = suck_u2(cb);
-               attribute_name =
-                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
-
-               if (attribute_name == NULL)
-                       return false;
-
-               if (attribute_name == utf_InnerClasses) {
-                       /* InnerClasses */
-
-                       if (c->innerclass != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
-                               return false;
-                       }
-                               
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* skip attribute length */
-                       suck_u4(cb);
-
-                       /* number of records */
-                       c->innerclasscount = suck_u2(cb);
-
-                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
-                               return false;
-
-                       /* allocate memory for innerclass structure */
-                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
-
-                       for (j = 0; j < c->innerclasscount; j++) {
-                               /* The innerclass structure contains a class with an encoded
-                                  name, its defining scope, its simple name and a bitmask of
-                                  the access flags. If an inner class is not a member, its
-                                  outer_class is NULL, if a class is anonymous, its name is
-                                  NULL. */
-                                                               
-                               innerclassinfo *info = c->innerclass + j;
-
-                               info->inner_class.ref =
-                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
-                               info->outer_class.ref =
-                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
-                               info->name =
-                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
-                               info->flags = suck_u2(cb);
-                       }
-               }
-               else if (attribute_name == utf_SourceFile) {
-                       /* SourceFile */
-
-                       if (!class_load_attribute_sourcefile(cb))
-                               return false;
-               }
-#if defined(ENABLE_JAVASE)
-               else if (attribute_name == utf_EnclosingMethod) {
-                       /* EnclosingMethod */
-
-                       if (!class_load_attribute_enclosingmethod(cb))
-                               return false;
-               }
-               else if (attribute_name == utf_Signature) {
-                       /* Signature */
-
-                       if (!loader_load_attribute_signature(cb, &(c->signature)))
-                               return false;
-               }
-               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
-                       /* RuntimeVisibleAnnotations */
-
-                       if (!annotation_load_attribute_runtimevisibleannotations(cb))
-                               return false;
-               }
-#endif
-               else {
-                       /* unknown attribute */
-
-                       if (!loader_skip_attribute_body(cb))
-                               return false;
-               }
-       }
-
-       return true;
-}
-
-
-/* class_freepool **************************************************************
-
-       Frees all resources used by this classes Constant Pool.
-
-*******************************************************************************/
-
-static void class_freecpool(classinfo *c)
-{
-       u4 idx;
-       u4 tag;
-       voidptr info;
-       
-       if (c->cptags && c->cpinfos) {
-               for (idx = 0; idx < c->cpcount; idx++) {
-                       tag = c->cptags[idx];
-                       info = c->cpinfos[idx];
-               
-                       if (info != NULL) {
-                               switch (tag) {
-                               case CONSTANT_Fieldref:
-                               case CONSTANT_Methodref:
-                               case CONSTANT_InterfaceMethodref:
-                                       FREE(info, constant_FMIref);
-                                       break;
-                               case CONSTANT_Integer:
-                                       FREE(info, constant_integer);
-                                       break;
-                               case CONSTANT_Float:
-                                       FREE(info, constant_float);
-                                       break;
-                               case CONSTANT_Long:
-                                       FREE(info, constant_long);
-                                       break;
-                               case CONSTANT_Double:
-                                       FREE(info, constant_double);
-                                       break;
-                               case CONSTANT_NameAndType:
-                                       FREE(info, constant_nameandtype);
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       if (c->cptags)
-               MFREE(c->cptags, u1, c->cpcount);
-
-       if (c->cpinfos)
-               MFREE(c->cpinfos, voidptr, c->cpcount);
-}
-
-
-/* class_getconstant ***********************************************************
-
-   Retrieves the value at position 'pos' of the constantpool of a
-   class. If the type of the value is other than 'ctype', an error is
-   thrown.
-
-*******************************************************************************/
-
-voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
-{
-       /* check index and type of constantpool entry */
-       /* (pos == 0 is caught by type comparison) */
-
-       if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool index");
-               return NULL;
-       }
-
-       return c->cpinfos[pos];
-}
-
-
-/* innerclass_getconstant ******************************************************
-
-   Like class_getconstant, but if cptags is ZERO, null is returned.
-       
-*******************************************************************************/
-
-voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
-{
-       /* invalid position in constantpool */
-
-       if (pos >= c->cpcount) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool index");
-               return NULL;
-       }
-
-       /* constantpool entry of type 0 */      
-
-       if (c->cptags[pos] == 0)
-               return NULL;
-
-       /* check type of constantpool entry */
-
-       if (c->cptags[pos] != ctype) {
-               *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
-               return NULL;
-       }
-               
-       return c->cpinfos[pos];
-}
-
-
-/* class_free ******************************************************************
-
-   Frees all resources used by the class.
-
-*******************************************************************************/
-
-void class_free(classinfo *c)
-{
-       s4 i;
-       vftbl_t *v;
-               
-       class_freecpool(c);
-
-       if (c->interfaces)
-               MFREE(c->interfaces, classinfo*, c->interfacescount);
-
-       if (c->fields) {
-               for (i = 0; i < c->fieldscount; i++)
-                       field_free(&(c->fields[i]));
-#if defined(ENABLE_CACAO_GC)
-               MFREE(c->fields, fieldinfo, c->fieldscount);
-#endif
-       }
-       
-       if (c->methods) {
-               for (i = 0; i < c->methodscount; i++)
-                       method_free(&(c->methods[i]));
-               MFREE(c->methods, methodinfo, c->methodscount);
-       }
-
-       if ((v = c->vftbl) != NULL) {
-               if (v->arraydesc)
-                       mem_free(v->arraydesc,sizeof(arraydescriptor));
-               
-               for (i = 0; i < v->interfacetablelength; i++) {
-                       MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
-               }
-               MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
-
-               i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
-                   sizeof(methodptr*) * (v->interfacetablelength -
-                                        (v->interfacetablelength > 0));
-               v = (vftbl_t*) (((methodptr*) v) -
-                                               (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
-               mem_free(v, i);
-       }
-
-       if (c->innerclass)
-               MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
-
-       /*      if (c->classvftbl)
-               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
-       
-/*     GCFREE(c); */
-}
-
-
-/* get_array_class *************************************************************
-
-   Returns the array class with the given name for the given
-   classloader, or NULL if an exception occurred.
-
-   Note: This function does eager loading. 
-
-*******************************************************************************/
-
-static classinfo *get_array_class(utf *name,java_objectheader *initloader,
-                                                                                       java_objectheader *defloader,bool link)
-{
-       classinfo *c;
-       
-       /* lookup this class in the classcache */
-       c = classcache_lookup(initloader,name);
-       if (!c)
-               c = classcache_lookup_defined(defloader,name);
-
-       if (!c) {
-               /* we have to create it */
-               c = class_create_classinfo(name);
-               c = load_newly_created_array(c,initloader);
-               if (c == NULL)
-                       return NULL;
-       }
-
-       assert(c);
-       assert(c->state & CLASS_LOADED);
-       assert(c->classloader == defloader);
-
-       if (link && !(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return NULL;
-
-       assert(!link || (c->state & CLASS_LINKED));
-
-       return c;
-}
-
-
-/* class_array_of **************************************************************
-
-   Returns an array class with the given component class. The array
-   class is dynamically created if neccessary.
-
-*******************************************************************************/
-
-classinfo *class_array_of(classinfo *component, bool link)
-{
-    s4 namelen;
-    char *namebuf;
-       s4 dumpsize;
-       classinfo *c;
-
-       dumpsize = dump_size();
-
-    /* Assemble the array class name */
-    namelen = component->name->blength;
-    
-    if (component->name->text[0] == '[') {
-        /* the component is itself an array */
-        namebuf = DMNEW(char, namelen + 1);
-        namebuf[0] = '[';
-        MCOPY(namebuf + 1, component->name->text, char, namelen);
-        namelen++;
-
-    } else {
-        /* the component is a non-array class */
-        namebuf = DMNEW(char, namelen + 3);
-        namebuf[0] = '[';
-        namebuf[1] = 'L';
-        MCOPY(namebuf + 2, component->name->text, char, namelen);
-        namebuf[2 + namelen] = ';';
-        namelen += 3;
-    }
-
-       c = get_array_class(utf_new(namebuf, namelen),
-                                               component->classloader,
-                                               component->classloader,
-                                               link);
-
-       dump_release(dumpsize);
-
-       return c;
-}
-
-
-/* class_multiarray_of *********************************************************
-
-   Returns an array class with the given dimension and element class.
-   The array class is dynamically created if neccessary.
-
-*******************************************************************************/
-
-classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
-{
-    s4 namelen;
-    char *namebuf;
-       s4 dumpsize;
-       classinfo *c;
-
-       dumpsize = dump_size();
-
-       if (dim < 1) {
-               log_text("Invalid array dimension requested");
-               assert(0);
-       }
-
-    /* Assemble the array class name */
-    namelen = element->name->blength;
-    
-    if (element->name->text[0] == '[') {
-        /* the element is itself an array */
-        namebuf = DMNEW(char, namelen + dim);
-        memcpy(namebuf + dim, element->name->text, namelen);
-        namelen += dim;
-    }
-    else {
-        /* the element is a non-array class */
-        namebuf = DMNEW(char, namelen + 2 + dim);
-        namebuf[dim] = 'L';
-        memcpy(namebuf + dim + 1, element->name->text, namelen);
-        namelen += (2 + dim);
-        namebuf[namelen - 1] = ';';
-    }
-       memset(namebuf, '[', dim);
-
-       c = get_array_class(utf_new(namebuf, namelen),
-                                               element->classloader,
-                                               element->classloader,
-                                               link);
-
-       dump_release(dumpsize);
-
-       return c;
-}
-
-
-/* class_lookup_classref *******************************************************
-
-   Looks up the constant_classref for a given classname in the classref
-   tables of a class.
-
-   IN:
-       cls..............the class containing the reference
-          name.............the name of the class refered to
-
-    RETURN VALUE:
-          a pointer to a constant_classref, or 
-          NULL if the reference was not found
-   
-*******************************************************************************/
-
-constant_classref *class_lookup_classref(classinfo *cls, utf *name)
-{
-       constant_classref *ref;
-       extra_classref *xref;
-       int count;
-
-       assert(cls);
-       assert(name);
-       assert(!cls->classrefcount || cls->classrefs);
-       
-       /* first search the main classref table */
-       count = cls->classrefcount;
-       ref = cls->classrefs;
-       for (; count; --count, ++ref)
-               if (ref->name == name)
-                       return ref;
-
-       /* next try the list of extra classrefs */
-       for (xref = cls->extclassrefs; xref; xref = xref->next) {
-               if (xref->classref.name == name)
-                       return &(xref->classref);
-       }
-
-       /* not found */
-       return NULL;
-}
-
-
-/* class_get_classref **********************************************************
-
-   Returns the constant_classref for a given classname.
-
-   IN:
-       cls..............the class containing the reference
-          name.............the name of the class refered to
-
-   RETURN VALUE:
-       a pointer to a constant_classref (never NULL)
-
-   NOTE:
-       The given name is not checked for validity!
-   
-*******************************************************************************/
-
-constant_classref *class_get_classref(classinfo *cls, utf *name)
-{
-       constant_classref *ref;
-       extra_classref *xref;
-
-       assert(cls);
-       assert(name);
-
-       ref = class_lookup_classref(cls,name);
-       if (ref)
-               return ref;
-
-       xref = NEW(extra_classref);
-       CLASSREF_INIT(xref->classref,cls,name);
-
-       xref->next = cls->extclassrefs;
-       cls->extclassrefs = xref;
-
-       return &(xref->classref);
-}
-
-
-/* class_get_self_classref *****************************************************
-
-   Returns the constant_classref to the class itself.
-
-   IN:
-       cls..............the class containing the reference
-
-   RETURN VALUE:
-       a pointer to a constant_classref (never NULL)
-
-*******************************************************************************/
-
-constant_classref *class_get_self_classref(classinfo *cls)
-{
-       /* XXX this should be done in a faster way. Maybe always make */
-       /* the classref of index 0 a self reference.                  */
-       return class_get_classref(cls,cls->name);
-}
-
-/* class_get_classref_multiarray_of ********************************************
-
-   Returns an array type reference with the given dimension and element class
-   reference.
-
-   IN:
-       dim..............the requested dimension
-                           dim must be in [1;255]. This is NOT checked!
-          ref..............the component class reference
-
-   RETURN VALUE:
-       a pointer to the class reference for the array type
-
-   NOTE:
-       The referer of `ref` is used as the referer for the new classref.
-
-*******************************************************************************/
-
-constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
-{
-    s4 namelen;
-    char *namebuf;
-       s4 dumpsize;
-       constant_classref *cr;
-
-       assert(ref);
-       assert(dim >= 1 && dim <= 255);
-
-       dumpsize = dump_size();
-
-    /* Assemble the array class name */
-    namelen = ref->name->blength;
-    
-    if (ref->name->text[0] == '[') {
-        /* the element is itself an array */
-        namebuf = DMNEW(char, namelen + dim);
-        memcpy(namebuf + dim, ref->name->text, namelen);
-        namelen += dim;
-    }
-    else {
-        /* the element is a non-array class */
-        namebuf = DMNEW(char, namelen + 2 + dim);
-        namebuf[dim] = 'L';
-        memcpy(namebuf + dim + 1, ref->name->text, namelen);
-        namelen += (2 + dim);
-        namebuf[namelen - 1] = ';';
-    }
-       memset(namebuf, '[', dim);
-
-    cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
-
-       dump_release(dumpsize);
-
-       return cr;
-}
-
-
-/* class_get_classref_component_of *********************************************
-
-   Returns the component classref of a given array type reference
-
-   IN:
-       ref..............the array type reference
-
-   RETURN VALUE:
-       a reference to the component class, or
-          NULL if `ref` is not an object array type reference
-
-   NOTE:
-       The referer of `ref` is used as the referer for the new classref.
-
-*******************************************************************************/
-
-constant_classref *class_get_classref_component_of(constant_classref *ref)
-{
-       s4 namelen;
-       char *name;
-       
-       assert(ref);
-
-       name = ref->name->text;
-       if (*name++ != '[')
-               return NULL;
-       
-       namelen = ref->name->blength - 1;
-       if (*name == 'L') {
-               name++;
-               namelen -= 2;
-       }
-       else if (*name != '[') {
-               return NULL;
-       }
-
-    return class_get_classref(ref->referer, utf_new(name, namelen));
-}
-
-
-/* class_findmethod ************************************************************
-       
-   Searches a 'classinfo' structure for a method having the given name
-   and descriptor. If descriptor is NULL, it is ignored.
-
-*******************************************************************************/
-
-methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
-{
-       methodinfo *m;
-       s4          i;
-
-       for (i = 0; i < c->methodscount; i++) {
-               m = &(c->methods[i]);
-
-               if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
-                       return m;
-       }
-
-       return NULL;
-}
-
-
-/* class_resolvemethod *********************************************************
-       
-   Searches a class and it's super classes for a method.
-
-   Superinterfaces are *not* searched.
-
-*******************************************************************************/
-
-methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
-{
-       methodinfo *m;
-
-       while (c) {
-               m = class_findmethod(c, name, desc);
-
-               if (m)
-                       return m;
-
-               /* JVM Specification bug: 
-
-                  It is important NOT to resolve special <init> and <clinit>
-                  methods to super classes or interfaces; yet, this is not
-                  explicited in the specification.  Section 5.4.3.3 should be
-                  updated appropriately.  */
-
-               if (name == utf_init || name == utf_clinit)
-                       return NULL;
-
-               c = c->super.cls;
-       }
-
-       return NULL;
-}
-
-
-/* class_resolveinterfacemethod_intern *****************************************
-
-   Internally used helper function. Do not use this directly.
-
-*******************************************************************************/
-
-static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
-                                                                                                          utf *name, utf *desc)
-{
-       methodinfo *m;
-       s4          i;
-
-       /* try to find the method in the class */
-
-       m = class_findmethod(c, name, desc);
-
-       if (m != NULL)
-               return m;
-
-       /* no method found? try the superinterfaces */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
-                                                                                                       name, desc);
-
-               if (m != NULL)
-                       return m;
-       }
-
-       /* no method found */
-
-       return NULL;
-}
-
-
-/* class_resolveclassmethod ****************************************************
-       
-   Resolves a reference from REFERER to a method with NAME and DESC in
-   class C.
-
-   If the method cannot be resolved the return value is NULL. If
-   EXCEPT is true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
-                                                                        classinfo *referer, bool throwexception)
-{
-       classinfo  *cls;
-       methodinfo *m;
-       s4          i;
-
-/*     if (c->flags & ACC_INTERFACE) { */
-/*             if (throwexception) */
-/*                     *exceptionptr = */
-/*                             new_exception(string_java_lang_IncompatibleClassChangeError); */
-/*             return NULL; */
-/*     } */
-
-       /* try class c and its superclasses */
-
-       cls = c;
-
-       m = class_resolvemethod(cls, name, desc);
-
-       if (m != NULL)
-               goto found;
-
-       /* try the superinterfaces */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
-                                                                                               name, desc);
-
-               if (m != NULL)
-                       goto found;
-       }
-       
-       if (throwexception) {
-#if defined(ENABLE_JAVASE)
-               exceptions_throw_nosuchmethoderror(c, name, desc);
-#else
-               exceptions_throw_virtualmachineerror();
-#endif
-       }
-
-       return NULL;
-
- found:
-       if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
-               if (throwexception) {
-#if defined(ENABLE_JAVASE)
-                       exceptions_throw_abstractmethoderror();
-#else
-                       exceptions_throw_virtualmachineerror();
-#endif
-               }
-
-               return NULL;
-       }
-
-       /* XXX check access rights */
-
-       return m;
-}
-
-
-/* class_resolveinterfacemethod ************************************************
-
-   Resolves a reference from REFERER to a method with NAME and DESC in
-   interface C.
-
-   If the method cannot be resolved the return value is NULL. If
-   EXCEPT is true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
-                                                                                classinfo *referer, bool throwexception)
-{
-       methodinfo *mi;
-
-       if (!(c->flags & ACC_INTERFACE)) {
-               if (throwexception)
-                       *exceptionptr =
-                               new_exception(string_java_lang_IncompatibleClassChangeError);
-
-               return NULL;
-       }
-
-       mi = class_resolveinterfacemethod_intern(c, name, desc);
-
-       if (mi != NULL)
-               return mi;
-
-       /* try class java.lang.Object */
-
-       mi = class_findmethod(class_java_lang_Object, name, desc);
-
-       if (mi != NULL)
-               return mi;
-
-       if (throwexception) {
-#if defined(ENABLE_JAVASE)
-               exceptions_throw_nosuchmethoderror(c, name, desc);
-#else
-               exceptions_throw_virtualmachineerror();
-#endif
-       }
-
-       return NULL;
-}
-
-
-/* class_findfield *************************************************************
-       
-   Searches for field with specified name and type in a classinfo
-   structure. If no such field is found NULL is returned.
-
-*******************************************************************************/
-
-fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
-{
-       s4 i;
-
-       for (i = 0; i < c->fieldscount; i++)
-               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
-                       return &(c->fields[i]);
-
-       if (c->super.cls)
-               return class_findfield(c->super.cls, name, desc);
-
-       return NULL;
-}
-
-
-/* class_findfield_approx ******************************************************
-       
-   Searches in 'classinfo'-structure for a field with the specified
-   name.
-
-*******************************************************************************/
-fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
-{
-       s4 i;
-
-       /* get field index */
-
-       i = class_findfield_index_by_name(c, name);
-
-       /* field was not found, return */
-
-       if (i == -1)
-               return NULL;
-
-       /* return field address */
-
-       return &(c->fields[i]);
-}
-
-
-s4 class_findfield_index_by_name(classinfo *c, utf *name)
-{
-       s4 i;
-
-       for (i = 0; i < c->fieldscount; i++) {
-               /* compare field names */
-
-               if ((c->fields[i].name == name))
-                       return i;
-       }
-
-       /* field was not found, raise exception */      
-
-       *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
-
-       return -1;
-}
-
-
-/****************** Function: class_resolvefield_int ***************************
-
-    This is an internally used helper function. Do not use this directly.
-
-       Tries to resolve a field having the given name and type.
-    If the field cannot be resolved, NULL is returned.
-
-*******************************************************************************/
-
-static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
-{
-       fieldinfo *fi;
-       s4         i;
-
-       /* search for field in class c */
-
-       for (i = 0; i < c->fieldscount; i++) { 
-               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
-                       return &(c->fields[i]);
-               }
-    }
-
-       /* try superinterfaces recursively */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
-               if (fi)
-                       return fi;
-       }
-
-       /* try superclass */
-
-       if (c->super.cls)
-               return class_resolvefield_int(c->super.cls, name, desc);
-
-       /* not found */
-
-       return NULL;
-}
-
-
-/********************* Function: class_resolvefield ***************************
-       
-       Resolves a reference from REFERER to a field with NAME and DESC in class C.
-
-    If the field cannot be resolved the return value is NULL. If EXCEPT is
-    true *exceptionptr is set, too.
-
-*******************************************************************************/
-
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
-                                                         classinfo *referer, bool throwexception)
-{
-       fieldinfo *fi;
-
-       fi = class_resolvefield_int(c, name, desc);
-
-       if (!fi) {
-               if (throwexception)
-                       *exceptionptr =
-                               new_exception_utfmessage(string_java_lang_NoSuchFieldError,
-                                                                                name);
-
-               return NULL;
-       }
-
-       /* XXX check access rights */
-
-       return fi;
-}
-
-
-/* class_issubclass ************************************************************
-
-   Checks if sub is a descendant of super.
-       
-*******************************************************************************/
-
-bool class_issubclass(classinfo *sub, classinfo *super)
-{
-       for (;;) {
-               if (!sub)
-                       return false;
-
-               if (sub == super)
-                       return true;
-
-               sub = sub->super.cls;
-       }
-}
-
-
-/* class_printflags ************************************************************
-
-   Prints flags of a class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_printflags(classinfo *c)
-{
-       if (c == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
-       if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
-       if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
-       if (c->flags & ACC_STATIC)       printf(" STATIC");
-       if (c->flags & ACC_FINAL)        printf(" FINAL");
-       if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
-       if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
-       if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
-       if (c->flags & ACC_NATIVE)       printf(" NATIVE");
-       if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
-       if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
-}
-#endif
-
-
-/* class_print *****************************************************************
-
-   Prints classname plus flags.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_print(classinfo *c)
-{
-       if (c == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       utf_display_printable_ascii(c->name);
-       class_printflags(c);
-}
-#endif
-
-
-/* class_classref_print ********************************************************
-
-   Prints classname plus referer class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_print(constant_classref *cr)
-{
-       if (cr == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       utf_display_printable_ascii(cr->name);
-       printf("(ref.by ");
-       if (cr->referer)
-               class_print(cr->referer);
-       else
-               printf("NULL");
-       printf(")");
-}
-#endif
-
-
-/* class_println ***************************************************************
-
-   Prints classname plus flags and new line.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_println(classinfo *c)
-{
-       class_print(c);
-       printf("\n");
-}
-#endif
-
-
-/* class_classref_println ******************************************************
-
-   Prints classname plus referer class and new line.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_println(constant_classref *cr)
-{
-       class_classref_print(cr);
-       printf("\n");
-}
-#endif
-
-
-/* class_classref_or_classinfo_print *******************************************
-
-   Prints classname plus referer class.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_classref_or_classinfo_print(classref_or_classinfo c)
-{
-       if (c.any == NULL) {
-               printf("(classref_or_classinfo) NULL");
-               return;
-       }
-       if (IS_CLASSREF(c))
-               class_classref_print(c.ref);
-       else
-               class_print(c.cls);
-}
-#endif
-
-
-/* class_classref_or_classinfo_println *****************************************
-
-   Prints classname plus referer class and a newline.
-
-*******************************************************************************/
-
-void class_classref_or_classinfo_println(classref_or_classinfo c)
-{
-       class_classref_or_classinfo_println(c);
-       printf("\n");
-}
-
-
-/* class_showconstantpool ******************************************************
-
-   Dump the constant pool of the given class to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_showconstantpool (classinfo *c) 
-{
-       u4 i;
-       voidptr e;
-
-       printf ("---- dump of constant pool ----\n");
-
-       for (i=0; i<c->cpcount; i++) {
-               printf ("#%d:  ", (int) i);
-               
-               e = c -> cpinfos [i];
-               if (e) {
-                       
-                       switch (c -> cptags [i]) {
-                       case CONSTANT_Class:
-                               printf ("Classreference -> ");
-                               utf_display_printable_ascii ( ((constant_classref*)e) -> name );
-                               break;
-                       case CONSTANT_Fieldref:
-                               printf ("Fieldref -> ");
-                               field_fieldref_print((constant_FMIref *) e);
-                               break;
-                       case CONSTANT_Methodref:
-                               printf ("Methodref -> ");
-                               method_methodref_print((constant_FMIref *) e);
-                               break;
-                       case CONSTANT_InterfaceMethodref:
-                               printf ("InterfaceMethod -> ");
-                               method_methodref_print((constant_FMIref *) e);
-                               break;
-                       case CONSTANT_String:
-                               printf ("String -> ");
-                               utf_display_printable_ascii (e);
-                               break;
-                       case CONSTANT_Integer:
-                               printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
-                               break;
-                       case CONSTANT_Float:
-                               printf ("Float -> %f", ((constant_float*)e) -> value);
-                               break;
-                       case CONSTANT_Double:
-                               printf ("Double -> %f", ((constant_double*)e) -> value);
-                               break;
-                       case CONSTANT_Long:
-                               {
-                                       u8 v = ((constant_long*)e) -> value;
-#if U8_AVAILABLE
-                                       printf ("Long -> %ld", (long int) v);
-#else
-                                       printf ("Long -> HI: %ld, LO: %ld\n", 
-                                                       (long int) v.high, (long int) v.low);
-#endif 
-                               }
-                               break;
-                       case CONSTANT_NameAndType:
-                               {
-                                       constant_nameandtype *cnt = e;
-                                       printf ("NameAndType: ");
-                                       utf_display_printable_ascii (cnt->name);
-                                       printf (" ");
-                                       utf_display_printable_ascii (cnt->descriptor);
-                               }
-                               break;
-                       case CONSTANT_Utf8:
-                               printf ("Utf8 -> ");
-                               utf_display_printable_ascii (e);
-                               break;
-                       default: 
-                               log_text("Invalid type of ConstantPool-Entry");
-                               assert(0);
-                       }
-               }
-
-               printf ("\n");
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* class_showmethods ***********************************************************
-
-   Dump info about the fields and methods of the given class to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void class_showmethods (classinfo *c)
-{
-       s4 i;
-       
-       printf("--------- Fields and Methods ----------------\n");
-       printf("Flags: ");
-       class_printflags(c);
-       printf("\n");
-
-       printf("This: ");
-       utf_display_printable_ascii(c->name);
-       printf("\n");
-
-       if (c->super.cls) {
-               printf("Super: ");
-               utf_display_printable_ascii(c->super.cls->name);
-               printf ("\n");
-       }
-
-       printf("Index: %d\n", c->index);
-       
-       printf("Interfaces:\n");        
-       for (i = 0; i < c->interfacescount; i++) {
-               printf("   ");
-               utf_display_printable_ascii(c->interfaces[i].cls->name);
-               printf (" (%d)\n", c->interfaces[i].cls->index);
-       }
-
-       printf("Fields:\n");
-       for (i = 0; i < c->fieldscount; i++)
-               field_println(&(c->fields[i]));
-
-       printf("Methods:\n");
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               if (!(m->flags & ACC_STATIC))
-                       printf("vftblindex: %d   ", m->vftblindex);
-
-               method_println(m);
-       }
-
-       printf ("Virtual function table:\n");
-       for (i = 0; i < c->vftbl->vftbllength; i++)
-               printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
-}
-#endif /* !defined(NDEBUG) */
-
-
-/*
- * 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:
- */
diff --git a/src/vm/class.h b/src/vm/class.h
deleted file mode 100644 (file)
index 323a080..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-/* src/vm/class.h - class related functions header
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: class.h 6251 2006-12-27 23:15:56Z twisti $
-
-*/
-
-
-#ifndef _CLASS_H
-#define _CLASS_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct classinfo      classinfo; 
-typedef struct innerclassinfo innerclassinfo;
-typedef struct extra_classref extra_classref;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"                  /* define java_objectheader for j.l.C */
-
-#include "native/jni.h"
-
-#if defined(ENABLE_JAVAME_CLDC1_1)
-# include "native/include/java_lang_String.h"
-#endif
-
-#include "native/include/java_lang_Class.h"
-
-#include "toolbox/list.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vm/annotation.h"
-#endif
-
-#include "vm/field.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/method.h"
-#include "vm/references.h"
-#include "vm/utf8.h"
-
-
-/* class state defines ********************************************************/
-
-#define CLASS_LOADING         0x0001
-#define CLASS_LOADED          0x0002
-#define CLASS_LINKING         0x0004
-#define CLASS_LINKED          0x0008
-#define CLASS_INITIALIZING    0x0010
-#define CLASS_INITIALIZED     0x0020
-#define CLASS_ERROR           0x0040
-
-
-/* some macros ****************************************************************/
-
-#define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
-    (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
-
-
-/* classinfo ******************************************************************/
-
-struct classinfo {                /* class structure                          */
-       java_lang_Class object;       /* classinfos are also j.l.C objects        */
-
-       s4          flags;            /* ACC flags                                */
-       utf        *name;             /* class name                               */
-
-       s4          cpcount;          /* number of entries in constant pool       */
-       u1         *cptags;           /* constant pool tags                       */
-       voidptr    *cpinfos;          /* pointer to constant pool info structures */
-
-       s4          classrefcount;    /* number of symbolic class references      */
-       constant_classref *classrefs; /* table of symbolic class references       */
-       extra_classref *extclassrefs; /* additional classrefs                     */
-       s4          parseddescsize;   /* size of the parsed descriptors block     */
-       u1         *parseddescs;      /* parsed descriptors                       */
-
-       classref_or_classinfo super;  /* super class                              */
-       classinfo  *sub;              /* sub class pointer                        */
-       classinfo  *nextsub;          /* pointer to next class in sub class list  */
-
-       s4          interfacescount;  /* number of interfaces                     */
-       classref_or_classinfo *interfaces; /* superinterfaces                     */
-
-       s4          fieldscount;      /* number of fields                         */
-       fieldinfo  *fields;           /* field table                              */
-
-       s4          methodscount;     /* number of methods                        */
-       methodinfo *methods;          /* method table                             */
-
-       listnode    listnode;         /* linkage                                  */
-
-       s4          state;            /* current class state                      */
-       s4          index;            /* hierarchy depth (classes) or index       */
-                                     /* (interfaces)                             */
-       s4          instancesize;     /* size of an instance of this class        */
-
-       vftbl_t    *vftbl;            /* pointer to virtual function table        */
-
-       methodinfo *finalizer;        /* finalizer method                         */
-
-       u2          innerclasscount;  /* number of inner classes                  */
-       innerclassinfo *innerclass;
-
-#if defined(ENABLE_JAVASE)
-       classref_or_classinfo  enclosingclass;  /* enclosing class                */
-       constant_nameandtype  *enclosingmethod; /* enclosing method               */
-#endif
-
-       utf        *packagename;      /* full name of the package                 */
-       utf        *sourcefile;       /* SourceFile attribute                     */
-#if defined(ENABLE_JAVASE)
-       utf        *signature;        /* Signature attribute                      */
-       s4            runtimevisibleannotationscount;
-       annotation_t *runtimevisibleannotations;
-#endif
-       java_objectheader *classloader; /* NULL for bootstrap classloader         */
-};
-
-
-/* innerclassinfo *************************************************************/
-
-struct innerclassinfo {
-       classref_or_classinfo inner_class; /* inner class pointer                 */
-       classref_or_classinfo outer_class; /* outer class pointer                 */
-       utf                  *name;        /* innerclass name                     */
-       s4                    flags;       /* ACC flags                           */
-};
-
-
-/* extra_classref **************************************************************
-
-   for classrefs not occurring within descriptors
-
-*******************************************************************************/
-
-struct extra_classref {
-       extra_classref    *next;
-       constant_classref  classref;
-};
-
-
-/* global variables ***********************************************************/
-
-extern list unlinkedclasses;   /* this is only used for eager class loading   */
-
-
-/* frequently used classes ****************************************************/
-
-/* important system classes */
-
-extern classinfo *class_java_lang_Object;
-extern classinfo *class_java_lang_Class;
-extern classinfo *class_java_lang_ClassLoader;
-extern classinfo *class_java_lang_Cloneable;
-extern classinfo *class_java_lang_SecurityManager;
-extern classinfo *class_java_lang_String;
-extern classinfo *class_java_lang_System;
-extern classinfo *class_java_lang_Thread;
-extern classinfo *class_java_lang_ThreadGroup;
-extern classinfo *class_java_lang_VMSystem;
-extern classinfo *class_java_lang_VMThread;
-extern classinfo *class_java_io_Serializable;
-
-
-/* system exception classes required in cacao */
-
-extern classinfo *class_java_lang_Throwable;
-extern classinfo *class_java_lang_Error;
-extern classinfo *class_java_lang_LinkageError;
-extern classinfo *class_java_lang_NoClassDefFoundError;
-extern classinfo *class_java_lang_OutOfMemoryError;
-extern classinfo *class_java_lang_VirtualMachineError;
-
-#if defined(ENABLE_JAVASE)
-extern classinfo *class_java_lang_AbstractMethodError;
-extern classinfo *class_java_lang_NoSuchMethodError;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-extern classinfo *class_java_lang_VMThrowable;
-#endif
-
-extern classinfo *class_java_lang_Exception;
-extern classinfo *class_java_lang_ClassCastException;
-extern classinfo *class_java_lang_ClassNotFoundException;
-extern classinfo *class_java_lang_IllegalArgumentException;
-extern classinfo *class_java_lang_IllegalMonitorStateException;
-
-
-#if defined(ENABLE_JAVASE)
-extern classinfo *class_java_lang_Void;
-#endif
-
-extern classinfo *class_java_lang_Boolean;
-extern classinfo *class_java_lang_Byte;
-extern classinfo *class_java_lang_Character;
-extern classinfo *class_java_lang_Short;
-extern classinfo *class_java_lang_Integer;
-extern classinfo *class_java_lang_Long;
-extern classinfo *class_java_lang_Float;
-extern classinfo *class_java_lang_Double;
-
-
-/* some runtime exception */
-
-extern classinfo *class_java_lang_NullPointerException;
-
-
-/* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-extern classinfo *class_java_lang_StackTraceElement;
-extern classinfo *class_java_lang_reflect_Constructor;
-extern classinfo *class_java_lang_reflect_Field;
-extern classinfo *class_java_lang_reflect_Method;
-extern classinfo *class_java_security_PrivilegedAction;
-extern classinfo *class_java_util_Vector;
-
-extern classinfo *arrayclass_java_lang_Object;
-#endif
-
-
-/* pseudo classes for the type checker ****************************************/
-
-/*
- * pseudo_class_Arraystub
- *     (extends Object implements Cloneable, java.io.Serializable)
- *
- *     If two arrays of incompatible component types are merged,
- *     the resulting reference has no accessible components.
- *     The result does, however, implement the interfaces Cloneable
- *     and java.io.Serializable. This pseudo class is used internally
- *     to represent such results. (They are *not* considered arrays!)
- *
- * pseudo_class_Null
- *
- *     This pseudo class is used internally to represent the
- *     null type.
- *
- * pseudo_class_New
- *
- *     This pseudo class is used internally to represent the
- *     the 'uninitialized object' type.
- */
-
-extern classinfo *pseudo_class_Arraystub;
-extern classinfo *pseudo_class_Null;
-extern classinfo *pseudo_class_New;
-
-
-/* function prototypes ********************************************************/
-
-/* create a new classinfo struct */
-classinfo *class_create_classinfo(utf *u);
-
-/* postset's the header.vftbl */
-void class_postset_header_vftbl(void);
-
-/* set the package name after the name has been set */
-void class_set_packagename(classinfo *c);
-
-bool class_load_attributes(classbuffer *cb);
-
-/* retrieve constantpool element */
-voidptr class_getconstant(classinfo *class, u4 pos, u4 ctype);
-voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
-
-/* frees all resources used by the class */
-void class_free(classinfo *);
-
-/* return an array class with the given component class */
-classinfo *class_array_of(classinfo *component,bool link);
-
-/* return an array class with the given dimension and element class */
-classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
-
-/* return a classref for the given class name */
-/* (does a linear search!)                    */
-constant_classref *class_lookup_classref(classinfo *cls,utf *name);
-
-/* return a classref for the given class name */
-/* (does a linear search!)                    */
-constant_classref *class_get_classref(classinfo *cls,utf *name);
-
-/* return a classref to the class itself */
-/* (does a linear search!)                    */
-constant_classref *class_get_self_classref(classinfo *cls);
-
-/* return a classref for an array with the given dimension of with the */
-/* given component type */
-constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
-
-/* return a classref for the component type of the given array type */
-constant_classref *class_get_classref_component_of(constant_classref *ref);
-
-/* get a class' field by name and descriptor */
-fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
-
-/* search 'classinfo'-structure for a field with the specified name */
-fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
-s4 class_findfield_index_by_name(classinfo *c, utf *name);
-
-/* search class for a field */
-fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer, bool throwexception);
-
-/* search for a method with a specified name and descriptor */
-methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
-methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
-methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
-methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
-
-bool class_issubclass(classinfo *sub, classinfo *super);
-
-/* some debugging functions */
-
-#if !defined(NDEBUG)
-void class_printflags(classinfo *c);
-void class_print(classinfo *c);
-void class_println(classinfo *c);
-void class_classref_print(constant_classref *cr);
-void class_classref_println(constant_classref *cr);
-void class_classref_or_classinfo_print(classref_or_classinfo c);
-void class_classref_or_classinfo_println(classref_or_classinfo c);
-#endif
-
-/* debug purposes */
-void class_showmethods(classinfo *c);
-void class_showconstantpool(classinfo *c);
-
-#endif /* _CLASS_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:
- */
diff --git a/src/vm/classcache.c b/src/vm/classcache.c
deleted file mode 100644 (file)
index ca33343..0000000
+++ /dev/null
@@ -1,1587 +0,0 @@
-/* src/vm/classcache.c - loaded class cache and loading constraints
-
-   Copyright (C) 1996-2005, 2006, 2007 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-            Christian Thalinger
-
-   $Id: classcache.c 6286 2007-01-10 10:03:38Z twisti $
-
-*/
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include <assert.h>
-
-#include "mm/memory.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
-
-#include "vm/classcache.h"
-#include "vm/exceptions.h"
-#include "vm/hashtable.h"
-#include "vm/stringlocal.h"
-#include "vm/utf8.h"
-
-
-/*************************************************************************
-
-  Class Cache
-
-  The classcache has two functions:
-  
-       1) caching the resolution of class references
-       2) storing and checking loading constraints
-
-  We will use the following terms in this description:
-
-       N          a class name: a utf string
-       (N,L)      a class reference with initiating loader L and class name N
-       C          a class (object): the result of resolving a reference (N,L)
-               We will write resultion as
-                               C = *(N,L)
-       (N,L1,L2)  a loading constraint indicating that (N,L1) and (N,L2) must
-                  resolve to the same class C. So (N,L1,L2) means
-                               *(N,L1) = *(N,L2)
-
-  The functions of the classcache require:
-
-    1) a mapping (N,L) |--> C for looking up prior resolution results.
-       2) storing the current set of loading constraints { (N,L1,L2) }
-
-  These functions can be rearranged like that:
-
-    a mapping N |--> (a mapping L |--> C or NULL, 
-                         a set of constraints {(L1,L2)})
-
-  Thus we can treat the mapping and constraints for each name N
-  separately. The implementation does this by keeping a hash table
-  mapping a name N to a `classcache_name_entry` which contains all
-  info with respect to N.
-
-  For a class name N we can define an equivalence relation ~N~ on
-  class loaders:
-
-       L1 ~N~ L2  <==>  *(N,L1) = *(N,L2)
-
-  A loading constraint (N,L1,L2) implies L1 ~N~ L2.
-
-  Also, if two references (N,L1) and (N,L2) resolve to the same class C
-  we have L1 ~N~ L2 because class loaders are required to return
-  consistent resolutions for a name N [XXX].
-
-  A `classcache_name_entry` keeps a set of tuples { (Cx,IL,CL) },
-  where
-               Cx...is a class C or NULL
-               IL...is the set of initiating loaders
-               CL...is the set of constrained loaders
-               
-  Such a tuple is called `classcache_class_entry` in the source code.
-
-  The following holds for each tuple (Cx,IL,CL):
-
-    .  (Cx is NULL) implies IL = {}.
-          
-       .  If Cx is a class, IL is the set of loaders that have been
-          recorded as initiating loaders for Cx. IL may be the
-          empty set {} in case Cx has already been defined but no
-          initiating loader has been recorded, yet.
-  
-    .  (IL u CL) is a subset of an equivalence class of ~N~.
-
-                (This means that all loaders in IL and CL must resolve
-                the name N to the same class.)
-
-  The following holds for the set of tuples { (Cx,IL,CL) }:
-
-    .  For a given class C there is at most one tuple with Cx = C
-          in the set. (There may be an arbitrary number of tuples
-          with Cx = NULL, however.)
-
-       .  For a given loader L there is at most one tuple with
-          L in (IL u CL).
-
-  The implementation stores sets of loaders as linked lists of
-  `classcache_loader_entry`s.
-
-  Comments about manipulating the classcache can be found in the
-  individual functions below.
-*************************************************************************/
-
-
-/* initial number of slots in the classcache hash table */
-#define CLASSCACHE_INIT_SIZE  2048
-
-/*============================================================================*/
-/* DEBUG HELPERS                                                              */
-/*============================================================================*/
-
-/*#define CLASSCACHE_VERBOSE*/
-
-/*============================================================================*/
-/* STATISTICS                                                                 */
-/*============================================================================*/
-
-/*#define CLASSCACHE_STATS*/
-
-#ifdef CLASSCACHE_STATS
-static int stat_classnames_stored = 0;
-static int stat_classes_stored = 0;
-static int stat_trivial_constraints = 0;
-static int stat_nontriv_constraints = 0;
-static int stat_nontriv_constraints_both = 0;
-static int stat_nontriv_constraints_merged = 0;
-static int stat_nontriv_constraints_one = 0;
-static int stat_nontriv_constraints_none = 0;
-static int stat_new_loader_entry = 0;
-static int stat_merge_class_entries = 0;
-static int stat_merge_loader_entries = 0;
-static int stat_lookup = 0;
-static int stat_lookup_class_entry_checked = 0;
-static int stat_lookup_loader_checked = 0;
-static int stat_lookup_name = 0;
-static int stat_lookup_name_entry = 0;
-static int stat_lookup_name_notfound = 0;
-static int stat_lookup_new_name = 0;
-static int stat_lookup_new_name_entry = 0;
-static int stat_lookup_new_name_collisions = 0;
-static int stat_rehash_names = 0;
-static int stat_rehash_names_collisions = 0;
-
-#define CLASSCACHE_COUNT(cnt)  (cnt)++
-#define CLASSCACHE_COUNTIF(cond,cnt)  do{if(cond) (cnt)++;} while(0)
-
-void classcache_print_statistics(FILE *file) {
-       fprintf(file,"classnames stored   : %8d\n",stat_classnames_stored);
-       fprintf(file,"classes stored      : %8d\n",stat_classes_stored);
-       fprintf(file,"trivial constraints : %8d\n",stat_trivial_constraints);
-       fprintf(file,"non-triv constraints: %8d\n",stat_nontriv_constraints);
-       fprintf(file,"   both loaders rec.: %8d\n",stat_nontriv_constraints_both);
-       fprintf(file,"       merged       : %8d\n",stat_nontriv_constraints_merged);
-       fprintf(file,"   one loader rec.  : %8d\n",stat_nontriv_constraints_one);
-       fprintf(file,"   no loaders rec.  : %8d\n",stat_nontriv_constraints_none);
-       fprintf(file,"new loader entries  : %8d\n",stat_new_loader_entry);
-       fprintf(file,"merge class entries : %8d\n",stat_merge_class_entries);
-       fprintf(file,"merge loader entries: %8d\n",stat_merge_loader_entries);
-       fprintf(file,"lookups             : %8d\n",stat_lookup);
-       fprintf(file,"   class entries ckd: %8d\n",stat_lookup_class_entry_checked);
-       fprintf(file,"   loader checked   : %8d\n",stat_lookup_loader_checked);
-       fprintf(file,"lookup name         : %8d\n",stat_lookup_name);
-       fprintf(file,"   entries checked  : %8d\n",stat_lookup_name_entry);
-       fprintf(file,"   not found        : %8d\n",stat_lookup_name_notfound);
-       fprintf(file,"lookup (new) name   : %8d\n",stat_lookup_new_name);
-       fprintf(file,"   entries checked  : %8d\n",stat_lookup_new_name_entry);
-       fprintf(file,"   new collisions   : %8d\n",stat_lookup_new_name_collisions);
-       fprintf(file,"names rehashed      : %8d times\n",stat_rehash_names);
-       fprintf(file,"    collisions      : %8d\n",stat_rehash_names_collisions);
-}
-#else
-#define CLASSCACHE_COUNT(cnt)
-#define CLASSCACHE_COUNTIF(cond,cnt)
-#endif
-
-/*============================================================================*/
-/* THREAD-SAFE LOCKING                                                        */
-/*============================================================================*/
-
-       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-       /* CAUTION: The static functions below are */
-       /*          NOT synchronized!              */
-       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-#if defined(ENABLE_THREADS)
-# define CLASSCACHE_LOCK()      LOCK_MONITOR_ENTER(lock_hashtable_classcache)
-# define CLASSCACHE_UNLOCK()    LOCK_MONITOR_EXIT(lock_hashtable_classcache)
-#else
-# define CLASSCACHE_LOCK()
-# define CLASSCACHE_UNLOCK()
-#endif
-
-/*============================================================================*/
-/* GLOBAL VARIABLES                                                           */
-/*============================================================================*/
-
-hashtable hashtable_classcache;
-
-#if defined(ENABLE_THREADS)
-static java_objectheader *lock_hashtable_classcache;
-#endif
-
-
-/*============================================================================*/
-/*                                                                            */
-/*============================================================================*/
-
-/* prototypes */
-
-static void classcache_free_class_entry(classcache_class_entry *clsen);
-static void classcache_remove_class_entry(classcache_name_entry *en,
-                                                                                 classcache_class_entry *clsen);
-
-/* hash function to use */
-
-#define CLASSCACHE_HASH utf_full_hashkey
-
-/* classcache_init *************************************************************
-   Initialize the class cache
-
-   Note: NOT synchronized!
-  
-*******************************************************************************/
-
-bool classcache_init(void)
-{
-       /* create the hashtable */
-
-       hashtable_create(&hashtable_classcache, CLASSCACHE_INIT_SIZE);
-
-#if defined(ENABLE_THREADS)
-       /* create utf hashtable lock object */
-
-       lock_hashtable_classcache = NEW(java_objectheader);
-
-       lock_init_object_lock(lock_hashtable_classcache);
-#endif
-
-       /* everything's ok */
-
-       return true;
-}
-
-/* classcache_new_loader_entry *************************************************
-   Create a new classcache_loader_entry struct
-   (internally used helper function)
-  
-   IN:
-       loader...........the ClassLoader object
-          next.............the next classcache_loader_entry
-
-   RETURN VALUE:
-       the new classcache_loader_entry
-  
-*******************************************************************************/
-
-static classcache_loader_entry * classcache_new_loader_entry(
-                                                                       classloader * loader,
-                                                                       classcache_loader_entry * next)
-{
-       classcache_loader_entry *lden;
-
-       lden = NEW(classcache_loader_entry);
-       lden->loader = loader;
-       lden->next = next;
-       CLASSCACHE_COUNT(stat_new_loader_entry);
-
-       return lden;
-}
-
-/* classcache_merge_loaders ****************************************************
-   Merge two lists of loaders into one
-   (internally used helper function)
-  
-   IN:
-       lista............first list (may be NULL)
-          listb............second list (may be NULL)
-
-   RETURN VALUE:
-       the merged list (may be NULL)
-
-   NOTE:
-       The lists given as arguments are destroyed!
-  
-*******************************************************************************/
-
-static classcache_loader_entry * classcache_merge_loaders(
-                                                                       classcache_loader_entry * lista,
-                                                                       classcache_loader_entry * listb)
-{
-       classcache_loader_entry *result;
-       classcache_loader_entry *ldenA;
-       classcache_loader_entry *ldenB;
-       classcache_loader_entry **chain;
-
-       CLASSCACHE_COUNT(stat_merge_loader_entries);
-
-       /* XXX This is a quadratic algorithm. If this ever
-        * becomes a problem, the loader lists should be
-        * stored as sorted lists and merged in linear time. */
-
-       result = NULL;
-       chain = &result;
-
-       for (ldenA = lista; ldenA; ldenA = ldenA->next) {
-
-               for (ldenB = listb; ldenB; ldenB = ldenB->next) {
-                       if (ldenB->loader == ldenA->loader)
-                               goto common_element;
-               }
-
-               /* this loader is only in lista */
-               *chain = ldenA;
-               chain = &(ldenA->next);
-
-         common_element:
-               /* XXX free the duplicated element */
-               ;
-       }
-
-       /* concat listb to the result */
-       *chain = listb;
-
-       return result;
-}
-
-/* classcache_merge_class_entries **********************************************
-   Merge two `classcache_class_entry`s into one.
-   (internally used helper function)
-  
-   IN:
-       en...............the classcache_name_entry containing both class entries
-       clsenA...........first class entry, will receive the result
-          clsenB...........second class entry
-
-   PRE-CONDITION:
-       Either both entries must have the same classobj, or one of them has
-          classobj == NULL.
-
-   NOTE:
-       clsenB is freed by this function!
-  
-*******************************************************************************/
-
-static void classcache_merge_class_entries(classcache_name_entry *en,
-                                                                                  classcache_class_entry *clsenA,
-                                                                                  classcache_class_entry *clsenB)
-{
-#ifdef CLASSCACHE_VERBOSE
-       char logbuffer[1024];
-#endif
-       
-       assert(en);
-       assert(clsenA);
-       assert(clsenB);
-       assert(!clsenA->classobj || !clsenB->classobj || clsenA->classobj == clsenB->classobj);
-
-#ifdef CLASSCACHE_VERBOSE
-       sprintf(logbuffer,"classcache_merge_class_entries(%p,%p->%p,%p->%p) ", 
-                       (void*)en,(void*)clsenA,(void*)clsenA->classobj,(void*)clsenB,(void*)clsenB->classobj);
-       if (clsenA->classobj)
-               utf_cat_classname(logbuffer, clsenA->classobj->name);
-       if (clsenB->classobj)
-               utf_cat_classname(logbuffer, clsenB->classobj->name);
-       log_text(logbuffer);
-#endif
-
-       CLASSCACHE_COUNT(stat_merge_class_entries);
-
-       /* clsenB will be merged into clsenA */
-       clsenA->loaders = classcache_merge_loaders(clsenA->loaders, clsenB->loaders);
-       clsenB->loaders = NULL; /* these have been freed or reused */
-
-       clsenA->constraints = classcache_merge_loaders(clsenA->constraints,
-                                                                                                  clsenB->constraints);
-       clsenB->constraints = NULL; /* these have been freed or reused */
-
-       if (!clsenA->classobj)
-               clsenA->classobj = clsenB->classobj;
-
-       /* remove clsenB from the list of class entries */
-       classcache_remove_class_entry(en, clsenB);
-}
-
-
-/* classcache_lookup_name ******************************************************
-   Lookup a name in the first level of the cache
-   (internally used helper function)
-   
-   IN:
-       name.............the name to look up
-  
-   RETURN VALUE:
-       a pointer to the classcache_name_entry for this name, or
-       null if no entry was found.
-          
-*******************************************************************************/
-
-static classcache_name_entry *classcache_lookup_name(utf *name)
-{
-       classcache_name_entry *c;           /* hash table element                 */
-       u4 key;                             /* hashkey computed from classname    */
-       u4 slot;                            /* slot in hashtable                  */
-
-       CLASSCACHE_COUNT(stat_lookup_name);
-
-       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
-       slot = key & (hashtable_classcache.size - 1);
-       c    = hashtable_classcache.ptr[slot];
-
-       /* search external hash chain for the entry */
-
-       while (c) {
-               /* entry found in hashtable */
-               CLASSCACHE_COUNT(stat_lookup_name_entry);
-
-               if (c->name == name)
-                       return c;
-
-               c = c->hashlink;                    /* next element in external chain */
-       }
-
-       /* not found */
-
-       CLASSCACHE_COUNT(stat_lookup_name_notfound);
-       return NULL;
-}
-
-
-/* classcache_new_name *********************************************************
-   Return a classcache_name_entry for the given name. The entry is created
-   if it is not already in the cache.
-   (internally used helper function)
-   
-   IN:
-       name.............the name to look up / create an entry for
-  
-   RETURN VALUE:
-       a pointer to the classcache_name_entry for this name
-          
-*******************************************************************************/
-
-static classcache_name_entry *classcache_new_name(utf *name)
-{
-       classcache_name_entry *c;       /* hash table element */
-       u4 key;                                         /* hashkey computed from classname */
-       u4 slot;                                        /* slot in hashtable               */
-       u4 i;
-
-       CLASSCACHE_COUNT(stat_lookup_new_name);
-
-       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
-       slot = key & (hashtable_classcache.size - 1);
-       c    = hashtable_classcache.ptr[slot];
-
-       /* search external hash chain for the entry */
-
-       while (c) {
-               /* entry found in hashtable */
-               CLASSCACHE_COUNT(stat_lookup_new_name_entry);
-
-               if (c->name == name)
-                       return c;
-
-               c = c->hashlink;                    /* next element in external chain */
-       }
-
-       /* location in hashtable found, create new entry */
-
-       c = NEW(classcache_name_entry);
-
-       c->name = name;
-       c->classes = NULL;
-
-       /* insert entry into hashtable */
-       c->hashlink = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-       CLASSCACHE_COUNTIF(c->hashlink,stat_lookup_new_name_collisions);
-       hashtable_classcache.ptr[slot] = c;
-
-       /* update number of hashtable-entries */
-       hashtable_classcache.entries++;
-       CLASSCACHE_COUNT(stat_classnames_stored);
-
-       if ((hashtable_classcache.entries*2) > hashtable_classcache.size) {
-               /* reorganization of hashtable */ 
-
-               classcache_name_entry *c2;
-               hashtable newhash;              /* the new hashtable */
-
-               CLASSCACHE_COUNT(stat_rehash_names);
-
-               /* create new hashtable, double the size */
-
-               hashtable_create(&newhash, hashtable_classcache.size * 2);
-               newhash.entries = hashtable_classcache.entries;
-
-               /* transfer elements to new hashtable */
-
-               for (i = 0; i < hashtable_classcache.size; i++) {
-                       c2 = (classcache_name_entry *) hashtable_classcache.ptr[i];
-                       while (c2) {
-                               classcache_name_entry *nextc = c2->hashlink;
-                               u4 newslot =
-                                       (CLASSCACHE_HASH(c2->name->text, (u4) c2->name->blength)) & (newhash.size - 1);
-
-                               c2->hashlink = (classcache_name_entry *) newhash.ptr[newslot];
-                               CLASSCACHE_COUNTIF(c2->hashlink,stat_rehash_names_collisions);
-                               newhash.ptr[newslot] = c2;
-
-                               c2 = nextc;
-                       }
-               }
-
-               /* dispose old table */
-
-               MFREE(hashtable_classcache.ptr, void *, hashtable_classcache.size);
-               hashtable_classcache = newhash;
-       }
-
-       return c;
-}
-
-
-/* classcache_lookup ***********************************************************
-   Lookup a possibly loaded class
-  
-   IN:
-       initloader.......initiating loader for resolving the class name
-       classname........class name to look up
-  
-   RETURN VALUE:
-       The return value is a pointer to the cached class object,
-       or NULL, if the class is not in the cache.
-
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-classinfo *classcache_lookup(classloader *initloader, utf *classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-       classinfo *cls = NULL;
-
-       CLASSCACHE_LOCK();
-
-       CLASSCACHE_COUNT(stat_lookup);
-       en = classcache_lookup_name(classname);
-
-       if (en) {
-               /* iterate over all class entries */
-
-               for (clsen = en->classes; clsen; clsen = clsen->next) {
-                       CLASSCACHE_COUNT(stat_lookup_class_entry_checked);
-                       /* check if this entry has been loaded by initloader */
-
-                       for (lden = clsen->loaders; lden; lden = lden->next) {
-                               CLASSCACHE_COUNT(stat_lookup_loader_checked);
-                               if (lden->loader == initloader) {
-                                       /* found the loaded class entry */
-
-                                       assert(clsen->classobj);
-                                       cls = clsen->classobj;
-                                       goto found;
-                               }
-                       }
-               }
-       }
-
-  found:
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-
-/* classcache_lookup_defined ***************************************************
-   Lookup a class with the given name and defining loader
-  
-   IN:
-       defloader........defining loader
-       classname........class name
-  
-   RETURN VALUE:
-       The return value is a pointer to the cached class object,
-       or NULL, if the class is not in the cache.
-   
-*******************************************************************************/
-
-classinfo *classcache_lookup_defined(classloader *defloader, utf *classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classinfo *cls = NULL;
-
-       CLASSCACHE_LOCK();
-
-       en = classcache_lookup_name(classname);
-
-       if (en) {
-               /* iterate over all class entries */
-               for (clsen = en->classes; clsen; clsen = clsen->next) {
-                       if (!clsen->classobj)
-                               continue;
-
-                       /* check if this entry has been defined by defloader */
-                       if (clsen->classobj->classloader == defloader) {
-                               cls = clsen->classobj;
-                               goto found;
-                       }
-               }
-       }
-
-  found:
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-
-/* classcache_lookup_defined_or_initiated **************************************
-   Lookup a class that has been defined or initiated by the given loader
-  
-   IN:
-       loader...........defining or initiating loader
-       classname........class name to look up
-  
-   RETURN VALUE:
-       The return value is a pointer to the cached class object,
-       or NULL, if the class is not in the cache.
-
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-classinfo *classcache_lookup_defined_or_initiated(classloader *loader, 
-                                                                                                 utf *classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-       classinfo *cls = NULL;
-
-       CLASSCACHE_LOCK();
-
-       en = classcache_lookup_name(classname);
-
-       if (en) {
-               /* iterate over all class entries */
-
-               for (clsen = en->classes; clsen; clsen = clsen->next) {
-
-                       /* check if this entry has been defined by loader */
-                       if (clsen->classobj && clsen->classobj->classloader == loader) {
-                               cls = clsen->classobj;
-                               goto found;
-                       }
-                       
-                       /* check if this entry has been initiated by loader */
-                       for (lden = clsen->loaders; lden; lden = lden->next) {
-                               if (lden->loader == loader) {
-                                       /* found the loaded class entry */
-
-                                       assert(clsen->classobj);
-                                       cls = clsen->classobj;
-                                       goto found;
-                               }
-                       }
-               }
-       }
-
-  found:
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-
-/* classcache_store ************************************************************
-   
-   Store a loaded class. If a class of the same name has already been stored
-   with the same initiating loader, then the given class CLS is freed (if
-   possible) and the previously stored class is returned.
-  
-   IN:
-       initloader.......initiating loader used to load the class
-                           (may be NULL indicating the bootstrap loader)
-       cls..............class object to cache
-          mayfree..........true if CLS may be freed in case another class is
-                           returned
-  
-   RETURN VALUE:
-       cls..............everything ok, the class was stored in the cache,
-          other classinfo..another class with the same (initloader,name) has been
-                           stored earlier. CLS has been freed[1] and the earlier
-                                               stored class is returned.
-       NULL.............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-
-   [1]...in case MAYFREE is true
-   
-*******************************************************************************/
-
-classinfo *classcache_store(classloader *initloader, classinfo *cls,
-                                                       bool mayfree)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-       classcache_class_entry *clsenB;
-       classcache_loader_entry *lden;
-#ifdef CLASSCACHE_VERBOSE
-       char logbuffer[1024];
-#endif
-       
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-
-       CLASSCACHE_LOCK();
-
-#ifdef CLASSCACHE_VERBOSE
-       sprintf(logbuffer,"classcache_store (%p,%d,%p=", (void*)initloader,mayfree,(void*)cls);
-       utf_cat_classname(logbuffer, cls->name);
-       strcat(logbuffer,")");
-       log_text(logbuffer);
-#endif
-
-       en = classcache_new_name(cls->name);
-
-       assert(en);
-
-       /* iterate over all class entries */
-       for (clsen = en->classes; clsen; clsen = clsen->next) {
-
-               /* check if this entry has already been loaded by initloader */
-               for (lden = clsen->loaders; lden; lden = lden->next) {
-                       if (lden->loader == initloader) {
-                          if (clsen->classobj != cls) {
-                                       /* A class with the same (initloader,name) pair has been stored already. */
-                                       /* We free the given class and return the earlier one.                   */
-#ifdef CLASSCACHE_VERBOSE
-                                       dolog("replacing %p with earlier loaded class %p",cls,clsen->classobj);
-#endif
-                                       assert(clsen->classobj);
-                                       if (mayfree)
-                                               class_free(cls);
-                                       cls = clsen->classobj;
-                          }
-                          goto return_success;
-                       }
-               }
-
-               /* {This entry has not been resolved with initloader} */
-
-               /* check if initloader is constrained to this entry */
-               for (lden = clsen->constraints; lden; lden = lden->next) {
-                       if (lden->loader == initloader) {
-                               /* we have to use this entry. check if it has been resolved */
-                               if (clsen->classobj) {
-                                       /* check if is has already been resolved to another class */
-                                       if (clsen->classobj != cls) {
-                                               /* a loading constraint is violated */
-                                               *exceptionptr = exceptions_new_linkageerror(
-                                                                                       "loading constraint violated: ",cls);
-                                               goto return_exception;
-                                       }
-
-                                       /* record initloader as initiating loader */
-                                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
-                                       goto return_success;
-                               }
-
-                               /* {this is the first resolution for this entry} */
-                               /* record initloader as initiating loader */
-                               clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
-
-                               /* maybe we can merge this entry with another one */
-                               for (clsenB = en->classes; clsenB; clsenB = clsenB->next) {
-                                       /* we dont want the entry that we have already */
-                                       if (clsenB->classobj == cls) {
-                                               /* this entry has the same classobj. let's merge them */
-                                               classcache_merge_class_entries(en,clsen,clsenB);
-                                               goto return_success;
-                                       }
-                               }
-
-                               /* record the loaded class object */
-                               clsen->classobj = cls;
-                               CLASSCACHE_COUNT(stat_classes_stored);
-
-                               /* done */
-                               goto return_success;
-                       }
-               }
-
-       }
-
-       /* {There is no class entry containing initloader as initiating 
-        *  or constrained loader.} */
-
-       /* we look for a class entry with the same classobj we want to store */
-       for (clsen = en->classes; clsen; clsen = clsen->next) {
-               if (clsen->classobj == cls) {
-                       /* this entry is about the same classobj. let's use it */
-                       /* check if this entry has already been loaded by initloader */
-                       for (lden = clsen->loaders; lden; lden = lden->next) {
-                               if (lden->loader == initloader)
-                                       goto return_success;
-                       }
-                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
-                       goto return_success;
-               }
-       }
-
-       /* create a new class entry for this class object with */
-       /* initiating loader initloader                        */
-
-       clsen = NEW(classcache_class_entry);
-       clsen->classobj = cls;
-       clsen->loaders = classcache_new_loader_entry(initloader, NULL);
-       clsen->constraints = NULL;
-
-       clsen->next = en->classes;
-       en->classes = clsen;
-       CLASSCACHE_COUNT(stat_classes_stored);
-
-  return_success:
-#ifdef CLASSCACHE_VERBOSE
-       classcache_debug_dump(stderr,cls->name);
-#endif
-       CLASSCACHE_UNLOCK();
-       return cls;
-
-  return_exception:
-       CLASSCACHE_UNLOCK();
-       return NULL;                            /* exception */
-}
-
-/* classcache_store_unique *****************************************************
-   
-   Store a loaded class as loaded by the bootstrap loader. This is a wrapper 
-   aroung classcache_store that throws an exception if a class with the same 
-   name has already been loaded by the bootstrap loader.
-
-   This function is used to register a few special classes during startup.
-   It should not be used otherwise.
-  
-   IN:
-       cls..............class object to cache
-  
-   RETURN VALUE:
-       true.............everything ok, the class was stored.
-       false............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-bool classcache_store_unique(classinfo *cls)
-{
-       classinfo *result;
-
-       result = classcache_store(NULL,cls,false);
-       if (result == NULL)
-               return false;
-
-       if (result != cls) {
-               exceptions_throw_internalerror("class already stored in the class cache");
-               return false;
-       }
-
-       return true;
-}
-
-/* classcache_store_defined ****************************************************
-   
-   Store a loaded class after it has been defined. If the class has already
-   been defined by the same defining loader in another thread, free the given
-   class and returned the one which has been defined earlier.
-  
-   IN:
-       cls..............class object to store. classloader must be set
-                           (classloader may be NULL, for bootloader)
-  
-   RETURN VALUE:
-       cls..............everything ok, the class was stored the cache,
-          other classinfo..the class had already been defined, CLS was freed, the
-                           class which was defined earlier is returned,
-       NULL.............an exception has been thrown.
-   
-*******************************************************************************/
-
-classinfo *classcache_store_defined(classinfo *cls)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsen;
-#ifdef CLASSCACHE_VERBOSE
-       char logbuffer[1024];
-#endif
-
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-
-       CLASSCACHE_LOCK();
-
-#ifdef CLASSCACHE_VERBOSE
-       sprintf(logbuffer,"classcache_store_defined (%p,", (void*)cls->classloader);
-       utf_cat_classname(logbuffer, cls->name);
-       strcat(logbuffer,")");
-       log_text(logbuffer);
-#endif
-
-       en = classcache_new_name(cls->name);
-
-       assert(en);
-
-       /* iterate over all class entries */
-       for (clsen = en->classes; clsen; clsen = clsen->next) {
-               
-               /* check if this class has been defined by the same classloader */
-               if (clsen->classobj && clsen->classobj->classloader == cls->classloader) {
-                       /* we found an earlier definition, delete the newer one */
-                       /* (if it is a different classinfo)                     */
-                       if (clsen->classobj != cls) {
-#ifdef CLASSCACHE_VERBOSE
-                               dolog("replacing %p with earlier defined class %p",cls,clsen->classobj);
-#endif
-                               class_free(cls);
-                               cls = clsen->classobj;
-                       }
-                       goto return_success;
-               }
-       }
-
-       /* create a new class entry for this class object */
-       /* the list of initiating loaders is empty at this point */
-
-       clsen = NEW(classcache_class_entry);
-       clsen->classobj = cls;
-       clsen->loaders = NULL;
-       clsen->constraints = NULL;
-
-       clsen->next = en->classes;
-       en->classes = clsen;
-       CLASSCACHE_COUNT(stat_classes_stored);
-
-return_success:
-#ifdef CLASSCACHE_VERBOSE
-       classcache_debug_dump(stderr,cls->name);
-#endif
-       CLASSCACHE_UNLOCK();
-       return cls;
-}
-
-/* classcache_find_loader ******************************************************
-   Find the class entry loaded by or constrained to a given loader
-   (internally used helper function)
-  
-   IN:
-       entry............the classcache_name_entry
-       loader...........the loader to look for
-  
-   RETURN VALUE:
-       the classcache_class_entry for the given loader, or
-          NULL if no entry was found
-   
-*******************************************************************************/
-
-static classcache_class_entry * classcache_find_loader(
-                                                                       classcache_name_entry * entry,
-                                                                       classloader * loader)
-{
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-
-       assert(entry);
-
-       /* iterate over all class entries */
-       for (clsen = entry->classes; clsen; clsen = clsen->next) {
-
-               /* check if this entry has already been loaded by initloader */
-               for (lden = clsen->loaders; lden; lden = lden->next) {
-                       if (lden->loader == loader)
-                               return clsen;   /* found */
-               }
-
-               /* check if loader is constrained to this entry */
-               for (lden = clsen->constraints; lden; lden = lden->next) {
-                       if (lden->loader == loader)
-                               return clsen;   /* found */
-               }
-       }
-
-       /* not found */
-       return NULL;
-}
-
-/* classcache_free_class_entry *************************************************
-   Free the memory used by a class entry
-  
-   IN:
-       clsen............the classcache_class_entry to free  
-          
-*******************************************************************************/
-
-static void classcache_free_class_entry(classcache_class_entry * clsen)
-{
-       classcache_loader_entry *lden;
-       classcache_loader_entry *next;
-
-       assert(clsen);
-
-       for (lden = clsen->loaders; lden; lden = next) {
-               next = lden->next;
-               FREE(lden, classcache_loader_entry);
-       }
-       for (lden = clsen->constraints; lden; lden = next) {
-               next = lden->next;
-               FREE(lden, classcache_loader_entry);
-       }
-
-       FREE(clsen, classcache_class_entry);
-}
-
-/* classcache_remove_class_entry ***********************************************
-   Remove a classcache_class_entry from the list of possible resolution of
-   a name entry
-   (internally used helper function)
-  
-   IN:
-       entry............the classcache_name_entry
-       clsen............the classcache_class_entry to remove
-  
-*******************************************************************************/
-
-static void classcache_remove_class_entry(classcache_name_entry * entry,
-                                                                                 classcache_class_entry * clsen)
-{
-       classcache_class_entry **chain;
-
-       assert(entry);
-       assert(clsen);
-
-       chain = &(entry->classes);
-       while (*chain) {
-               if (*chain == clsen) {
-                       *chain = clsen->next;
-                       classcache_free_class_entry(clsen);
-                       return;
-               }
-               chain = &((*chain)->next);
-       }
-}
-
-/* classcache_free_name_entry **************************************************
-   Free the memory used by a name entry
-  
-   IN:
-       entry............the classcache_name_entry to free  
-          
-*******************************************************************************/
-
-static void classcache_free_name_entry(classcache_name_entry * entry)
-{
-       classcache_class_entry *clsen;
-       classcache_class_entry *next;
-
-       assert(entry);
-
-       for (clsen = entry->classes; clsen; clsen = next) {
-               next = clsen->next;
-               classcache_free_class_entry(clsen);
-       }
-
-       FREE(entry, classcache_name_entry);
-}
-
-/* classcache_free *************************************************************
-   Free the memory used by the class cache
-
-   NOTE:
-       The class cache may not be used any more after this call, except
-          when it is reinitialized with classcache_init.
-  
-   Note: NOT synchronized!
-  
-*******************************************************************************/
-
-void classcache_free(void)
-{
-       u4 slot;
-       classcache_name_entry *entry;
-       classcache_name_entry *next;
-
-       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
-               for (entry = (classcache_name_entry *) hashtable_classcache.ptr[slot]; entry; entry = next) {
-                       next = entry->hashlink;
-                       classcache_free_name_entry(entry);
-               }
-       }
-
-       MFREE(hashtable_classcache.ptr, voidptr, hashtable_classcache.size);
-       hashtable_classcache.size = 0;
-       hashtable_classcache.entries = 0;
-       hashtable_classcache.ptr = NULL;
-}
-
-/* classcache_add_constraint ***************************************************
-   Add a loading constraint
-  
-   IN:
-       a................first initiating loader
-       b................second initiating loader
-       classname........class name
-  
-   RETURN VALUE:
-       true.............everything ok, the constraint has been added,
-       false............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool classcache_add_constraint(classloader * a,
-                                                          classloader * b,
-                                                          utf * classname)
-{
-       classcache_name_entry *en;
-       classcache_class_entry *clsenA;
-       classcache_class_entry *clsenB;
-
-       assert(classname);
-
-#ifdef CLASSCACHE_VERBOSE
-       fprintf(stderr, "classcache_add_constraint(%p,%p,", (void *) a, (void *) b);
-       utf_fprint_printable_ascii_classname(stderr, classname);
-       fprintf(stderr, ")\n");
-#endif
-
-       /* a constraint with a == b is trivially satisfied */
-       if (a == b) {
-               CLASSCACHE_COUNT(stat_trivial_constraints);
-               return true;
-       }
-
-       CLASSCACHE_LOCK();
-
-       en = classcache_new_name(classname);
-
-       assert(en);
-       CLASSCACHE_COUNT(stat_nontriv_constraints);
-
-       /* find the entry loaded by / constrained to each loader */
-       clsenA = classcache_find_loader(en, a);
-       clsenB = classcache_find_loader(en, b);
-
-       if (clsenA && clsenB) {
-               /* { both loaders have corresponding entries } */
-               CLASSCACHE_COUNT(stat_nontriv_constraints_both);
-
-               /* if the entries are the same, the constraint is already recorded */
-               if (clsenA == clsenB)
-                       goto return_success;
-
-               /* check if the entries can be merged */
-               if (clsenA->classobj && clsenB->classobj
-                       && clsenA->classobj != clsenB->classobj) {
-                       /* no, the constraint is violated */
-                       *exceptionptr = exceptions_new_linkageerror(
-                                                         "loading constraint violated: ",clsenA->classobj);
-                       goto return_exception;
-               }
-
-               /* yes, merge the entries */
-               classcache_merge_class_entries(en,clsenA,clsenB);
-               CLASSCACHE_COUNT(stat_nontriv_constraints_merged);
-       }
-       else {
-               /* { at most one of the loaders has a corresponding entry } */
-
-               /* set clsenA to the single class entry we have */
-               if (!clsenA)
-                       clsenA = clsenB;
-
-               if (!clsenA) {
-                       /* { no loader has a corresponding entry } */
-                       CLASSCACHE_COUNT(stat_nontriv_constraints_none);
-
-                       /* create a new class entry with the constraint (a,b,en->name) */
-                       clsenA = NEW(classcache_class_entry);
-                       clsenA->classobj = NULL;
-                       clsenA->loaders = NULL;
-                       clsenA->constraints = classcache_new_loader_entry(b, NULL);
-                       clsenA->constraints = classcache_new_loader_entry(a, clsenA->constraints);
-
-                       clsenA->next = en->classes;
-                       en->classes = clsenA;
-               }
-               else {
-                       CLASSCACHE_COUNT(stat_nontriv_constraints_one);
-
-                       /* make b the loader that has no corresponding entry */
-                       if (clsenB)
-                               b = a;
-
-                       /* loader b must be added to entry clsenA */
-                       clsenA->constraints = classcache_new_loader_entry(b, clsenA->constraints);
-               }
-       }
-
-  return_success:
-       CLASSCACHE_UNLOCK();
-       return true;
-
-  return_exception:
-       CLASSCACHE_UNLOCK();
-       return false;                           /* exception */
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-/* classcache_add_constraints_for_params ***************************************
-   Add loading constraints for the parameters and return type of 
-   the given method.
-  
-   IN:
-       a................first initiating loader
-       b................second initiating loader
-       m................methodinfo 
-  
-   RETURN VALUE:
-       true.............everything ok, the constraints have been added,
-       false............an exception has been thrown.
-   
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool classcache_add_constraints_for_params(classloader * a,
-                                                                                  classloader * b,
-                                                                                  methodinfo *m)
-{
-       methoddesc *md;
-       typedesc *td;
-       s4 i;
-
-       /* a constraint with a == b is trivially satisfied */
-
-       if (a == b) {
-               return true;
-       }
-
-       /* get the parsed descriptor */
-
-       assert(m);
-       md = m->parseddesc;
-       assert(md);
-
-       /* constrain the return type */
-
-       if (md->returntype.type == TYPE_ADR) {
-               if (!classcache_add_constraint(a, b, md->returntype.classref->name))
-                       return false; /* exception */
-       }
-
-       /* constrain each reference type used in the parameters */
-
-       td = md->paramtypes;
-       i = md->paramcount;
-       for (; i--; td++) {
-               if (td->type != TYPE_ADR)
-                       continue;
-
-               if (!classcache_add_constraint(a, b, td->classref->name))
-                       return false; /* exception */
-       }
-
-       /* everything ok */
-       return true;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* classcache_number_of_loaded_classes *****************************************
-
-   Counts the number of loaded classes and returns it.
-
-   Note: This function assumes that the CLASSCACHE_LOCK is held by the
-   caller!
-
-*******************************************************************************/
-
-static s4 classcache_number_of_loaded_classes(void)
-{
-       classcache_name_entry  *en;
-       classcache_class_entry *clsen;
-       s4                      number;
-       s4                      i;
-
-       /* initialize class counter */
-
-       number = 0;
-
-       for (i = 0; i < hashtable_classcache.size; i++) {
-               /* iterate over hashlink */
-
-               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
-                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
-
-                       if (en->name->text[0] == '$')
-                               continue;
-
-                       /* iterate over classes with same name */
-
-                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
-                               /* get only loaded classes */
-
-                               if (clsen->classobj != NULL)
-                                       number++;
-                       }
-               }
-       }
-
-       return number;
-}
-
-
-/* classcache_get_loaded_class_count *******************************************
-
-   Counts the number of loaded classes and returns it.
-
-*******************************************************************************/
-
-s4 classcache_get_loaded_class_count(void)
-{
-       s4 count;
-
-       CLASSCACHE_LOCK();
-
-       count = classcache_number_of_loaded_classes();
-       
-       CLASSCACHE_UNLOCK();
-
-       return count;
-}
-
-
-/* classcache_get_loaded_classes ***********************************************
-
-   Returns an array of all loaded classes as array.  The array is
-   allocaed on the Java heap.
-
-*******************************************************************************/
-
-#if defined(ENABLE_JVMTI)
-void classcache_get_loaded_classes(s4 *class_count_ptr,
-                                                                  classinfo ***classes_ptr)
-{
-       classinfo              **classes;
-       s4                       class_count;
-       classcache_name_entry   *en;
-       classcache_class_entry  *clsen;
-       s4                       i;
-       s4                       j;
-
-       CLASSCACHE_LOCK();
-
-       /* get the number of loaded classes and allocate the array */
-
-       class_count = classcache_number_of_loaded_classes();
-
-       classes = GCMNEW(classinfo*, class_count);
-
-       /* look in every slot of the hashtable */
-
-       for (i = 0, j = 0; i < hashtable_classcache.size; i++) {
-               /* iterate over hashlink */
-
-               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
-                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
-
-                       if (en->name->text[0] == '$')
-                               continue;
-
-                       /* iterate over classes with same name */
-
-                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
-                               /* get only loaded classes */
-
-                               if (clsen->classobj != NULL) {
-                                       classes[j] = clsen->classobj;
-                                       j++;
-                               }
-                       }
-               }
-       }
-
-       /* pass the return values */
-
-       *class_count_ptr = class_count;
-       *classes_ptr     = classes;
-
-       CLASSCACHE_UNLOCK();
-}
-#endif /* defined(ENABLE_JVMTI) */
-
-
-/* classcache_foreach_loaded_class *********************************************
-
-   Calls the given function for each loaded class.
-
-*******************************************************************************/
-
-void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
-                                                                        void *data)
-{
-       classcache_name_entry   *en;
-       classcache_class_entry  *clsen;
-       s4                       i;
-
-       CLASSCACHE_LOCK();
-
-       /* look in every slot of the hashtable */
-
-       for (i = 0; i < hashtable_classcache.size; i++) {
-               /* iterate over hashlink */
-
-               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
-                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
-
-                       if (en->name->text[0] == '$')
-                               continue;
-
-                       /* iterate over classes with same name */
-
-                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
-                               /* get only loaded classes */
-
-                               if (clsen->classobj != NULL) {
-                                       (*func)(clsen->classobj, data);
-                               }
-                       }
-               }
-       }
-
-       CLASSCACHE_UNLOCK();
-}
-
-
-/*============================================================================*/
-/* DEBUG DUMPS                                                                */
-/*============================================================================*/
-
-/* classcache_debug_dump *******************************************************
-   Print the contents of the loaded class cache to a stream
-  
-   IN:
-       file.............output stream
-          only.............if != NULL, only print entries for this name
-                           (Currently we print also the rest of the hash chain to
-                                                get a feel for the average length of hash chains.)
-  
-   Note: synchronized with global tablelock
-   
-*******************************************************************************/
-
-#ifndef NDEBUG
-void classcache_debug_dump(FILE * file,utf *only)
-{
-       classcache_name_entry *c;
-       classcache_class_entry *clsen;
-       classcache_loader_entry *lden;
-       u4 slot;
-
-       CLASSCACHE_LOCK();
-
-       fprintf(file, "\n=== [loaded class cache] =====================================\n\n");
-       fprintf(file, "hash size   : %d\n", (int) hashtable_classcache.size);
-       fprintf(file, "hash entries: %d\n", (int) hashtable_classcache.entries);
-       fprintf(file, "\n");
-
-       if (only) {
-               c = classcache_lookup_name(only);
-               slot = 0; /* avoid compiler warning */
-               goto dump_it;
-       }
-
-       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
-               c = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
-dump_it:
-               for (; c; c = c->hashlink) {
-                       utf_fprint_printable_ascii_classname(file, c->name);
-                       fprintf(file, "\n");
-
-                       /* iterate over all class entries */
-                       for (clsen = c->classes; clsen; clsen = clsen->next) {
-                               if (clsen->classobj) {
-                                       fprintf(file, "    loaded %p\n", (void *) clsen->classobj);
-                               }
-                               else {
-                                       fprintf(file, "    unresolved\n");
-                               }
-                               fprintf(file, "        loaders:");
-                               for (lden = clsen->loaders; lden; lden = lden->next) {
-                                       fprintf(file, "<%p> %p", (void *) lden, (void *) lden->loader);
-                               }
-                               fprintf(file, "\n        constraints:");
-                               for (lden = clsen->constraints; lden; lden = lden->next) {
-                                       fprintf(file, "<%p> %p", (void *) lden, (void *) lden->loader);
-                               }
-                               fprintf(file, "\n");
-                       }
-               }
-
-               if (only)
-                       break;
-       }
-       fprintf(file, "\n==============================================================\n\n");
-
-       CLASSCACHE_UNLOCK();
-}
-#endif /* NDEBUG */
-
-/*
- * 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:
- */
diff --git a/src/vm/classcache.h b/src/vm/classcache.h
deleted file mode 100644 (file)
index 9457aa7..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/* src/vm/classcache.h - loaded class cache and loading constraints
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: Christian Thalinger
-
-   $Id: classcache.h 6209 2006-12-16 21:14:23Z edwin $
-
-*/
-
-
-#ifndef _CLASSCACHE_H
-#define _CLASSCACHE_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include <stdio.h>  /* for FILE */
-
-#if defined(ENABLE_JVMTI)
-# include "native/jni.h"
-#endif
-
-#include "vm/hashtable.h"
-#include "vm/references.h"
-
-
-/* forward declarations *******************************************************/
-
-typedef struct classcache_name_entry classcache_name_entry;
-typedef struct classcache_class_entry classcache_class_entry;
-typedef struct classcache_loader_entry classcache_loader_entry;
-
-typedef java_objectheader classloader;
-
-/* global variables ***********************************************************/
-
-extern hashtable hashtable_classcache;
-
-
-/* structs ********************************************************************/
-
-/*----------------------------------------------------------------------------*/
-/* The Loaded Class Cache                                                     */
-/*                                                                            */
-/* The loaded class cache is implemented as a two-level data structure.       */
-/*                                                                            */
-/* The first level is a hash table indexed by class names. For each class     */
-/* name in the cache there is a classcache_name_entry, which collects all     */
-/* information about classes with this class name.                            */
-/*                                                                            */
-/* Second level: For each classcache_name_entry there is a list of            */
-/* classcache_class_entry:s representing the possible different resolutions   */
-/* of the class name.                                                         */
-/*                                                                            */
-/* A classcache_class_entry records the following:                            */
-/*                                                                            */
-/* - the loaded class object, if this entry has been resolved, otherwise NULL */
-/* - the list of initiating loaders which have resolved the class name to     */
-/*   this class object                                                        */
-/* - the list of initiating loaders which are constrained to resolve this     */
-/*   class name to this class object in the future                            */
-/*                                                                            */
-/* The classcache_class_entry:s approximate the equivalence classes created   */
-/* by the loading constraints and the equivalence of loaded classes.          */
-/*                                                                            */
-/* When a loading constraint (loaderA,loaderB,NAME) is added, then the        */
-/* classcache_class_entry:s for NAME containing loaderA and loaderB resp.     */
-/* must be merged into one entry. If this is impossible, because the entries  */
-/* have already been resolved to different class objects, then the constraint */
-/* is violated and an expception must be thrown.                              */
-/*----------------------------------------------------------------------------*/
-
-
-/* classcache_name_entry
- *
- * For each classname a classcache_name_entry struct is created.
- */
-
-struct classcache_name_entry
-{
-       utf                     *name;        /* class name                       */
-       classcache_name_entry   *hashlink;    /* link for external chaining       */
-       classcache_class_entry  *classes;     /* equivalence classes for this name*/
-};
-
-struct classcache_class_entry
-{
-       classinfo               *classobj;    /* the loaded class object, or NULL */
-       classcache_loader_entry *loaders;
-       classcache_loader_entry *constraints;
-       classcache_class_entry  *next;        /* next class entry for same name   */
-};
-
-struct classcache_loader_entry
-{
-       classloader              *loader;     /* class loader object              */
-       classcache_loader_entry  *next;       /* next loader entry in the list    */
-};
-
-
-/* callback function type for  classcache_foreach_loaded_class */
-
-typedef void (*classcache_foreach_functionptr_t)(classinfo *, void *);
-
-
-/* function prototypes ********************************************************/
-
-/* initialize the loaded class cache */
-bool classcache_init(void);
-void classcache_free(void);
-
-classinfo * classcache_lookup(classloader *initloader,utf *classname);
-classinfo * classcache_lookup_defined(classloader *defloader,utf *classname);
-classinfo * classcache_lookup_defined_or_initiated(classloader *loader,utf *classname);
-
-bool classcache_store_unique(classinfo *cls);
-classinfo * classcache_store(classloader *initloader,classinfo *cls,bool mayfree);
-classinfo * classcache_store_defined(classinfo *cls);
-
-#if defined(ENABLE_VERIFIER)
-bool classcache_add_constraint(classloader *a,classloader *b,utf *classname);
-bool classcache_add_constraints_for_params(classloader *a,classloader *b,
-                                                                                  methodinfo *m);
-#endif
-
-s4 classcache_get_loaded_class_count(void);
-
-void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
-                                                                        void *data);
-
-#if defined(ENABLE_JVMTI)
-void classcache_get_loaded_classes(s4 *class_count_ptr,
-                                                                  classinfo ***classes_ptr);
-#endif
-
-#ifndef NDEBUG
-void classcache_debug_dump(FILE *file,utf *only);
-#endif
-       
-#endif /* _CLASSCACHE_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
-
diff --git a/src/vm/descriptor.c b/src/vm/descriptor.c
deleted file mode 100644 (file)
index c5e512d..0000000
+++ /dev/null
@@ -1,1366 +0,0 @@
-/* src/vm/descriptor.c - checking and parsing of field / method descriptors
-
-   Copyright (C) 1996-2005, 2006, 2007 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-   $Id: descriptor.c 6286 2007-01-10 10:03:38Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "md-abi.h"
-
-#include "mm/memory.h"
-#include "vm/descriptor.h"
-#include "vm/exceptions.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
-
-
-/* constants (private to descriptor.c) ****************************************/
-
-/* initial number of entries for the classrefhash of a descriptor_pool */
-/* (currently the hash is never grown!) */
-#define CLASSREFHASH_INIT_SIZE  64
-
-/* initial number of entries for the descriptorhash of a descriptor_pool */
-/* (currently the hash is never grown!) */
-#define DESCRIPTORHASH_INIT_SIZE  128
-
-/* data structures (private to descriptor.c) **********************************/ 
-
-typedef struct classref_hash_entry classref_hash_entry;
-typedef struct descriptor_hash_entry descriptor_hash_entry;
-
-/* entry struct for the classrefhash of descriptor_pool */
-struct classref_hash_entry {
-       classref_hash_entry *hashlink;  /* for hash chaining            */
-       utf                 *name;      /* name of the class refered to */
-       u2                   index;     /* index into classref table    */
-};
-
-/* entry struct for the descriptorhash of descriptor_pool */
-struct descriptor_hash_entry {
-       descriptor_hash_entry *hashlink;
-       utf                   *desc;
-       parseddesc             parseddesc;
-       s2                     paramslots; /* number of params, LONG/DOUBLE counted as 2 */
-};
-
-
-/****************************************************************************/
-/* MACROS FOR DESCRIPTOR PARSING (private to descriptor.c)                  */
-/****************************************************************************/
-
-/* SKIP_FIELDDESCRIPTOR:
- * utf_ptr must point to the first character of a field descriptor.
- * After the macro call utf_ptr points to the first character after
- * the field descriptor.
- *
- * CAUTION: This macro does not check for an unexpected end of the
- * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
- */
-#define SKIP_FIELDDESCRIPTOR(utf_ptr)                                                  \
-       do { while (*(utf_ptr)=='[') (utf_ptr)++;                                       \
-               if (*(utf_ptr)++=='L')                                                                  \
-                       while(*(utf_ptr)++ != ';') /* skip */; } while(0)
-
-/* SKIP_FIELDDESCRIPTOR_SAFE:
- * utf_ptr must point to the first character of a field descriptor.
- * After the macro call utf_ptr points to the first character after
- * the field descriptor.
- *
- * Input:
- *     utf_ptr....points to first char of descriptor
- *     end_ptr....points to first char after the end of the string
- *     errorflag..must be initialized (to false) by the caller!
- * Output:
- *     utf_ptr....points to first char after the descriptor
- *     errorflag..set to true if the string ended unexpectedly
- */
-#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                   \
-       do { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;     \
-               if ((utf_ptr) == (end_ptr))                                                                             \
-                       (errorflag) = true;                                                                                     \
-               else                                                                                                                    \
-                       if (*(utf_ptr)++=='L') {                                                                        \
-                               while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';')    \
-                                       /* skip */;                                                                                     \
-                               if ((utf_ptr)[-1] != ';')                                                               \
-                                       (errorflag) = true; }} while(0)
-
-
-/****************************************************************************/
-/* DEBUG HELPERS                                                            */
-/****************************************************************************/
-
-/*#define DESCRIPTOR_VERBOSE*/
-
-/****************************************************************************/
-/* FUNCTIONS                                                                */
-/****************************************************************************/
-
-/* descriptor_to_basic_type ****************************************************
-
-   Return the basic type to use for a value with this descriptor.
-
-   IN:
-       utf..............descriptor utf string
-
-   OUT:
-       A TYPE_* constant.
-
-   PRECONDITIONS:
-       This function assumes that the descriptor has passed 
-          descriptor_pool_add checks and that it does not start with '('.
-
-*******************************************************************************/
-
-u2 descriptor_to_basic_type(utf *descriptor)
-{
-       assert(descriptor->blength >= 1);
-       
-       switch (descriptor->text[0]) {
-               case 'B': 
-               case 'C':
-               case 'I':
-               case 'S':  
-               case 'Z':  return TYPE_INT;
-               case 'D':  return TYPE_DBL;
-               case 'F':  return TYPE_FLT;
-               case 'J':  return TYPE_LNG;
-               case 'L':
-               case '[':  return TYPE_ADR;
-       }
-                       
-       assert(0);
-
-       return 0; /* keep the compiler happy */
-}
-
-/* descriptor_typesize**** ****************************************************
-
-   Return the size in bytes needed for the given type.
-
-   IN:
-       td..............typedesc describing the type
-
-   OUT:
-       The number of bytes
-
-*******************************************************************************/
-
-u2 descriptor_typesize(typedesc *td)
-{
-       assert(td);
-
-       switch (td->type) {
-               case TYPE_INT: return 4;
-               case TYPE_LNG: return 8;
-               case TYPE_FLT: return 4;
-               case TYPE_DBL: return 8;
-               case TYPE_ADR: return sizeof(voidptr);
-       }
-
-       assert(0);
-
-       return 0; /* keep the compiler happy */
-}
-
-/* name_from_descriptor ********************************************************
-
-   Return the class name indicated by the given descriptor
-   (Internally used helper function)
-
-   IN:
-       c................class containing the descriptor
-       utf_ptr..........first character of descriptor
-       end_ptr..........first character after the end of the string
-       mode.............a combination (binary or) of the following flags:
-
-               (Flags marked with * are the default settings.)
-
-               How to handle "V" descriptors:
-
-                            * DESCRIPTOR_VOID.....handle it like other primitive types
-                   DESCRIPTOR_NOVOID...treat it as an error
-
-               How to deal with extra characters after the end of the
-               descriptor:
-
-                            * DESCRIPTOR_NOCHECKEND...ignore (useful for parameter lists)
-                   DESCRIPTOR_CHECKEND.....treat them as an error
-
-   OUT:
-       *next............if non-NULL, *next is set to the first character after
-                        the descriptor. (Undefined if an error occurs.)
-       *name............set to the utf name of the class
-
-   RETURN VALUE:
-       true.............descriptor parsed successfully
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-#define DESCRIPTOR_VOID          0      /* default */
-#define DESCRIPTOR_NOVOID        0x0040
-#define DESCRIPTOR_NOCHECKEND    0      /* default */
-#define DESCRIPTOR_CHECKEND      0x1000
-
-static bool 
-name_from_descriptor(classinfo *c,
-                                        char *utf_ptr, char *end_ptr,
-                                        char **next, int mode, utf **name)
-{
-       char *start = utf_ptr;
-       bool error = false;
-
-       assert(c);
-       assert(utf_ptr);
-       assert(end_ptr);
-       assert(name);
-       
-       *name = NULL;           
-       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
-
-       if (mode & DESCRIPTOR_CHECKEND)
-               error |= (utf_ptr != end_ptr);
-       
-       if (!error) {
-               if (next) *next = utf_ptr;
-               
-               switch (*start) {
-                 case 'V':
-                         if (mode & DESCRIPTOR_NOVOID)
-                                 break;
-                         /* FALLTHROUGH! */
-                 case 'I':
-                 case 'J':
-                 case 'F':
-                 case 'D':
-                 case 'B':
-                 case 'C':
-                 case 'S':
-                 case 'Z':
-                         return true;
-                         
-                 case 'L':
-                         start++;
-                         utf_ptr--;
-                         /* FALLTHROUGH! */
-                 case '[':
-                         *name = utf_new(start, utf_ptr - start);
-                         return true;
-               }
-       }
-
-       *exceptionptr = new_classformaterror(c,"invalid descriptor");
-       return false;
-}
-
-
-/* descriptor_to_typedesc ******************************************************
-   Parse the given type descriptor and fill a typedesc struct
-   (Internally used helper function)
-
-   IN:
-       pool.............the descriptor pool
-          utf_ptr..........points to first character of type descriptor
-          end_pos..........points after last character of the whole descriptor
-
-   OUT:
-       *next............set to next character after type descriptor
-          *d...............filled with parsed information
-
-   RETURN VALUE:
-       true.............parsing succeeded  
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-static bool
-descriptor_to_typedesc(descriptor_pool *pool, char *utf_ptr, char *end_pos,
-                                          char **next, typedesc *td)
-{
-       utf *name;
-       
-       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, next, 0, &name))
-               return false;
-
-       if (name) {
-               /* a reference type */
-               td->type = TYPE_ADR;
-               td->decltype = TYPE_ADR;
-               td->arraydim = 0;
-               for (utf_ptr = name->text; *utf_ptr == '['; ++utf_ptr)
-                       td->arraydim++;
-               td->classref = descriptor_pool_lookup_classref(pool, name);
-
-       } else {
-               /* a primitive type */
-               switch (*utf_ptr) {
-               case 'B': 
-                       td->decltype = PRIMITIVETYPE_BYTE;
-                       td->type = TYPE_INT;
-                       break;
-               case 'C':
-                       td->decltype = PRIMITIVETYPE_CHAR;
-                       td->type = TYPE_INT;
-                       break;
-               case 'S':  
-                       td->decltype = PRIMITIVETYPE_SHORT;
-                       td->type = TYPE_INT;
-                       break;
-               case 'Z':
-                       td->decltype = PRIMITIVETYPE_BOOLEAN;
-                       td->type = TYPE_INT;
-                       break;
-               case 'I':
-                       td->decltype = PRIMITIVETYPE_INT;
-                       td->type = TYPE_INT;
-                       break;
-               case 'D':
-                       td->decltype = PRIMITIVETYPE_DOUBLE;
-                       td->type = TYPE_DBL;
-                       break;
-               case 'F':
-                       td->decltype = PRIMITIVETYPE_FLOAT;
-                       td->type = TYPE_FLT;
-                       break;
-               case 'J':
-                       td->decltype = PRIMITIVETYPE_LONG;
-                       td->type = TYPE_LNG;
-                       break;
-               case 'V':
-                       td->decltype = PRIMITIVETYPE_VOID;
-                       td->type = TYPE_VOID;
-                       break;
-               default:
-                       assert(false);
-               }
-
-               td->arraydim = 0;
-               td->classref = NULL;
-       }
-
-       return true;
-}
-
-
-/* descriptor_pool_new *********************************************************
-   Allocate a new descriptor_pool
-
-   IN:
-       referer..........class for which to create the pool
-
-   RETURN VALUE:
-       a pointer to the new descriptor_pool
-
-*******************************************************************************/
-
-descriptor_pool * 
-descriptor_pool_new(classinfo *referer)
-{
-       descriptor_pool *pool;
-       u4 hashsize;
-       u4 slot;
-
-       pool = DNEW(descriptor_pool);
-       assert(pool);
-
-       pool->referer = referer;
-       pool->fieldcount = 0;
-       pool->methodcount = 0;
-       pool->paramcount = 0;
-       pool->descriptorsize = 0;
-       pool->descriptors = NULL;
-       pool->descriptors_next = NULL;
-       pool->classrefs = NULL;
-       pool->descriptor_kind = NULL;
-       pool->descriptor_kind_next = NULL;
-
-       hashsize = CLASSREFHASH_INIT_SIZE;
-       pool->classrefhash.size = hashsize;
-       pool->classrefhash.entries = 0;
-       pool->classrefhash.ptr = DMNEW(voidptr,hashsize);
-       for (slot=0; slot<hashsize; ++slot)
-               pool->classrefhash.ptr[slot] = NULL;
-
-       hashsize = DESCRIPTORHASH_INIT_SIZE;
-       pool->descriptorhash.size = hashsize;
-       pool->descriptorhash.entries = 0;
-       pool->descriptorhash.ptr = DMNEW(voidptr,hashsize);
-       for (slot=0; slot<hashsize; ++slot)
-               pool->descriptorhash.ptr[slot] = NULL;
-
-       return pool;
-}
-
-
-/* descriptor_pool_add_class ***************************************************
-   Add the given class reference to the pool
-
-   IN:
-       pool.............the descriptor_pool
-          name.............the class reference to add
-
-   RETURN VALUE:
-       true.............reference has been added
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-bool 
-descriptor_pool_add_class(descriptor_pool *pool, utf *name)
-{
-       u4 key,slot;
-       classref_hash_entry *c;
-       
-       assert(pool);
-       assert(name);
-
-#ifdef DESCRIPTOR_VERBOSE
-       fprintf(stderr,"descriptor_pool_add_class(%p,",(void*)pool);
-       utf_fprint_printable_ascii(stderr,name);fprintf(stderr,")\n");
-#endif
-
-       /* find a place in the hashtable */
-
-       key = utf_hashkey(name->text, name->blength);
-       slot = key & (pool->classrefhash.size - 1);
-       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-
-       while (c) {
-               if (c->name == name)
-                       return true; /* already stored */
-               c = c->hashlink;
-       }
-
-       /* check if the name is a valid classname */
-
-       if (!is_valid_name(name->text,UTF_END(name))) {
-               *exceptionptr = new_classformaterror(pool->referer,
-                                                                                        "Invalid class name");
-               return false; /* exception */
-       }
-
-       /* XXX check maximum array dimension */
-       
-       c = DNEW(classref_hash_entry);
-       c->name = name;
-       c->index = pool->classrefhash.entries++;
-       c->hashlink = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-       pool->classrefhash.ptr[slot] = c;
-
-       return true;
-}
-
-
-/* descriptor_pool_add *********************************************************
-   Check the given descriptor and add it to the pool
-
-   IN:
-       pool.............the descriptor_pool
-          desc.............the descriptor to add. Maybe a field or method desc.
-
-   OUT:
-       *paramslots......if non-NULL, set to the number of parameters.
-                           LONG and DOUBLE are counted twice
-
-   RETURN VALUE:
-       true.............descriptor has been added
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-bool 
-descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
-{
-       u4 key,slot;
-       descriptor_hash_entry *d;
-       char *utf_ptr;
-       char *end_pos;
-       utf *name;
-       s4 argcount = 0;
-       
-#ifdef DESCRIPTOR_VERBOSE
-       fprintf(stderr,"descriptor_pool_add(%p,",(void*)pool);
-       utf_fprint_printable_ascii(stderr,desc);fprintf(stderr,")\n");
-#endif
-
-       assert(pool);
-       assert(desc);
-
-       /* find a place in the hashtable */
-
-       key = utf_hashkey(desc->text, desc->blength);
-       slot = key & (pool->descriptorhash.size - 1);
-       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-
-       /* Save all method descriptors in the hashtable, since the parsed         */
-       /* descriptor may vary between differenf methods (static vs. non-static). */
-
-       utf_ptr = desc->text;
-
-       if (*utf_ptr != '(') {
-               while (d) {
-                       if (d->desc == desc) {
-                               if (paramslots)
-                                       *paramslots = d->paramslots;
-                               return true; /* already stored */
-                       }
-                       d = d->hashlink;
-               }
-       }
-
-       /* add the descriptor to the pool */
-
-       d = DNEW(descriptor_hash_entry);
-       d->desc = desc;
-       d->parseddesc.any = NULL;
-       d->hashlink = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-       pool->descriptorhash.ptr[slot] = d;
-
-       /* now check the descriptor */
-
-       end_pos = UTF_END(desc);
-       
-       if (*utf_ptr == '(') {
-               /* a method descriptor */
-
-               pool->methodcount++;
-               utf_ptr++;
-
-               /* check arguments */
-
-               while ((utf_ptr != end_pos) && (*utf_ptr != ')')) {
-                       pool->paramcount++;
-
-                       /* We cannot count the `this' argument here because
-                        * we don't know if the method is static. */
-
-                       if (*utf_ptr == 'J' || *utf_ptr == 'D')
-                               argcount += 2;
-                       else
-                               argcount++;
-
-                       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, &utf_ptr,
-                                                                     DESCRIPTOR_NOVOID, &name))
-                               return false;
-
-                       if (name)
-                               if (!descriptor_pool_add_class(pool, name))
-                                       return false;
-               }
-
-               if (utf_ptr == end_pos) {
-                       *exceptionptr = new_classformaterror(pool->referer,"Missing ')' in method descriptor");
-                       return false;
-               }
-
-               utf_ptr++; /* skip ')' */
-
-               if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
-                                                                 DESCRIPTOR_CHECKEND, &name))
-                       return false;
-
-               if (name)
-                       if (!descriptor_pool_add_class(pool,name))
-                               return false;
-
-               if (argcount > 255) {
-                       *exceptionptr =
-                               new_classformaterror(pool->referer,"Too many arguments in signature");
-                       return false;
-               }
-
-       } else {
-               /* a field descriptor */
-
-               pool->fieldcount++;
-               
-           if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
-                                                         DESCRIPTOR_NOVOID | DESCRIPTOR_CHECKEND,
-                                                                 &name))
-                       return false;
-
-               if (name)
-                       if (!descriptor_pool_add_class(pool,name))
-                               return false;
-       }
-
-       d->paramslots = argcount;
-
-       if (paramslots)
-               *paramslots = argcount;
-
-       return true;
-}
-
-
-/* descriptor_pool_create_classrefs ********************************************
-   Create a table containing all the classrefs which were added to the pool
-
-   IN:
-       pool.............the descriptor_pool
-
-   OUT:
-       *count...........if count is non-NULL, this is set to the number
-                           of classrefs in the table
-
-   RETURN VALUE:
-       a pointer to the constant_classref table
-
-*******************************************************************************/
-
-constant_classref * 
-descriptor_pool_create_classrefs(descriptor_pool *pool, s4 *count)
-{
-       u4 nclasses;
-       u4 slot;
-       classref_hash_entry *c;
-       constant_classref *ref;
-       
-       assert(pool);
-
-       nclasses = pool->classrefhash.entries;
-       pool->classrefs = MNEW(constant_classref,nclasses);
-
-       /* fill the constant_classref structs */
-
-       for (slot = 0; slot < pool->classrefhash.size; ++slot) {
-               c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-               while (c) {
-                       ref = pool->classrefs + c->index;
-                       CLASSREF_INIT(*ref, pool->referer, c->name);
-                       c = c->hashlink;
-               }
-       }
-
-       if (count)
-               *count = nclasses;
-
-       return pool->classrefs;
-}
-
-
-/* descriptor_pool_lookup_classref *********************************************
-   Return the constant_classref for the given class name
-
-   IN:
-       pool.............the descriptor_pool
-          classname........name of the class to look up
-
-   RETURN VALUE:
-       a pointer to the constant_classref, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-constant_classref * 
-descriptor_pool_lookup_classref(descriptor_pool *pool, utf *classname)
-{
-       u4 key,slot;
-       classref_hash_entry *c;
-
-       assert(pool);
-       assert(pool->classrefs);
-       assert(classname);
-
-       key = utf_hashkey(classname->text, classname->blength);
-       slot = key & (pool->classrefhash.size - 1);
-       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-
-       while (c) {
-               if (c->name == classname)
-                       return pool->classrefs + c->index;
-               c = c->hashlink;
-       }
-
-       exceptions_throw_internalerror("Class reference not found in descriptor pool");
-       return NULL;
-}
-
-
-/* descriptor_pool_alloc_parsed_descriptors ************************************
-   Allocate space for the parsed descriptors
-
-   IN:
-       pool.............the descriptor_pool
-
-   NOTE:
-       This function must be called after all descriptors have been added
-          with descriptor_pool_add.
-
-*******************************************************************************/
-
-void 
-descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool)
-{
-       u4 size;
-       
-       assert(pool);
-
-       /* TWISTI: paramcount + 1: we don't know if the method is static or   */
-       /* not, i have no better solution yet.                                */
-
-       size =
-               pool->fieldcount * sizeof(typedesc) +
-               pool->methodcount * (sizeof(methoddesc) - sizeof(typedesc)) +
-               pool->paramcount * sizeof(typedesc) +
-               pool->methodcount * sizeof(typedesc);      /* possible `this' pointer */
-
-       pool->descriptorsize = size;
-       if (size) {
-               pool->descriptors = MNEW(u1, size);
-               pool->descriptors_next = pool->descriptors;
-       }
-
-       size = pool->fieldcount + pool->methodcount;
-       if (size) {
-               pool->descriptor_kind = DMNEW(u1, size);
-               pool->descriptor_kind_next = pool->descriptor_kind;
-       }
-}
-
-
-/* descriptor_pool_parse_field_descriptor **************************************
-   Parse the given field descriptor
-
-   IN:
-       pool.............the descriptor_pool
-          desc.............the field descriptor
-
-   RETURN VALUE:
-       a pointer to the parsed field descriptor, or
-          NULL if an exception has been thrown
-
-   NOTE:
-       descriptor_pool_alloc_parsed_descriptors must be called (once)
-       before this function is used.
-
-*******************************************************************************/
-
-typedesc * 
-descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc)
-{
-       u4 key,slot;
-       descriptor_hash_entry *d;
-       typedesc *td;
-
-       assert(pool);
-       assert(pool->descriptors);
-       assert(pool->descriptors_next);
-
-       /* lookup the descriptor in the hashtable */
-
-       key = utf_hashkey(desc->text, desc->blength);
-       slot = key & (pool->descriptorhash.size - 1);
-       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-
-       while (d) {
-               if (d->desc == desc) {
-                       /* found */
-                       if (d->parseddesc.fd)
-                               return d->parseddesc.fd;
-                       break;
-               }
-               d = d->hashlink;
-       }
-
-       assert(d);
-       
-       if (desc->text[0] == '(') {
-               *exceptionptr = new_classformaterror(pool->referer,
-                               "Method descriptor used in field reference");
-               return NULL;
-       }
-
-       td = (typedesc *) pool->descriptors_next;
-       pool->descriptors_next += sizeof(typedesc);
-       
-       if (!descriptor_to_typedesc(pool, desc->text, UTF_END(desc), NULL, td))
-               return NULL;
-
-       *(pool->descriptor_kind_next++) = 'f';
-
-       d->parseddesc.fd = td;
-
-       return td;
-}
-
-
-/* descriptor_pool_parse_method_descriptor *************************************
-   Parse the given method descriptor
-
-   IN:
-       pool.............the descriptor_pool
-       desc.............the method descriptor
-       mflags...........the method flags
-          thisclass........classref to the class containing the method.
-                                               This is ignored if mflags contains ACC_STATIC.
-                                               The classref is stored for inserting the 'this' argument.
-
-   RETURN VALUE:
-       a pointer to the parsed method descriptor, or
-          NULL if an exception has been thrown
-
-   NOTE: 
-       descriptor_pool_alloc_parsed_descriptors must be called
-       (once) before this function is used.
-
-*******************************************************************************/
-
-methoddesc * 
-descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
-                                                                               s4 mflags,constant_classref *thisclass)
-{
-       u4 key, slot;
-       descriptor_hash_entry *d;
-       methoddesc            *md;
-       typedesc              *td;
-       char *utf_ptr;
-       char *end_pos;
-       s2 paramcount = 0;
-       s2 paramslots = 0;
-
-#ifdef DESCRIPTOR_VERBOSE
-       fprintf(stderr,"descriptor_pool_parse_method_descriptor(%p,%d,%p,",
-                       (void*)pool,(int)mflags,(void*)thisclass);
-       utf_fprint_printable_ascii(stderr,desc); fprintf(stderr,")\n");
-#endif
-
-       assert(pool);
-       assert(pool->descriptors);
-       assert(pool->descriptors_next);
-
-       /* check that it is a method descriptor */
-       
-       if (desc->text[0] != '(') {
-               *exceptionptr = new_classformaterror(pool->referer,
-                               "Field descriptor used in method reference");
-               return NULL;
-       }
-
-       /* lookup the descriptor in the hashtable */
-
-       key = utf_hashkey(desc->text, desc->blength);
-       slot = key & (pool->descriptorhash.size - 1);
-       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-
-       /* find an un-parsed descriptor */
-
-       while (d) {
-               if (d->desc == desc)
-                       if (!d->parseddesc.md)
-                               break;
-               d = d->hashlink;
-       }
-
-       assert(d);
-
-       md = (methoddesc *) pool->descriptors_next;
-       pool->descriptors_next += sizeof(methoddesc) - sizeof(typedesc);
-
-       utf_ptr = desc->text + 1; /* skip '(' */
-       end_pos = UTF_END(desc);
-
-       td = md->paramtypes;
-
-       /* count the `this' pointer */
-
-       if ((mflags != ACC_UNDEF) && !(mflags & ACC_STATIC)) {
-               td->type = TYPE_ADR;
-               td->decltype = TYPE_ADR;
-               td->arraydim = 0;
-               td->classref = thisclass;
-
-               td++;
-               pool->descriptors_next += sizeof(typedesc);
-               paramcount++;
-               paramslots++;
-       }
-
-       while (*utf_ptr != ')') {
-               /* parse a parameter type */
-
-               if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, &utf_ptr, td))
-                       return NULL;
-
-               if (IS_2_WORD_TYPE(td->type))
-                       paramslots++;
-               
-               td++;
-               pool->descriptors_next += sizeof(typedesc);
-               paramcount++;
-               paramslots++;
-       }
-       utf_ptr++; /* skip ')' */
-
-       /* Skip possible `this' pointer in paramtypes array to allow a possible   */
-       /* memory move later in parse.                                            */
-       /* We store the thisclass reference, so we can later correctly fill in    */
-       /* the parameter slot of the 'this' argument.                             */
-
-       if (mflags == ACC_UNDEF) {
-               td->classref = thisclass;
-               td++;
-               pool->descriptors_next += sizeof(typedesc);
-       }
-
-       /* parse return type */
-
-       if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, NULL,
-                                                               &(md->returntype)))
-               return NULL;
-
-       md->paramcount = paramcount;
-       md->paramslots = paramslots;
-
-       /* If m != ACC_UNDEF we parse a real loaded method, so do param prealloc. */
-       /* Otherwise we do this in stack analysis.                                */
-
-       if (mflags != ACC_UNDEF) {
-               if (md->paramcount > 0) {
-                       /* allocate memory for params */
-
-                       md->params = MNEW(paramdesc, md->paramcount);
-               }
-               else {
-                       md->params = METHODDESC_NOPARAMS;
-               }
-
-               /* fill the paramdesc */
-               /* md_param_alloc has to be called if md->paramcount == 0,
-                  too, so it can make the reservation for the Linkage Area,
-                  Return Register... */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (!opt_intrp)
-# endif
-                       md_param_alloc(md);
-#endif
-
-       } else {
-               /* params will be allocated later by
-                  descriptor_params_from_paramtypes if necessary */
-
-               md->params = NULL;
-       }
-
-       *(pool->descriptor_kind_next++) = 'm';
-
-       d->parseddesc.md = md;
-
-       return md;
-}
-
-/* descriptor_params_from_paramtypes *******************************************
-   Create the paramdescs for a method descriptor. This function is called
-   when we know whether the method is static or not. This function may only
-   be called once for each methoddesc, and only if md->params == NULL.
-
-   IN:
-       md...............the parsed method descriptor
-                           md->params MUST be NULL.
-          mflags...........the ACC_* access flags of the method. Only the
-                           ACC_STATIC bit is checked.
-                                               The value ACC_UNDEF is NOT allowed.
-
-   RETURN VALUE:
-       true.............the paramdescs were created successfully
-          false............an exception has been thrown
-
-   POSTCONDITION:
-       md->parms != NULL
-
-*******************************************************************************/
-
-bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
-{
-       typedesc *td;
-
-       assert(md);
-       assert(md->params == NULL);
-       assert(mflags != ACC_UNDEF);
-
-       td = md->paramtypes;
-
-       /* check for `this' pointer */
-
-       if (!(mflags & ACC_STATIC)) {
-               constant_classref *thisclass;
-
-               /* fetch class reference from reserved param slot */
-               thisclass = td[md->paramcount].classref;
-               assert(thisclass);
-
-               if (md->paramcount > 0) {
-                       /* shift param types by 1 argument */
-                       MMOVE(td + 1, td, typedesc, md->paramcount);
-               }
-
-               /* fill in first argument `this' */
-
-               td->type = TYPE_ADR;
-               td->decltype = TYPE_ADR;
-               td->arraydim = 0;
-               td->classref = thisclass;
-
-               md->paramcount++;
-               md->paramslots++;
-       }
-
-       /* if the method has params, process them */
-
-       if (md->paramcount > 0) {
-               /* allocate memory for params */
-
-               md->params = MNEW(paramdesc, md->paramcount);
-
-       } else {
-               md->params = METHODDESC_NOPARAMS;
-       }
-
-       /* fill the paramdesc */
-       /* md_param_alloc has to be called if md->paramcount == 0, too, so
-          it can make the reservation for the Linkage Area, Return
-          Register.. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-       if (!opt_intrp)
-# endif
-               md_param_alloc(md);
-#endif
-
-       return true;
-}
-
-
-/* descriptor_pool_get_parsed_descriptors **************************************
-   Return a pointer to the block of parsed descriptors
-
-   IN:
-       pool.............the descriptor_pool
-
-   OUT:
-          *size............if size is non-NULL, this is set to the size of the
-                           parsed descriptor block (in u1)
-
-   RETURN VALUE:
-       a pointer to the block of parsed descriptors
-
-   NOTE:
-       descriptor_pool_alloc_parsed_descriptors must be called (once)
-       before this function is used.
-
-*******************************************************************************/
-
-void * 
-descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size)
-{
-       assert(pool);
-       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
-       
-       if (size)
-               *size = pool->descriptorsize;
-
-       return pool->descriptors;
-}
-
-
-/* descriptor_pool_get_sizes ***************************************************
-   Get the sizes of the class reference table and the parsed descriptors
-
-   IN:
-       pool.............the descriptor_pool
-
-   OUT:
-       *classrefsize....set to size of the class reference table
-          *descsize........set to size of the parsed descriptors
-
-   NOTE:
-       This function may only be called after both
-              descriptor_pool_create_classrefs, and
-                  descriptor_pool_alloc_parsed_descriptors
-          have been called.
-
-*******************************************************************************/
-
-void 
-descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize, u4 *descsize)
-{
-       assert(pool);
-       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
-       assert(pool->classrefs);
-       assert(classrefsize);
-       assert(descsize);
-
-       *classrefsize = pool->classrefhash.entries * sizeof(constant_classref);
-       *descsize = pool->descriptorsize;
-}
-
-
-/****************************************************************************/
-/* DEBUG HELPERS                                                            */
-/****************************************************************************/
-
-#ifndef NDEBUG
-/* descriptor_debug_print_typedesc *********************************************
-   Print the given typedesc to the given stream
-
-   IN:
-          file.............stream to print to
-          d................the parsed descriptor
-
-*******************************************************************************/
-
-void 
-descriptor_debug_print_typedesc(FILE *file,typedesc *d)
-{
-       int ch;
-
-       if (!d) {
-               fprintf(file,"(typedesc *)NULL");
-               return;
-       }
-       
-       if (d->type == TYPE_ADR) {
-               if (d->classref)
-                       utf_fprint_printable_ascii(file,d->classref->name);
-               else
-                       fprintf(file,"<class=NULL>");
-       }
-       else {
-               switch (d->decltype) {
-                       case PRIMITIVETYPE_INT    : ch='I'; break;
-                       case PRIMITIVETYPE_CHAR   : ch='C'; break;
-                       case PRIMITIVETYPE_BYTE   : ch='B'; break;
-                       case PRIMITIVETYPE_SHORT  : ch='S'; break;
-                       case PRIMITIVETYPE_BOOLEAN: ch='Z'; break;
-                       case PRIMITIVETYPE_LONG   : ch='J'; break;
-                       case PRIMITIVETYPE_FLOAT  : ch='F'; break;
-                       case PRIMITIVETYPE_DOUBLE : ch='D'; break;
-                       case PRIMITIVETYPE_VOID   : ch='V'; break;
-                       default                   : ch='!';
-               }
-               fputc(ch,file);
-       }
-       if (d->arraydim)
-               fprintf(file,"[%d]",d->arraydim);
-}
-
-/* descriptor_debug_print_paramdesc ********************************************
-   Print the given paramdesc to the given stream
-
-   IN:
-          file.............stream to print to
-          d................the parameter descriptor
-
-*******************************************************************************/
-
-void
-descriptor_debug_print_paramdesc(FILE *file,paramdesc *d)
-{
-       if (!d) {
-               fprintf(file,"(paramdesc *)NULL");
-               return;
-       }
-       
-       if (d->inmemory) {
-               fprintf(file,"<m%d>",d->regoff);
-       }
-       else {
-               fprintf(file,"<r%d>",d->regoff);
-       }
-}
-
-/* descriptor_debug_print_methoddesc *******************************************
-   Print the given methoddesc to the given stream
-
-   IN:
-          file.............stream to print to
-          d................the parsed descriptor
-
-*******************************************************************************/
-
-void 
-descriptor_debug_print_methoddesc(FILE *file,methoddesc *d)
-{
-       int i;
-       
-       if (!d) {
-               fprintf(file,"(methoddesc *)NULL");
-               return;
-       }
-       
-       fputc('(',file);
-       for (i=0; i<d->paramcount; ++i) {
-               if (i)
-                       fputc(',',file);
-               descriptor_debug_print_typedesc(file,d->paramtypes + i);
-               if (d->params) {
-                       descriptor_debug_print_paramdesc(file,d->params + i);
-               }
-       }
-       if (d->params == METHODDESC_NOPARAMS)
-               fputs("<NOPARAMS>",file);
-       fputc(')',file);
-       descriptor_debug_print_typedesc(file,&(d->returntype));
-}
-
-/* descriptor_pool_debug_dump **************************************************
-   Print the state of the descriptor_pool to the given stream
-
-   IN:
-       pool.............the descriptor_pool
-          file.............stream to print to
-
-*******************************************************************************/
-
-void 
-descriptor_pool_debug_dump(descriptor_pool *pool,FILE *file)
-{
-       u4 slot;
-       u1 *pos;
-       u1 *kind;
-       u4 size;
-       
-       fprintf(file,"======[descriptor_pool for ");
-       utf_fprint_printable_ascii(file,pool->referer->name);
-       fprintf(file,"]======\n");
-
-       fprintf(file,"fieldcount:     %d\n",pool->fieldcount);
-       fprintf(file,"methodcount:    %d\n",pool->methodcount);
-       fprintf(file,"paramcount:     %d\n",pool->paramcount);
-       fprintf(file,"classrefcount:  %d\n",pool->classrefhash.entries);
-       fprintf(file,"descriptorsize: %d bytes\n",pool->descriptorsize);
-       fprintf(file,"classrefsize:   %d bytes\n",
-                       (int)(pool->classrefhash.entries * sizeof(constant_classref)));
-
-       fprintf(file,"class references:\n");
-       for (slot=0; slot<pool->classrefhash.size; ++slot) {
-               classref_hash_entry *c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-               while (c) {
-                       fprintf(file,"    %4d: ",c->index);
-                       utf_fprint_printable_ascii(file,c->name);
-                       fprintf(file,"\n");
-                       c = c->hashlink;
-               }
-       }
-
-       fprintf(file,"hashed descriptors:\n");
-       for (slot=0; slot<pool->descriptorhash.size; ++slot) {
-               descriptor_hash_entry *c = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-               while (c) {
-                       fprintf(file,"    %p: ",c->parseddesc.any);
-                       utf_fprint_printable_ascii(file,c->desc);
-                       fprintf(file,"\n");
-                       c = c->hashlink;
-               }
-       }
-
-       fprintf(file,"descriptors:\n");
-       if (pool->descriptors) {
-               pos = pool->descriptors;
-               size = pool->descriptors_next - pool->descriptors;
-               fprintf(file,"    size: %d bytes\n",size);
-               
-               if (pool->descriptor_kind) {
-                       kind = pool->descriptor_kind;
-
-                       while (pos < (pool->descriptors + size)) {
-                               fprintf(file,"    %p: ",pos);
-                               switch (*kind++) {
-                                       case 'f':
-                                               descriptor_debug_print_typedesc(file,(typedesc*)pos);
-                                               pos += sizeof(typedesc);
-                                               break;
-                                       case 'm':
-                                               descriptor_debug_print_methoddesc(file,(methoddesc*)pos);
-                                               pos += ((methoddesc*)pos)->paramcount * sizeof(typedesc);
-                                               pos += sizeof(methoddesc) - sizeof(typedesc);
-                                               break;
-                                       default:
-                                               fprintf(file,"INVALID KIND");
-                               }
-                               fputc('\n',file);
-                       }
-               }
-               else {
-                       while (size >= sizeof(voidptr)) {
-                               fprintf(file,"    %p\n",*((voidptr*)pos));
-                               pos += sizeof(voidptr);
-                               size -= sizeof(voidptr);
-                       }
-               }
-       }
-
-       fprintf(file,"==========================================================\n");
-}
-#endif /* !defined(NDEBUG) */
-
-/*
- * 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:
- */
-
diff --git a/src/vm/descriptor.h b/src/vm/descriptor.h
deleted file mode 100644 (file)
index 9183fff..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/* vm/descriptor.h - checking and parsing of field / method descriptors
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id: descriptor.h 6012 2006-11-16 19:45:15Z twisti $
-
-*/
-
-
-#ifndef _DESCRIPTOR_H
-#define _DESCRIPTOR_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct descriptor_pool descriptor_pool;
-typedef struct typedesc        typedesc;
-typedef struct paramdesc       paramdesc;
-typedef struct methoddesc      methoddesc;
-
-
-#include "vm/class.h"
-#include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/method.h"
-#include "vm/references.h"
-
-
-/* data structures ************************************************************/
-
-/*----------------------------------------------------------------------------*/
-/* Descriptor Pools                                                           */
-/*                                                                            */
-/* A descriptor_pool is a temporary data structure used during loading of     */
-/* a class. The descriptor_pool is used to allocate the table of              */
-/* constant_classrefs the class uses, and for parsing the field and method    */
-/* descriptors which occurr within the class. The inner workings of           */
-/* descriptor_pool are not important for outside code.                        */
-/*                                                                            */
-/* You use a descriptor_pool as follows:                                      */
-/*                                                                            */
-/* 1. create one with descriptor_pool_new                                     */
-/* 2. add all explicit class references with descriptor_pool_add_class        */
-/* 3. add all field/method descriptors with descriptor_pool_add               */
-/* 4. call descriptor_pool_create_classrefs                                   */
-/*    You can now lookup classrefs with descriptor_pool_lookup_classref       */
-/* 5. call descriptor_pool_alloc_parsed_descriptors                           */
-/* 6. for each field descriptor call descriptor_pool_parse_field_descriptor   */
-/*    for each method descriptor call descriptor_pool_parse_method_descriptor */
-/* 7. call descriptor_pool_get_parsed_descriptors                             */
-/*                                                                            */
-/* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
-/*            memory which can be thrown away when the steps above have been  */
-/*            done.                                                           */
-/*----------------------------------------------------------------------------*/
-
-struct descriptor_pool {
-       classinfo         *referer;
-       u4                 fieldcount;
-       u4                 methodcount;
-       u4                 paramcount;
-       u4                 descriptorsize;
-       u1                *descriptors;
-       u1                *descriptors_next;
-       hashtable          descriptorhash;
-       constant_classref *classrefs;
-       hashtable          classrefhash;
-       u1                *descriptor_kind;       /* useful for debugging */
-       u1                *descriptor_kind_next;  /* useful for debugging */
-};
-
-
-/* data structures for parsed field/method descriptors ************************/
-
-struct typedesc {
-       constant_classref *classref;   /* class reference for TYPE_ADR types      */
-       u1                 type;       /* TYPE_??? constant [1]                   */
-       u1                 decltype;   /* (PRIMITIVE)TYPE_??? constant [2]        */
-       u1                 arraydim;   /* array dimension (0 if no array)         */
-};
-
-/* [1]...the type field contains the basic type used within the VM. So ints,  */
-/*       shorts, chars, bytes, booleans all have TYPE_INT.                    */
-/* [2]...the decltype field contains the declared type.                       */
-/*       So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR.         */
-/*       For non-primitive types decltype is TYPE_ADR.                        */
-
-struct paramdesc {
-#if defined(__MIPS__)
-       u1   type;                  /* TYPE_??? of the register allocated         */
-#endif
-       bool inmemory;              /* argument in register or on stack           */
-       s4   regoff;                /* register index or stack offset             */
-};
-
-struct methoddesc {
-       s2         paramcount;      /* number of parameters                       */
-       s2         paramslots;      /* like above but LONG,DOUBLE count twice     */
-       s4         argintreguse;    /* number of used integer argument registers  */
-       s4         argfltreguse;    /* number of used float argument registers    */
-       s4         memuse;          /* number of stack slots used                 */
-       paramdesc *params;          /* allocated parameter descriptions [3]       */
-       typedesc   returntype;      /* parsed descriptor of the return type       */
-       typedesc   paramtypes[1];   /* parameter types, variable length!          */
-};
-
-/* [3]...If params is NULL, the parameter descriptions have not yet been      */
-/*       allocated. In this case ___the possible 'this' pointer of the method */
-/*       is NOT counted in paramcount/paramslots and it is NOT included in    */
-/*       the paramtypes array___.                                             */
-/*       If params != NULL, the parameter descriptions have been              */
-/*       allocated, and the 'this' pointer of the method, if any, IS included.*/
-/*       In case the method has no parameters at all, the special value       */
-/*       METHODDESC_NO_PARAMS is used (see below).                            */
-
-/* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field    */
-/* indicating that the method is a static method without any parameters.      */
-/* This special value must be != NULL and it may only be set if               */
-/* md->paramcount == 0.                                                       */
-
-#define METHODDESC_NOPARAMS  ((paramdesc*)1)
-
-/* function prototypes ********************************************************/
-
-descriptor_pool * descriptor_pool_new(classinfo *referer);
-
-bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
-bool descriptor_pool_add(descriptor_pool *pool,utf *desc,int *paramslots);
-
-u2 descriptor_to_basic_type(utf *desc);
-u2 descriptor_typesize(typedesc *td);
-
-constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
-                                                                                                        s4 *count);
-constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
-
-void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
-
-typedesc *descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc);
-methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags,
-                                                                                                       constant_classref *thisclass);
-
-bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags);
-
-void *descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size);
-void descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize,
-                                                          u4 *descsize);
-
-#ifndef NDEBUG
-void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
-void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
-void descriptor_debug_print_paramdesc(FILE *file,paramdesc *d);
-void descriptor_pool_debug_dump(descriptor_pool *pool, FILE *file);
-#endif /* !defined(NDEBUG) */
-
-/* machine dependent descriptor function */
-void md_param_alloc(methoddesc *md);
-
-#endif /* _DESCRIPTOR_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
index ada417089c7a095b2763dd3b402f69f3c739e9c2..24fb984ebdaeb62149667043537b14e5972dc3bd 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/exceptions.c - exception related functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Edwin Steiner
-
-   $Id: exceptions.c 7228 2007-01-19 01:13:48Z edwin $
+   $Id: exceptions.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#else
+# include "threads/none/threads.h"
+#endif
+
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
-#include "vm/class.h"
+
+#include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
 
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
 
 /* for raising exceptions from native methods *********************************/
 
@@ -89,13 +96,6 @@ bool exceptions_init(void)
                return false;
 
 #if defined(ENABLE_JAVASE)
-       /* java/lang/AbstractMethodError */
-
-       if (!(class_java_lang_AbstractMethodError =
-                 load_class_bootstrap(utf_java_lang_AbstractMethodError)) ||
-               !link_class(class_java_lang_AbstractMethodError))
-               return false;
-
        /* java/lang/LinkageError */
 
        if (!(class_java_lang_LinkageError =
@@ -111,15 +111,6 @@ bool exceptions_init(void)
                !link_class(class_java_lang_NoClassDefFoundError))
                return false;
 
-#if defined(ENABLE_JAVASE)
-       /* java/lang/NoSuchMethodError */
-
-       if (!(class_java_lang_NoSuchMethodError =
-                 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
-               !link_class(class_java_lang_NoSuchMethodError))
-               return false;
-#endif
-
        /* java/lang/OutOfMemoryError */
 
        if (!(class_java_lang_OutOfMemoryError =
@@ -156,20 +147,6 @@ bool exceptions_init(void)
                !link_class(class_java_lang_ClassNotFoundException))
                return false;
 
-       /* java/lang/IllegalArgumentException */
-
-       if (!(class_java_lang_IllegalArgumentException =
-                 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
-               !link_class(class_java_lang_IllegalArgumentException))
-               return false;
-
-       /* java/lang/IllegalMonitorStateException */
-
-       if (!(class_java_lang_IllegalMonitorStateException =
-                 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
-               !link_class(class_java_lang_IllegalMonitorStateException))
-               return false;
-
        /* java/lang/NullPointerException */
 
        if (!(class_java_lang_NullPointerException =
@@ -322,72 +299,138 @@ void throw_cacao_exception_exit(const char *exception, const char *message, ...)
 }
 
 
-/* new_exception ***************************************************************
+/* exceptions_new_class ********************************************************
 
-   Creates an exception object with the given name and initalizes it.
+   Creates an exception object from the given class and initalizes it.
 
    IN:
-      classname....class name in UTF-8
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+      class....class pointer
 
 *******************************************************************************/
 
-java_objectheader *new_exception(const char *classname)
+static java_objectheader *exceptions_new_class(classinfo *c)
 {
        java_objectheader *o;
-       classinfo         *c;
-
-       if (!(c = load_class_bootstrap(utf_new_char(classname))))
-               return *exceptionptr;
 
        o = native_new_and_init(c);
 
-       if (!o)
+       if (o == NULL)
                return *exceptionptr;
 
        return o;
 }
 
 
-/* new_exception_message *******************************************************
+/* exceptions_new_utf **********************************************************
 
-   Creates an exception object with the given name and initalizes it
-   with the given char message.
+   Creates an exception object with the given name and initalizes it.
 
    IN:
       classname....class name in UTF-8
-         message......message in UTF-8
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
 
 *******************************************************************************/
 
-java_objectheader *new_exception_message(const char *classname,
-                                                                                const char *message)
+static java_objectheader *exceptions_new_utf(utf *classname)
 {
-       java_lang_String *s;
+       classinfo         *c;
+       java_objectheader *o;
 
-       s = javastring_new_from_utf_string(message);
-       if (!s)
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
                return *exceptionptr;
 
-       return new_exception_javastring(classname, s);
+       o = exceptions_new_class(c);
+
+       return o;
 }
 
 
-/* new_exception_throwable *****************************************************
+/* exceptions_throw_class ******************************************************
+
+   Creates an exception object from the given class, initalizes and
+   throws it.
+
+   IN:
+      class....class pointer
+
+*******************************************************************************/
+
+static void exceptions_throw_class(classinfo *c)
+{
+       java_objectheader *o;
+
+       o = exceptions_new_class(c);
+
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
+}
+
+
+/* exceptions_throw_utf ********************************************************
+
+   Creates an exception object with the given name, initalizes and
+   throws it.
+
+   IN:
+      classname....class name in UTF-8
+
+*******************************************************************************/
+
+static void exceptions_throw_utf(utf *classname)
+{
+       classinfo *c;
+
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       exceptions_throw_class(c);
+}
+
+
+/* exceptions_throw_utf_throwable **********************************************
 
    Creates an exception object with the given name and initalizes it
    with the given java/lang/Throwable exception.
 
    IN:
       classname....class name in UTF-8
-         throwable....the given Throwable
+         cause........the given Throwable
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_throwable(utf *classname,
+                                                                                  java_objectheader *cause)
+{
+       java_objectheader *o;
+       classinfo         *c;
+   
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       o = native_new_and_init_throwable(c, cause);
+
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
+}
+
+
+/* exceptions_new_utf_javastring ***********************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/String message.
+
+   IN:
+      classname....class name in UTF-8
+         message......the message as a java.lang.String
 
    RETURN VALUE:
       an exception pointer (in any case -- either it is the newly created
@@ -395,25 +438,56 @@ java_objectheader *new_exception_message(const char *classname,
 
 *******************************************************************************/
 
-java_objectheader *new_exception_throwable(const char *classname,
-                                                                                  java_lang_Throwable *throwable)
+static java_objectheader *exceptions_new_utf_javastring(utf *classname,
+                                                                                                               java_objectheader *message)
 {
        java_objectheader *o;
        classinfo         *c;
    
-       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
                return *exceptionptr;
 
-       o = native_new_and_init_throwable(c, throwable);
+       o = native_new_and_init_string(c, message);
 
-       if (!o)
+       if (o == NULL)
                return *exceptionptr;
 
        return o;
 }
 
 
-/* new_exception_utfmessage ****************************************************
+/* exceptions_new_class_utf ****************************************************
+
+   Creates an exception object of the given class and initalizes it.
+
+   IN:
+      c..........class pointer
+      message....the message as UTF-8 string
+
+*******************************************************************************/
+
+static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
+{
+       java_objectheader *o;
+       java_objectheader *s;
+
+       s = javastring_new(message);
+
+       if (s == NULL)
+               return *exceptionptr;
+
+       o = native_new_and_init_string(c, s);
+
+       if (o == NULL)
+               return *exceptionptr;
+
+       return o;
+}
+
+
+/* exceptions_new_utf_utf ******************************************************
 
    Creates an exception object with the given name and initalizes it
    with the given utf message.
@@ -428,26 +502,30 @@ java_objectheader *new_exception_throwable(const char *classname,
 
 *******************************************************************************/
 
-java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
+static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
 {
-       java_lang_String *s;
+       classinfo         *c;
+       java_objectheader *o;
 
-       s = javastring_new(message);
-       if (!s)
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
                return *exceptionptr;
 
-       return new_exception_javastring(classname, s);
+       o = exceptions_new_class_utf(c, message);
+
+       return o;
 }
 
 
-/* new_exception_javastring ****************************************************
+/* new_exception_message *******************************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given java/lang/String message.
+   with the given char message.
 
    IN:
       classname....class name in UTF-8
-         message......the message as a java.lang.String
+         message......message in UTF-8
 
    RETURN VALUE:
       an exception pointer (in any case -- either it is the newly created
@@ -455,24 +533,57 @@ java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
 
 *******************************************************************************/
 
-java_objectheader *new_exception_javastring(const char *classname,
-                                                                                       java_lang_String *message)
+static java_objectheader *new_exception_message(const char *classname,
+                                                                                               const char *message)
 {
        java_objectheader *o;
-       classinfo         *c;
-   
-       if (!(c = load_class_bootstrap(utf_new_char(classname))))
-               return *exceptionptr;
+       java_objectheader *s;
 
-       o = native_new_and_init_string(c, message);
+       s = javastring_new_from_utf_string(message);
 
-       if (!o)
+       if (s == NULL)
                return *exceptionptr;
 
+       o = exceptions_new_utf_javastring(classname, s);
+
        return o;
 }
 
 
+/* exceptions_throw_class_utf **************************************************
+
+   Creates an exception object of the given class, initalizes and
+   throws it with the given utf message.
+
+   IN:
+      c..........class pointer
+         message....the message as an UTF-8
+
+*******************************************************************************/
+
+static void exceptions_throw_class_utf(classinfo *c, utf *message)
+{
+       *exceptionptr = exceptions_new_class_utf(c, message);
+}
+
+
+/* exceptions_throw_utf_utf ****************************************************
+
+   Creates an exception object with the given name, initalizes and
+   throws it with the given utf message.
+
+   IN:
+      classname....class name in UTF-8
+         message......the message as an utf *
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_utf(utf *classname, utf *message)
+{
+       *exceptionptr = exceptions_new_utf_utf(classname, message);
+}
+
+
 /* new_exception_int ***********************************************************
 
    Creates an exception object with the given name and initalizes it
@@ -505,39 +616,20 @@ java_objectheader *new_exception_int(const char *classname, s4 i)
 }
 
 
-/* exceptions_new_abstractmethoderror ******************************************
+/* exceptions_new_abstractmethoderror ****************************************
 
    Generates a java.lang.AbstractMethodError for the VM.
 
 *******************************************************************************/
 
-#if defined(ENABLE_JAVASE)
 java_objectheader *exceptions_new_abstractmethoderror(void)
 {
-       java_objectheader *e;
-
-       e = native_new_and_init(class_java_lang_AbstractMethodError);
-
-       if (e == NULL)
-               return *exceptionptr;
-
-       return e;
-}
-#endif
-
-
-/* exceptions_throw_abstractmethoderror ****************************************
-
-   Generates a java.lang.AbstractMethodError for the VM and throws it.
+       java_objectheader *o;
 
-*******************************************************************************/
+       o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
 
-#if defined(ENABLE_JAVASE)
-void exceptions_throw_abstractmethoderror(void)
-{
-       *exceptionptr = exceptions_new_abstractmethoderror();
+       return o;
 }
-#endif
 
 
 /* exceptions_asm_new_abstractmethoderror **************************************
@@ -574,21 +666,84 @@ java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
 }
 
 
-/* new_classformaterror ********************************************************
+/* exceptions_new_arraystoreexception ******************************************
+
+   Generates a java.lang.ArrayStoreException for the VM.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_new_arraystoreexception(void)
+{
+       java_objectheader *o;
+
+       o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
+
+       return o;
+}
+
+
+/* exceptions_throw_abstractmethoderror ****************************************
+
+   Generates and throws a java.lang.AbstractMethodError for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_abstractmethoderror(void)
+{
+       exceptions_throw_utf(utf_java_lang_AbstractMethodError);
+}
+
+
+/* exceptions_throw_classcircularityerror **************************************
 
-   generates a java.lang.ClassFormatError for the classloader
+   Generates and throws a java.lang.ClassCircularityError for the
+   classloader.
 
    IN:
       c............the class in which the error was found
-         message......UTF-8 format string
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+*******************************************************************************/
+
+void exceptions_throw_classcircularityerror(classinfo *c)
+{
+       java_objectheader *o;
+       char              *msg;
+       s4                 msglen;
+
+       /* calculate message length */
+
+       msglen = utf_bytes(c->name) + strlen("0");
+
+       /* allocate a buffer */
+
+       msg = MNEW(char, msglen);
+
+       /* print message into allocated buffer */
+
+       utf_copy_classname(msg, c->name);
+
+       o = new_exception_message(utf_java_lang_ClassCircularityError, msg);
+
+       MFREE(msg, char, msglen);
+
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
+}
+
+
+/* exceptions_throw_classformaterror *******************************************
+
+   Generates and throws a java.lang.ClassFormatError for the VM.
+
+   IN:
+      c............the class in which the error was found
+         message......UTF-8 format string
 
 *******************************************************************************/
 
-java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
+void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
 {
        java_objectheader *o;
        char              *msg;
@@ -599,14 +754,14 @@ java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
 
        msglen = 0;
 
-       if (c)
+       if (c != NULL)
                msglen += utf_bytes(c->name) + strlen(" (");
 
        va_start(ap, message);
        msglen += get_variable_message_length(message, ap);
        va_end(ap);
 
-       if (c)
+       if (c != NULL)
                msglen += strlen(")");
 
        msglen += strlen("0");
@@ -617,7 +772,7 @@ java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
 
        /* print message into allocated buffer */
 
-       if (c) {
+       if (c != NULL) {
                utf_copy_classname(msg, c->name);
                strcat(msg, " (");
        }
@@ -626,141 +781,161 @@ java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
        vsprintf(msg + strlen(msg), message, ap);
        va_end(ap);
 
-       if (c)
+       if (c != NULL)
                strcat(msg, ")");
 
-       o = new_exception_message(string_java_lang_ClassFormatError, msg);
+       o = new_exception_message(utf_java_lang_ClassFormatError, msg);
 
        MFREE(msg, char, msglen);
 
-       return o;
+       *exceptionptr = o;
 }
 
 
-/* exceptions_throw_classformaterror *******************************************
+/* exceptions_throw_classnotfoundexception *************************************
 
-   Generate a java.lang.ClassFormatError for the VM system and throw it.
+   Generates and throws a java.lang.ClassNotFoundException for the
+   VM.
 
    IN:
-      c............the class in which the error was found
-         message......UTF-8 format string
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+      name.........name of the class not found as a utf *
 
 *******************************************************************************/
 
-void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
+void exceptions_throw_classnotfoundexception(utf *name)
 {
-       va_list ap;
+       /* we use class here, as this one is rather frequent */
 
-       va_start(ap, message);
-       *exceptionptr = new_classformaterror(c, message, ap);
-       va_end(ap);
+       exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
 }
 
 
-/* new_classnotfoundexception **************************************************
+/* exceptions_throw_noclassdeffounderror ***************************************
 
-   Generates a java.lang.ClassNotFoundException for the classloader.
+   Generates and throws a java.lang.NoClassDefFoundError.
 
    IN:
       name.........name of the class not found as a utf *
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+*******************************************************************************/
+
+void exceptions_throw_noclassdeffounderror(utf *name)
+{
+       exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
+}
+
+
+/* classnotfoundexception_to_noclassdeffounderror ******************************
+
+   Check the *exceptionptr for a ClassNotFoundException. If it is one,
+   convert it to a NoClassDefFoundError.
 
 *******************************************************************************/
 
-java_objectheader *new_classnotfoundexception(utf *name)
+void classnotfoundexception_to_noclassdeffounderror(void)
 {
-       java_objectheader *o;
-       java_lang_String  *s;
+       java_objectheader   *xptr;
+       java_objectheader   *cause;
+       java_lang_Throwable *t;
+       java_lang_String    *s;
 
-       s = javastring_new(name);
-       if (!s)
-               return *exceptionptr;
+       /* get the cause */
 
-       o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
+       cause = *exceptionptr;
 
-       if (!o)
-               return *exceptionptr;
+       /* convert ClassNotFoundException's to NoClassDefFoundError's */
 
-       return o;
-}
+       if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
+               /* clear exception, because we are calling jit code again */
 
+               *exceptionptr = NULL;
 
-/* new_noclassdeffounderror ****************************************************
+               /* create new error */
 
-   Generates a java.lang.NoClassDefFoundError
+               t = (java_lang_Throwable *) cause;
+               s = t->detailMessage;
 
-   IN:
-      name.........name of the class not found as a utf *
+               xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+               /* we had an exception while creating the error */
 
-*******************************************************************************/
+               if (*exceptionptr)
+                       return;
 
-java_objectheader *new_noclassdeffounderror(utf *name)
-{
-       java_objectheader *o;
-       java_lang_String  *s;
+               /* set new exception */
 
-       s = javastring_new(name);
-       if (!s)
-               return *exceptionptr;
+               *exceptionptr = xptr;
+       }
+}
 
-       o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
 
-       if (!o)
-               return *exceptionptr;
+/* exceptions_throw_exceptionininitializererror ********************************
 
-       return o;
+   Generates and throws a java.lang.ExceptionInInitializerError for
+   the VM.
+
+   IN:
+      cause......cause exception object
+
+*******************************************************************************/
+
+void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
+{
+       exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
+                                                                  cause);
 }
 
 
-/* classnotfoundexception_to_noclassdeffounderror ******************************
+/* exceptions_throw_incompatibleclasschangeerror *******************************
 
-   Check the *exceptionptr for a ClassNotFoundException. If it is one,
-   convert it to a NoClassDefFoundError.
+   Generates and throws a java.lang.IncompatibleClassChangeError for
+   the VM.
+
+   IN:
+      message......UTF-8 message format string
 
 *******************************************************************************/
 
-void classnotfoundexception_to_noclassdeffounderror(void)
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
 {
-       java_objectheader *xptr;
-       java_objectheader *cause;
+       java_objectheader *o;
+       char              *msg;
+       s4                 msglen;
 
-       /* get the cause */
+       /* calculate exception message length */
 
-       cause = *exceptionptr;
+       msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
 
-       /* convert ClassNotFoundException's to NoClassDefFoundError's */
+       /* allocate memory */
 
-       if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
-               /* clear exception, because we are calling jit code again */
+       msg = MNEW(char, msglen);
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, message);
+
+       o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
+                                                                  javastring_new_from_utf_string(msg));
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
 
-               *exceptionptr = NULL;
+       if (o == NULL)
+               return;
 
-               /* create new error */
+       *exceptionptr = o;
+}
 
-               xptr =
-                       new_exception_javastring(string_java_lang_NoClassDefFoundError,
-                                       ((java_lang_Throwable *) cause)->detailMessage);
 
-               /* we had an exception while creating the error */
+/* exceptions_throw_instantiationerror *****************************************
 
-               if (*exceptionptr)
-                       return;
+   Generates and throws a java.lang.InstantiationError for the VM.
 
-               /* set new exception */
+*******************************************************************************/
 
-               *exceptionptr = xptr;
-       }
+void exceptions_throw_instantiationerror(classinfo *c)
+{
+       exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
 }
 
 
@@ -798,7 +973,7 @@ void exceptions_throw_internalerror(const char *message, ...)
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_InternalError, msg);
+       o = new_exception_message(utf_java_lang_InternalError, msg);
 
        /* free memory */
 
@@ -811,23 +986,18 @@ void exceptions_throw_internalerror(const char *message, ...)
 }
 
 
-/* exceptions_new_linkageerror *************************************************
+/* exceptions_throw_linkageerror ***********************************************
 
-   Generates a java.lang.LinkageError with an error message.
+   Generates and throws java.lang.LinkageError with an error message.
 
    IN:
       message......UTF-8 message
          c............class related to the error. If this is != NULL
                       the name of c is appended to the error message.
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
 *******************************************************************************/
 
-java_objectheader *exceptions_new_linkageerror(const char *message,
-                                                                                          classinfo *c)
+void exceptions_throw_linkageerror(const char *message, classinfo *c)
 {
        java_objectheader *o;
        char              *msg;
@@ -836,9 +1006,9 @@ java_objectheader *exceptions_new_linkageerror(const char *message,
        /* calculate exception message length */
 
        msglen = strlen(message) + 1;
-       if (c) {
+
+       if (c != NULL)
                msglen += utf_bytes(c->name);
-       }
                
        /* allocate memory */
 
@@ -847,9 +1017,9 @@ java_objectheader *exceptions_new_linkageerror(const char *message,
        /* generate message */
 
        strcpy(msg,message);
-       if (c) {
+
+       if (c != NULL)
                utf_cat_classname(msg, c->name);
-       }
 
        o = native_new_and_init_string(class_java_lang_LinkageError,
                                                                   javastring_new_from_utf_string(msg));
@@ -858,40 +1028,33 @@ java_objectheader *exceptions_new_linkageerror(const char *message,
 
        MFREE(msg, char, msglen);
 
-       if (!o)
-               return *exceptionptr;
+       if (o == NULL)
+               return;
 
-       return o;
+       *exceptionptr = o;
 }
 
 
-/* exceptions_new_nosuchmethoderror ********************************************
+/* exceptions_throw_nosuchfielderror *******************************************
 
-   Generates a java.lang.NoSuchMethodError with an error message.
+   Generates and throws a java.lang.NoSuchFieldError with an error
+   message.
 
    IN:
-      c............class in which the method was not found
-         name.........name of the method
-         desc.........descriptor of the method
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+      c............class in which the field was not found
+         name.........name of the field
 
 *******************************************************************************/
 
-#if defined(ENABLE_JAVASE)
-java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
-                                                                                                       utf *name, utf *desc)
+void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
 {
-       java_objectheader *o;
-       char              *msg;
-       s4                 msglen;
+       char *msg;
+       s4    msglen;
+       utf  *u;
 
        /* calculate exception message length */
 
-       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
-               utf_bytes(desc) + strlen("0");
+       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
 
        /* allocate memory */
 
@@ -902,26 +1065,21 @@ java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
        utf_copy_classname(msg, c->name);
        strcat(msg, ".");
        utf_cat(msg, name);
-       utf_cat(msg, desc);
 
-       o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
-                                                                  javastring_new_from_utf_string(msg));
+       u = utf_new_char(msg);
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       if (o == NULL)
-               return *exceptionptr;
-
-       return o;
+       exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
 }
-#endif
 
 
 /* exceptions_throw_nosuchmethoderror ******************************************
 
-   Generates a java.lang.NoSuchMethodError with an error message.
+   Generates and throws a java.lang.NoSuchMethodError with an error
+   message.
 
    IN:
       c............class in which the method was not found
@@ -930,12 +1088,36 @@ java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
 
 *******************************************************************************/
 
-#if defined(ENABLE_JAVASE)
 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 {
-       *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
+               utf_bytes(desc) + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, ".");
+       utf_cat(msg, name);
+       utf_cat(msg, desc);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
 }
-#endif
 
 
 /* exceptions_throw_outofmemoryerror *******************************************
@@ -946,45 +1128,49 @@ void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 
 void exceptions_throw_outofmemoryerror(void)
 {
-       java_objectheader *e;
+       exceptions_throw_class(class_java_lang_OutOfMemoryError);
+}
 
-       e = native_new_and_init(class_java_lang_OutOfMemoryError);
 
-       if (e == NULL)
-               return;
+/* exceptions_throw_unsatisfiedlinkerror ***************************************
+
+   Generates and throws a java.lang.UnsatisfiedLinkError for the
+   classloader.
+
+   IN:
+         name......UTF-8 name string
 
-       *exceptionptr = e;
+*******************************************************************************/
+
+void exceptions_throw_unsatisfiedlinkerror(utf *name)
+{
+       exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
 }
 
 
-/* new_unsupportedclassversionerror ********************************************
+/* exceptions_throw_unsupportedclassversionerror *******************************
 
-   Generate a java.lang.UnsupportedClassVersionError for the classloader
+   Generates and throws a java.lang.UnsupportedClassVersionError for
+   the classloader.
 
    IN:
       c............class in which the method was not found
          message......UTF-8 format string
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
 *******************************************************************************/
 
-java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
+void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
 {
        java_objectheader *o;
-       va_list            ap;
        char              *msg;
     s4                 msglen;
 
        /* calculate exception message length */
 
-       msglen = utf_bytes(c->name) + strlen(" (") + strlen(")") + strlen("0");
-
-       va_start(ap, message);
-       msglen += get_variable_message_length(message, ap);
-       va_end(ap);
+       msglen =
+               utf_bytes(c->name) +
+               strlen(" (Unsupported major.minor version 00.0)") +
+               strlen("0");
 
        /* allocate memory */
 
@@ -993,43 +1179,35 @@ java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *me
        /* generate message */
 
        utf_copy_classname(msg, c->name);
-       strcat(msg, " (");
-
-       va_start(ap, message);
-       vsprintf(msg + strlen(msg), message, ap);
-       va_end(ap);
-
-       strcat(msg, ")");
+       sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
+                       ma, mi);
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
-                                                         msg);
+       o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       return o;
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
 }
 
 
-/* exceptions_new_verifyerror **************************************************
+/* exceptions_throw_verifyerror ************************************************
 
-   Generates a java.lang.VerifyError for the JIT compiler.
+   Generates and throws a java.lang.VerifyError for the JIT compiler.
 
    IN:
       m............method in which the error was found
          message......UTF-8 format string
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
 *******************************************************************************/
 
-java_objectheader *exceptions_new_verifyerror(methodinfo *m,
-                                                                                         const char *message, ...)
+void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 {
        java_objectheader *o;
        va_list            ap;
@@ -1040,8 +1218,9 @@ java_objectheader *exceptions_new_verifyerror(methodinfo *m,
 
        msglen = 0;
 
-       if (m)
-               msglen = strlen("(class: ") + utf_bytes(m->class->name) +
+       if (m != NULL)
+               msglen =
+                       strlen("(class: ") + utf_bytes(m->class->name) +
                        strlen(", method: ") + utf_bytes(m->name) +
                        strlen(" signature: ") + utf_bytes(m->descriptor) +
                        strlen(") ") + strlen("0");
@@ -1056,7 +1235,7 @@ java_objectheader *exceptions_new_verifyerror(methodinfo *m,
 
        /* generate message */
 
-       if (m) {
+       if (m != NULL) {
                strcpy(msg, "(class: ");
                utf_cat_classname(msg, m->class->name);
                strcat(msg, ", method: ");
@@ -1072,25 +1251,13 @@ java_objectheader *exceptions_new_verifyerror(methodinfo *m,
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_VerifyError, msg);
+       o = new_exception_message(utf_java_lang_VerifyError, msg);
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       return o;
-}
-
-
-/* exceptions_throw_verifyerror ************************************************
-
-   Throws a java.lang.VerifyError for the VM system.
-
-*******************************************************************************/
-
-void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
-{
-       *exceptionptr = exceptions_new_verifyerror(m, message);
+       *exceptionptr = o;
 }
 
 
@@ -1160,7 +1327,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_VerifyError, msg);
+       o = new_exception_message(utf_java_lang_VerifyError, msg);
 
        /* free memory */
 
@@ -1170,54 +1337,34 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
 }
 
 
-/* exceptions_new_virtualmachineerror ******************************************
-
-   Generates a java.lang.VirtualMachineError for the VM system.
-
-*******************************************************************************/
-
-java_objectheader *exceptions_new_virtualmachineerror(void)
-{
-       java_objectheader *e;
-
-       e = native_new_and_init(class_java_lang_VirtualMachineError);
-
-       if (e == NULL)
-               return *exceptionptr;
-
-       return e;
-}
-
-
 /* exceptions_throw_virtualmachineerror ****************************************
 
-   Throws a java.lang.VirtualMachineError for the VM system.
+   Generates and throws a java.lang.VirtualMachineError for the VM.
 
 *******************************************************************************/
 
 void exceptions_throw_virtualmachineerror(void)
 {
-       *exceptionptr = exceptions_new_virtualmachineerror();
+       exceptions_throw_class(class_java_lang_VirtualMachineError);
 }
 
 
-/* new_arithmeticexception *****************************************************
+/* exceptions_new_arithmeticexception ******************************************
 
-   Generates a java.lang.ArithmeticException for the jit compiler.
+   Generates a java.lang.ArithmeticException for the JIT compiler.
 
 *******************************************************************************/
 
-java_objectheader *new_arithmeticexception(void)
+java_objectheader *exceptions_new_arithmeticexception(void)
 {
-       java_objectheader *e;
+       java_objectheader *o;
 
-       e = new_exception_message(string_java_lang_ArithmeticException,
-                                                         string_java_lang_ArithmeticException_message);
+       o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
 
-       if (!e)
+       if (o == NULL)
                return *exceptionptr;
 
-       return e;
+       return o;
 }
 
 
@@ -1228,12 +1375,11 @@ java_objectheader *new_arithmeticexception(void)
 
 *******************************************************************************/
 
-java_objectheader *new_arrayindexoutofboundsexception(s4 index)
+java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
 {
-       java_objectheader *e;
-       methodinfo        *m;
        java_objectheader *o;
-       java_lang_String  *s;
+       methodinfo        *m;
+       java_objectheader *s;
 
        /* convert the index into a String, like Sun does */
 
@@ -1246,73 +1392,44 @@ java_objectheader *new_arrayindexoutofboundsexception(s4 index)
        if (m == NULL)
                return *exceptionptr;
 
-       o = vm_call_method(m, NULL, index);
-
-       s = (java_lang_String *) o;
+       s = vm_call_method(m, NULL, index);
 
        if (s == NULL)
                return *exceptionptr;
 
-       e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
-                                                                s);
+       o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
+                                                                         s);
 
-       if (e == NULL)
+       if (o == NULL)
                return *exceptionptr;
 
-       return e;
+       return o;
 }
 
 
 /* exceptions_throw_arrayindexoutofboundsexception *****************************
 
-   Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
-   system.
+   Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
+   the VM.
 
 *******************************************************************************/
 
 void exceptions_throw_arrayindexoutofboundsexception(void)
 {
-       java_objectheader *e;
-
-       e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
-
-       if (!e)
-               return;
-
-       *exceptionptr = e;
-}
-
-
-/* exceptions_new_arraystoreexception ******************************************
-
-   Generates a java.lang.ArrayStoreException for the VM compiler.
-
-*******************************************************************************/
-
-java_objectheader *exceptions_new_arraystoreexception(void)
-{
-       java_objectheader *e;
-
-       e = new_exception(string_java_lang_ArrayStoreException);
-/*     e = native_new_and_init(class_java_lang_ArrayStoreException); */
-
-       if (!e)
-               return *exceptionptr;
-
-       return e;
+       exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
 }
 
 
 /* exceptions_throw_arraystoreexception ****************************************
 
-   Generates a java.lang.ArrayStoreException for the VM system and
-   throw it in the VM system.
+   Generates and throws a java.lang.ArrayStoreException for the VM.
 
 *******************************************************************************/
 
 void exceptions_throw_arraystoreexception(void)
 {
-       *exceptionptr = exceptions_new_arraystoreexception();
+       exceptions_throw_utf(utf_java_lang_ArrayStoreException);
+/*     e = native_new_and_init(class_java_lang_ArrayStoreException); */
 }
 
 
@@ -1341,99 +1458,110 @@ java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
 }
 
 
-/* exceptions_new_illegalargumentexception *************************************
+/* exceptions_throw_clonenotsupportedexception *********************************
 
-   Generates a java.lang.IllegalArgumentException for the VM system.
+   Generates and throws a java.lang.CloneNotSupportedException for the
+   VM.
 
 *******************************************************************************/
 
-java_objectheader *new_illegalargumentexception(void)
+void exceptions_throw_clonenotsupportedexception(void)
 {
-       java_objectheader *e;
+       exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
+}
 
-       e = native_new_and_init(class_java_lang_IllegalArgumentException);
 
-       if (!e)
-               return *exceptionptr;
+/* exceptions_throw_illegalaccessexception *************************************
 
-       return e;
+   Generates and throws a java.lang.IllegalAccessException for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalaccessexception(classinfo *c)
+{
+       /* XXX handle argument */
+
+       exceptions_throw_utf(utf_java_lang_IllegalAccessException);
 }
 
 
 /* exceptions_throw_illegalargumentexception ***********************************
 
-   Generates a java.lang.IllegalArgumentException for the VM system
-   and throw it in the VM system.
+   Generates and throws a java.lang.IllegalArgumentException for the
+   VM.
 
 *******************************************************************************/
 
 void exceptions_throw_illegalargumentexception(void)
 {
-       *exceptionptr = new_illegalargumentexception();
+       exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
 }
 
 
-/* exceptions_new_illegalmonitorstateexception *********************************
+/* exceptions_throw_illegalmonitorstateexception *******************************
 
-   Generates a java.lang.IllegalMonitorStateException for the VM
-   thread system.
+   Generates and throws a java.lang.IllegalMonitorStateException for
+   the VM.
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_illegalmonitorstateexception(void)
+void exceptions_throw_illegalmonitorstateexception(void)
 {
-       java_objectheader *e;
-
-       e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
-
-       if (e == NULL)
-               return *exceptionptr;
-
-       return e;
+       exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
 }
 
 
-/* exceptions_throw_illegalmonitorstateexception *******************************
+/* exceptions_throw_instantiationexception *************************************
 
-   Generates a java.lang.IllegalMonitorStateException for the VM
-   system and throw it in the VM system.
+   Generates and throws a java.lang.InstantiationException for the VM.
 
 *******************************************************************************/
 
-void exceptions_throw_illegalmonitorstateexception(void)
+void exceptions_throw_instantiationexception(classinfo *c)
 {
-       *exceptionptr = exceptions_new_illegalmonitorstateexception();
+       exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
 }
 
 
-/* exceptions_new_negativearraysizeexception ***********************************
+/* exceptions_throw_interruptedexception ***************************************
 
-   Generates a java.lang.NegativeArraySizeException for the VM system.
+   Generates and throws a java.lang.InterruptedException for the VM.
 
 *******************************************************************************/
 
-java_objectheader *new_negativearraysizeexception(void)
+void exceptions_throw_interruptedexception(void)
 {
-       java_objectheader *e;
+       exceptions_throw_utf(utf_java_lang_InterruptedException);
+}
 
-       e = new_exception(string_java_lang_NegativeArraySizeException);
 
-       if (!e)
-               return *exceptionptr;
+/* exceptions_throw_invocationtargetexception **********************************
 
-       return e;
+   Generates and throws a java.lang.InvocationTargetException for the
+   VM.
+
+   IN:
+      cause......cause exception object
+
+*******************************************************************************/
+
+void exceptions_throw_invocationtargetexception(java_objectheader *cause)
+{
+       exceptions_throw_utf_throwable(utf_java_lang_InvocationTargetException,
+                                                                  cause);
 }
 
 
 /* exceptions_throw_negativearraysizeexception *********************************
 
-   Generates a java.lang.NegativeArraySizeException for the VM system.
+   Generates and throws a java.lang.NegativeArraySizeException for the
+   VM.
 
 *******************************************************************************/
 
 void exceptions_throw_negativearraysizeexception(void)
 {
-       *exceptionptr = new_negativearraysizeexception();
+       exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
 }
 
 
@@ -1445,14 +1573,11 @@ void exceptions_throw_negativearraysizeexception(void)
 
 java_objectheader *exceptions_new_nullpointerexception(void)
 {
-       java_objectheader *e;
-
-       e = native_new_and_init(class_java_lang_NullPointerException);
+       java_objectheader *o;
 
-       if (e == NULL)
-               return *exceptionptr;
+       o = exceptions_new_class(class_java_lang_NullPointerException);
 
-       return e;
+       return o;
 }
 
 
@@ -1465,40 +1590,62 @@ java_objectheader *exceptions_new_nullpointerexception(void)
 
 void exceptions_throw_nullpointerexception(void)
 {
-       *exceptionptr = exceptions_new_nullpointerexception();
+       exceptions_throw_class(class_java_lang_NullPointerException);
 }
 
 
-/* exceptions_new_stringindexoutofboundsexception ******************************
+/* exceptions_throw_stringindexoutofboundsexception ****************************
 
-   Generates a java.lang.StringIndexOutOfBoundsException for the VM
-   system.
+   Generates and throws a java.lang.StringIndexOutOfBoundsException
+   for the VM.
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
+void exceptions_throw_stringindexoutofboundsexception(void)
 {
-       java_objectheader *e;
+       exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
+}
 
-       e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
 
-       if (e == NULL)
-               return *exceptionptr;
+/* exceptions_get_exception ****************************************************
 
-       return e;
+   Returns the current exception pointer of the current thread.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_get_exception(void)
+{
+       /* return the exception */
+
+       return *exceptionptr;
 }
 
 
-/* exceptions_throw_stringindexoutofboundsexception ****************************
+/* exceptions_set_exception ****************************************************
 
-   Throws a java.lang.StringIndexOutOfBoundsException for the VM
-   system.
+   Sets the exception pointer of the current thread.
 
 *******************************************************************************/
 
-void exceptions_throw_stringindexoutofboundsexception(void)
+void exceptions_set_exception(java_objectheader *o)
+{
+       /* set the exception */
+
+       *exceptionptr = o;
+}
+
+
+/* exceptions_clear_exception **************************************************
+
+   Clears the current exception pointer of the current thread.
+
+*******************************************************************************/
+
+void exceptions_clear_exception(void)
 {
-       *exceptionptr = exceptions_new_stringindexoutofboundsexception();
+       /* and clear the exception */
+
+       *exceptionptr = NULL;
 }
 
 
@@ -1761,6 +1908,23 @@ void exceptions_print_exception(java_objectheader *xptr)
 }
 
 
+/* exceptions_print_current_exception ******************************************
+
+   Prints the current pending exception, the detail message and the
+   cause, if available, with CACAO internal functions to stdout.
+
+*******************************************************************************/
+
+void exceptions_print_current_exception(void)
+{
+       java_objectheader *xptr;
+
+       xptr = *exceptionptr;
+
+       exceptions_print_exception(xptr);
+}
+
+
 /*
  * 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
index 70e9088e2916eb5d878f79381e56a61c3f0b0002..0c8a21cfc376e16b7582e1f7cfa44c554db46822 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/exceptions.h - exception related functions prototypes
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Edwin Steiner
-
-   $Id: exceptions.h 6286 2007-01-10 10:03:38Z twisti $
+   $Id: exceptions.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "native/jni.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
-#include "vm/builtin.h"
-#include "vm/references.h"
-#include "vm/method.h"
+
+#include "vmcore/references.h"
+#include "vmcore/method.h"
 
 
 /* hardware-exception defines **************************************************
 #define EXCEPTION_LOAD_DISP_PATCHER                  5
 
 
-/* exception pointer **********************************************************/
-
-#if defined(ENABLE_THREADS)
-#define exceptionptr    &(THREADOBJECT->_exceptionptr)
-#else
-#define exceptionptr    &_no_threads_exceptionptr
-#endif
-
-#if !defined(ENABLE_THREADS)
-extern java_objectheader *_no_threads_exceptionptr;
-#endif
-
-
 /* function prototypes ********************************************************/
 
 /* load and link exceptions used in the system */
@@ -101,90 +80,68 @@ void throw_cacao_exception_exit(const char *exception,
 
 /* initialize new exceptions */
 
-java_objectheader *new_exception(const char *classname);
-
-java_objectheader *new_exception_message(const char *classname,
-                                                                                const char *message);
-
-java_objectheader *new_exception_throwable(const char *classname,
-                                                                                  java_lang_Throwable *cause);
-
 java_objectheader *new_exception_utfmessage(const char *classname,
                                                                                        utf *message);
 
-java_objectheader *new_exception_javastring(const char *classname,
-                                                                                       java_lang_String *message);
-
 java_objectheader *new_exception_int(const char *classname, s4 i);
 
 
 /* functions to generate compiler exceptions */
 
-#if defined(ENABLE_JAVASE)
 java_objectheader *exceptions_new_abstractmethoderror(void);
-void               exceptions_throw_abstractmethoderror(void);
-#endif
-
 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra);
+java_objectheader *exceptions_new_arraystoreexception(void);
 
-java_objectheader *new_classformaterror(classinfo *c, const char *message, ...);
+void exceptions_throw_abstractmethoderror(void);
+void exceptions_throw_classcircularityerror(classinfo *c);
 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...);
-
-java_objectheader *new_classnotfoundexception(utf *name);
-java_objectheader *new_noclassdeffounderror(utf *name);
-java_objectheader *exceptions_new_linkageerror(const char *message,classinfo *c);
-
-#if defined(ENABLE_JAVASE)
-java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
-                                                                                                       utf *name, utf *desc);
+void exceptions_throw_classnotfoundexception(utf *name);
+void exceptions_throw_noclassdeffounderror(utf *name);
+void exceptions_throw_linkageerror(const char *message, classinfo *c);
+void exceptions_throw_nosuchfielderror(classinfo *c, utf *name);
 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc);
-#endif
-
+void exceptions_throw_exceptionininitializererror(java_objectheader *cause);
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c,
+                                                                                                  const char *message);
+void exceptions_throw_instantiationerror(classinfo *c);
 void exceptions_throw_internalerror(const char *message, ...);
-
 void exceptions_throw_outofmemoryerror(void);
-
-java_objectheader *exceptions_new_verifyerror(methodinfo *m,
-                                                                                         const char *message, ...);
 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...);
 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type);
+void exceptions_throw_virtualmachineerror(void);
+void exceptions_throw_unsatisfiedlinkerror(utf *name);
+void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi);
 
-java_objectheader *exceptions_new_virtualmachineerror(void);
-void               exceptions_throw_virtualmachineerror(void);
-
-java_objectheader *new_unsupportedclassversionerror(classinfo *c,
-                                                                                                       const char *message, ...);
+java_objectheader *exceptions_new_arithmeticexception(void);
 
-java_objectheader *new_arithmeticexception(void);
-
-java_objectheader *new_arrayindexoutofboundsexception(s4 index);
+java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index);
 void exceptions_throw_arrayindexoutofboundsexception(void);
-
-java_objectheader *exceptions_new_arraystoreexception(void);
 void exceptions_throw_arraystoreexception(void);
 
 java_objectheader *exceptions_new_classcastexception(java_objectheader *o);
 
-java_objectheader *new_illegalargumentexception(void);
+void exceptions_throw_clonenotsupportedexception(void);
+void exceptions_throw_illegalaccessexception(classinfo *c);
 void exceptions_throw_illegalargumentexception(void);
-
-java_objectheader *exceptions_new_illegalmonitorstateexception(void);
-void               exceptions_throw_illegalmonitorstateexception(void);
-
-java_objectheader *new_negativearraysizeexception(void);
+void exceptions_throw_illegalmonitorstateexception(void);
+void exceptions_throw_interruptedexception(void);
+void exceptions_throw_instantiationexception(classinfo *c);
+void exceptions_throw_invocationtargetexception(java_objectheader *cause);
 void exceptions_throw_negativearraysizeexception(void);
 
 java_objectheader *exceptions_new_nullpointerexception(void);
 void exceptions_throw_nullpointerexception(void);
-
-java_objectheader *exceptions_new_stringindexoutofboundsexception(void);
 void exceptions_throw_stringindexoutofboundsexception(void);
 
 void classnotfoundexception_to_noclassdeffounderror(void);
 
+java_objectheader *exceptions_get_exception(void);
+void               exceptions_set_exception(java_objectheader *o);
+void               exceptions_clear_exception(void);
 java_objectheader *exceptions_get_and_clear_exception(void);
 
 void exceptions_print_exception(java_objectheader *xptr);
+void exceptions_print_current_exception(void);
 
 #endif /* _EXCEPTIONS_H */
 
diff --git a/src/vm/field.c b/src/vm/field.c
deleted file mode 100644 (file)
index 08eee65..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* src/vm/field.c - field functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Andreas Krall
-            Roman Obermaiser
-            Mark Probst
-            Edwin Steiner
-            Christian Thalinger
-
-   $Id: field.c 4879 2006-05-05 17:34:49Z edwin $
-
-*/
-
-
-#include "config.h"
-
-#include <stdio.h>
-
-#include "vm/types.h"
-
-#include "vm/field.h"
-#include "vm/utf8.h"
-
-
-/* field_free ******************************************************************
-
-   Frees a fields' resources.
-
-*******************************************************************************/
-
-void field_free(fieldinfo *f)
-{
-       /* empty */
-}
-
-
-/* field_printflags ************************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_printflags(fieldinfo *f)
-{
-       if (f == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (f->flags & ACC_PUBLIC)       printf(" PUBLIC");
-       if (f->flags & ACC_PRIVATE)      printf(" PRIVATE");
-       if (f->flags & ACC_PROTECTED)    printf(" PROTECTED");
-       if (f->flags & ACC_STATIC)       printf(" STATIC");
-       if (f->flags & ACC_FINAL)        printf(" FINAL");
-       if (f->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
-       if (f->flags & ACC_VOLATILE)     printf(" VOLATILE");
-       if (f->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
-       if (f->flags & ACC_NATIVE)       printf(" NATIVE");
-       if (f->flags & ACC_INTERFACE)    printf(" INTERFACE");
-       if (f->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
-}
-#endif
-
-
-/* field_print *****************************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_print(fieldinfo *f)
-{
-       if (f == NULL) {
-               printf("(fieldinfo*)NULL");
-               return;
-       }
-
-       utf_display_printable_ascii_classname(f->class->name);
-       printf(".");
-       utf_display_printable_ascii(f->name);
-       printf(" ");
-       utf_display_printable_ascii(f->descriptor);     
-
-       field_printflags(f);
-}
-#endif
-
-
-/* field_println ***************************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_println(fieldinfo *f)
-{
-       field_print(f);
-       printf("\n");
-}
-#endif
-
-/* field_fieldref_print ********************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_fieldref_print(constant_FMIref *fr)
-{
-       if (fr == NULL) {
-               printf("(constant_FMIref *)NULL");
-               return;
-       }
-
-       if (IS_FMIREF_RESOLVED(fr)) {
-               printf("<field> ");
-               field_print(fr->p.field);
-       }
-       else {
-               printf("<fieldref> ");
-               utf_display_printable_ascii_classname(fr->p.classref->name);
-               printf(".");
-               utf_display_printable_ascii(fr->name);
-               printf(" ");
-               utf_display_printable_ascii(fr->descriptor);
-       }
-}
-#endif
-
-/* field_fieldref_println ******************************************************
-
-   (debugging only)
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void field_fieldref_println(constant_FMIref *fr)
-{
-       field_fieldref_print(fr);
-       printf("\n");
-}
-#endif
-
-/*
- * 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:
- */
diff --git a/src/vm/field.h b/src/vm/field.h
deleted file mode 100644 (file)
index 9847658..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/* src/vm/field.h - field functions header
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Christian Thalinger
-
-   $Id: field.h 6012 2006-11-16 19:45:15Z twisti $
-*/
-
-
-#ifndef _FIELD_H
-#define _FIELD_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct fieldinfo fieldinfo; 
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-#include "vm/utf8.h"
-#include "vm/references.h"
-#include "vm/descriptor.h"
-
-
-/* fieldinfo ******************************************************************/
-
-struct fieldinfo {           /* field of a class                                 */
-
-       /* CAUTION: The first field must be a pointer that is never the same      */
-       /*          value as CLASSREF_PSEUDO_VFTBL! This is used to check whether */
-       /*          a constant_FMIref has been resolved.                          */
-
-       classinfo *class;     /* needed by typechecker. Could be optimized        */
-                             /* away by using constant_FMIref instead of         */
-                             /* fieldinfo throughout the compiler.               */
-
-       s4         flags;     /* ACC flags                                        */
-       s4         type;      /* basic data type                                  */
-       utf       *name;      /* name of field                                    */
-       utf       *descriptor;/* JavaVM descriptor string of field                */
-       utf       *signature; /* Signature attribute string                       */
-       typedesc  *parseddesc;/* parsed descriptor                                */
-
-       s4         offset;    /* offset from start of object (instance variables) */
-
-       imm_union  value;     /* storage for static values (class variables)      */
-};
-
-
-/* function prototypes ********************************************************/
-
-void field_free(fieldinfo *f);
-
-#if !defined(NDEBUG)
-void field_printflags(fieldinfo *f);
-void field_print(fieldinfo *f);
-void field_println(fieldinfo *f);
-void field_fieldref_print(constant_FMIref *fr);
-void field_fieldref_println(constant_FMIref *fr);
-#endif
-
-#endif /* _FIELD_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:
- */
index 7f9632bd89792b42109f0115cdd6499aee900bec..7154e8595940938856cab36fb0428b3d68317c7b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/finalizer.c - finalizer linked list and thread
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: finalizer.c 6251 2006-12-27 23:15:56Z twisti $
+   $Id: finalizer.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #endif
 
 #if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
 # include "threads/native/lock.h"
 #endif
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 
+#include "vmcore/options.h"
+
 
 /* global variables ***********************************************************/
 
diff --git a/src/vm/hashtable.c b/src/vm/hashtable.c
deleted file mode 100644 (file)
index a15d123..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/* src/vm/hashtable.c - functions for internal hashtables
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Mark Probst
-            Andreas Krall
-            Christian Thalinger
-
-   $Id: hashtable.c 4921 2006-05-15 14:24:36Z twisti $
-
-*/
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
-
-#include "vm/hashtable.h"
-
-
-/* hashtable_create ************************************************************
-
-   Initializes a hashtable structure and allocates memory. The
-   parameter size specifies the initial size of the hashtable.
-       
-*******************************************************************************/
-
-void hashtable_create(hashtable *hash, u4 size)
-{
-       /* initialize locking pointer */
-
-#if defined(ENABLE_THREADS)
-       /* We need to seperately allocate a java_objectheader here, as we
-          need to store the lock object in the new hashtable if it's
-          resized.  Otherwise we get an IllegalMonitorStateException. */
-
-       hash->header = NEW(java_objectheader);
-
-       lock_init_object_lock(hash->header);
-#endif
-
-       /* set initial hash values */
-
-       hash->size    = size;
-       hash->entries = 0;
-       hash->ptr     = MNEW(void*, size);
-
-       /* MNEW always allocates memory zeroed out, no need to clear the table */
-}
-
-
-/* hashtable_resize ************************************************************
-
-   Creates a new hashtable with specified size and moves the important
-   stuff from the old hashtable.
-
-*******************************************************************************/
-
-hashtable *hashtable_resize(hashtable *hash, u4 size)
-{
-       hashtable *newhash;
-
-       /* create new hashtable with specified size */
-
-       newhash = NEW(hashtable);
-
-       hashtable_create(newhash, size);
-
-#if defined(ENABLE_THREADS)
-       /* We need to store the old lock object in the new hashtable.
-          Otherwise we get an IllegalMonitorStateException. */
-
-       FREE(newhash->header, java_objectheader);
-
-       newhash->header  = hash->header;
-#endif
-
-       /* store the number of entries in the new hashtable */
-
-       newhash->entries = hash->entries;
-
-       return newhash;
-}
-
-
-/* hashtable_free **************************************************************
-
-   Simply frees the hashtable.
-
-   ATTENTION: It does NOT free the lock object!
-
-*******************************************************************************/
-
-void hashtable_free(hashtable *hash)
-{
-       MFREE(hash->ptr, void*, hash->size);
-       FREE(hash, hashtable);
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/hashtable.h b/src/vm/hashtable.h
deleted file mode 100644 (file)
index 7f718c2..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/* src/vm/hashtable.h - functions for internal hashtables
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Christian Thalinger
-
-   $Id: hashtable.h 4921 2006-05-15 14:24:36Z twisti $
-
-*/
-
-
-#ifndef _HASHTABLE_H
-#define _HASHTABLE_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct hashtable hashtable;
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/utf8.h"
-
-
-/* data structures for hashtables ********************************************
-
-   All utf-symbols, javastrings and classes are stored in global
-   hashtables, so every symbol exists only once. Equal symbols have
-   identical pointers.  The functions for adding hashtable elements
-   search the table for the element with the specified name/text and
-   return it on success. Otherwise a new hashtable element is created.
-
-   The hashtables use external linking for handling collisions. The
-   hashtable structure contains a pointer <ptr> to the array of
-   hashtable slots. The number of hashtable slots and therefore the
-   size of this array is specified by the element <size> of hashtable
-   structure. <entries> contains the number of all hashtable elements
-   stored in the table, including those in the external chains.  The
-   hashtable element structures (utf, literalstring, classinfo)
-   contain both a pointer to the next hashtable element as a link for
-   the external hash chain and the key of the element. The key is
-   computed from the text of the string or the classname by using up
-   to 8 characters.
-       
-   If the number of entries in the hashtable exceeds twice the size of
-   the hashtableslot-array it is supposed that the average length of
-   the external chains has reached a value beyond 2. Therefore the
-   functions for adding hashtable elements (utf_new, class_new,
-   literalstring_new) double the hashtableslot-array. In this
-   restructuring process all elements have to be inserted into the new
-   hashtable and new external chains must be built.
-
-   Example for the layout of a hashtable:
-
-hashtable.ptr-->+-------------------+
-                |                   |
-                         ...
-                |                   |
-                +-------------------+   +-------------------+   +-------------------+
-                | hashtable element |-->| hashtable element |-->| hashtable element |-->NULL
-                +-------------------+   +-------------------+   +-------------------+
-                | hashtable element |
-                +-------------------+   +-------------------+   
-                | hashtable element |-->| hashtable element |-->NULL
-                +-------------------+   +-------------------+   
-                | hashtable element |-->NULL
-                +-------------------+
-                |                   |
-                         ...
-                |                   |
-                +-------------------+
-
-*/
-
-
-/* hashtable ******************************************************************/
-
-struct hashtable {            
-#if defined(ENABLE_THREADS)
-       java_objectheader  *header;         /* required for locking               */
-#endif
-       u4                  size;           /* current size of the hashtable      */
-       u4                  entries;        /* number of entries in the table     */
-       void              **ptr;            /* pointer to hashtable               */
-};
-
-
-/* function prototypes ********************************************************/
-
-/* create hashtable */
-void hashtable_create(hashtable *hash, u4 size);
-
-/* creates and resizes a hashtable */
-hashtable *hashtable_resize(hashtable *hash, u4 size);
-
-/* frees a hashtable */
-void hashtable_free(hashtable *hash);
-
-#endif /* _HASHTABLE_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:
- */
index c3a86b719c61bc284c48330000e3761b9b5d82bf..366f85f9df446c2c39f0458929f932f7821ca1cf 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/initialize.c - static class initializer functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Mark Probst
-            Andreas Krall
-            Christian Thalinger
-
-   $Id: initialize.c 5123 2006-07-12 21:45:34Z twisti $
+   $Id: initialize.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/global.h"
 #include "vm/initialize.h"
 #include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/loader.h"
 #include "vm/exceptions.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 
 /* private functions **********************************************************/
 
@@ -95,7 +92,7 @@ bool initialize_class(classinfo *c)
        error and we have to throw a NoClassDefFoundError */
 
        if (c->state & CLASS_ERROR) {
-               *exceptionptr = new_noclassdeffounderror(c->name);
+               exceptions_throw_noclassdeffounderror(c->name);
 
                LOCK_MONITOR_EXIT(c);
 
@@ -196,9 +193,9 @@ static bool initialize_class_intern(classinfo *c)
 
        /* we have an exception or error */
 
-       xptr = *exceptionptr;
+       xptr = exceptions_get_exception();
 
-       if (xptr) {
+       if (xptr != NULL) {
                /* class is NOT initialized and is marked with error */
 
                c->state |= CLASS_ERROR;
@@ -208,13 +205,11 @@ static bool initialize_class_intern(classinfo *c)
                if (builtin_instanceof(xptr, class_java_lang_Exception)) {
                        /* clear exception, because we are calling jit code again */
 
-                       *exceptionptr = NULL;
+                       exceptions_clear_exception();
 
                        /* wrap the exception */
 
-                       *exceptionptr =
-                               new_exception_throwable(string_java_lang_ExceptionInInitializerError,
-                                                                               (java_lang_Throwable *) xptr);
+                       exceptions_throw_exceptionininitializererror(xptr);
                }
 
                return false;
index bc1f7cc0eb66337e5fdad9d73bf6c2d0e33acffe..39ecc07a0bfd3d79f4ef8231ddb4796a0919b986 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/initialize.h - static class initializer functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Mark Probst
-            Andreas Krall
-            Christian Thalinger
-
-   $Id: initialize.h 4357 2006-01-22 23:33:38Z twisti $
+   $Id: initialize.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #ifndef _INITIALIZE_H
 #define _INITIALIZE_H
 
+#include "config.h"
+
 #include "vm/global.h"
-#include "vm/references.h"
+
+#include "vmcore/references.h"
 
 
 /* function prototypes ********************************************************/
index 1725e17b3e3910d308065dd4b0448849b8f389ad..a28d936f39eab7cd6d61000da8eeb0cde0cfef07 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/abi.h - common ABI defines
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: abi.h 5079 2006-07-06 11:36:01Z twisti $
+   $Id: abi.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -40,6 +34,7 @@
 #include "vm/types.h"
 
 #include "vm/jit/abi-asm.h"
+#include "vm/jit/jit.h"
 
 
 /* ABI externs ****************************************************************/
index a6b148a075c5fd1b40f3addfc2611e422200a4b5..f3557e08a27f4d3647e8c7e90e1f1ae4f2b63219 100644 (file)
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Andreas Krall
-            Stefan Ring
-            Christian Thalinger
-            Christian Ullrich
-            Michael Starzinger
-            Edwin Steiner
-
-   $Id: simplereg.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: simplereg.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "arch.h"
 #include "md-abi.h"
 
+#include "mm/memory.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "mm/memory.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/reg.h"
 #include "vm/jit/allocator/simplereg.h"
 #include "vm/jit/show.h"
 
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
 
 #if 0
 #    define LOG(args) printf args
index 1702d5e49ba48e7e77098c33b260d81aeb3a69e8..27a50dd0ec69626798073575c7d9c4c5d854f017 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: asmpart.h 7216 2007-01-16 09:54:47Z twisti $
+   $Id: asmpart.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "config.h"
 #include "vm/types.h"
 
-
 #if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
 # include "threads/native/critical.h"
 #endif
 
 #include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/resolve.h"
 #include "vm/vm.h"
+
 #include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
+
+#include "vmcore/linker.h"
 
 
 /* some macros ****************************************************************/
index d106b8985e3f51b638c6777e65e30a77dd2cd973..abe1565573db4514c76e4993bfaa0630b5babf84 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/code.c - codeinfo struct for representing compiled code
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
 
 #include "arch.h"
 
+#include "mm/memory.h"
 #include "vm/jit/code.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/methodheader.h"
-#include "mm/memory.h"
-#include "vm/options.h"
-#include "vm/jit/code.h"
+#include "vmcore/options.h"
 
 
 /* code_init *******************************************************************
index 60ad5147e9d3d7877d3e61a0a48e6e4a0272e8a1..aab97eaf7ea9a8f28a47eea2b915bb574380557f 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/code.h - codeinfo struct for representing compiled code
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-            Christian Thalinger
-
    $Id$
 
 */
@@ -43,9 +38,11 @@ typedef struct codeinfo codeinfo;
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vm/method.h"
+
 #include "vm/jit/replace.h"
 
+#include "vmcore/method.h"
+
 
 /* constants ******************************************************************/
 
index 5ef123e3907f0411b7b617f77d261f9a49ec993f..2eb113e7156135198ca6c25ec7fc0d91eee3dacf 100644 (file)
@@ -39,7 +39,7 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen-common.c 7229 2007-01-22 00:58:36Z twisti $
+   $Id: codegen-common.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #endif
 
 #include "mm/memory.h"
+
 #include "toolbox/avl.h"
 #include "toolbox/list.h"
 #include "toolbox/logging.h"
+
 #include "native/jni.h"
 #include "native/native.h"
 
 #endif
 
 #include "vm/exceptions.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 
 #include "vm/jit/intrp/intrp.h"
 #endif
 
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 
 /* in this tree we store all method addresses *********************************/
 
index 649665b95ef405459de174e54c31caab9a5ec2ca..6776b122ecfe7ea29d822ae886b0839934ca64c9 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/codegen-common.h - architecture independent code generator stuff
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Christian Ullrich
-            Edwin Steiner
-
-   $Id: codegen-common.h 6265 2007-01-02 20:40:57Z edwin $
+   $Id: codegen-common.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -51,14 +45,17 @@ typedef struct linenumberref              linenumberref;
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vm/references.h"
-#include "vm/method.h"
+
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/code.h"
 #include "vm/jit/replace.h"
 
+#include "vmcore/descriptor.h"
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+
 
 #define MCODEINITSIZE (1<<15)       /* 32 Kbyte code area initialization size */
 #define DSEGINITSIZE  (1<<12)       /*  4 Kbyte data area initialization size */
index 83e26b57e10a8c57a438cc083eaebed5c477b30c..abacc37377311bdef804eec82d636bcbebf66643 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/dseg.c - data segment handling stuff
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
@@ -30,7 +30,7 @@
             Joseph Wenninger
             Edwin Steiner
 
-   $Id: dseg.c 6077 2006-11-28 22:04:29Z twisti $
+   $Id: dseg.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include <assert.h>
 
-#include "vm/options.h"
 #include "vm/types.h"
 
 #include "mm/memory.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/methodheader.h"
+#include "vmcore/options.h"
 
 
 /* dseg_finish *****************************************************************
index 228f742a93816350da5cbb893acbcd5a486c149c..e0f6a9d4f08c79676b6d2d8838fce71a99eff94e 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/dseg.c - data segment handling stuff
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Andreas  Krall
-            Christian Thalinger
-            Joseph Wenninger
-
-   $Id: dseg.h 6091 2006-11-29 20:44:10Z twisti $
+   $Id: dseg.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -45,13 +38,15 @@ typedef struct dseg_exception_entry  dseg_exception_entry;
 
 
 #include "config.h"
-
 #include "vm/types.h"
 
 #include "toolbox/list.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/codegen-common.h"
 
+#include "vmcore/references.h"
+
 
 /* convenience macros *********************************************************/
 
index a31da52be81ce674fd5244143154a38935885d6a..d9ca2ea405adff4d52a6b0cc846661ccd0aaf41e 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/emit-common.c - common code emitter functions
 
-   Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   Copyright (C) 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Edwin Steiner
-
    $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
 
 */
 
 #include "codegen.h"
 
-#include "vm/options.h"
+#include "vm/jit/emit-common.h"
+#include "vm/jit/jit.h"
+#include "vmcore/options.h"
 
 #if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
+# include "vmcore/statistics.h"
 #endif
 
-#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
-
 
 /* emit_load_s1 ****************************************************************
 
index ea2db8de6a56b2b767c8219b9d642e4a4833b519..edfa2c79d6eaee1ece8c9b7e5496656ba175ed0d 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: jit.c 7229 2007-01-22 00:58:36Z twisti $
+   $Id: jit.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "mm/memory.h"
 #include "native/native.h"
 #include "toolbox/logging.h"
 # include "threads/none/lock.h"
 #endif
 
-#include "vm/class.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
+
 #include "vm/jit/asmpart.h"
 
 # include "vm/jit/cfg.h"
 #include "vm/jit/optimizing/reorder.h"
 
 #include "vm/jit/verify/typecheck.h"
-#include "vm/rt-timing.h"
 
 #if defined(ENABLE_THREADS)
 # include "threads/native/threads.h"
 #endif
 
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+#include "vmcore/rt-timing.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 
 /* debug macros ***************************************************************/
 
index 1fa0febe056057bdee95f8ea581325e9d01e0782..e951249563d89fbe62e8e9e789c4758f0f90f730 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: jit.h 7229 2007-01-22 00:58:36Z twisti $
+   $Id: jit.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -46,14 +46,11 @@ typedef struct exception_entry exception_entry;
 #include "vm/types.h"
 
 #include "toolbox/chain.h"
+
 #include "vm/global.h"
-#include "vm/method.h"
-#include "vm/references.h"
-#include "vm/resolve.h"
-#include "vm/statistics.h"
+
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/stacktrace.h"
 #include "vm/jit/replace.h"
 
 #if defined(ENABLE_INLINING)
@@ -72,6 +69,15 @@ typedef struct exception_entry exception_entry;
 
 #include "vm/jit/verify/typeinfo.h"
 
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+#include "vmcore/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+
 /* common jit/codegen macros **************************************************/
 
 #if defined(ENABLE_STATISTICS)
index bdebe61988ab310233c0c4063d32f6a30ec2ef08..e8facd3937654883cc1c70f1c02024ab970f8df3 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/loop/graph.h - control flow graph header
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: graph.h 4699 2006-03-28 14:52:32Z twisti $
+   $Id: graph.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "config.h"
 #include "vm/types.h"
 
-#include "vm/method.h"
 #include "vm/jit/loop/loop.h"
 
+#include "vmcore/method.h"
+
 
 /* function prototypes ********************************************************/
 
index 16b121951785dc99414a0f8fc71540ec8f30339b..3d791e0e73b65a281b3074c39d8c84934e064dd5 100644 (file)
@@ -1,6 +1,6 @@
-/* vm/jit/loop/loop.h - array bound removal header
+/* src/vm/jit/loop/loop.h - array bound removal header
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christopher Kruegel
-
-   Changes: Christian Thalinger
-
-   $Id: loop.h 5785 2006-10-15 22:25:54Z edwin $
+   $Id: loop.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vm/method.h"
+
 #include "vm/jit/jit.h"
 
+#include "vmcore/method.h"
+
 
 /*     Different types for struct Trace                                                                                */
 #define TRACE_UNKNOWN 0                        /* unknown                                                                      */
index 2a778ac2ee2ed2edbe7439ab147e8a03a792f88f..a80946728cad028ab5d7d02c05bea0e944242aa1 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/ifconv/ifconv.c - if-conversion
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: stack.c 4455 2006-02-06 01:02:59Z edwin $
 
 */
 
 #include "vm/types.h"
 
-#include "vm/method.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/show.h"
 
+#include "vmcore/method.h"
+
 
 /* patterns for a total number of 3 instructions ******************************/
 
index 03865ce20b22bdd18b3279f090b6ebee6b675128..d1f185d14ea0391cff48a7c562a808bfc5fac1e4 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/jit/ifconv/ifconv.h - if-conversion
+/* src/vm/jit/optimizing/ifconv.h - if-conversion
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: stack.c 4455 2006-02-06 01:02:59Z edwin $
 
 */
 #include "config.h"
 #include "vm/types.h"
 
-#include "vm/method.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/reg.h"
 
+#include "vmcore/method.h"
+
 
 /* function prototypes ********************************************************/
 
index cf5771c95848b46c2a527fe9d302c756e94f8cd5..7b6a66ebc41aadff17cfe66e80b57766ea86e13f 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/optimizing/profile.c - runtime profiling
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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, J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
    $Id: cacao.c 4357 2006-01-22 23:33:38Z twisti $
 
 */
@@ -41,6 +35,7 @@
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/include/java_lang_Thread.h"
 #include "native/include/java_lang_VMThread.h"
 #endif
 
 #include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/classcache.h"
-#include "vm/method.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/optimizing/recompile.h"
 
+#include "vmcore/class.h"
+#include "vmcore/classcache.h"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
 
 /* global variables ***********************************************************/
 
index ad9517743b8a0bf99f53fabf260988b63d5c03b8..b92d4655f3fc6af174c979f49b616698963f53a2 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/optimizing/recompile.c - recompilation system
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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, J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
    $Id: cacao.c 4357 2006-01-22 23:33:38Z twisti $
 
 */
@@ -39,6 +35,7 @@
 #include "vm/types.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/include/java_lang_Thread.h"
 
 #endif
 
 #include "toolbox/list.h"
+
 #include "vm/builtin.h"
-#include "vm/classcache.h"
 #include "vm/exceptions.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/optimizing/recompile.h"
 
+#include "vmcore/classcache.h"
+
 
 /* global variables ***********************************************************/
 
@@ -196,7 +196,7 @@ static void recompile_thread(void)
                        else {
                                /* XXX what is the right-thing(tm) to do here? */
 
-                               exceptions_print_exception(*exceptionptr);
+                               exceptions_print_current_exception();
                        }
 
                        /* remove the compiled method */
index 1d694427cb2437e1f2663106087d0a130f54f9ae..655f6c6e4f04f592dcdfa4c7beb243791f0ffba3 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Carolyn Oates
-            Edwin Steiner
-            Joseph Wenninger
-            Christian Thalinger
-
-   $Id: parse.c 6175 2006-12-11 20:16:10Z twisti $
+   $Id: parse.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #endif
 
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/resolve.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
-#include "vm/suck.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/loop/loop.h"
 
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/suck.h"
+
 #define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
                                    /* allocate if space runs out              */
 
index 057f293362be60a1ce87ecfb2e9bad9a8d74f718..eeba56943ab6cf6fb35497b37e0395f2dfcec010 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Stefan Ring
-            Christian Thalinger
-            Christian Ullrich
-            Edwin Steiner
-
-   $Id: codegen.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: codegen.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/md.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
 #include "vm/jit/replace.h"
+#include "vm/jit/stacktrace.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
 
 /* codegen *********************************************************************
 
index 4b5aa15706eb12074f44ddeb5b849b7f38c19e11..86b57d782e367a603249a6a7e59975e7097935e4 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc/emit.c - PowerPC code emitter functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
    $Id: emit.c 4398 2006-01-31 23:43:08Z twisti $
 
 */
 #include "vm/jit/powerpc/codegen.h"
 
 #include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "vm/options.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/replace.h"
 
+#include "vmcore/options.h"
+
 
 /* emit_load *******************************************************************
 
index 13b64bf9e67244dd61faa742f315131d1e9196f3..83ec65ab063d1c4ebdcfc31218b6ea936702f88a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc/linux/md-abi.c - functions for PowerPC Linux ABI
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Christian Ullrich
-
-   $Id: md-abi.c 5634 2006-10-02 14:18:04Z edwin $
+   $Id: md-abi.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "vm/jit/powerpc/linux/md-abi.h"
 
-#include "vm/descriptor.h"
 #include "vm/global.h"
+
 #include "vm/jit/abi.h"
 
+#include "vmcore/descriptor.h"
+
 
 #define _ALIGN(a)    do { if ((a) & 1) (a)++; } while (0)
 
index 8e6b0e84f792b95e46cd022b88cc30c502577ab6..3ec67f0211e7bf1e3ea4eabfb86424480ede2ae7 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc/md.c - machine dependent PowerPC functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Edwin Steiner
-
-   $Id: md.c 6265 2007-01-02 20:40:57Z edwin $
+   $Id: md.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/jit/powerpc/codegen.h"
 
 #include "vm/global.h"
+
 #include "vm/jit/asmpart.h"
+#include "vm/jit/stacktrace.h"
 
 #if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER)
-#include "vm/options.h" /* XXX debug */
-#include "vm/jit/disass.h" /* XXX debug */
+# include "vm/jit/disass.h" /* XXX debug */
+# include "vmcore/options.h" /* XXX debug */
 #endif
 
 
index 0996932a3b403b8b51ba4f2d3aa15c246041dd0d..e7a1360621269e795d549febaed87d5fa41ea503 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/powerpc/patcher.c - PowerPC code patching functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: patcher.c 5942 2006-11-09 10:52:34Z twisti $
+   $Id: patcher.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "mm/memory.h"
 #include "native/native.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
 #include "vm/exceptions.h"
-#include "vm/field.h"
 #include "vm/initialize.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/references.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
+#include "vm/jit/md.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/class.h"
+#include "vmcore/field.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+#include "vmcore/references.h"
 
 
 /* patcher_wrapper *************************************************************
index 4410e3f7384a8799d0f470a40cca8bd86d69318e..3781ba2ea02a0105df5cf0bcfda1c99bd614c71c 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/show.c - showing the intermediate representation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
    $Id$
 
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "mm/memory.h"
 
 #if defined(ENABLE_THREADS)
@@ -48,7 +42,6 @@
 #endif
 
 #include "vm/global.h"
-#include "vm/options.h"
 #include "vm/builtin.h"
 #include "vm/stringlocal.h"
 #include "vm/jit/jit.h"
@@ -56,6 +49,7 @@
 #include "vm/jit/disass.h"
 #include "vm/jit/stack.h"
 #include "vm/jit/parse.h"
+#include "vmcore/options.h"
 
 
 /* global variables ***********************************************************/
@@ -694,7 +688,7 @@ void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
         if (stage >= SHOW_PARSE) {                                   \
             putchar('"');                                            \
             utf_display_printable_ascii(                             \
-                javastring_toutf((java_lang_String *)(val), false)); \
+               javastring_toutf((java_objectheader *)(val), false)); \
             printf("\" ");                                           \
         }                                                            \
         else {                                                       \
index 5be8d75015615bde2de4ee4e88615f90e9435cbc..14b18ac4f3f7233556db613f9b501abda4b327cf 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-   $Id: stack.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: stack.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -52,9 +45,6 @@
 
 #include "vm/global.h"
 #include "vm/builtin.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
 #include "vm/types.h"
 
 # include "vm/jit/allocator/lsra.h"
 #endif
 
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 /*#define STACK_VERBOSE*/
 
 
index beaae0c7716fec52f9a7d2ee8d01309758daa8d7..e79ee038eb7bec9b8d999823c871443c7387fd28 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/stacktrace.c - machine independent stacktrace system
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Joseph Wenninger
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: stacktrace.c 6251 2006-12-27 23:15:56Z twisti $
+   $Id: stacktrace.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -43,9 +37,9 @@
 
 #include "mm/gc-common.h"
 #include "mm/memory.h"
-#include "native/native.h"
 
 #include "vm/global.h"                   /* required here for native includes */
+#include "native/jni.h"
 #include "native/include/java_lang_Throwable.h"
 
 #if defined(WITH_CLASSPATH_GNU)
 #endif
 
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
+#include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/methodheader.h"
-#include "vm/cycles-stats.h"
+
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
 
 
 /* global variables ***********************************************************/
@@ -349,7 +346,7 @@ java_objectheader *stacktrace_inline_arithmeticexception(u1 *pv, u1 *sp,
 
        /* create exception */
 
-       o = new_arithmeticexception();
+       o = exceptions_new_arithmeticexception();
 
        /* remove stackframeinfo */
 
@@ -380,7 +377,7 @@ java_objectheader *stacktrace_inline_arrayindexoutofboundsexception(u1 *pv,
 
        /* create exception */
 
-       o = new_arrayindexoutofboundsexception(index);
+       o = exceptions_new_arrayindexoutofboundsexception(index);
 
        /* remove stackframeinfo */
 
@@ -546,7 +543,7 @@ java_objectheader *stacktrace_hardware_arithmeticexception(u1 *pv, u1 *sp,
 
        /* create exception */
 
-       o = new_arithmeticexception();
+       o = exceptions_new_arithmeticexception();
 
        /* remove stackframeinfo */
 
@@ -1167,15 +1164,15 @@ return_NULL:
 #if defined(ENABLE_JAVASE)
 java_objectarray *stacktrace_getStack(void)
 {
-       stacktracebuffer *stb;
-       stacktrace_entry *ste;
-       java_objectarray *oa;
-       java_objectarray *classes;
-       java_objectarray *methodnames;
-       classinfo        *c;
-       java_lang_String *str;
-       s4                i;
-       s4                dumpsize;
+       stacktracebuffer  *stb;
+       stacktrace_entry  *ste;
+       java_objectarray  *oa;
+       java_objectarray  *classes;
+       java_objectarray  *methodnames;
+       classinfo         *c;
+       java_objectheader *string;
+       s4                 i;
+       s4                 dumpsize;
        CYCLES_STATS_DECLARE_AND_START
 
        /* mark start of dump memory area */
@@ -1221,12 +1218,13 @@ java_objectarray *stacktrace_getStack(void)
                c = ste->method->class;
 
                classes->data[i] = (java_objectheader *) c;
-               str = javastring_new(ste->method->name);
 
-               if (str == NULL)
+               string = javastring_new(ste->method->name);
+
+               if (string == NULL)
                        goto return_NULL;
 
-               methodnames->data[i] = (java_objectheader *) str;
+               methodnames->data[i] = string;
        }
 
        /* return the 2-dimensional array */
@@ -1300,28 +1298,6 @@ void stacktrace_dump_trace(threadobject *thread)
        stacktracebuffer *stb;
        s4                dumpsize;
 
-#if 0
-       /* get methodinfo pointer from data segment */
-
-       m = *((methodinfo **) (pv + MethodPointer));
-
-       /* get current stackframe info pointer */
-
-       psfi = STACKFRAMEINFO;
-
-       /* fill new stackframe info structure */
-
-       sfi->prev   = *psfi;
-       sfi->method = NULL;
-       sfi->pv     = NULL;
-       sfi->sp     = sp;
-       sfi->ra     = ra;
-
-       /* store new stackframe info pointer */
-
-       *psfi = sfi;
-#endif
-
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
@@ -1332,7 +1308,7 @@ void stacktrace_dump_trace(threadobject *thread)
 
        /* print stacktrace */
 
-       if (stb)
+       if (stb != NULL)
                stacktrace_print_trace_from_buffer(stb);
        else {
                puts("\t<<No stacktrace available>>");
index c8e3257968adae58614263fb01c55a2ca07c8d55..2372ddd4c8df09a4f610fd8b6937c3d051ce4d5a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/stacktrace.h - header file for stacktrace generation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: stacktrace.h 6248 2006-12-27 22:39:39Z twisti $
+   $Id: stacktrace.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -51,7 +45,8 @@ typedef struct stacktrace_entry stacktrace_entry;
 # include "threads/none/threads.h"
 #endif
 
-#include "vm/method.h"
+#include "vmcore/class.h"
+#include "vmcore/method.h"
 
 
 /* stackframeinfo **************************************************************
@@ -70,14 +65,6 @@ struct stackframeinfo {
        u1             *xpc;                /* XPC (for inline stubs)             */
 };
 
-#if defined(ENABLE_THREADS)
-#define STACKFRAMEINFO    (&(THREADOBJECT->_stackframeinfo))
-#else
-extern stackframeinfo *_no_threads_stackframeinfo;
-
-#define STACKFRAMEINFO    (&_no_threads_stackframeinfo)
-#endif
-
 
 /* stacktrace_entry ***********************************************************/
 
index 38d077d35184fbdb9ec9ac453809ca67dcd26334..d3e86d2e9a5435fd9ed7a555f9bf83ddc8cfccdb 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/tools/genoffsets.c - generate asmpart offsets of structures
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Edwin Steiner
-
-   $Id: genoffsets.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: genoffsets.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/types.h"
 
 #include "mm/memory.h"
-#include "vm/class.h"
+
 #include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/method.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.h"
 #include "vm/jit/replace.h"
 
+#include "vmcore/class.h"
+#include "vmcore/linker.h"
+#include "vmcore/method.h"
+
 
 int main(int argc, char **argv)
 {
index 9abb9a7cf2d7156612fce2d76cbef34499760fa3..a2c909dedf19acf879bf6dfc0d680306ee3c67c0 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/verify/typecheck-stackbased.c - stack-based verifier
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: 
-
    $Id$
 
 */
 
 #include "vm/types.h"
 
+#include "vm/builtin.h"
 #include "mm/memory.h"
+
 #include "vm/global.h"
+
 #include "vm/jit/parse.h"
 #include "vm/jit/show.h"
 #include "vm/jit/stack.h"
index 6ea736eb2e63c649844f9db9d562c22f43464f03..d300c85713881ffa8fa468a7ebee8076f5ee3813 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/verify/typecheck-typeinferer.c - type inference pass
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
    $Id$
 
 */
 #include "mm/memory.h"
 #include "toolbox/logging.h"
 #include "native/native.h"
+
+#include "vm/access.h"
 #include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/vm.h"
+
 #include "vm/jit/patcher.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/show.h"
 #include "vm/jit/parse.h"
-#include "vm/access.h"
-#include "vm/resolve.h"
-#include "vm/exceptions.h"
-#include "vm/vm.h"
+
 #include "vm/jit/verify/typecheck-typeinferer.h"
 
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
 #define TYPECHECK_NO_STATISTICS
 #include <typecheck-common.h>
 
index da521e1b1bc501a9aecf070ba58ea7650c1d3129..4720feba3dba09f0c80ef97bebee15760b18e1c9 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: Christian Thalinger
-
-   $Id: typecheck.c 6275 2007-01-03 22:39:14Z edwin $
+   $Id: typecheck.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -141,28 +135,34 @@ error reporting.
     citeseer.ist.psu.edu/article/coglio03improving.html
 */
 
+
 #include "config.h"
-#include "vm/types.h"
-#include "vm/global.h"
 
 #include <assert.h>
 #include <string.h>
 
+#include "vm/types.h"
+
 #ifdef ENABLE_VERIFIER
 
 #include "mm/memory.h"
-#include "toolbox/logging.h"
 #include "native/native.h"
+
+#include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/jit/patcher.h"
-#include "vm/loader.h"
-#include "vm/options.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+
+#include "vm/access.h"
 #include "vm/jit/jit.h"
-#include "vm/jit/show.h"
 #include "vm/jit/parse.h"
-#include "vm/access.h"
-#include "vm/resolve.h"
-#include "vm/exceptions.h"
+#include "vm/jit/patcher.h"
+#include "vm/jit/show.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
 
 #include <typecheck-common.h>
 
index 1c3dcb9d8ddf30db8b733ba3f6e43c2d9fa2586d..660a25b1233f5f298040d234105a7faabc784e46 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   $Id: typeinfo.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: typeinfo.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "mm/memory.h"
 #include "toolbox/logging.h"
-#include "vm/class.h"
-#include "vm/loader.h"
+
+#include "vm/exceptions.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/verify/typeinfo.h"
-#include "vm/descriptor.h"
-#include "vm/resolve.h"
-#include "vm/exceptions.h"
+
+#include "vmcore/class.h"
+#include "vmcore/descriptor.h"
+#include "vmcore/loader.h"
+#include "vmcore/resolve.h"
 
 
 /* check if a linked class is an array class. Only use for linked classes! */
index 4dffce704a6537c9b9898abc83e83cdec8f915ab..8cfeca6c9e1828d05ade9ac63a51ae72955b5f8f 100644 (file)
@@ -1,6 +1,6 @@
-/* typeinfo.h - type system used by the type checker
+/* src/vm/jit/verify/typeinfo.h - type system used by the type checker
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   $Id: typeinfo.h 6023 2006-11-19 15:22:53Z edwin $
+   $Id: typeinfo.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -43,7 +39,8 @@ typedef struct typedescriptor typedescriptor;
 #include "vm/types.h"
 
 #include "vm/global.h"
-#include "vm/references.h"
+
+#include "vmcore/references.h"
 
 
 /* configuration **************************************************************/
diff --git a/src/vm/linker.c b/src/vm/linker.c
deleted file mode 100644 (file)
index e967b3b..0000000
+++ /dev/null
@@ -1,1413 +0,0 @@
-/* src/vm/linker.c - class linker functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Andreas Krall
-            Roman Obermaiser
-            Mark Probst
-            Edwin Steiner
-            Christian Thalinger
-
-   $Id: linker.c 7228 2007-01-19 01:13:48Z edwin $
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "native/native.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
-
-#include "vm/class.h"
-#include "vm/classcache.h"
-#include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/access.h"
-#include "vm/rt-timing.h"
-#include "vm/vm.h"
-#include "vm/jit/asmpart.h"
-
-
-#if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code)  do { if (opt_inline_debug_log) { code } } while (0)
-#else
-#define INLINELOG(code)
-#endif
-
-
-/* global variables ***********************************************************/
-
-static s4 interfaceindex;       /* sequential numbering of interfaces         */
-static s4 classvalue;
-
-
-/* primitivetype_table *********************************************************
-
-   Structure for primitive classes: contains the class for wrapping
-   the primitive type, the primitive class, the name of the class for
-   wrapping, the one character type signature and the name of the
-   primitive class.
-   CAUTION: Don't change the order of the types. This table is indexed
-   by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
-
-*******************************************************************************/
-
-primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
-       { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
-       { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
-       { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
-       { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
-       { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
-       { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
-       { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
-       { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
-       { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
-       { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
-#if defined(ENABLE_JAVASE)
-       { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }
-#else
-       { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
-#endif
-};
-
-
-/* private functions **********************************************************/
-
-static bool link_primitivetype_table(void);
-static classinfo *link_class_intern(classinfo *c);
-static arraydescriptor *link_array(classinfo *c);
-static void linker_compute_class_values(classinfo *c);
-static void linker_compute_subclasses(classinfo *c);
-static bool linker_addinterface(classinfo *c, classinfo *ic);
-static s4 class_highestinterface(classinfo *c);
-
-
-/* linker_init *****************************************************************
-
-   Initializes the linker subsystem.
-
-*******************************************************************************/
-
-bool linker_init(void)
-{
-       /* reset interface index */
-
-       interfaceindex = 0;
-
-       /* link java.lang.Class as first class of the system, because we
-       need it's vftbl for all other classes so we can use a class as
-       object */
-
-       if (!link_class(class_java_lang_Class))
-               return false;
-
-       /* now set the header.vftbl of all classes which were created
-       before java.lang.Class was linked */
-
-       class_postset_header_vftbl();
-
-
-       /* link important system classes */
-
-       if (!link_class(class_java_lang_Object))
-               return false;
-
-       if (!link_class(class_java_lang_String))
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_Cloneable))
-               return false;
-
-       if (!link_class(class_java_io_Serializable))
-               return false;
-#endif
-
-
-       /* link classes for wrapping primitive types */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_Void))
-               return false;
-#endif
-
-       if (!link_class(class_java_lang_Boolean))
-               return false;
-
-       if (!link_class(class_java_lang_Byte))
-               return false;
-
-       if (!link_class(class_java_lang_Character))
-               return false;
-
-       if (!link_class(class_java_lang_Short))
-               return false;
-
-       if (!link_class(class_java_lang_Integer))
-               return false;
-
-       if (!link_class(class_java_lang_Long))
-               return false;
-
-       if (!link_class(class_java_lang_Float))
-               return false;
-
-       if (!link_class(class_java_lang_Double))
-               return false;
-
-
-       /* load some other important classes */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_ClassLoader))
-               return false;
-
-       if (!link_class(class_java_lang_SecurityManager))
-               return false;
-#endif
-
-       if (!link_class(class_java_lang_System))
-               return false;
-
-       if (!link_class(class_java_lang_Thread))
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_ThreadGroup))
-               return false;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       if (!link_class(class_java_lang_VMSystem))
-               return false;
-
-       if (!link_class(class_java_lang_VMThread))
-               return false;
-#endif
-
-
-       /* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_StackTraceElement))
-               return false;
-
-       if (!link_class(class_java_lang_reflect_Constructor))
-               return false;
-
-       if (!link_class(class_java_lang_reflect_Field))
-               return false;
-
-       if (!link_class(class_java_lang_reflect_Method))
-               return false;
-
-       if (!link_class(class_java_security_PrivilegedAction))
-               return false;
-
-       if (!link_class(class_java_util_Vector))
-               return false;
-
-       if (!link_class(arrayclass_java_lang_Object))
-               return false;
-#endif
-
-
-       /* create pseudo classes used by the typechecker */
-
-    /* pseudo class for Arraystubs (extends java.lang.Object) */
-
-       pseudo_class_Arraystub =
-               class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
-       pseudo_class_Arraystub->state            |= CLASS_LOADED;
-       pseudo_class_Arraystub->super.cls         = class_java_lang_Object;
-
-#if defined(ENABLE_JAVASE)
-       pseudo_class_Arraystub->interfacescount   = 2;
-       pseudo_class_Arraystub->interfaces        = MNEW(classref_or_classinfo, 2);
-       pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
-       pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-       pseudo_class_Arraystub->interfacescount   = 0;
-       pseudo_class_Arraystub->interfaces        = NULL;
-#endif
-
-       if (!classcache_store_unique(pseudo_class_Arraystub)) {
-               log_text("could not cache pseudo_class_Arraystub");
-               assert(0);
-       }
-
-       if (!link_class(pseudo_class_Arraystub))
-               return false;
-
-       /* pseudo class representing the null type */
-
-       pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
-       pseudo_class_Null->state |= CLASS_LOADED;
-       pseudo_class_Null->super.cls = class_java_lang_Object;
-
-       if (!classcache_store_unique(pseudo_class_Null)) {
-               log_text("could not cache pseudo_class_Null");
-               assert(0);
-       }
-
-       if (!link_class(pseudo_class_Null))
-               return false;
-
-       /* pseudo class representing new uninitialized objects */
-    
-       pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
-       pseudo_class_New->state |= CLASS_LOADED;
-       pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
-       pseudo_class_New->super.cls = class_java_lang_Object;
-
-       if (!classcache_store_unique(pseudo_class_New)) {
-               log_text("could not cache pseudo_class_New");
-               assert(0);
-       }
-
-       /* create classes representing primitive types */
-
-       if (!link_primitivetype_table())
-               return false;
-
-
-       /* Correct vftbl-entries (retarded loading and linking of class           */
-       /* java/lang/String).                                                     */
-
-       stringtable_update();
-
-       return true;
-}
-
-
-/* link_primitivetype_table ****************************************************
-
-   Create classes representing primitive types.
-
-*******************************************************************************/
-
-static bool link_primitivetype_table(void)
-{  
-       classinfo *c;
-       utf       *u;
-       s4         i;
-
-       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
-               /* skip dummies */
-
-               if (!primitivetype_table[i].name)
-                       continue;
-               
-               /* create primitive class */
-
-               c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
-
-               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
-               
-               /* prevent loader from loading primitive class */
-
-               c->state |= CLASS_LOADED;
-
-               /* INFO: don't put primitive classes into the classcache */
-
-               if (!link_class(c))
-                       return false;
-
-               primitivetype_table[i].class_primitive = c;
-
-               /* create class for wrapping the primitive type */
-
-               u = utf_new_char(primitivetype_table[i].wrapname);
-
-               if (!(c = load_class_bootstrap(u)))
-                       return false;
-
-               primitivetype_table[i].class_wrap = c;
-
-               /* create the primitive array class */
-
-               if (primitivetype_table[i].arrayname) {
-                       u = utf_new_char(primitivetype_table[i].arrayname);
-                       c = class_create_classinfo(u);
-                       c = load_newly_created_array(c, NULL);
-                       if (c == NULL)
-                               return false;
-
-                       primitivetype_table[i].arrayclass = c;
-
-                       assert(c->state & CLASS_LOADED);
-
-                       if (!(c->state & CLASS_LINKED))
-                               if (!link_class(c))
-                                       return false;
-
-                       primitivetype_table[i].arrayvftbl = c->vftbl;
-               }
-       }
-
-       return true;
-}
-
-
-/* link_class ******************************************************************
-
-   Wrapper function for link_class_intern to ease monitor enter/exit
-   and exception handling.
-
-*******************************************************************************/
-
-classinfo *link_class(classinfo *c)
-{
-       classinfo *r;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_end;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       if (c == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       LOCK_MONITOR_ENTER(c);
-
-       /* maybe the class is already linked */
-
-       if (c->state & CLASS_LINKED) {
-               LOCK_MONITOR_EXIT(c);
-
-               return c;
-       }
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getcompilingtime)
-               compilingtime_stop();
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* call the internal function */
-
-       r = link_class_intern(c);
-
-       /* if return value is NULL, we had a problem and the class is not linked */
-
-       if (!r)
-               c->state &= ~CLASS_LINKING;
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-
-       if (opt_getcompilingtime)
-               compilingtime_start();
-#endif
-
-       LOCK_MONITOR_EXIT(c);
-
-       RT_TIMING_GET_TIME(time_end);
-
-       RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
-
-       return r;
-}
-
-
-/* linker_overwrite_method *****************************************************
-
-   Overwrite a method with another one, update method flags and check
-   assumptions.
-
-   IN:
-      mg................the general method being overwritten
-         ms................the overwriting (more specialized) method
-         wl................worklist where to add invalidated methods
-
-   RETURN VALUE:
-      true..............everything ok
-         false.............an exception has been thrown
-
-*******************************************************************************/
-
-static bool linker_overwrite_method(methodinfo *mg,
-                                                                       methodinfo *ms,
-                                                                       method_worklist **wl)
-{
-       classinfo *cg;
-       classinfo *cs;
-
-       cg = mg->class;
-       cs = ms->class;
-
-       /* overriding a final method is illegal */
-
-       if (mg->flags & ACC_FINAL) {
-               *exceptionptr =
-                       new_exception(string_java_lang_VerifyError);
-               return false;
-       }
-
-       /* method ms overwrites method mg */
-
-#if defined(ENABLE_VERIFIER)
-       /* Add loading constraints (for the more general types of method mg). */
-       /* Not for <init>, as it is not invoked virtually.                    */
-
-       if ((ms->name != utf_init)
-                       && !classcache_add_constraints_for_params(
-                               cs->classloader, cg->classloader, mg))
-       {
-               return false;
-       }
-#endif
-
-       /* inherit the vftbl index, and record the overwriting */
-
-       ms->vftblindex = mg->vftblindex;
-       ms->overwrites = mg;
-
-       /* update flags and check assumptions */
-       /* <init> methods are a special case, as they are never dispatched dynamically */
-
-       if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
-               do {
-                       if (mg->flags & ACC_METHOD_IMPLEMENTED) {
-                               /* this adds another implementation */
-
-                               mg->flags &= ~ACC_METHOD_MONOMORPHIC;
-
-                               INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
-
-                               method_break_assumption_monomorphic(mg, wl);
-                       }
-                       else {
-                               /* this is the first implementation */
-
-                               mg->flags |= ACC_METHOD_IMPLEMENTED;
-
-                               INLINELOG( printf("becomes implemented: "); method_println(mg); );
-                       }
-
-                       ms = mg;
-                       mg = mg->overwrites;
-               } while (mg != NULL);
-       }
-
-       return true;
-}
-
-
-/* link_class_intern ***********************************************************
-
-   Tries to link a class. The function calculates the length in bytes
-   that an instance of this class requires as well as the VTBL for
-   methods and interface methods.
-       
-*******************************************************************************/
-
-static classinfo *link_class_intern(classinfo *c)
-{
-       classinfo *super;             /* super class                              */
-       classinfo *tc;                /* temporary class variable                 */
-       s4 supervftbllength;          /* vftbllegnth of super class               */
-       s4 vftbllength;               /* vftbllength of current class             */
-       s4 interfacetablelength;      /* interface table length                   */
-       vftbl_t *v;                   /* vftbl of current class                   */
-       s4 i;                         /* interface/method/field counter           */
-       arraydescriptor *arraydesc;   /* descriptor for array classes             */
-       method_worklist *worklist;    /* worklist for recompilation               */
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_resolving, time_compute_vftbl,
-                                       time_abstract, time_compute_iftbl, time_fill_vftbl,
-                                       time_offsets, time_fill_iftbl, time_finalizer,
-                                       time_subclasses;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       /* the class is already linked */
-
-       if (c->state & CLASS_LINKED)
-               return c;
-
-#if !defined(NDEBUG)
-       if (linkverbose)
-               log_message_class("Linking class: ", c);
-#endif
-
-       /* the class must be loaded */
-
-       /* XXX should this be a specific exception? */
-       assert(c->state & CLASS_LOADED);
-
-       /* cache the self-reference of this class                          */
-       /* we do this for cases where the defining loader of the class     */
-       /* has not yet been recorded as an initiating loader for the class */
-       /* this is needed so subsequent code can assume that self-refs     */
-       /* will always resolve lazily                                      */
-       /* No need to do it for the bootloader - it is always registered   */
-       /* as initiating loader for the classes it loads.                  */
-       if (c->classloader)
-               classcache_store(c->classloader,c,false);
-
-       /* this class is currently linking */
-
-       c->state |= CLASS_LINKING;
-
-       arraydesc = NULL;
-       worklist = NULL;
-
-       /* check interfaces */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               /* resolve this super interface */
-
-               if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
-                                                                                  true, false, &tc))
-                       return NULL;
-
-               c->interfaces[i].cls = tc;
-               
-               /* detect circularity */
-
-               if (tc == c) {
-                       *exceptionptr =
-                               new_exception_utfmessage(string_java_lang_ClassCircularityError,
-                                                                                c->name);
-                       return NULL;
-               }
-
-               assert(tc->state & CLASS_LOADED);
-
-               if (!(tc->flags & ACC_INTERFACE)) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_IncompatibleClassChangeError,
-                                                                         "Implementing class");
-                       return NULL;
-               }
-
-               if (!(tc->state & CLASS_LINKED))
-                       if (!link_class(tc))
-                               return NULL;
-       }
-       
-       /* check super class */
-
-       super = NULL;
-
-       if (c->super.any == NULL) {                     /* class java.lang.Object */
-               c->index = 0;
-               c->instancesize = sizeof(java_objectheader);
-               
-               vftbllength = supervftbllength = 0;
-
-               c->finalizer = NULL;
-
-       } else {
-               /* resolve super class */
-
-               if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
-                                                                                  &super))
-                       return NULL;
-               c->super.cls = super;
-               
-               /* detect circularity */
-
-               if (super == c) {
-                       *exceptionptr =
-                               new_exception_utfmessage(string_java_lang_ClassCircularityError,
-                                                                                c->name);
-                       return NULL;
-               }
-
-               assert(super->state & CLASS_LOADED);
-
-               if (super->flags & ACC_INTERFACE) {
-                       /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
-                       log_text("Interface specified as super class");
-                       assert(0);
-               }
-
-               /* Don't allow extending final classes */
-
-               if (super->flags & ACC_FINAL) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_VerifyError,
-                                                                         "Cannot inherit from final class");
-                       return NULL;
-               }
-
-               /* link the superclass if necessary */
-               
-               if (!(super->state & CLASS_LINKED))
-                       if (!link_class(super))
-                               return NULL;
-
-               /* OR the ACC_CLASS_HAS_POINTERS flag */
-
-               c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
-
-               /* handle array classes */
-
-               if (c->name->text[0] == '[')
-                       if (!(arraydesc = link_array(c)))
-                               return NULL;
-
-               if (c->flags & ACC_INTERFACE)
-                       c->index = interfaceindex++;
-               else
-                       c->index = super->index + 1;
-               
-               c->instancesize = super->instancesize;
-
-               vftbllength = supervftbllength = super->vftbl->vftbllength;
-               
-               c->finalizer = super->finalizer;
-       }
-       RT_TIMING_GET_TIME(time_resolving);
-
-
-       /* compute vftbl length */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               if (!(m->flags & ACC_STATIC)) { /* is instance method */
-                       tc = super;
-
-                       while (tc) {
-                               s4 j;
-
-                               for (j = 0; j < tc->methodscount; j++) {
-                                       if (method_canoverwrite(m, &(tc->methods[j]))) {
-                                               if (tc->methods[j].flags & ACC_PRIVATE)
-                                                       goto notfoundvftblindex;
-
-                                               /* package-private methods in other packages */
-                                               /* must not be overridden                    */
-                                               /* (see Java Language Specification 8.4.8.1) */
-                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
-                                                        && !SAME_PACKAGE(c,tc) ) 
-                                               {
-                                                   goto notfoundvftblindex;
-                                               }
-
-                                               if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
-                                                       return NULL;
-
-                                               goto foundvftblindex;
-                                       }
-                               }
-
-                               tc = tc->super.cls;
-                       }
-
-               notfoundvftblindex:
-                       m->vftblindex = (vftbllength++);
-               foundvftblindex:
-                       ;
-               }
-       }
-       RT_TIMING_GET_TIME(time_compute_vftbl);
-
-
-       /* Check all interfaces of an abstract class (maybe be an
-          interface too) for unimplemented methods.  Such methods are
-          called miranda-methods and are marked with the ACC_MIRANDA
-          flag.  VMClass.getDeclaredMethods does not return such
-          methods. */
-
-       if (c->flags & ACC_ABSTRACT) {
-               classinfo  *ic;
-               methodinfo *im;
-               s4 abstractmethodscount;
-               s4 j;
-               s4 k;
-
-               abstractmethodscount = 0;
-
-               /* check all interfaces of the abstract class */
-
-               for (i = 0; i < c->interfacescount; i++) {
-                       ic = c->interfaces[i].cls;
-
-                       for (j = 0; j < ic->methodscount; j++) {
-                               im = &(ic->methods[j]);
-
-                               /* skip `<clinit>' and `<init>' */
-
-                               if ((im->name == utf_clinit) || (im->name == utf_init))
-                                       continue;
-
-                               for (tc = c; tc != NULL; tc = tc->super.cls) {
-                                       for (k = 0; k < tc->methodscount; k++) {
-                                               if (method_canoverwrite(im, &(tc->methods[k])))
-                                                       goto noabstractmethod;
-                                       }
-                               }
-
-                               abstractmethodscount++;
-
-                       noabstractmethod:
-                               ;
-                       }
-               }
-
-               if (abstractmethodscount > 0) {
-                       methodinfo *am;
-
-                       /* reallocate methods memory */
-
-                       c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
-                                                                 c->methodscount + abstractmethodscount);
-
-                       for (i = 0; i < c->interfacescount; i++) {
-                               ic = c->interfaces[i].cls;
-
-                               for (j = 0; j < ic->methodscount; j++) {
-                                       im = &(ic->methods[j]);
-
-                                       /* skip `<clinit>' and `<init>' */
-
-                                       if ((im->name == utf_clinit) || (im->name == utf_init))
-                                               continue;
-
-                                       for (tc = c; tc != NULL; tc = tc->super.cls) {
-                                               for (k = 0; k < tc->methodscount; k++) {
-                                                       if (method_canoverwrite(im, &(tc->methods[k])))
-                                                               goto noabstractmethod2;
-                                               }
-                                       }
-
-                                       /* Copy the method found into the new c->methods
-                                          array and tag it as miranda-method. */
-
-                                       am = &(c->methods[c->methodscount]);
-                                       c->methodscount++;
-
-                                       MCOPY(am, im, methodinfo, 1);
-
-                                       am->vftblindex  = (vftbllength++);
-                                       am->class       = c;
-                                       am->flags      |= ACC_MIRANDA;
-
-                               noabstractmethod2:
-                                       ;
-                               }
-                       }
-               }
-       }
-       RT_TIMING_GET_TIME(time_abstract);
-
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_vftbl_len +=
-                       sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
-#endif
-
-       /* compute interfacetable length */
-
-       interfacetablelength = 0;
-
-       for (tc = c; tc != NULL; tc = tc->super.cls) {
-               for (i = 0; i < tc->interfacescount; i++) {
-                       s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
-
-                       if (h > interfacetablelength)
-                               interfacetablelength = h;
-               }
-       }
-       RT_TIMING_GET_TIME(time_compute_iftbl);
-
-       /* allocate virtual function table */
-
-       v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
-                                                         sizeof(methodptr) * (vftbllength - 1) +
-                                                         sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
-       v = (vftbl_t *) (((methodptr *) v) +
-                                        (interfacetablelength - 1) * (interfacetablelength > 1));
-
-       c->vftbl                = v;
-       v->class                = c;
-       v->vftbllength          = vftbllength;
-       v->interfacetablelength = interfacetablelength;
-       v->arraydesc            = arraydesc;
-
-       /* store interface index in vftbl */
-
-       if (c->flags & ACC_INTERFACE)
-               v->baseval = -(c->index);
-
-       /* copy virtual function table of super class */
-
-       for (i = 0; i < supervftbllength; i++) 
-               v->table[i] = super->vftbl->table[i];
-
-       /* Fill the remaining vftbl slots with the AbstractMethodError
-          stub (all after the super class slots, because they are already
-          initialized). */
-
-       for (; i < vftbllength; i++) {
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-               else
-# endif
-                       v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
-#else
-               v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-#endif
-       }
-
-       /* add method stubs into virtual function table */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               assert(m->stubroutine == NULL);
-
-               /* Don't create a compiler stub for abstract methods as they
-                  throw an AbstractMethodError with the default stub in the
-                  vftbl.  This entry is simply copied by sub-classes. */
-
-               if (m->flags & ACC_ABSTRACT)
-                       continue;
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       m->stubroutine = intrp_createcompilerstub(m);
-               else
-#endif
-                       m->stubroutine = createcompilerstub(m);
-#else
-               m->stubroutine = intrp_createcompilerstub(m);
-#endif
-
-               /* static methods are not in the vftbl */
-
-               if (m->flags & ACC_STATIC)
-                       continue;
-
-               /* insert the stubroutine into the vftbl */
-
-               v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
-       }
-       RT_TIMING_GET_TIME(time_fill_vftbl);
-
-       /* compute instance size and offset of each field */
-       
-       for (i = 0; i < c->fieldscount; i++) {
-               s4 dsize;
-               fieldinfo *f = &(c->fields[i]);
-               
-               if (!(f->flags & ACC_STATIC)) {
-                       dsize = descriptor_typesize(f->parseddesc);
-
-                       /* On i386 we only align to 4 bytes even for double and s8.    */
-                       /* This matches what gcc does for struct members. We must      */
-                       /* do the same as gcc here because the offsets in native       */
-                       /* header structs like java_lang_Double must match the offsets */
-                       /* of the Java fields (eg. java.lang.Double.value).            */
-#if defined(__I386__)
-                       c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
-#else
-                       c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
-#endif
-
-                       f->offset = c->instancesize;
-                       c->instancesize += dsize;
-               }
-       }
-       RT_TIMING_GET_TIME(time_offsets);
-
-       /* initialize interfacetable and interfacevftbllength */
-
-       v->interfacevftbllength = MNEW(s4, interfacetablelength);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
-#endif
-
-       for (i = 0; i < interfacetablelength; i++) {
-               v->interfacevftbllength[i] = 0;
-               v->interfacetable[-i] = NULL;
-       }
-
-       /* add interfaces */
-
-       for (tc = c; tc != NULL; tc = tc->super.cls)
-               for (i = 0; i < tc->interfacescount; i++)
-                       if (!linker_addinterface(c, tc->interfaces[i].cls))
-                               return NULL;
-
-       RT_TIMING_GET_TIME(time_fill_iftbl);
-
-       /* add finalizer method (not for java.lang.Object) */
-
-       if (super) {
-               methodinfo *fi;
-
-               fi = class_findmethod(c, utf_finalize, utf_void__void);
-
-               if (fi)
-                       if (!(fi->flags & ACC_STATIC))
-                               c->finalizer = fi;
-       }
-       RT_TIMING_GET_TIME(time_finalizer);
-
-       /* final tasks */
-
-       linker_compute_subclasses(c);
-
-       RT_TIMING_GET_TIME(time_subclasses);
-
-       /* revert the linking state and class is linked */
-
-       c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
-
-       /* check worklist */
-
-       /* XXX must this also be done in case of exception? */
-
-       while (worklist != NULL) {
-               method_worklist *wi = worklist;
-
-               worklist = worklist->next;
-
-               INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
-               jit_invalidate_code(wi->m);
-
-               /* XXX put worklist into dump memory? */
-               FREE(wi, method_worklist);
-       }
-
-#if !defined(NDEBUG)
-       if (linkverbose)
-               log_message_class("Linking done class: ", c);
-#endif
-
-       RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
-       RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
-       RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
-       RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
-       RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
-       RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
-       RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
-       RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
-       RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
-
-       /* just return c to show that we didn't had a problem */
-
-       return c;
-}
-
-
-/* link_array ******************************************************************
-
-   This function is called by link_class to create the arraydescriptor
-   for an array class.
-
-   This function returns NULL if the array cannot be linked because
-   the component type has not been linked yet.
-
-*******************************************************************************/
-
-static arraydescriptor *link_array(classinfo *c)
-{
-       classinfo       *comp;
-       s4               namelen;
-       arraydescriptor *desc;
-       vftbl_t         *compvftbl;
-       utf             *u;
-
-       comp = NULL;
-       namelen = c->name->blength;
-
-       /* Check the component type */
-
-       switch (c->name->text[1]) {
-       case '[':
-               /* c is an array of arrays. */
-               u = utf_new(c->name->text + 1, namelen - 1);
-               if (!(comp = load_class_from_classloader(u, c->classloader)))
-                       return NULL;
-               break;
-
-       case 'L':
-               /* c is an array of objects. */
-               u = utf_new(c->name->text + 2, namelen - 3);
-               if (!(comp = load_class_from_classloader(u, c->classloader)))
-                       return NULL;
-               break;
-       }
-
-       /* If the component type has not been linked, link it now */
-
-       assert(!comp || (comp->state & CLASS_LOADED));
-
-       if (comp && !(comp->state & CLASS_LINKED))
-               if (!link_class(comp))
-                       return NULL;
-
-       /* Allocate the arraydescriptor */
-
-       desc = NEW(arraydescriptor);
-
-       if (comp) {
-               /* c is an array of references */
-               desc->arraytype = ARRAYTYPE_OBJECT;
-               desc->componentsize = sizeof(void*);
-               desc->dataoffset = OFFSET(java_objectarray, data);
-               
-               compvftbl = comp->vftbl;
-
-               if (!compvftbl) {
-                       log_text("Component class has no vftbl");
-                       assert(0);
-               }
-
-               desc->componentvftbl = compvftbl;
-               
-               if (compvftbl->arraydesc) {
-                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
-
-                       if (compvftbl->arraydesc->dimension >= 255) {
-                               log_text("Creating array of dimension >255");
-                               assert(0);
-                       }
-
-                       desc->dimension = compvftbl->arraydesc->dimension + 1;
-                       desc->elementtype = compvftbl->arraydesc->elementtype;
-
-               } else {
-                       desc->elementvftbl = compvftbl;
-                       desc->dimension = 1;
-                       desc->elementtype = ARRAYTYPE_OBJECT;
-               }
-
-       } else {
-               /* c is an array of a primitive type */
-               switch (c->name->text[1]) {
-               case 'Z':
-                       desc->arraytype = ARRAYTYPE_BOOLEAN;
-                       desc->dataoffset = OFFSET(java_booleanarray,data);
-                       desc->componentsize = sizeof(u1);
-                       break;
-
-               case 'B':
-                       desc->arraytype = ARRAYTYPE_BYTE;
-                       desc->dataoffset = OFFSET(java_bytearray,data);
-                       desc->componentsize = sizeof(u1);
-                       break;
-
-               case 'C':
-                       desc->arraytype = ARRAYTYPE_CHAR;
-                       desc->dataoffset = OFFSET(java_chararray,data);
-                       desc->componentsize = sizeof(u2);
-                       break;
-
-               case 'D':
-                       desc->arraytype = ARRAYTYPE_DOUBLE;
-                       desc->dataoffset = OFFSET(java_doublearray,data);
-                       desc->componentsize = sizeof(double);
-                       break;
-
-               case 'F':
-                       desc->arraytype = ARRAYTYPE_FLOAT;
-                       desc->dataoffset = OFFSET(java_floatarray,data);
-                       desc->componentsize = sizeof(float);
-                       break;
-
-               case 'I':
-                       desc->arraytype = ARRAYTYPE_INT;
-                       desc->dataoffset = OFFSET(java_intarray,data);
-                       desc->componentsize = sizeof(s4);
-                       break;
-
-               case 'J':
-                       desc->arraytype = ARRAYTYPE_LONG;
-                       desc->dataoffset = OFFSET(java_longarray,data);
-                       desc->componentsize = sizeof(s8);
-                       break;
-
-               case 'S':
-                       desc->arraytype = ARRAYTYPE_SHORT;
-                       desc->dataoffset = OFFSET(java_shortarray,data);
-                       desc->componentsize = sizeof(s2);
-                       break;
-
-               default:
-                       *exceptionptr = new_noclassdeffounderror(c->name);
-                       return NULL;
-               }
-               
-               desc->componentvftbl = NULL;
-               desc->elementvftbl = NULL;
-               desc->dimension = 1;
-               desc->elementtype = desc->arraytype;
-       }
-
-       return desc;
-}
-
-
-/* linker_compute_subclasses ***************************************************
-
-   XXX
-
-*******************************************************************************/
-
-static void linker_compute_subclasses(classinfo *c)
-{
-#if defined(ENABLE_THREADS)
-       compiler_lock();
-#endif
-
-       if (!(c->flags & ACC_INTERFACE)) {
-               c->nextsub = 0;
-               c->sub = 0;
-       }
-
-       if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
-               c->nextsub = c->super.cls->sub;
-               c->super.cls->sub = c;
-       }
-
-       classvalue = 0;
-
-       /* compute class values */
-
-       linker_compute_class_values(class_java_lang_Object);
-
-#if defined(ENABLE_THREADS)
-       compiler_unlock();
-#endif
-}
-
-
-/* linker_compute_class_values *************************************************
-
-   XXX
-
-*******************************************************************************/
-
-static void linker_compute_class_values(classinfo *c)
-{
-       classinfo *subs;
-
-       c->vftbl->baseval = ++classvalue;
-
-       subs = c->sub;
-
-       while (subs) {
-               linker_compute_class_values(subs);
-
-               subs = subs->nextsub;
-       }
-
-       c->vftbl->diffval = classvalue - c->vftbl->baseval;
-}
-
-
-/* linker_addinterface *********************************************************
-
-   Is needed by link_class for adding a VTBL to a class. All
-   interfaces implemented by ic are added as well.
-
-   RETURN VALUE:
-      true.........everything ok
-         false........an exception has been thrown
-
-*******************************************************************************/
-
-static bool linker_addinterface(classinfo *c, classinfo *ic)
-{
-       s4          j, k;
-       vftbl_t    *v;
-       s4          i;
-       classinfo  *sc;
-       methodinfo *m;
-
-       v = c->vftbl;
-       i = ic->index;
-
-       if (i >= v->interfacetablelength)
-               vm_abort("Internal error: interfacetable overflow");
-
-       /* if this interface has already been added, return immediately */
-
-       if (v->interfacetable[-i] != NULL)
-               return true;
-
-       if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
-               v->interfacevftbllength[i] = 1;
-               v->interfacetable[-i]      = MNEW(methodptr, 1);
-               v->interfacetable[-i][0]   = NULL;
-       }
-       else {
-               v->interfacevftbllength[i] = ic->methodscount;
-               v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_vftbl_len += sizeof(methodptr) *
-                               (ic->methodscount + (ic->methodscount == 0));
-#endif
-
-               for (j = 0; j < ic->methodscount; j++) {
-                       for (sc = c; sc != NULL; sc = sc->super.cls) {
-                               for (k = 0; k < sc->methodscount; k++) {
-                                       m = &(sc->methods[k]);
-
-                                       if (method_canoverwrite(m, &(ic->methods[j]))) {
-                                               /* method m overwrites the (abstract) method */
-#if defined(ENABLE_VERIFIER)
-                                               /* Add loading constraints (for the more
-                                                  general types of the method
-                                                  ic->methods[j]).  */
-                                               if (!classcache_add_constraints_for_params(
-                                                                       c->classloader, ic->classloader,
-                                                                       &(ic->methods[j])))
-                                               {
-                                                       return false;
-                                               }
-#endif
-
-                                               /* XXX taken from gcj */
-                                               /* check for ACC_STATIC: IncompatibleClassChangeError */
-
-                                               /* check for !ACC_PUBLIC: IllegalAccessError */
-
-                                               /* check for ACC_ABSTRACT: AbstracMethodError,
-                                                  not sure about that one */
-
-                                               v->interfacetable[-i][j] = v->table[m->vftblindex];
-                                               goto foundmethod;
-                                       }
-                               }
-                       }
-
-                       /* If no method was found, insert the AbstractMethodError
-                          stub. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-                       if (opt_intrp)
-                               v->interfacetable[-i][j] =
-                                       (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-                       else
-# endif
-                               v->interfacetable[-i][j] =
-                                       (methodptr) (ptrint) &asm_abstractmethoderror;
-#else
-                       v->interfacetable[-i][j] =
-                               (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-#endif
-
-               foundmethod:
-                       ;
-               }
-       }
-
-       /* add superinterfaces of this interface */
-
-       for (j = 0; j < ic->interfacescount; j++)
-               if (!linker_addinterface(c, ic->interfaces[j].cls))
-                       return false;
-
-       /* everything ok */
-
-       return true;
-}
-
-
-/* class_highestinterface ******************************************************
-
-   Used by the function link_class to determine the amount of memory
-   needed for the interface table.
-
-*******************************************************************************/
-
-static s4 class_highestinterface(classinfo *c)
-{
-       s4 h;
-       s4 h2;
-       s4 i;
-       
-    /* check for ACC_INTERFACE bit already done in link_class_intern */
-
-    h = c->index;
-
-       for (i = 0; i < c->interfacescount; i++) {
-               h2 = class_highestinterface(c->interfaces[i].cls);
-
-               if (h2 > h)
-                       h = h2;
-       }
-
-       return 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:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/vm/linker.h b/src/vm/linker.h
deleted file mode 100644 (file)
index e8c6b11..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/* src/vm/linker.h - class linker header
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: linker.h 4357 2006-01-22 23:33:38Z twisti $
-*/
-
-
-#ifndef _LINKER_H
-#define _LINKER_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct _vftbl vftbl_t;
-typedef struct arraydescriptor arraydescriptor;
-typedef struct primitivetypeinfo primitivetypeinfo;
-
-
-#include "vm/class.h"
-#include "vm/references.h"
-
-
-/* virtual function table ******************************************************
-
-   The vtbl has a bidirectional layout with open ends at both sides.
-   interfacetablelength gives the number of entries of the interface
-   table at the start of the vftbl. The vftbl pointer points to
-   &interfacetable[0].  vftbllength gives the number of entries of
-   table at the end of the vftbl.
-
-   runtime type check (checkcast):
-
-   Different methods are used for runtime type check depending on the
-   argument of checkcast/instanceof.
-       
-   A check against a class is implemented via relative numbering on
-   the class hierachy tree. The tree is numbered in a depth first
-   traversal setting the base field and the diff field. The diff field
-   gets the result of (high - base) so that a range check can be
-   implemented by an unsigned compare. A sub type test is done by
-   checking the inclusion of base of the sub class in the range of the
-   superclass.
-
-   A check against an interface is implemented via the
-   interfacevftbl. If the interfacevftbl contains a nonnull value a
-   class is a subclass of this interface.
-
-   interfacetable:
-
-   Like standard virtual methods interface methods are called using
-   virtual function tables. All interfaces are numbered sequentially
-   (starting with zero). For each class there exist an interface table
-   of virtual function tables for each implemented interface. The
-   length of the interface table is determined by the highest number
-   of an implemented interface.
-
-   The following example assumes a class which implements interface 0 and 3:
-
-   interfacetablelength = 4
-
-                  | ...       |            +----------+
-                     +-----------+            | method 2 |---> method z
-                     | class     |            | method 1 |---> method y
-                     +-----------+            | method 0 |---> method x
-                     | ivftbl  0 |----------> +----------+
-       vftblptr ---> +-----------+
-                  | ivftbl -1 |--> NULL    +----------+
-                  | ivftbl -2 |--> NULL    | method 1 |---> method x
-                  | ivftbl -3 |-----+      | method 0 |---> method a
-                  +-----------+     +----> +----------+
-     
-                              +---------------+
-                                 | length 3 = 2  |
-                                 | length 2 = 0  |
-                                 | length 1 = 0  |
-                                 | length 0 = 3  |
-       interfacevftbllength ---> +---------------+
-
-*******************************************************************************/
-
-struct _vftbl {
-       methodptr   *interfacetable[1];    /* interface table (access via macro)  */
-       classinfo   *class;                /* class, the vtbl belongs to          */
-       arraydescriptor *arraydesc;        /* for array classes, otherwise NULL   */
-       s4           vftbllength;          /* virtual function table length       */
-       s4           interfacetablelength; /* interface table length              */
-       s4           baseval;              /* base for runtime type check         */
-                                          /* (-index for interfaces)             */
-       s4           diffval;              /* high - base for runtime type check  */
-       s4          *interfacevftbllength; /* length of interface vftbls          */
-       methodptr    table[1];             /* class vftbl                         */
-};
-
-
-/* arraydescriptor *************************************************************
-
-   For every array class an arraydescriptor is allocated which
-   describes the array class. The arraydescriptor is referenced from
-   the vftbl of the array class.
-
-*******************************************************************************/
-
-struct arraydescriptor {
-       vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
-       vftbl_t *elementvftbl;   /* vftbl of the element type, NULL for primitive */
-       s2       arraytype;      /* ARRAYTYPE_* constant                          */
-       s2       dimension;      /* dimension of the array (always >= 1)          */
-       s4       dataoffset;     /* offset of the array data from object pointer  */
-       s4       componentsize;  /* size of a component in bytes                  */
-       s2       elementtype;    /* ARRAYTYPE_* constant                          */
-};
-
-
-/* primitivetypeinfo **********************************************************/
-
-struct primitivetypeinfo {
-       classinfo *class_wrap;               /* class for wrapping primitive type */
-       classinfo *class_primitive;          /* primitive class                   */
-       char      *wrapname;                 /* name of class for wrapping        */
-       char       typesig;                  /* one character type signature      */
-       char      *name;                     /* name of primitive class           */
-       char      *arrayname;                /* name of primitive array class     */
-       classinfo *arrayclass;               /* primitive array class             */
-       vftbl_t   *arrayvftbl;               /* vftbl of primitive array class    */
-};
-
-
-/* global variables ***********************************************************/
-
-/* This array can be indexed by the PRIMITIVETYPE_ and ARRAYTYPE_ constants   */
-/* (except ARRAYTYPE_OBJECT).                                                 */
-
-extern primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT];
-
-
-/* function prototypes ********************************************************/
-
-/* initialize the linker subsystem */
-bool linker_init(void);
-
-/* link a class */
-classinfo *link_class(classinfo *c);
-
-#endif /* _LINKER_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:
- */
diff --git a/src/vm/loader.c b/src/vm/loader.c
deleted file mode 100644 (file)
index 75b4521..0000000
+++ /dev/null
@@ -1,2623 +0,0 @@
-/* src/vm/loader.c - class loader functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Andreas Krall
-            Roman Obermaiser
-            Mark Probst
-            Edwin Steiner
-            Christian Thalinger
-
-   $Id: loader.c 7240 2007-01-27 13:01:35Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "native/native.h"
-#include "native/include/java_lang_Throwable.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#endif
-
-#include "toolbox/logging.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vm/annotation.h"
-# include "vm/stackmap.h"
-#endif
-
-#include "vm/builtin.h"
-#include "vm/classcache.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/suck.h"
-#include "vm/vm.h"
-
-#if defined(ENABLE_ZLIB)
-# include "vm/zip.h"
-#endif
-
-#include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
-#include "vm/rt-timing.h"
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
-
-/* loader_init *****************************************************************
-
-   Initializes all lists and loads all classes required for the system
-   or the compiler.
-
-*******************************************************************************/
-bool loader_init(void)
-{
-#if defined(ENABLE_THREADS)
-       list_classpath_entry *lce;
-
-       /* Initialize the monitor pointer for zip/jar file locking. */
-
-       for (lce = list_first(list_classpath_entries); lce != NULL;
-                lce = list_next(list_classpath_entries, lce))
-               if (lce->type == CLASSPATH_ARCHIVE)
-                       lock_init_object_lock((java_objectheader *) lce);
-#endif
-
-       /* load some important classes */
-
-       if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
-               return false;
-
-       if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       if (!(class_java_lang_Cloneable =
-                 load_class_bootstrap(utf_java_lang_Cloneable)))
-               return false;
-
-       if (!(class_java_io_Serializable =
-                 load_class_bootstrap(utf_java_io_Serializable)))
-               return false;
-#endif
-
-       /* load classes for wrapping primitive types */
-
-#if defined(ENABLE_JAVASE)
-       if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
-               return false;
-#endif
-
-       if (!(class_java_lang_Boolean =
-                 load_class_bootstrap(utf_java_lang_Boolean)))
-               return false;
-
-       if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
-               return false;
-
-       if (!(class_java_lang_Character =
-                 load_class_bootstrap(utf_java_lang_Character)))
-               return false;
-
-       if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
-               return false;
-
-       if (!(class_java_lang_Integer =
-                 load_class_bootstrap(utf_java_lang_Integer)))
-               return false;
-
-       if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
-               return false;
-
-       if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
-               return false;
-
-       if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
-               return false;
-
-
-       /* load some other important classes */
-
-       if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       if (!(class_java_lang_ClassLoader =
-                 load_class_bootstrap(utf_java_lang_ClassLoader)))
-               return false;
-
-       if (!(class_java_lang_SecurityManager =
-                 load_class_bootstrap(utf_java_lang_SecurityManager)))
-               return false;
-#endif
-
-       if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
-               return false;
-
-       if (!(class_java_lang_Thread =
-                 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
-               return false;
-
-#if defined(ENABLE_JAVASE)
-       if (!(class_java_lang_ThreadGroup =
-                 load_class_bootstrap(utf_java_lang_ThreadGroup)))
-               return false;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       if (!(class_java_lang_VMSystem =
-                 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
-
-               return false;
-
-       if (!(class_java_lang_VMThread =
-                 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
-               return false;
-#endif
-
-
-       /* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-       if (!(class_java_lang_StackTraceElement =
-                 load_class_bootstrap(utf_java_lang_StackTraceElement)))
-               return false;
-
-       if (!(class_java_lang_reflect_Constructor =
-                 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
-               return false;
-
-       if (!(class_java_lang_reflect_Field =
-                 load_class_bootstrap(utf_java_lang_reflect_Field)))
-               return false;
-
-       if (!(class_java_lang_reflect_Method =
-                 load_class_bootstrap(utf_java_lang_reflect_Method)))
-               return false;
-
-       if (!(class_java_security_PrivilegedAction =
-                 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
-               return false;
-
-       if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
-               return false;
-
-       if (!(arrayclass_java_lang_Object =
-                 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
-               return false;
-#endif
-
-       return true;
-}
-
-
-/* loader_load_all_classes *****************************************************
-
-   Loads all classes specified in the BOOTCLASSPATH.
-
-*******************************************************************************/
-
-void loader_load_all_classes(void)
-{
-       list_classpath_entry    *lce;
-#if defined(ENABLE_ZLIB)
-       hashtable               *ht;
-       s4                       slot;
-       hashtable_zipfile_entry *htzfe;
-       utf                     *u;
-#endif
-
-       for (lce = list_first(list_classpath_entries); lce != NULL;
-                lce = list_next(list_classpath_entries, lce)) {
-#if defined(ENABLE_ZLIB)
-               if (lce->type == CLASSPATH_ARCHIVE) {
-                       /* get the classes hashtable */
-
-                       ht = lce->htclasses;
-
-                       for (slot = 0; slot < ht->size; slot++) {
-                               htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
-
-                               for (; htzfe; htzfe = htzfe->hashlink) {
-                                       u = htzfe->filename;
-
-                                       /* skip all entries in META-INF and .properties,
-                       .png files */
-
-                                       if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
-                                               strstr(u->text, ".properties") ||
-                                               strstr(u->text, ".png"))
-                                               continue;
-
-                                       /* load class from bootstrap classloader */
-
-                                       if (!load_class_bootstrap(u)) {
-                                               fprintf(stderr, "Error loading: ");
-                                               utf_fprint_printable_ascii_classname(stderr, u);
-                                               fprintf(stderr, "\n");
-
-#if !defined(NDEBUG)
-                                               /* print out exception and cause */
-
-                                               exceptions_print_exception(*exceptionptr);
-#endif
-                                       }
-                               }
-                       }
-
-               } else {
-#endif
-#if defined(ENABLE_ZLIB)
-               }
-#endif
-       }
-}
-
-
-/* loader_skip_attribute_body **************************************************
-
-   Skips an attribute the attribute_name_index has already been read.
-       
-   attribute_info {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 info[attribute_length];
-   }
-
-*******************************************************************************/
-
-bool loader_skip_attribute_body(classbuffer *cb)
-{
-       u4 attribute_length;
-
-       if (!suck_check_classbuffer_size(cb, 4))
-               return false;
-
-       attribute_length = suck_u4(cb);
-
-       if (!suck_check_classbuffer_size(cb, attribute_length))
-               return false;
-
-       suck_skip_nbytes(cb, attribute_length);
-
-       return true;
-}
-
-
-/* load_constantpool ***********************************************************
-
-   Loads the constantpool of a class, the entries are transformed into
-   a simpler format by resolving references (a detailed overview of
-   the compact structures can be found in global.h).
-
-*******************************************************************************/
-
-static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
-{
-
-       /* The following structures are used to save information which cannot be 
-          processed during the first pass. After the complete constantpool has 
-          been traversed the references can be resolved. 
-          (only in specific order)                                                */
-       
-       /* CONSTANT_Class entries */
-       typedef struct forward_class {
-               struct forward_class *next;
-               u2 thisindex;
-               u2 name_index;
-       } forward_class;
-
-       /* CONSTANT_String */
-       typedef struct forward_string {
-               struct forward_string *next;
-               u2 thisindex;
-               u2 string_index;
-       } forward_string;
-
-       /* CONSTANT_NameAndType */
-       typedef struct forward_nameandtype {
-               struct forward_nameandtype *next;
-               u2 thisindex;
-               u2 name_index;
-               u2 sig_index;
-       } forward_nameandtype;
-
-       /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
-       typedef struct forward_fieldmethint {
-               struct forward_fieldmethint *next;
-               u2 thisindex;
-               u1 tag;
-               u2 class_index;
-               u2 nameandtype_index;
-       } forward_fieldmethint;
-
-
-       classinfo *c;
-       u4 idx;
-
-       forward_class *forward_classes = NULL;
-       forward_string *forward_strings = NULL;
-       forward_nameandtype *forward_nameandtypes = NULL;
-       forward_fieldmethint *forward_fieldmethints = NULL;
-
-       forward_class *nfc;
-       forward_string *nfs;
-       forward_nameandtype *nfn;
-       forward_fieldmethint *nff;
-
-       u4 cpcount;
-       u1 *cptags;
-       voidptr *cpinfos;
-
-       c = cb->class;
-
-       /* number of entries in the constant_pool table plus one */
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       cpcount = c->cpcount = suck_u2(cb);
-
-       /* allocate memory */
-       cptags  = c->cptags  = MNEW(u1, cpcount);
-       cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
-
-       if (cpcount < 1) {
-               exceptions_throw_classformaterror(c, "Illegal constant pool size");
-               return false;
-       }
-       
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
-#endif
-       
-       /* initialize constantpool */
-       for (idx = 0; idx < cpcount; idx++) {
-               cptags[idx] = CONSTANT_UNUSED;
-               cpinfos[idx] = NULL;
-       }
-
-                       
-       /******* first pass *******/
-       /* entries which cannot be resolved now are written into 
-          temporary structures and traversed again later        */
-                  
-       idx = 1;
-       while (idx < cpcount) {
-               u4 t;
-
-               /* get constant type */
-               if (!suck_check_classbuffer_size(cb, 1))
-                       return false;
-
-               t = suck_u1(cb);
-
-               switch (t) {
-               case CONSTANT_Class:
-                       nfc = DNEW(forward_class);
-
-                       nfc->next = forward_classes;
-                       forward_classes = nfc;
-
-                       nfc->thisindex = idx;
-                       /* reference to CONSTANT_NameAndType */
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       nfc->name_index = suck_u2(cb);
-
-                       idx++;
-                       break;
-                       
-               case CONSTANT_String:
-                       nfs = DNEW(forward_string);
-                               
-                       nfs->next = forward_strings;
-                       forward_strings = nfs;
-                               
-                       nfs->thisindex = idx;
-
-                       /* reference to CONSTANT_Utf8_info with string characters */
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       nfs->string_index = suck_u2(cb);
-                               
-                       idx++;
-                       break;
-
-               case CONSTANT_NameAndType:
-                       nfn = DNEW(forward_nameandtype);
-                               
-                       nfn->next = forward_nameandtypes;
-                       forward_nameandtypes = nfn;
-                               
-                       nfn->thisindex = idx;
-
-                       if (!suck_check_classbuffer_size(cb, 2 + 2))
-                               return false;
-
-                       /* reference to CONSTANT_Utf8_info containing simple name */
-                       nfn->name_index = suck_u2(cb);
-
-                       /* reference to CONSTANT_Utf8_info containing field or method
-                          descriptor */
-                       nfn->sig_index = suck_u2(cb);
-                               
-                       idx++;
-                       break;
-
-               case CONSTANT_Fieldref:
-               case CONSTANT_Methodref:
-               case CONSTANT_InterfaceMethodref:
-                       nff = DNEW(forward_fieldmethint);
-                       
-                       nff->next = forward_fieldmethints;
-                       forward_fieldmethints = nff;
-
-                       nff->thisindex = idx;
-                       /* constant type */
-                       nff->tag = t;
-
-                       if (!suck_check_classbuffer_size(cb, 2 + 2))
-                               return false;
-
-                       /* class or interface type that contains the declaration of the
-                          field or method */
-                       nff->class_index = suck_u2(cb);
-
-                       /* name and descriptor of the field or method */
-                       nff->nameandtype_index = suck_u2(cb);
-
-                       idx++;
-                       break;
-                               
-               case CONSTANT_Integer: {
-                       constant_integer *ci = NEW(constant_integer);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_integer);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 4))
-                               return false;
-
-                       ci->value = suck_s4(cb);
-                       cptags[idx] = CONSTANT_Integer;
-                       cpinfos[idx] = ci;
-
-                       idx++;
-                       break;
-               }
-                               
-               case CONSTANT_Float: {
-                       constant_float *cf = NEW(constant_float);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_float);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 4))
-                               return false;
-
-                       cf->value = suck_float(cb);
-                       cptags[idx] = CONSTANT_Float;
-                       cpinfos[idx] = cf;
-
-                       idx++;
-                       break;
-               }
-                               
-               case CONSTANT_Long: {
-                       constant_long *cl = NEW(constant_long);
-                                       
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_long);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 8))
-                               return false;
-
-                       cl->value = suck_s8(cb);
-                       cptags[idx] = CONSTANT_Long;
-                       cpinfos[idx] = cl;
-                       idx += 2;
-                       if (idx > cpcount) {
-                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
-                               return false;
-                       }
-                       break;
-               }
-                       
-               case CONSTANT_Double: {
-                       constant_double *cd = NEW(constant_double);
-                               
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_const_pool_len += sizeof(constant_double);
-#endif
-
-                       if (!suck_check_classbuffer_size(cb, 8))
-                               return false;
-
-                       cd->value = suck_double(cb);
-                       cptags[idx] = CONSTANT_Double;
-                       cpinfos[idx] = cd;
-                       idx += 2;
-                       if (idx > cpcount) {
-                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
-                               return false;
-                       }
-                       break;
-               }
-                               
-               case CONSTANT_Utf8: { 
-                       u4 length;
-
-                       /* number of bytes in the bytes array (not string-length) */
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       length = suck_u2(cb);
-                       cptags[idx] = CONSTANT_Utf8;
-
-                       /* validate the string */
-                       if (!suck_check_classbuffer_size(cb, length))
-                               return false;
-
-#ifdef ENABLE_VERIFIER
-                       if (opt_verify &&
-                               !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
-                       {
-                               exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
-                               return false;
-                       }
-#endif /* ENABLE_VERIFIER */
-                       /* insert utf-string into the utf-symboltable */
-                       cpinfos[idx] = utf_new((char *) cb->pos, length);
-
-                       /* skip bytes of the string (buffer size check above) */
-                       suck_skip_nbytes(cb, length);
-                       idx++;
-                       break;
-               }
-                                                                               
-               default:
-                       exceptions_throw_classformaterror(c, "Illegal constant pool type");
-                       return false;
-               }  /* end switch */
-       } /* end while */
-
-
-       /* resolve entries in temporary structures */
-
-       while (forward_classes) {
-               utf *name =
-                       class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
-               if (!name)
-                       return false;
-
-#ifdef ENABLE_VERIFIER
-               if (opt_verify && !is_valid_name_utf(name)) {
-                       exceptions_throw_classformaterror(c, "Class reference with invalid name");
-                       return false;
-               }
-#endif /* ENABLE_VERIFIER */
-
-               /* add all class references to the descriptor_pool */
-
-               if (!descriptor_pool_add_class(descpool, name))
-                       return false;
-
-               cptags[forward_classes->thisindex] = CONSTANT_Class;
-
-               if (opt_eager) {
-                       classinfo *tc;
-
-                       if (!(tc = load_class_bootstrap(name)))
-                               return false;
-
-                       /* link the class later, because we cannot link the class currently
-                          loading */
-                       list_add_first(&unlinkedclasses, tc);
-               }
-
-               /* the classref is created later */
-               cpinfos[forward_classes->thisindex] = name;
-
-               nfc = forward_classes;
-               forward_classes = forward_classes->next;
-       }
-
-       while (forward_strings) {
-               utf *text =
-                       class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
-               if (!text)
-                       return false;
-
-               /* resolve utf-string */
-               cptags[forward_strings->thisindex] = CONSTANT_String;
-               cpinfos[forward_strings->thisindex] = text;
-               
-               nfs = forward_strings;
-               forward_strings = forward_strings->next;
-       }
-
-       while (forward_nameandtypes) {
-               constant_nameandtype *cn = NEW(constant_nameandtype);   
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_const_pool_len += sizeof(constant_nameandtype);
-#endif
-
-               /* resolve simple name and descriptor */
-               cn->name = class_getconstant(c,
-                                                                        forward_nameandtypes->name_index,
-                                                                        CONSTANT_Utf8);
-               if (!cn->name)
-                       return false;
-
-               cn->descriptor = class_getconstant(c,
-                                                                                  forward_nameandtypes->sig_index,
-                                                                                  CONSTANT_Utf8);
-               if (!cn->descriptor)
-                       return false;
-
-#ifdef ENABLE_VERIFIER
-               if (opt_verify) {
-                       /* check name */
-                       if (!is_valid_name_utf(cn->name)) {
-                               exceptions_throw_classformaterror(c,
-                                                                                                 "Illegal Field name \"%s\"",
-                                                                                                 cn->name->text);
-
-                               return false;
-                       }
-
-                       /* disallow referencing <clinit> among others */
-                       if (cn->name->text[0] == '<' && cn->name != utf_init) {
-                               exceptions_throw_classformaterror(c, "Illegal reference to special method");
-                               return false;
-                       }
-               }
-#endif /* ENABLE_VERIFIER */
-
-               cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
-               cpinfos[forward_nameandtypes->thisindex] = cn;
-
-               nfn = forward_nameandtypes;
-               forward_nameandtypes = forward_nameandtypes->next;
-       }
-
-       while (forward_fieldmethints) {
-               constant_nameandtype *nat;
-               constant_FMIref *fmi = NEW(constant_FMIref);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_const_pool_len += sizeof(constant_FMIref);
-#endif
-               /* resolve simple name and descriptor */
-
-               nat = class_getconstant(c,
-                                                               forward_fieldmethints->nameandtype_index,
-                                                               CONSTANT_NameAndType);
-               if (!nat)
-                       return false;
-
-               /* add all descriptors in {Field,Method}ref to the descriptor_pool */
-
-               if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
-                       return false;
-
-               /* the classref is created later */
-
-               fmi->p.index = forward_fieldmethints->class_index;
-               fmi->name = nat->name;
-               fmi->descriptor = nat->descriptor;
-
-               cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
-               cpinfos[forward_fieldmethints->thisindex] = fmi;
-       
-               nff = forward_fieldmethints;
-               forward_fieldmethints = forward_fieldmethints->next;
-       }
-
-       /* everything was ok */
-
-       return true;
-}
-
-
-/* loader_load_attribute_signature *********************************************
-
-   Signature_attribute {
-       u2 attribute_name_index;
-          u4 atrribute_length;
-          u2 signature_index;
-   }
-
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
-{
-       classinfo *c;
-       u4         attribute_length;
-       u2         signature_index;
-
-       /* get classinfo */
-
-       c = cb->class;
-
-       /* check remaining bytecode */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* check attribute length */
-
-       attribute_length = suck_u4(cb);
-
-       if (attribute_length != 2) {
-               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-               return false;
-       }
-
-       if (*signature != NULL) {
-               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
-               return false;
-       }
-
-       /* get signature */
-
-       signature_index = suck_u2(cb);
-
-       if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
-               return false;
-
-       return true;
-}
-#endif /* defined(ENABLE_JAVASE) */
-
-
-/* load_field ******************************************************************
-
-   Load everything about a class field from the class file and fill a
-   'fieldinfo' structure. For static fields, space in the data segment
-   is allocated.
-
-*******************************************************************************/
-
-#define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
-
-static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
-{
-       classinfo *c;
-       u4 attrnum, i;
-       u4 jtype;
-       u4 pindex = field_load_NOVALUE;     /* constantvalue_index */
-       utf *u;
-
-       c = cb->class;
-
-       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
-               return false;
-
-       f->flags = suck_u2(cb);
-
-       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-               return false;
-
-       f->name = u;
-
-       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-               return false;
-
-       f->descriptor = u;
-       f->parseddesc = NULL;
-
-       if (!descriptor_pool_add(descpool, u, NULL))
-               return false;
-
-       /* descriptor_pool_add accepts method descriptors, so we have to check  */
-       /* against them here before the call of descriptor_to_basic_type below. */
-       if (u->text[0] == '(') {
-               exceptions_throw_classformaterror(c, "Method descriptor used for field");
-               return false;
-       }
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-               /* check name */
-               if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
-                       exceptions_throw_classformaterror(c,
-                                                                                         "Illegal Field name \"%s\"",
-                                                                                         f->name->text);
-                       return false;
-               }
-
-               /* check flag consistency */
-               i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
-
-               if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
-                       ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
-                       exceptions_throw_classformaterror(c,
-                                                                                         "Illegal field modifiers: 0x%X",
-                                                                                         f->flags);
-                       return false;
-               }
-
-               if (c->flags & ACC_INTERFACE) {
-                       if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
-                               != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
-                               f->flags & ACC_TRANSIENT) {
-                               exceptions_throw_classformaterror(c,
-                                                                                                 "Illegal field modifiers: 0x%X",
-                                                                                                 f->flags);
-                               return false;
-                       }
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-
-       f->type   = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
-       f->offset = 0;                             /* offset from start of object */
-       f->class  = c;
-
-       switch (f->type) {
-       case TYPE_INT:
-               f->value.i = 0;
-               break;
-
-       case TYPE_FLT:
-               f->value.f = 0.0;
-               break;
-
-       case TYPE_DBL:
-               f->value.d = 0.0;
-               break;
-
-       case TYPE_ADR:
-               f->value.a = NULL;
-               if (!(f->flags & ACC_STATIC))
-                       c->flags |= ACC_CLASS_HAS_POINTERS;
-               break;
-
-       case TYPE_LNG:
-#if U8_AVAILABLE
-               f->value.l = 0;
-#else
-               f->value.l.low  = 0;
-               f->value.l.high = 0;
-#endif
-               break;
-       }
-
-       /* read attributes */
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       attrnum = suck_u2(cb);
-       for (i = 0; i < attrnum; i++) {
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
-                       return false;
-
-               if (u == utf_ConstantValue) {
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* check attribute length */
-
-                       if (suck_u4(cb) != 2) {
-                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
-                               return false;
-                       }
-                       
-                       /* constant value attribute */
-
-                       if (pindex != field_load_NOVALUE) {
-                               exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
-                               return false;
-                       }
-                       
-                       /* index of value in constantpool */
-
-                       pindex = suck_u2(cb);
-               
-                       /* initialize field with value from constantpool */             
-                       switch (jtype) {
-                       case TYPE_INT: {
-                               constant_integer *ci; 
-
-                               if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
-                                       return false;
-
-                               f->value.i = ci->value;
-                       }
-                       break;
-                                       
-                       case TYPE_LNG: {
-                               constant_long *cl; 
-
-                               if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
-                                       return false;
-
-                               f->value.l = cl->value;
-                       }
-                       break;
-
-                       case TYPE_FLT: {
-                               constant_float *cf;
-
-                               if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
-                                       return false;
-
-                               f->value.f = cf->value;
-                       }
-                       break;
-                                                                                       
-                       case TYPE_DBL: {
-                               constant_double *cd;
-
-                               if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
-                                       return false;
-
-                               f->value.d = cd->value;
-                       }
-                       break;
-                                               
-                       case TYPE_ADR:
-                               if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
-                                       return false;
-
-                               /* create javastring from compressed utf8-string */
-                               f->value.a = literalstring_new(u);
-                               break;
-       
-                       default: 
-                               log_text("Invalid Constant - Type");
-                       }
-               }
-#if defined(ENABLE_JAVASE)
-               else if (u == utf_Signature) {
-                       /* Signature */
-
-                       if (!loader_load_attribute_signature(cb, &(f->signature)))
-                               return false;
-               }
-#endif
-               else {
-                       /* unknown attribute */
-
-                       if (!loader_skip_attribute_body(cb))
-                               return false;
-               }
-       }
-
-       /* everything was ok */
-
-       return true;
-}
-
-
-/* loader_load_method **********************************************************
-
-   Loads a method from the class file and fills an existing
-   'methodinfo' structure. For native methods, the function pointer
-   field is set to the real function pointer, for JavaVM methods a
-   pointer to the compiler is used preliminarily.
-
-   method_info {
-       u2 access_flags;
-          u2 name_index;
-          u2 descriptor_index;
-          u2 attributes_count;
-          attribute_info attributes[attribute_count];
-   }
-
-   attribute_info {
-       u2 attribute_name_index;
-          u4 attribute_length;
-          u1 info[attribute_length];
-   }
-
-   LineNumberTable_attribute {
-       u2 attribute_name_index;
-          u4 attribute_length;
-          u2 line_number_table_length;
-          {
-              u2 start_pc;
-                  u2 line_number;
-          } line_number_table[line_number_table_length];
-   }
-
-*******************************************************************************/
-
-static bool loader_load_method(classbuffer *cb, methodinfo *m,
-                                                          descriptor_pool *descpool)
-{
-       classinfo *c;
-       int argcount;
-       s4         i, j, k, l;
-       utf       *u;
-       u2         name_index;
-       u2         descriptor_index;
-       u2         attributes_count;
-       u2         attribute_name_index;
-       utf       *attribute_name;
-       u2         code_attributes_count;
-       u2         code_attribute_name_index;
-       utf       *code_attribute_name;
-
-       /* get classinfo */
-
-       c = cb->class;
-
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&m->header);
-#endif
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_all_methods++;
-#endif
-
-       /* all fields of m have been zeroed in load_class_from_classbuffer */
-
-       m->class = c;
-       
-       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
-               return false;
-
-       /* access flags */
-
-       m->flags = suck_u2(cb);
-
-       /* name */
-
-       name_index = suck_u2(cb);
-
-       if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
-               return false;
-
-       m->name = u;
-
-       /* descriptor */
-
-       descriptor_index = suck_u2(cb);
-
-       if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
-               return false;
-
-       m->descriptor = u;
-
-       if (!descriptor_pool_add(descpool, u, &argcount))
-               return false;
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-               if (!is_valid_name_utf(m->name)) {
-                       exceptions_throw_classformaterror(c, "Method with invalid name");
-                       return false;
-               }
-
-               if (m->name->text[0] == '<' &&
-                       m->name != utf_init && m->name != utf_clinit) {
-                       exceptions_throw_classformaterror(c, "Method with invalid special name");
-                       return false;
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-       
-       if (!(m->flags & ACC_STATIC))
-               argcount++; /* count the 'this' argument */
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-               if (argcount > 255) {
-                       exceptions_throw_classformaterror(c, "Too many arguments in signature");
-                       return false;
-               }
-
-               /* check flag consistency */
-               if (m->name != utf_clinit) {
-                       i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
-
-                       if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
-                               exceptions_throw_classformaterror(c,
-                                                                                                 "Illegal method modifiers: 0x%X",
-                                                                                                 m->flags);
-                               return false;
-                       }
-
-                       if (m->flags & ACC_ABSTRACT) {
-                               if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
-                                                                ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
-                                       exceptions_throw_classformaterror(c,
-                                                                                                         "Illegal method modifiers: 0x%X",
-                                                                                                         m->flags);
-                                       return false;
-                               }
-                       }
-
-                       if (c->flags & ACC_INTERFACE) {
-                               if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
-                                       exceptions_throw_classformaterror(c,
-                                                                                                         "Illegal method modifiers: 0x%X",
-                                                                                                         m->flags);
-                                       return false;
-                               }
-                       }
-
-                       if (m->name == utf_init) {
-                               if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
-                                                               ACC_NATIVE | ACC_ABSTRACT)) {
-                                       exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
-                                       return false;
-                               }
-                       }
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-
-       /* mark the method as monomorphic until further notice */
-
-       m->flags |= ACC_METHOD_MONOMORPHIC;
-
-       /* non-abstract methods have an implementation in this class */
-
-       if (!(m->flags & ACC_ABSTRACT))
-               m->flags |= ACC_METHOD_IMPLEMENTED;
-               
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* attributes count */
-
-       attributes_count = suck_u2(cb);
-
-       for (i = 0; i < attributes_count; i++) {
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               /* attribute name index */
-
-               attribute_name_index = suck_u2(cb);
-
-               if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
-                       return false;
-
-               if (attribute_name == utf_Code) {
-                       /* Code */
-                       if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
-                               exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
-                               return false;
-                       }
-                       
-                       if (m->jcode) {
-                               exceptions_throw_classformaterror(c, "Multiple Code attributes");
-                               return false;
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
-                               return false;
-
-                       suck_u4(cb);
-                       m->maxstack = suck_u2(cb);
-                       m->maxlocals = suck_u2(cb);
-
-                       if (m->maxlocals < argcount) {
-                               exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
-                               return false;
-                       }
-                       
-                       if (!suck_check_classbuffer_size(cb, 4))
-                               return false;
-
-                       m->jcodelength = suck_u4(cb);
-
-                       if (m->jcodelength == 0) {
-                               exceptions_throw_classformaterror(c, "Code of a method has length 0");
-                               return false;
-                       }
-                       
-                       if (m->jcodelength > 65535) {
-                               exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
-                               return false;
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, m->jcodelength))
-                               return false;
-
-                       m->jcode = MNEW(u1, m->jcodelength);
-                       suck_nbytes(m->jcode, cb, m->jcodelength);
-
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       m->rawexceptiontablelength = suck_u2(cb);
-                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
-                               return false;
-
-                       m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
-
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat) {
-                               count_vmcode_len += m->jcodelength + 18;
-                               count_extable_len +=
-                                       m->rawexceptiontablelength * sizeof(raw_exception_entry);
-                       }
-#endif
-
-                       for (j = 0; j < m->rawexceptiontablelength; j++) {
-                               u4 idx;
-                               m->rawexceptiontable[j].startpc = suck_u2(cb);
-                               m->rawexceptiontable[j].endpc = suck_u2(cb);
-                               m->rawexceptiontable[j].handlerpc = suck_u2(cb);
-
-                               idx = suck_u2(cb);
-                               if (!idx) {
-                                       m->rawexceptiontable[j].catchtype.any = NULL;
-
-                               } else {
-                                       /* the classref is created later */
-                                       if (!(m->rawexceptiontable[j].catchtype.any =
-                                                 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
-                                               return false;
-                               }
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, 2))
-                               return false;
-
-                       /* code attributes count */
-
-                       code_attributes_count = suck_u2(cb);
-
-                       for (k = 0; k < code_attributes_count; k++) {
-                               if (!suck_check_classbuffer_size(cb, 2))
-                                       return false;
-
-                               /* code attribute name index */
-
-                               code_attribute_name_index = suck_u2(cb);
-
-                               if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
-                                       return false;
-
-                               /* check which code attribute */
-
-                               if (code_attribute_name == utf_LineNumberTable) {
-                                       /* LineNumberTable */
-                                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                                               return false;
-
-                                       /* attribute length */
-
-                                       (void) suck_u4(cb);
-
-                                       /* line number table length */
-
-                                       m->linenumbercount = suck_u2(cb);
-
-                                       if (!suck_check_classbuffer_size(cb,
-                                                                                               (2 + 2) * m->linenumbercount))
-                                               return false;
-
-                                       m->linenumbers = MNEW(lineinfo, m->linenumbercount);
-                                       
-                                       for (l = 0; l < m->linenumbercount; l++) {
-                                               m->linenumbers[l].start_pc    = suck_u2(cb);
-                                               m->linenumbers[l].line_number = suck_u2(cb);
-                                       }
-                               }
-#if defined(ENABLE_JAVASE)
-                               else if (code_attribute_name == utf_StackMapTable) {
-                                       /* StackTableMap */
-
-                                       if (!stackmap_load_attribute_stackmaptable(cb, m))
-                                               return false;
-                               }
-#endif
-                               else {
-                                       /* unknown code attribute */
-
-                                       if (!loader_skip_attribute_body(cb))
-                                               return false;
-                               }
-                       }
-               }
-               else if (attribute_name == utf_Exceptions) {
-                       /* Exceptions */
-
-                       if (m->thrownexceptions != NULL) {
-                               exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
-                               return false;
-                       }
-
-                       if (!suck_check_classbuffer_size(cb, 4 + 2))
-                               return false;
-
-                       /* attribute length */
-
-                       (void) suck_u4(cb);
-
-                       m->thrownexceptionscount = suck_u2(cb);
-
-                       if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
-                               return false;
-
-                       m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
-
-                       for (j = 0; j < m->thrownexceptionscount; j++) {
-                               /* the classref is created later */
-                               if (!((m->thrownexceptions)[j].any =
-                                         (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
-                                       return false;
-                       }
-               }
-#if defined(ENABLE_JAVASE)
-               else if (attribute_name == utf_Signature) {
-                       /* Signature */
-
-                       if (!loader_load_attribute_signature(cb, &(m->signature)))
-                               return false;
-               }
-#endif
-               else {
-                       /* unknown attribute */
-
-                       if (!loader_skip_attribute_body(cb))
-                               return false;
-               }
-       }
-
-       if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
-               exceptions_throw_classformaterror(c, "Missing Code attribute");
-               return false;
-       }
-
-       /* everything was ok */
-
-       return true;
-}
-
-
-/* load_class_from_sysloader ***************************************************
-
-   Load the class with the given name using the system class loader
-
-   IN:
-       name.............the classname
-
-   RETURN VALUE:
-       the loaded class, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-classinfo *load_class_from_sysloader(utf *name)
-{
-       methodinfo        *m;
-       java_objectheader *cl;
-       classinfo         *c;
-
-       assert(class_java_lang_Object);
-       assert(class_java_lang_ClassLoader);
-       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
-       
-       m = class_resolveclassmethod(class_java_lang_ClassLoader,
-                                                                utf_getSystemClassLoader,
-                                                                utf_void__java_lang_ClassLoader,
-                                                                class_java_lang_Object,
-                                                                false);
-
-       if (!m)
-               return false;
-
-       cl = vm_call_method(m, NULL);
-
-       if (!cl)
-               return false;
-
-       c = load_class_from_classloader(name, cl);
-
-       return c;
-}
-
-
-/* load_class_from_classloader *************************************************
-
-   Load the class with the given name using the given user-defined class loader.
-
-   IN:
-       name.............the classname
-          cl...............user-defined class loader
-          
-   RETURN VALUE:
-       the loaded class, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       classinfo         *tmpc;
-       java_lang_String  *s;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_lookup, time_prepare, time_java, 
-                                       time_cache;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       assert(name);
-
-       /* lookup if this class has already been loaded */
-
-       c = classcache_lookup(cl, name);
-
-       RT_TIMING_GET_TIME(time_lookup);
-       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
-
-       if (c)
-               return c;
-
-       /* if other class loader than bootstrap, call it */
-
-       if (cl) {
-               methodinfo *lc;
-               char       *text;
-               s4          namelen;
-
-               text = name->text;
-               namelen = name->blength;
-
-               /* handle array classes */
-               if (text[0] == '[') {
-                       classinfo *comp;
-                       utf       *u;
-
-                       switch (text[1]) {
-                       case 'L':
-                               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
-                               if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
-                                       *exceptionptr = new_noclassdeffounderror(name);
-                                       return false;
-                               }
-
-                               u = utf_new(text + 2, namelen - 3);
-
-                               if (!(comp = load_class_from_classloader(u, cl)))
-                                       return false;
-
-                               /* create the array class */
-
-                               c = class_array_of(comp, false);
-
-                               tmpc = classcache_store(cl, c, true);
-
-                               if (tmpc == NULL) {
-                                       /* exception, free the loaded class */
-                                       c->state &= ~CLASS_LOADING;
-                                       class_free(c);
-                               }
-
-                               return tmpc;
-
-                       case '[':
-                               /* load the component class */
-
-                               u = utf_new(text + 1, namelen - 1);
-
-                               if (!(comp = load_class_from_classloader(u, cl)))
-                                       return false;
-
-                               /* create the array class */
-
-                               c = class_array_of(comp, false);
-
-                               tmpc = classcache_store(cl, c, true);
-
-                               if (tmpc == NULL) {
-                                       /* exception, free the loaded class */
-                                       c->state &= ~CLASS_LOADING;
-                                       class_free(c);
-                               }
-
-                               return tmpc;
-
-                       default:
-                               /* primitive array classes are loaded by the bootstrap loader */
-
-                               c = load_class_bootstrap(name);
-
-                               return c;
-                       }
-               }
-               
-               assert(class_java_lang_Object);
-
-               lc = class_resolveclassmethod(cl->vftbl->class,
-                                                                         utf_loadClass,
-                                                                         utf_java_lang_String__java_lang_Class,
-                                                                         class_java_lang_Object,
-                                                                         true);
-
-               if (!lc)
-                       return false; /* exception */
-
-               /* move return value into `o' and cast it afterwards to a classinfo* */
-
-               s = javastring_new_slash_to_dot(name);
-
-               RT_TIMING_GET_TIME(time_prepare);
-
-               o = vm_call_method(lc, cl, s);
-
-               RT_TIMING_GET_TIME(time_java);
-
-               c = (classinfo *) o;
-
-               if (c) {
-                       /* Store this class in the loaded class cache. If another
-                          class with the same (initloader,name) pair has been
-                          stored earlier it will be returned by classcache_store
-                          In this case classcache_store may not free the class
-                          because it has already been exposed to Java code which
-                          may have kept references to that class. */
-
-                   tmpc = classcache_store(cl, c, false);
-
-                       if (tmpc == NULL) {
-                               /* exception, free the loaded class */
-                               c->state &= ~CLASS_LOADING;
-                               class_free(c);
-                       }
-
-                       c = tmpc;
-
-               } else {
-                       /* loadClass has thrown an exception.  We must convert
-                          ClassNotFoundException into
-                          NoClassDefFoundException. */
-
-                       /* XXX Maybe we should have a flag that avoids this
-                          conversion for calling load_class_from_classloader from
-                          Class.forName.  Currently we do a double conversion in
-                          these cases.  */
-
-                       classnotfoundexception_to_noclassdeffounderror();
-               }
-
-               RT_TIMING_GET_TIME(time_cache);
-
-               RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
-               RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
-               RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
-
-               /* SUN compatible -verbose:class output */
-
-               if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
-                       printf("[Loaded ");
-                       utf_display_printable_ascii_classname(name);
-                       printf("]\n");
-               }
-
-#if defined(ENABLE_JVMTI)
-               /* fire Class Load JVMTI event */
-               if (jvmti) jvmti_ClassLoadPrepare(false, c);
-#endif
-
-
-               return c;
-       } 
-
-       c = load_class_bootstrap(name);
-
-       return c;
-}
-
-
-/* load_class_bootstrap ********************************************************
-       
-   Load the class with the given name using the bootstrap class loader.
-
-   IN:
-       name.............the classname
-
-   RETURN VALUE:
-       loaded classinfo, or
-          NULL if an exception has been thrown
-
-   SYNCHRONIZATION:
-       load_class_bootstrap is synchronized. It can be treated as an
-          atomic operation.
-
-*******************************************************************************/
-
-classinfo *load_class_bootstrap(utf *name)
-{
-       classbuffer *cb;
-       classinfo   *c;
-       classinfo   *r;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_lookup, time_array, time_suck, 
-                                       time_load, time_cache;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       /* for debugging */
-
-       assert(name);
-
-       /* lookup if this class has already been loaded */
-
-       if ((r = classcache_lookup(NULL, name))) {
-
-               RT_TIMING_GET_TIME(time_lookup);
-               RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
-               
-               return r;
-       }
-
-       RT_TIMING_GET_TIME(time_lookup);
-       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
-               
-       /* create the classinfo */
-
-       c = class_create_classinfo(name);
-
-       /* handle array classes */
-
-       if (name->text[0] == '[') {
-               c = load_newly_created_array(c, NULL);
-               if (c == NULL)
-                       return NULL;
-               assert(c->state & CLASS_LOADED);
-
-               RT_TIMING_GET_TIME(time_array);
-               RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
-               
-               return c;
-       }
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getcompilingtime)
-               compilingtime_stop();
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* load classdata, throw exception on error */
-
-       if ((cb = suck_start(c)) == NULL) {
-               /* this normally means, the classpath was not set properly */
-
-               if (name == utf_java_lang_Object)
-                       vm_abort("%s: java/lang/Object", string_java_lang_NoClassDefFoundError);
-
-               *exceptionptr = new_noclassdeffounderror(name);
-
-               return NULL;
-       }
-
-       RT_TIMING_GET_TIME(time_suck);
-       
-       /* load the class from the buffer */
-
-       r = load_class_from_classbuffer(cb);
-
-       RT_TIMING_GET_TIME(time_load);
-       
-       if (!r) {
-               /* the class could not be loaded, free the classinfo struct */
-
-               class_free(c);
-
-       } else {
-               /* Store this class in the loaded class cache this step also
-               checks the loading constraints. If the class has been loaded
-               before, the earlier loaded class is returned. */
-
-               classinfo *res = classcache_store(NULL, c, true);
-
-               if (!res) {
-                       /* exception */
-                       class_free(c);
-               }
-
-               r = res;
-       }
-
-       RT_TIMING_GET_TIME(time_cache);
-       
-       /* SUN compatible -verbose:class output */
-
-       if (opt_verboseclass && r) {
-               printf("[Loaded ");
-               utf_display_printable_ascii_classname(name);
-               printf(" from %s]\n", cb->path);
-       }
-
-       /* free memory */
-
-       suck_stop(cb);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-
-       if (opt_getcompilingtime)
-               compilingtime_start();
-#endif
-
-       RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
-       RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
-       RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
-       RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
-
-       return r;
-}
-
-
-/* load_class_from_classbuffer *************************************************
-       
-   Loads everything interesting about a class from the class file. The
-   'classinfo' structure must have been allocated previously.
-
-   The super class and the interfaces implemented by this class need
-   not be loaded. The link is set later by the function 'class_link'.
-
-   The loaded class is removed from the list 'unloadedclasses' and
-   added to the list 'unlinkedclasses'.
-       
-   SYNCHRONIZATION:
-       This function is NOT synchronized!
-   
-*******************************************************************************/
-
-classinfo *load_class_from_classbuffer(classbuffer *cb)
-{
-       classinfo *c;
-       utf *name;
-       utf *supername;
-       u4 i,j;
-       u4 ma, mi;
-       s4 dumpsize;
-       descriptor_pool *descpool;
-#if defined(ENABLE_STATISTICS)
-       u4 classrefsize;
-       u4 descsize;
-#endif
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_checks, time_ndpool, time_cpool,
-                                       time_setup, time_fields, time_methods, time_classrefs,
-                                       time_descs,     time_setrefs, time_parsefds, time_parsemds,
-                                       time_parsecpool, time_verify, time_attrs;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       /* get the classbuffer's class */
-
-       c = cb->class;
-
-       /* the class is already loaded */
-
-       if (c->state & CLASS_LOADED)
-               return c;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_class_loads++;
-#endif
-
-#if !defined(NDEBUG)
-       /* output for debugging purposes */
-
-       if (loadverbose)
-               log_message_class("Loading class: ", c);
-#endif
-
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       /* class is currently loading */
-
-       c->state |= CLASS_LOADING;
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
-               goto return_exception;
-
-       /* check signature */
-
-       if (suck_u4(cb) != MAGIC) {
-               exceptions_throw_classformaterror(c, "Bad magic number");
-
-               goto return_exception;
-       }
-
-       /* check version */
-
-       mi = suck_u2(cb);
-       ma = suck_u2(cb);
-
-       if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
-               *exceptionptr =
-                       new_unsupportedclassversionerror(c,
-                                                                                        "Unsupported major.minor version %d.%d",
-                                                                                        ma, mi);
-
-               goto return_exception;
-       }
-       RT_TIMING_GET_TIME(time_checks);
-
-       /* create a new descriptor pool */
-
-       descpool = descriptor_pool_new(c);
-
-       RT_TIMING_GET_TIME(time_ndpool);
-
-       /* load the constant pool */
-
-       if (!load_constantpool(cb, descpool))
-               goto return_exception;
-
-       RT_TIMING_GET_TIME(time_cpool);
-
-       /* ACC flags */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               goto return_exception;
-
-       c->flags = suck_u2(cb);
-
-       /* check ACC flags consistency */
-
-       if (c->flags & ACC_INTERFACE) {
-               if (!(c->flags & ACC_ABSTRACT)) {
-                       /* We work around this because interfaces in JDK 1.1 are
-                        * not declared abstract. */
-
-                       c->flags |= ACC_ABSTRACT;
-               }
-
-               if (c->flags & ACC_FINAL) {
-                       exceptions_throw_classformaterror(c,
-                                                                                         "Illegal class modifiers: 0x%X",
-                                                                                         c->flags);
-                       goto return_exception;
-               }
-
-               if (c->flags & ACC_SUPER) {
-                       c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
-               }
-       }
-
-       if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
-               exceptions_throw_classformaterror(c,
-                                                                                 "Illegal class modifiers: 0x%X",
-                                                                                 c->flags);
-               goto return_exception;
-       }
-
-       if (!suck_check_classbuffer_size(cb, 2 + 2))
-               goto return_exception;
-
-       /* this class */
-
-       i = suck_u2(cb);
-       if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
-               goto return_exception;
-
-       if (c->name == utf_not_named_yet) {
-               /* we finally have a name for this class */
-               c->name = name;
-               class_set_packagename(c);
-
-       } else if (name != c->name) {
-               char *msg;
-               s4    msglen;
-
-               msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
-                       utf_bytes(name) + strlen(")") + strlen("0");
-
-               msg = MNEW(char, msglen);
-
-               utf_copy_classname(msg, c->name);
-               strcat(msg, " (wrong name: ");
-               utf_cat_classname(msg, name);
-               strcat(msg, ")");
-
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NoClassDefFoundError, msg);
-
-               MFREE(msg, char, msglen);
-
-               goto return_exception;
-       }
-
-       /* retrieve superclass */
-
-       c->super.any = NULL;
-       if ((i = suck_u2(cb))) {
-               if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
-                       goto return_exception;
-
-               /* java.lang.Object may not have a super class. */
-
-               if (c->name == utf_java_lang_Object) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_ClassFormatError,
-                                                                         "java.lang.Object with superclass");
-
-                       goto return_exception;
-               }
-
-               /* Interfaces must have java.lang.Object as super class. */
-
-               if ((c->flags & ACC_INTERFACE) &&
-                       supername != utf_java_lang_Object) {
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_ClassFormatError,
-                                                                         "Interfaces must have java.lang.Object as superclass");
-
-                       goto return_exception;
-               }
-
-       } else {
-               supername = NULL;
-
-               /* This is only allowed for java.lang.Object. */
-
-               if (c->name != utf_java_lang_Object) {
-                       exceptions_throw_classformaterror(c, "Bad superclass index");
-                       goto return_exception;
-               }
-       }
-
-       /* retrieve interfaces */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               goto return_exception;
-
-       c->interfacescount = suck_u2(cb);
-
-       if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
-               goto return_exception;
-
-       c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
-       for (i = 0; i < c->interfacescount; i++) {
-               /* the classrefs are created later */
-               if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
-                       goto return_exception;
-       }
-
-       RT_TIMING_GET_TIME(time_setup);
-
-       /* load fields */
-       if (!suck_check_classbuffer_size(cb, 2))
-               goto return_exception;
-
-       c->fieldscount = suck_u2(cb);
-#if defined(ENABLE_GC_CACAO)
-       c->fields = MNEW(fieldinfo, c->fieldscount);
-       MZERO(c->fields, fieldinfo, c->fieldscount);
-#else
-       c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
-#endif
-
-       for (i = 0; i < c->fieldscount; i++) {
-               if (!load_field(cb, &(c->fields[i]),descpool))
-                       goto return_exception;
-       }
-
-       RT_TIMING_GET_TIME(time_fields);
-
-       /* load methods */
-       if (!suck_check_classbuffer_size(cb, 2))
-               goto return_exception;
-
-       c->methodscount = suck_u2(cb);
-       c->methods = MNEW(methodinfo, c->methodscount);
-
-       MZERO(c->methods, methodinfo, c->methodscount);
-       
-       for (i = 0; i < c->methodscount; i++) {
-               if (!loader_load_method(cb, &(c->methods[i]), descpool))
-                       goto return_exception;
-       }
-
-       RT_TIMING_GET_TIME(time_methods);
-
-       /* create the class reference table */
-
-       c->classrefs =
-               descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
-
-       RT_TIMING_GET_TIME(time_classrefs);
-
-       /* allocate space for the parsed descriptors */
-
-       descriptor_pool_alloc_parsed_descriptors(descpool);
-       c->parseddescs =
-               descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat) {
-               descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
-               count_classref_len += classrefsize;
-               count_parsed_desc_len += descsize;
-       }
-#endif
-
-       RT_TIMING_GET_TIME(time_descs);
-
-       /* put the classrefs in the constant pool */
-       for (i = 0; i < c->cpcount; i++) {
-               if (c->cptags[i] == CONSTANT_Class) {
-                       utf *name = (utf *) c->cpinfos[i];
-                       c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
-               }
-       }
-
-       /* set the super class reference */
-
-       if (supername) {
-               c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
-               if (!c->super.ref)
-                       goto return_exception;
-       }
-
-       /* set the super interfaces references */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               c->interfaces[i].ref =
-                       descriptor_pool_lookup_classref(descpool,
-                                                                                       (utf *) c->interfaces[i].any);
-               if (!c->interfaces[i].ref)
-                       goto return_exception;
-       }
-
-       RT_TIMING_GET_TIME(time_setrefs);
-
-       /* parse field descriptors */
-
-       for (i = 0; i < c->fieldscount; i++) {
-               c->fields[i].parseddesc =
-                       descriptor_pool_parse_field_descriptor(descpool,
-                                                                                                  c->fields[i].descriptor);
-               if (!c->fields[i].parseddesc)
-                       goto return_exception;
-       }
-
-       RT_TIMING_GET_TIME(time_parsefds);
-
-       /* parse method descriptors */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &c->methods[i];
-               m->parseddesc =
-                       descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
-                                                                                                       m->flags, class_get_self_classref(m->class));
-               if (!m->parseddesc)
-                       goto return_exception;
-
-               for (j = 0; j < m->rawexceptiontablelength; j++) {
-                       if (!m->rawexceptiontable[j].catchtype.any)
-                               continue;
-                       if ((m->rawexceptiontable[j].catchtype.ref =
-                                descriptor_pool_lookup_classref(descpool,
-                                               (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
-                               goto return_exception;
-               }
-
-               for (j = 0; j < m->thrownexceptionscount; j++) {
-                       if (!m->thrownexceptions[j].any)
-                               continue;
-                       if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
-                                               (utf *) m->thrownexceptions[j].any)) == NULL)
-                               goto return_exception;
-               }
-       }
-
-       RT_TIMING_GET_TIME(time_parsemds);
-
-       /* parse the loaded descriptors */
-
-       for (i = 0; i < c->cpcount; i++) {
-               constant_FMIref *fmi;
-               s4               index;
-
-               switch (c->cptags[i]) {
-               case CONSTANT_Fieldref:
-                       fmi = (constant_FMIref *) c->cpinfos[i];
-                       fmi->parseddesc.fd =
-                               descriptor_pool_parse_field_descriptor(descpool,
-                                                                                                          fmi->descriptor);
-                       if (!fmi->parseddesc.fd)
-                               goto return_exception;
-                       index = fmi->p.index;
-                       fmi->p.classref =
-                               (constant_classref *) class_getconstant(c, index,
-                                                                                                               CONSTANT_Class);
-                       if (!fmi->p.classref)
-                               goto return_exception;
-                       break;
-               case CONSTANT_Methodref:
-               case CONSTANT_InterfaceMethodref:
-                       fmi = (constant_FMIref *) c->cpinfos[i];
-                       index = fmi->p.index;
-                       fmi->p.classref =
-                               (constant_classref *) class_getconstant(c, index,
-                                                                                                               CONSTANT_Class);
-                       if (!fmi->p.classref)
-                               goto return_exception;
-                       fmi->parseddesc.md =
-                               descriptor_pool_parse_method_descriptor(descpool,
-                                                                                                               fmi->descriptor,
-                                                                                                               ACC_UNDEF,
-                                                                                                               fmi->p.classref);
-                       if (!fmi->parseddesc.md)
-                               goto return_exception;
-                       break;
-               }
-       }
-
-       RT_TIMING_GET_TIME(time_parsecpool);
-
-#ifdef ENABLE_VERIFIER
-       /* Check if all fields and methods can be uniquely
-        * identified by (name,descriptor). */
-
-       if (opt_verify) {
-               /* We use a hash table here to avoid making the
-                * average case quadratic in # of methods, fields.
-                */
-               static int shift = 0;
-               u2 *hashtab;
-               u2 *next; /* for chaining colliding hash entries */
-               size_t len;
-               size_t hashlen;
-               u2 index;
-               u2 old;
-
-               /* Allocate hashtable */
-               len = c->methodscount;
-               if (len < c->fieldscount) len = c->fieldscount;
-               hashlen = 5 * len;
-               hashtab = MNEW(u2,(hashlen + len));
-               next = hashtab + hashlen;
-
-               /* Determine bitshift (to get good hash values) */
-               if (!shift) {
-                       len = sizeof(utf);
-                       while (len) {
-                               len >>= 1;
-                               shift++;
-                       }
-               }
-
-               /* Check fields */
-               memset(hashtab, 0, sizeof(u2) * (hashlen + len));
-
-               for (i = 0; i < c->fieldscount; ++i) {
-                       fieldinfo *fi = c->fields + i;
-
-                       /* It's ok if we lose bits here */
-                       index = ((((size_t) fi->name) +
-                                         ((size_t) fi->descriptor)) >> shift) % hashlen;
-
-                       if ((old = hashtab[index])) {
-                               old--;
-                               next[i] = old;
-                               do {
-                                       if (c->fields[old].name == fi->name &&
-                                               c->fields[old].descriptor == fi->descriptor) {
-                                               exceptions_throw_classformaterror(c, "Repetitive field name/signature");
-                                               goto return_exception;
-                                       }
-                               } while ((old = next[old]));
-                       }
-                       hashtab[index] = i + 1;
-               }
-
-               /* Check methods */
-               memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
-
-               for (i = 0; i < c->methodscount; ++i) {
-                       methodinfo *mi = c->methods + i;
-
-                       /* It's ok if we lose bits here */
-                       index = ((((size_t) mi->name) +
-                                         ((size_t) mi->descriptor)) >> shift) % hashlen;
-
-                       /*{ JOWENN
-                               int dbg;
-                               for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
-                                       printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
-                               }
-                       }*/
-
-                       if ((old = hashtab[index])) {
-                               old--;
-                               next[i] = old;
-                               do {
-                                       if (c->methods[old].name == mi->name &&
-                                               c->methods[old].descriptor == mi->descriptor) {
-                                               exceptions_throw_classformaterror(c, "Repetitive method name/signature");
-                                               goto return_exception;
-                                       }
-                               } while ((old = next[old]));
-                       }
-                       hashtab[index] = i + 1;
-               }
-
-               MFREE(hashtab, u2, (hashlen + len));
-       }
-#endif /* ENABLE_VERIFIER */
-
-       RT_TIMING_GET_TIME(time_verify);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat) {
-               size_classinfo  += sizeof(classinfo*) * c->interfacescount;
-               size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
-               size_methodinfo += sizeof(methodinfo) * c->methodscount;
-       }
-#endif
-
-       /* load attribute structures */
-
-       if (!class_load_attributes(cb))
-               goto return_exception;
-
-       /* Pre Java 1.5 version don't check this. This implementation is like
-          Java 1.5 do it: for class file version 45.3 we don't check it, older
-          versions are checked.
-        */
-
-       if (((ma == 45) && (mi > 3)) || (ma > 45)) {
-               /* check if all data has been read */
-               s4 classdata_left = ((cb->data + cb->size) - cb->pos);
-
-               if (classdata_left > 0) {
-                       exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
-                       goto return_exception;
-               }
-       }
-
-       RT_TIMING_GET_TIME(time_attrs);
-
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       /* revert loading state and class is loaded */
-
-       c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
-
-#if defined(ENABLE_JVMTI)
-       /* fire Class Prepare JVMTI event */
-
-       if (jvmti)
-               jvmti_ClassLoadPrepare(true, c);
-#endif
-
-#if !defined(NDEBUG)
-       if (loadverbose)
-               log_message_class("Loading done class: ", c);
-#endif
-
-       RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
-       RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
-       RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
-       RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
-       RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
-       RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
-       RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
-       RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
-       RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
-       RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
-       RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
-       RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
-       RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
-       RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
-       RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
-
-       return c;
-
-return_exception:
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       /* an exception has been thrown */
-
-       return NULL;
-}
-
-
-/* load_newly_created_array ****************************************************
-
-   Load a newly created array class.
-
-       RETURN VALUE:
-           c....................the array class C has been loaded
-               other classinfo......the array class was found in the class cache, 
-                                    C has been freed
-           NULL.................an exception has been thrown
-
-       Note:
-               This is an internal function. Do not use it unless you know exactly
-               what you are doing!
-
-               Use one of the load_class_... functions for general array class loading.
-
-*******************************************************************************/
-
-classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
-{
-       classinfo         *comp = NULL;
-       methodinfo        *clone;
-       methoddesc        *clonedesc;
-       constant_classref *classrefs;
-       char              *text;
-       s4                 namelen;
-       utf               *u;
-
-       text = c->name->text;
-       namelen = c->name->blength;
-
-       /* Check array class name */
-
-       if (namelen < 2 || text[0] != '[') {
-               *exceptionptr = new_noclassdeffounderror(c->name);
-               return NULL;
-       }
-
-       /* Check the element type */
-
-       switch (text[1]) {
-       case '[':
-               /* c is an array of arrays. We have to create the component class. */
-
-               u = utf_new(text + 1, namelen - 1);
-               if (!(comp = load_class_from_classloader(u, loader)))
-                       return NULL;
-
-               assert(comp->state & CLASS_LOADED);
-
-               if (opt_eager)
-                       if (!link_class(c))
-                               return NULL;
-
-               /* the array's flags are that of the component class */
-               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
-               c->classloader = comp->classloader;
-               break;
-
-       case 'L':
-               /* c is an array of objects. */
-
-               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
-               if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
-                       *exceptionptr = new_noclassdeffounderror(c->name);
-                       return NULL;
-               }
-
-               u = utf_new(text + 2, namelen - 3);
-
-               if (!(comp = load_class_from_classloader(u, loader)))
-                       return NULL;
-
-               assert(comp->state & CLASS_LOADED);
-
-               if (opt_eager)
-                       if (!link_class(c))
-                               return NULL;
-
-               /* the array's flags are that of the component class */
-               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
-               c->classloader = comp->classloader;
-               break;
-
-       default:
-               /* c is an array of a primitive type */
-
-               /* check for cases like `[II' */
-               if (namelen > 2) {
-                       *exceptionptr = new_noclassdeffounderror(c->name);
-                       return NULL;
-               }
-
-               /* the accessibility of the array class is public (VM Spec 5.3.3) */
-               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
-               c->classloader = NULL;
-       }
-
-       assert(class_java_lang_Object);
-#if defined(ENABLE_JAVASE)
-       assert(class_java_lang_Cloneable);
-       assert(class_java_io_Serializable);
-#endif
-
-       /* setup the array class */
-
-       c->super.cls = class_java_lang_Object;
-
-#if defined(ENABLE_JAVASE)
-       c->interfacescount = 2;
-    c->interfaces = MNEW(classref_or_classinfo, 2);
-
-       if (opt_eager) {
-               classinfo *tc;
-
-               tc = class_java_lang_Cloneable;
-               assert(tc->state & CLASS_LOADED);
-               list_add_first(&unlinkedclasses, tc);
-               c->interfaces[0].cls = tc;
-
-               tc = class_java_io_Serializable;
-               assert(tc->state & CLASS_LOADED);
-               list_add_first(&unlinkedclasses, tc);
-               c->interfaces[1].cls = tc;
-       }
-       else {
-               c->interfaces[0].cls = class_java_lang_Cloneable;
-               c->interfaces[1].cls = class_java_io_Serializable;
-       }
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-       c->interfacescount = 0;
-       c->interfaces = NULL;
-#else
-#error unknow java configuration
-#endif
-
-       c->methodscount = 1;
-       c->methods = MNEW(methodinfo, c->methodscount);
-       MZERO(c->methods, methodinfo, c->methodscount);
-
-       classrefs = MNEW(constant_classref, 2);
-       CLASSREF_INIT(classrefs[0], c, c->name);
-       CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
-
-       /* create descriptor for clone method */
-       /* we need one paramslot which is reserved for the 'this' parameter */
-       clonedesc = NEW(methoddesc);
-       clonedesc->returntype.type = TYPE_ADR;
-       clonedesc->returntype.classref = classrefs + 1;
-       clonedesc->returntype.arraydim = 0;
-       /* initialize params to "empty", add real params below in
-          descriptor_params_from_paramtypes */
-       clonedesc->paramcount = 0;
-       clonedesc->paramslots = 0;
-       clonedesc->paramtypes[0].classref = classrefs + 0;
-       clonedesc->params = NULL;
-
-       /* create methodinfo */
-
-       clone = c->methods;
-       MSET(clone, 0, methodinfo, 1);
-
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&clone->header);
-#endif
-
-       /* ATTENTION: if you delete the ACC_NATIVE below, set
-          clone->maxlocals=1 (interpreter related) */
-
-       clone->flags      = ACC_PUBLIC | ACC_NATIVE;
-       clone->name       = utf_clone;
-       clone->descriptor = utf_void__java_lang_Object;
-       clone->parseddesc = clonedesc;
-       clone->class      = c;
-
-       /* parse the descriptor to get the register allocation */
-
-       if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
-               return false;
-
-       clone->code = codegen_createnativestub(BUILTIN_clone, clone);
-
-       /* XXX: field: length? */
-
-       /* array classes are not loaded from class files */
-
-       c->state          |= CLASS_LOADED;
-       c->parseddescs    = (u1 *) clonedesc;
-       c->parseddescsize = sizeof(methodinfo);
-       c->classrefs      = classrefs;
-       c->classrefcount  = 1;
-
-       /* insert class into the loaded class cache */
-       /* XXX free classinfo if NULL returned? */
-
-       return classcache_store(loader, c, true);
-}
-
-
-/* loader_close ****************************************************************
-
-   Frees all resources.
-       
-*******************************************************************************/
-
-void loader_close(void)
-{
-       /* empty */
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/loader.h b/src/vm/loader.h
deleted file mode 100644 (file)
index ee2db94..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* src/vm/loader.h - class loader header
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Christian Thalinger
-
-   $Id: loader.h 6216 2006-12-18 18:21:37Z twisti $
-*/
-
-
-#ifndef _LOADER_H
-#define _LOADER_H
-
-#include "config.h"
-
-#include <stdio.h>
-
-#include "vm/types.h"
-
-
-/* forward typedefs ***********************************************************/
-
-typedef struct classbuffer classbuffer;
-
-
-#include "vm/class.h"
-#include "vm/descriptor.h"
-#include "vm/global.h"
-#include "vm/references.h"
-#include "vm/method.h"
-#include "vm/utf8.h"
-
-
-/* constant pool entries *******************************************************
-
-       All constant pool entries need a data structure which contain the entrys
-       value. In some cases this structure exist already, in the remaining cases
-       this structure must be generated:
-
-               kind                      structure                     generated?
-       ----------------------------------------------------------------------
-    CONSTANT_Class               constant_classref                  yes
-    CONSTANT_Fieldref            constant_FMIref                    yes
-    CONSTANT_Methodref           constant_FMIref                    yes
-    CONSTANT_InterfaceMethodref  constant_FMIref                    yes
-    CONSTANT_String              unicode                             no
-    CONSTANT_Integer             constant_integer                   yes
-    CONSTANT_Float               constant_float                     yes
-    CONSTANT_Long                constant_long                      yes
-    CONSTANT_Double              constant_double                    yes
-    CONSTANT_NameAndType         constant_nameandtype               yes
-    CONSTANT_Utf8                unicode                             no
-    CONSTANT_UNUSED              -
-
-*******************************************************************************/
-
-typedef struct {            /* Integer                                        */
-       s4 value;
-} constant_integer;
-
-       
-typedef struct {            /* Float                                          */
-       float value;
-} constant_float;
-
-
-typedef struct {            /* Long                                           */
-       s8 value;
-} constant_long;
-       
-
-typedef struct {            /* Double                                         */
-       double value;
-} constant_double;
-
-
-typedef struct {            /* NameAndType (Field or Method)                  */
-       utf *name;              /* field/method name                              */
-       utf *descriptor;        /* field/method type descriptor string            */
-} constant_nameandtype;
-
-
-/* classbuffer ****************************************************************/
-
-struct classbuffer {
-       classinfo *class;                   /* pointer to classinfo structure     */
-       u1        *data;                    /* pointer to byte code               */
-       s4         size;                    /* size of the byte code              */
-       u1        *pos;                     /* current read position              */
-       char      *path;                    /* path to file (for debugging)       */
-};
-
-
-/* function prototypes ********************************************************/
-
-/* initialize loader, load important systemclasses */
-bool loader_init(void);
-
-void loader_load_all_classes(void);
-
-bool loader_skip_attribute_body(classbuffer *cb);
-
-#if defined(ENABLE_JAVASE)
-bool loader_load_attribute_signature(classbuffer *cb, utf **signature);
-#endif
-
-/* free resources */
-void loader_close(void);
-
-/* class loading functions */
-classinfo *load_class_from_sysloader(utf *name);
-classinfo *load_class_from_classloader(utf *name, java_objectheader *cl);
-classinfo *load_class_bootstrap(utf *name);
-
-/* (don't use the following directly) */
-classinfo *load_class_from_classbuffer(classbuffer *cb);
-classinfo *load_newly_created_array(classinfo *c,java_objectheader *loader);
-
-#endif /* _LOADER_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/vm/method.c b/src/vm/method.c
deleted file mode 100644 (file)
index 58e0da3..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/* src/vm/method.c - method functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Andreas Krall
-            Roman Obermaiser
-            Mark Probst
-            Edwin Steiner
-            Christian Thalinger
-
-   $Id: method.c 7228 2007-01-19 01:13:48Z edwin $
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "vm/class.h"
-#include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/jit/methodheader.h"
-
-
-#if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code)  do { if (opt_inline_debug_log) { code } } while (0)
-#else
-#define INLINELOG(code)
-#endif
-
-
-/* method_free *****************************************************************
-
-   Frees all memory that was allocated for this method.
-
-*******************************************************************************/
-
-void method_free(methodinfo *m)
-{
-       if (m->jcode)
-               MFREE(m->jcode, u1, m->jcodelength);
-
-       if (m->rawexceptiontable)
-               MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
-
-       code_free_code_of_method(m);
-
-       if (m->stubroutine) {
-               if (m->flags & ACC_NATIVE) {
-                       removenativestub(m->stubroutine);
-
-               } else {
-                       removecompilerstub(m->stubroutine);
-               }
-       }
-}
-
-
-/* method_canoverwrite *********************************************************
-
-   Check if m and old are identical with respect to type and
-   name. This means that old can be overwritten with m.
-       
-*******************************************************************************/
-
-bool method_canoverwrite(methodinfo *m, methodinfo *old)
-{
-       if (m->name != old->name)
-               return false;
-
-       if (m->descriptor != old->descriptor)
-               return false;
-
-       if (m->flags & ACC_STATIC)
-               return false;
-
-       return true;
-}
-
-
-/* method_vftbl_lookup *********************************************************
-
-   Does a method lookup in the passed virtual function table.  This
-   function does exactly the same thing as JIT, but additionally
-   relies on the fact, that the methodinfo pointer is at the first
-   data segment slot (even for compiler stubs).
-
-*******************************************************************************/
-
-methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
-{
-       methodptr   mptr;
-       methodptr  *pmptr;
-       methodinfo *resm;                   /* pointer to new resolved method     */
-       codeinfo   *code;
-
-       /* If the method is not an instance method, just return it. */
-
-       if (m->flags & ACC_STATIC)
-               return m;
-
-       assert(vftbl);
-
-       /* Get the method from the virtual function table.  Is this an
-          interface method? */
-
-       if (m->class->flags & ACC_INTERFACE) {
-               pmptr = vftbl->interfacetable[-(m->class->index)];
-               mptr  = pmptr[(m - m->class->methods)];
-       }
-       else {
-               mptr = vftbl->table[m->vftblindex];
-       }
-
-       /* and now get the codeinfo pointer from the first data segment slot */
-
-       code = *((codeinfo **) (mptr + CodeinfoPointer));
-
-       resm = code->m;
-
-       return resm;
-}
-
-
-/* method_count_implementations ************************************************
-
-   Count the implementations of a method in a class cone (a class and all its
-   subclasses.)
-
-   IN:
-       m................the method to count
-          c................class at which to start the counting (this class and
-                           all its subclasses will be searched)
-
-   OUT:
-       *found...........if found != NULL, *found receives the method
-                           implementation that was found. This value is only
-                                               meaningful if the return value is 1.
-
-   RETURN VALUE:
-       the number of implementations found
-
-*******************************************************************************/
-
-s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
-{
-       s4          count;
-       methodinfo *mp;
-       methodinfo *mend;
-       classinfo  *child;
-
-       count = 0;
-
-       mp = c->methods;
-       mend = mp + c->methodscount;
-
-       for (; mp < mend; ++mp) {
-               if (method_canoverwrite(mp, m)) {
-                       if (found)
-                               *found = mp;
-                       count++;
-                       break;
-               }
-       }
-
-       for (child = c->sub; child != NULL; child = child->nextsub) {
-               count += method_count_implementations(m, child, found);
-       }
-
-       return count;
-}
-
-
-/* method_add_to_worklist ******************************************************
-
-   Add the method to the given worklist. If the method already occurs in
-   the worklist, the worklist remains unchanged.
-
-*******************************************************************************/
-
-static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
-{
-       method_worklist *wi;
-
-       for (wi = *wl; wi != NULL; wi = wi->next)
-               if (wi->m == m)
-                       return;
-
-       wi = NEW(method_worklist);
-       wi->next = *wl;
-       wi->m = m;
-
-       *wl = wi;
-}
-
-
-/* method_add_assumption_monomorphic *******************************************
-
-   Record the assumption that the method is monomorphic.
-
-   IN:
-      m.................the method
-         caller............the caller making the assumption
-
-*******************************************************************************/
-
-void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
-{
-       method_assumption *as;
-
-       /* XXX LOCKING FOR THIS FUNCTION? */
-
-       /* check if we already have registered this assumption */
-
-       for (as = m->assumptions; as != NULL; as = as->next) {
-               if (as->context == caller)
-                       return;
-       }
-
-       /* register the assumption */
-
-       as = NEW(method_assumption);
-       as->next = m->assumptions;
-       as->context = caller;
-
-       m->assumptions = as;
-}
-
-
-/* method_break_assumption_monomorphic *****************************************
-
-   Break the assumption that this method is monomorphic. All callers that
-   have registered this assumption are added to the worklist.
-
-   IN:
-      m.................the method
-         wl................worklist where to add invalidated callers
-
-*******************************************************************************/
-
-void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
-{
-       method_assumption *as;
-
-       /* XXX LOCKING FOR THIS FUNCTION? */
-
-       for (as = m->assumptions; as != NULL; as = as->next) {
-               INLINELOG(
-                       printf("ASSUMPTION BROKEN (monomorphism): ");
-                       method_print(m);
-                       printf(" in ");
-                       method_println(as->context);
-               );
-
-               method_add_to_worklist(as->context, wl);
-       }
-}
-
-
-/* method_printflags ***********************************************************
-
-   Prints the flags of a method to stdout like.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_printflags(methodinfo *m)
-{
-       if (m == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       if (m->flags & ACC_PUBLIC)       printf(" PUBLIC");
-       if (m->flags & ACC_PRIVATE)      printf(" PRIVATE");
-       if (m->flags & ACC_PROTECTED)    printf(" PROTECTED");
-       if (m->flags & ACC_STATIC)       printf(" STATIC");
-       if (m->flags & ACC_FINAL)        printf(" FINAL");
-       if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
-       if (m->flags & ACC_VOLATILE)     printf(" VOLATILE");
-       if (m->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
-       if (m->flags & ACC_NATIVE)       printf(" NATIVE");
-       if (m->flags & ACC_INTERFACE)    printf(" INTERFACE");
-       if (m->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
-       if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
-       if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_print ****************************************************************
-
-   Prints a method to stdout like:
-
-   java.lang.Object.<init>()V
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_print(methodinfo *m)
-{
-       if (m == NULL) {
-               printf("NULL");
-               return;
-       }
-
-       utf_display_printable_ascii_classname(m->class->name);
-       printf(".");
-       utf_display_printable_ascii(m->name);
-       utf_display_printable_ascii(m->descriptor);
-
-       method_printflags(m);
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_println **************************************************************
-
-   Prints a method plus new line to stdout like:
-
-   java.lang.Object.<init>()V
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_println(methodinfo *m)
-{
-       if (opt_debugcolor) printf("\033[31m"); /* red */
-       method_print(m);
-       if (opt_debugcolor) printf("\033[m");   
-       printf("\n");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_methodref_print ******************************************************
-
-   Prints a method reference to stdout.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_methodref_print(constant_FMIref *mr)
-{
-       if (!mr) {
-               printf("(constant_FMIref *)NULL");
-               return;
-       }
-
-       if (IS_FMIREF_RESOLVED(mr)) {
-               printf("<method> ");
-               method_print(mr->p.method);
-       }
-       else {
-               printf("<methodref> ");
-               utf_display_printable_ascii_classname(mr->p.classref->name);
-               printf(".");
-               utf_display_printable_ascii(mr->name);
-               utf_display_printable_ascii(mr->descriptor);
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* method_methodref_println ****************************************************
-
-   Prints a method reference to stdout, followed by a newline.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void method_methodref_println(constant_FMIref *mr)
-{
-       method_methodref_print(mr);
-       printf("\n");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/*
- * 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:
- */
diff --git a/src/vm/method.h b/src/vm/method.h
deleted file mode 100644 (file)
index 4dd819b..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* src/vm/method.h - method functions header
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: method.h 6273 2007-01-03 22:20:25Z edwin $
-*/
-
-
-#ifndef _METHOD_H
-#define _METHOD_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct methodinfo          methodinfo; 
-typedef struct raw_exception_entry raw_exception_entry;
-typedef struct lineinfo            lineinfo; 
-typedef struct method_assumption   method_assumption;
-typedef struct method_worklist     method_worklist;
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/descriptor.h"
-#include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/references.h"
-
-#if defined(ENABLE_JAVASE)
-# include "vm/stackmap.h"
-#endif
-
-#include "vm/utf8.h"
-#include "vm/jit/code.h"
-#include "vm/jit/jit.h"
-
-
-/* methodinfo *****************************************************************/
-
-struct methodinfo {                 /* method structure                       */
-       java_objectheader header;       /* we need this in jit's monitorenter     */
-       s4            flags;            /* ACC flags                              */
-       utf          *name;             /* name of method                         */
-       utf          *descriptor;       /* JavaVM descriptor string of method     */
-#if defined(ENABLE_JAVASE)
-       utf          *signature;        /* Signature attribute                    */
-       stack_map_t  *stack_map;        /* StackMapTable attribute                */
-#endif
-
-       methoddesc   *parseddesc;       /* parsed descriptor                      */
-                            
-       classinfo    *class;            /* class, the method belongs to           */
-       s4            vftblindex;       /* index of method in virtual function    */
-                                       /* table (if it is a virtual method)      */
-       s4            maxstack;         /* maximum stack depth of method          */
-       s4            maxlocals;        /* maximum number of local variables      */
-       s4            jcodelength;      /* length of JavaVM code                  */
-       u1           *jcode;            /* pointer to JavaVM code                 */
-
-       s4            rawexceptiontablelength;  /* exceptiontable length          */
-       raw_exception_entry *rawexceptiontable; /* the exceptiontable             */
-
-       u2            thrownexceptionscount; /* number of exceptions attribute    */
-       classref_or_classinfo *thrownexceptions; /* except. a method may throw    */
-
-       u2            linenumbercount;  /* number of linenumber attributes        */
-       lineinfo     *linenumbers;      /* array of lineinfo items                */
-
-       u1           *stubroutine;      /* stub for compiling or calling natives  */
-       codeinfo     *code;             /* current code of this method            */
-
-#if defined(ENABLE_LSRA)
-       s4            maxlifetimes;     /* helper for lsra                        */
-#endif
-
-       methodinfo   *overwrites;       /* method that is directly overwritten    */
-       method_assumption *assumptions; /* list of assumptions about this method  */
-};
-
-
-/* method_assumption ***********************************************************
-
-   This struct is used for registering assumptions about methods.
-
-*******************************************************************************/
-
-struct method_assumption {
-       method_assumption *next;
-       methodinfo        *context;
-};
-
-
-/* method_worklist *************************************************************
-
-   List node used for method worklists.
-
-*******************************************************************************/
-
-struct method_worklist {
-       method_worklist *next;
-       methodinfo      *m;
-};
-
-
-/* raw_exception_entry ********************************************************/
-
-/* exception table entry read by the loader */
-
-struct raw_exception_entry {    /* exceptiontable entry in a method           */
-       classref_or_classinfo catchtype; /* catchtype of exc. (0 == catchall)     */
-       u2              startpc;    /* start pc of guarded area (inclusive)       */
-       u2              endpc;      /* end pc of guarded area (exklusive)         */
-       u2              handlerpc;  /* pc of exception handler                    */
-};
-
-
-/* lineinfo *******************************************************************/
-
-struct lineinfo {
-       u2 start_pc;
-       u2 line_number;
-};
-
-
-/* function prototypes ********************************************************/
-
-void method_free(methodinfo *m);
-bool method_canoverwrite(methodinfo *m, methodinfo *old);
-
-methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m);
-
-void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller);
-void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl);
-
-s4   method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found);
-
-#if !defined(NDEBUG)
-void method_printflags(methodinfo *m);
-void method_print(methodinfo *m);
-void method_println(methodinfo *m);
-void method_methodref_print(constant_FMIref *mr);
-void method_methodref_println(constant_FMIref *mr);
-#endif
-
-#endif /* _METHOD_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/vm/options.c b/src/vm/options.c
deleted file mode 100644 (file)
index 17d063c..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/* src/vm/options.c - contains global options
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: options.c 7228 2007-01-19 01:13:48Z edwin $
-
-*/
-
-
-#include "config.h"
-
-#include <string.h>
-#include <limits.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "native/jni.h"
-#include "vm/options.h"
-
-
-/* command line option ********************************************************/
-
-s4    opt_index = 0;            /* index of processed arguments               */
-char *opt_arg;                  /* this one exports the option argument       */
-
-bool opt_foo = false;           /* option for development                     */
-
-bool opt_jar = false;
-
-#if defined(ENABLE_JIT)
-bool opt_jit = true;            /* JIT mode execution (default)               */
-bool opt_intrp = false;         /* interpreter mode execution                 */
-#else
-bool opt_jit = false;           /* JIT mode execution                         */
-bool opt_intrp = true;          /* interpreter mode execution (default)       */
-#endif
-
-bool opt_run = true;
-
-s4   opt_heapmaxsize   = 0;     /* maximum heap size                          */
-s4   opt_heapstartsize = 0;     /* initial heap size                          */
-s4   opt_stacksize     = 0;     /* thread stack size                          */
-
-bool opt_verbose = false;
-bool opt_debugcolor = false;   /* use ANSI terminal sequences                */
-bool compileall = false;
-
-bool loadverbose = false;
-bool linkverbose = false;
-bool initverbose = false;
-
-bool opt_verboseclass     = false;
-bool opt_verbosegc        = false;
-bool opt_verbosejni       = false;
-bool opt_verbosecall      = false;      /* trace all method invocation        */
-bool opt_verboseexception = false;
-
-bool showmethods = false;
-bool showconstantpool = false;
-bool showutf = false;
-
-char *opt_method = NULL;
-char *opt_signature = NULL;
-
-bool compileverbose =  false;           /* trace compiler actions             */
-bool showstack = false;
-
-bool opt_showdisassemble    = false;    /* generate disassembler listing      */
-bool opt_shownops           = false;
-bool opt_showddatasegment   = false;    /* generate data segment listing      */
-bool opt_showintermediate   = false;    /* generate intermediate code listing */
-bool opt_showexceptionstubs = false;
-bool opt_shownativestub     = false;
-
-bool checkbounds = true;       /* check array bounds                         */
-bool checknull = true;         /* check null pointers                        */
-bool opt_noieee = false;       /* don't implement ieee compliant floats      */
-bool checksync = true;         /* do synchronization                         */
-#if defined(ENABLE_LOOP)
-bool opt_loops = false;        /* optimize array accesses in loops           */
-#endif
-
-bool makeinitializations = true;
-
-#if defined(ENABLE_STATISTICS)
-bool opt_stat    = false;
-bool opt_getloadingtime = false;   /* to measure the runtime                 */
-bool opt_getcompilingtime = false; /* compute compile time                   */
-#endif
-#if defined(ENABLE_VERIFIER)
-bool opt_verify  = true;       /* true if classfiles should be verified      */
-#endif
-bool opt_eager   = false;
-
-#if defined(ENABLE_PROFILING)
-bool opt_prof    = false;
-bool opt_prof_bb = false;
-#endif
-
-
-/* inlining options ***********************************************************/
-
-#if defined(ENABLE_INLINING)
-bool opt_inlining = false;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-s4 opt_replace_verbose = 0;
-s4 opt_inline_debug_min_size = 0;
-s4 opt_inline_debug_max_size = INT_MAX;
-s4 opt_inline_debug_end_counter = INT_MAX;
-bool opt_inline_debug_all = false;
-#endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
-#if !defined(NDEBUG)
-bool opt_inline_debug_log = false;
-#endif /* !defined(NDEBUG) */
-#endif /* defined(ENABLE_INLINING) */
-
-
-/* optimization options *******************************************************/
-
-#if defined(ENABLE_IFCONV)
-bool opt_ifconv = false;
-#endif
-
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-bool opt_lsra = false;
-#endif
-
-
-/* interpreter options ********************************************************/
-
-#if defined(ENABLE_INTRP)
-bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
-bool opt_no_replication = false;        /* don't use replication in intrp     */
-bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
-                                                                                  part of dynamic superinstructions */
-
-s4   opt_static_supers = 0x7fffffff;
-bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
-#endif
-
-
-/* options_get *****************************************************************
-
-   DOCUMENT ME!!!
-
-*******************************************************************************/
-
-s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
-{
-       char *option;
-       s4    i;
-
-       if (opt_index >= vm_args->nOptions)
-               return OPT_DONE;
-
-       /* get the current option */
-
-       option = vm_args->options[opt_index].optionString;
-
-       if ((option == NULL) || (option[0] != '-'))
-               return OPT_DONE;
-
-       for (i = 0; opts[i].name; i++) {
-               if (!opts[i].arg) {
-                       /* boolean option found */
-
-                       if (strcmp(option + 1, opts[i].name) == 0) {
-                               opt_index++;
-                               return opts[i].value;
-                       }
-
-               } else {
-                       /* parameter option found */
-
-                       /* with a space between */
-
-                       if (strcmp(option + 1, opts[i].name) == 0) {
-                               opt_index++;
-
-                               if (opt_index < vm_args->nOptions) {
-                                       opt_arg = strdup(vm_args->options[opt_index].optionString);
-                                       opt_index++;
-                                       return opts[i].value;
-                               }
-
-                               return OPT_ERROR;
-
-                       } else {
-                               /* parameter and option have no space between */
-
-                               /* FIXME: this assumption is plain wrong, hits you if there is a
-                                * parameter with no argument starting with same letter as param with argument
-                                * but named after that one, ouch! */
-
-                               size_t l = strlen(opts[i].name);
-
-                               if (strlen(option + 1) > l) {
-                                       if (memcmp(option + 1, opts[i].name, l) == 0) {
-                                               opt_index++;
-                                               opt_arg = strdup(option + 1 + l);
-                                               return opts[i].value;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return OPT_ERROR;
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/options.h b/src/vm/options.h
deleted file mode 100644 (file)
index 983083c..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/* src/vm/options.h - define global options extern
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: options.h 7228 2007-01-19 01:13:48Z edwin $
-
-*/
-
-
-#ifndef _OPTIONS_H
-#define _OPTIONS_H
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "native/jni.h"
-#include "vm/global.h"
-
-
-/* reserved option numbers ****************************************************/
-
-/* define these negative since the other options are an enum */
-
-#define OPT_DONE       -1
-#define OPT_ERROR      -2
-#define OPT_IGNORE     -3
-
-
-typedef struct opt_struct opt_struct;
-
-struct opt_struct {
-       char *name;
-       bool  arg;
-       int   value;
-};
-
-
-/* global variables ***********************************************************/
-
-extern s4    opt_index;
-extern char *opt_arg;
-
-extern bool opt_foo;
-
-extern bool opt_jit;
-extern bool opt_intrp;
-
-extern bool opt_jar;
-extern bool opt_run;
-
-extern s4   opt_heapmaxsize;
-extern s4   opt_heapstartsize;
-extern s4   opt_stacksize;
-
-extern bool opt_verbose;
-extern bool opt_debugcolor;
-extern bool compileall;
-
-extern bool loadverbose;         /* Print debug messages during loading */
-extern bool linkverbose;
-extern bool initverbose;         /* Log class initialization */ 
-
-extern bool opt_verboseclass;
-extern bool opt_verbosegc;
-extern bool opt_verbosejni;
-extern bool opt_verbosecall;
-extern bool opt_verboseexception;
-
-extern bool showmethods;
-extern bool showconstantpool;
-extern bool showutf;
-
-extern char *opt_method;
-extern char *opt_signature;
-
-extern bool compileverbose;
-extern bool showstack;
-
-extern bool opt_showdisassemble;
-extern bool opt_shownops;
-extern bool opt_showddatasegment;
-extern bool opt_showintermediate;
-extern bool opt_showexceptionstubs;
-extern bool opt_shownativestub;
-
-extern bool checkbounds;
-extern bool checknull;
-extern bool opt_noieee;
-extern bool checksync;
-#if defined(ENABLE_LOOP)
-extern bool opt_loops;
-#endif
-
-extern bool makeinitializations;
-
-#if defined(ENABLE_STATISTICS)
-extern bool opt_stat;
-extern bool opt_getloadingtime;
-extern bool opt_getcompilingtime;
-#endif
-#if defined(ENABLE_VERIFIER)
-extern bool opt_verify;
-#endif
-extern bool opt_eager;
-
-#if defined(ENABLE_PROFILING)
-extern bool opt_prof;
-extern bool opt_prof_bb;
-#endif
-
-/* inlining options ***********************************************************/
-
-#if defined(ENABLE_INLINING)
-extern bool opt_inlining;
-#if defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG)
-extern s4 opt_replace_verbose;
-extern s4 opt_inline_debug_min_size;
-extern s4 opt_inline_debug_max_size;
-extern s4 opt_inline_debug_end_counter;
-extern bool opt_inline_debug_all;
-#endif /* defined(ENABLE_INLINING_DEBUG) || !defined(NDEBUG) */
-#if !defined(NDEBUG)
-extern bool opt_inline_debug_log;
-#endif /* !defined(NDEBUG) */
-#endif /* defined(ENABLE_INLINING) */
-
-
-/* optimization options *******************************************************/
-
-#if defined(ENABLE_IFCONV)
-extern bool opt_ifconv;
-#endif
-
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-extern bool opt_lsra;
-#endif
-
-
-/* interpreter options ********************************************************/
-
-#if defined(ENABLE_INTRP)
-extern bool opt_no_dynamic;
-extern bool opt_no_replication;
-extern bool opt_no_quicksuper;
-
-extern s4   opt_static_supers;
-extern bool vm_debug;
-#endif
-
-
-/* function prototypes ********************************************************/
-
-s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args);
-
-#endif /* _OPTIONS_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:
- */
index ba2935e520e69df2a869f0802c13ff557c923b1c..6e85df5b3b2375649abcf5d3878885caeaa3b261 100644 (file)
@@ -22,7 +22,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: properties.c 7234 2007-01-22 17:03:04Z twisti $
+   $Id: properties.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "vm/global.h"
 #include "native/include/java_lang_String.h"
 
-#if defined(ENABLE_JAVASE)
-# include "native/include/java_util_Properties.h"
-#endif
-
 #include "toolbox/list.h"
 #include "toolbox/util.h"
-#include "vm/method.h"
-#include "vm/options.h"
+
 #include "vm/properties.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
 
 /* internal property structure ************************************************/
 
@@ -376,9 +375,9 @@ char *properties_get(char *key)
 
 void properties_system_add(java_objectheader *p, char *key, char *value)
 {
-       methodinfo       *m;
-       java_lang_String *k;
-       java_lang_String *v;
+       methodinfo        *m;
+       java_objectheader *k;
+       java_objectheader *v;
 
        /* search for method to add properties */
 
@@ -405,19 +404,22 @@ void properties_system_add(java_objectheader *p, char *key, char *value)
    Adds all properties from the properties list to the Java system
    properties.
 
+   ARGUMENTS:
+       p.... is actually a java_util_Properties structure
+
 *******************************************************************************/
 
 #if defined(ENABLE_JAVASE)
-void properties_system_add_all(java_util_Properties *p)
+void properties_system_add_all(java_objectheader *p)
 {
        list_properties_entry *pe;
        methodinfo            *m;
-       java_lang_String      *key;
-       java_lang_String      *value;
+       java_objectheader     *key;
+       java_objectheader     *value;
 
        /* search for method to add properties */
 
-       m = class_resolveclassmethod(p->header.vftbl->class,
+       m = class_resolveclassmethod(p->vftbl->class,
                                                                 utf_put,
                                                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
                                                                 NULL,
index 42769336e01b05046cdf4be05ebbe8c69fbf70ee..0c2defa1916d26e2abfe0e9893479357a7168319 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: properties.h 7234 2007-01-22 17:03:04Z twisti $
+   $Id: properties.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 #include "config.h"
 #include "vm/types.h"
 
-#if defined(ENABLE_JAVASE)
-# include "native/jni.h"
-# include "native/include/java_util_Properties.h"
-#endif
-
 #include "vm/global.h"
 
 
@@ -56,7 +47,7 @@ char *properties_get(char *key);
 void  properties_system_add(java_objectheader *p, char *key, char *value);
 
 #if defined(ENABLE_JAVASE)
-void  properties_system_add_all(java_util_Properties *p);
+void  properties_system_add_all(java_objectheader *p);
 #endif
 
 #endif /* _PROPERTIES_H */
diff --git a/src/vm/references.h b/src/vm/references.h
deleted file mode 100644 (file)
index 25569b8..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/* src/vm/references.h - references to classes/fields/methods
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-            Christian Thalinger
-
-   $Id: references.h 6012 2006-11-16 19:45:15Z twisti $
-
-*/
-
-#ifndef _REFERENCES_H_
-#define _REFERENCES_H_
-
-/* forward typedefs ***********************************************************/
-
-typedef struct constant_classref constant_classref;
-typedef struct constant_FMIref   constant_FMIref;
-
-
-/* constant_classref **********************************************************/
-
-struct constant_classref {
-       void             *pseudo_vftbl; /* for distinguishing it from classinfo   */
-       struct classinfo *referer;    /* class containing the reference           */
-       struct utf       *name;       /* name of the class refered to             */
-};
-
-
-/* classref_or_classinfo ******************************************************/
-
-typedef union classref_or_classinfo {
-       constant_classref *ref;       /* a symbolic class reference               */
-       struct classinfo  *cls;       /* an already loaded class                  */
-       void              *any;       /* used for general access (x != NULL,...)  */
-} classref_or_classinfo;
-
-
-/* parseddesc *****************************************************************/
-
-typedef union parseddesc {
-       struct typedesc   *fd;        /* parsed field descriptor                  */
-       struct methoddesc *md;        /* parsed method descriptor                 */
-       void              *any;       /* used for simple test against NULL        */
-} parseddesc;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/class.h"
-#include "vm/descriptor.h"
-#include "vm/field.h"
-#include "vm/global.h"
-#include "vm/method.h"
-#include "vm/utf8.h"
-
-
-/*----------------------------------------------------------------------------*/
-/* References                                                                 */
-/*                                                                            */
-/* This header files defines the following types used for references to       */
-/* classes/methods/fields and descriptors:                                    */
-/*                                                                            */
-/*     classinfo *                a loaded class                              */
-/*     constant_classref          a symbolic reference                        */
-/*     classref_or_classinfo      a loaded class or a symbolic reference      */
-/*                                                                            */
-/*     constant_FMIref            a symb. ref. to a field/method/intf.method  */
-/*                                                                            */
-/*     typedesc *                 describes a field type                      */
-/*     methoddesc *               descrives a method type                     */
-/*     parseddesc                 describes a field type or a method type     */
-/*----------------------------------------------------------------------------*/
-
-/* structs ********************************************************************/
-
-/* constant_FMIref ************************************************************/
-
-struct constant_FMIref{     /* Fieldref, Methodref and InterfaceMethodref     */
-       union {
-               s4                 index;     /* used only within the loader          */
-               constant_classref *classref;  /* class having this field/meth./intfm. */
-               fieldinfo         *field;     /* resolved field                       */
-               methodinfo        *method;    /* resolved method                      */
-       } p;
-       utf       *name;        /* field/method/interfacemethod name              */
-       utf       *descriptor;  /* field/method/intfmeth. type descriptor string  */
-       parseddesc parseddesc;  /* parsed descriptor                              */
-};
-
-
-/* macros *********************************************************************/
-
-/* a value that never occurrs in classinfo.header.vftbl                       */
-#define CLASSREF_PSEUDO_VFTBL ((void *) 1)
-
-/* macro for testing if a classref_or_classinfo is a classref                 */
-/* `reforinfo` is only evaluated once                                         */
-#define IS_CLASSREF(reforinfo)  \
-       ((reforinfo).ref->pseudo_vftbl == CLASSREF_PSEUDO_VFTBL)
-
-/* macro for testing if a constant_FMIref has been resolved                   */
-/* `fmiref` is only evaluated once                                            */
-#define IS_FMIREF_RESOLVED(fmiref)  \
-       ((fmiref)->p.classref->pseudo_vftbl != CLASSREF_PSEUDO_VFTBL)
-
-/* the same as IS_CLASSREF, but also check against NULL */
-#define IS_XCLASSREF(reforinfo)  \
-       ((reforinfo).any && IS_CLASSREF(reforinfo))
-
-/* macro for casting a classref/classinfo * to a classref_or_classinfo        */
-#define CLASSREF_OR_CLASSINFO(value) \
-       (*((classref_or_classinfo *)(&(value))))
-
-/* macro for accessing the name of a classref/classinfo                       */
-#define CLASSREF_OR_CLASSINFO_NAME(value) \
-       (IS_CLASSREF(value) ? (value).ref->name : (value).cls->name)
-
-/* macro for accessing the class name of a method reference                   */
-#define METHODREF_CLASSNAME(fmiref) \
-       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->class->name \
-                                                               : (fmiref)->p.classref->name)
-
-/* macro for accessing the class name of a method reference                   */
-#define FIELDREF_CLASSNAME(fmiref) \
-       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->class->name \
-                                                               : (fmiref)->p.classref->name)
-
-/* initialize a constant_classref with referer `ref` and name `classname`     */
-
-#define CLASSREF_INIT(c,ref,classname) \
-    do { \
-        (c).pseudo_vftbl = CLASSREF_PSEUDO_VFTBL; \
-        (c).referer = (ref); \
-        (c).name = (classname); \
-    } while (0)
-
-#endif /* _REFERENCES_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
-
diff --git a/src/vm/resolve.c b/src/vm/resolve.c
deleted file mode 100644 (file)
index 31544d8..0000000
+++ /dev/null
@@ -1,2995 +0,0 @@
-/* src/vm/resolve.c - resolving classes/interfaces/fields/methods
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: Christan Thalinger
-
-   $Id: resolve.c 6244 2006-12-27 15:15:31Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-
-#include "mm/memory.h"
-#include "vm/resolve.h"
-#include "vm/access.h"
-#include "vm/classcache.h"
-#include "vm/descriptor.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/stringlocal.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/verify/typeinfo.h"
-
-
-/******************************************************************************/
-/* DEBUG HELPERS                                                              */
-/******************************************************************************/
-
-/*#define RESOLVE_VERBOSE*/
-
-/******************************************************************************/
-/* CLASS RESOLUTION                                                           */
-/******************************************************************************/
-
-/* resolve_class_from_name *****************************************************
-   Resolve a symbolic class reference
-  
-   IN:
-       referer..........the class containing the reference
-       refmethod........the method from which resolution was triggered
-                        (may be NULL if not applicable)
-       classname........class name to resolve
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-          checkaccess......if true, access rights to the class are checked
-          link.............if true, guarantee that the returned class, if any,
-                           has been linked
-  
-   OUT:
-       *result..........set to result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-                        (*result may still be NULL for resolveLazy)
-       false............an exception has been thrown
-
-   NOTE:
-       The returned class is *not* guaranteed to be linked!
-          (It is guaranteed to be loaded, though.)
-   
-*******************************************************************************/
-
-bool resolve_class_from_name(classinfo *referer,
-                                                        methodinfo *refmethod,
-                                                        utf *classname,
-                                                        resolve_mode_t mode,
-                                                        bool checkaccess,
-                                                        bool link,
-                                                        classinfo **result)
-{
-       classinfo *cls = NULL;
-       char *utf_ptr;
-       int len;
-       
-       assert(result);
-       assert(referer);
-       assert(classname);
-       assert(mode == resolveLazy || mode == resolveEager);
-       
-       *result = NULL;
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_class_from_name(");
-       utf_fprint_printable_ascii(stdout,referer->name);
-       printf(",%p,",(void*)referer->classloader);
-       utf_fprint_printable_ascii(stdout,classname);
-       printf(",%d,%d)\n",(int)checkaccess,(int)link);
-#endif
-
-       /* lookup if this class has already been loaded */
-
-       cls = classcache_lookup(referer->classloader, classname);
-
-#ifdef RESOLVE_VERBOSE
-       printf("    lookup result: %p\n",(void*)cls);
-#endif
-
-       if (!cls) {
-               /* resolve array types */
-
-               if (classname->text[0] == '[') {
-                       utf_ptr = classname->text + 1;
-                       len = classname->blength - 1;
-
-                       /* classname is an array type name */
-
-                       switch (*utf_ptr) {
-                               case 'L':
-                                       utf_ptr++;
-                                       len -= 2;
-                                       /* FALLTHROUGH */
-                               case '[':
-                                       /* the component type is a reference type */
-                                       /* resolve the component type */
-                                       if (!resolve_class_from_name(referer,refmethod,
-                                                                          utf_new(utf_ptr,len),
-                                                                          mode,checkaccess,link,&cls))
-                                               return false; /* exception */
-                                       if (!cls) {
-                                               assert(mode == resolveLazy);
-                                               return true; /* be lazy */
-                                       }
-                                       /* create the array class */
-                                       cls = class_array_of(cls,false);
-                                       if (!cls)
-                                               return false; /* exception */
-                       }
-               }
-               else {
-                       /* the class has not been loaded, yet */
-                       if (mode == resolveLazy)
-                               return true; /* be lazy */
-               }
-
-#ifdef RESOLVE_VERBOSE
-               printf("    loading...\n");
-#endif
-
-               /* load the class */
-               if (!cls) {
-                       if (!(cls = load_class_from_classloader(classname,
-                                                                                                       referer->classloader)))
-                               return false; /* exception */
-               }
-       }
-
-       /* the class is now loaded */
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-
-#ifdef RESOLVE_VERBOSE
-       printf("    checking access rights...\n");
-#endif
-       
-       /* check access rights of referer to refered class */
-       if (checkaccess && !access_is_accessible_class(referer,cls)) {
-               int msglen;
-               char *message;
-
-               msglen = utf_bytes(cls->name) + utf_bytes(referer->name) + 100;
-               message = MNEW(char, msglen);
-               strcpy(message, "class is not accessible (");
-               utf_cat_classname(message, cls->name);
-               strcat(message, " from ");
-               utf_cat_classname(message, referer->name);
-               strcat(message, ")");
-               *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
-               MFREE(message,char,msglen);
-               return false; /* exception */
-       }
-
-       /* link the class if necessary */
-       if (link) {
-               if (!(cls->state & CLASS_LINKED))
-                       if (!link_class(cls))
-                               return false; /* exception */
-
-               assert(cls->state & CLASS_LINKED);
-       }
-
-       /* resolution succeeds */
-#ifdef RESOLVE_VERBOSE
-       printf("    success.\n");
-#endif
-       *result = cls;
-       return true;
-}
-
-/* resolve_classref ************************************************************
-   Resolve a symbolic class reference
-  
-   IN:
-       refmethod........the method from which resolution was triggered
-                        (may be NULL if not applicable)
-       ref..............class reference
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-          checkaccess......if true, access rights to the class are checked
-          link.............if true, guarantee that the returned class, if any,
-                           has been linked
-  
-   OUT:
-       *result..........set to result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-                        (*result may still be NULL for resolveLazy)
-       false............an exception has been thrown
-   
-*******************************************************************************/
-
-bool resolve_classref(methodinfo *refmethod,
-                                         constant_classref *ref,
-                                         resolve_mode_t mode,
-                                         bool checkaccess,
-                                         bool link,
-                                         classinfo **result)
-{
-       return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
-}
-
-/* resolve_classref_or_classinfo ***********************************************
-   Resolve a symbolic class reference if necessary
-  
-   IN:
-       refmethod........the method from which resolution was triggered
-                        (may be NULL if not applicable)
-       cls..............class reference or classinfo
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-          checkaccess......if true, access rights to the class are checked
-          link.............if true, guarantee that the returned class, if any,
-                           has been linked
-  
-   OUT:
-       *result..........set to result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-                        (*result may still be NULL for resolveLazy)
-       false............an exception has been thrown
-   
-*******************************************************************************/
-
-bool resolve_classref_or_classinfo(methodinfo *refmethod,
-                                                                  classref_or_classinfo cls,
-                                                                  resolve_mode_t mode,
-                                                                  bool checkaccess,
-                                                                  bool link,
-                                                                  classinfo **result)
-{
-       classinfo         *c;
-       
-       assert(cls.any);
-       assert(mode == resolveEager || mode == resolveLazy);
-       assert(result);
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_classref_or_classinfo(");
-       utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
-       printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
-#endif
-
-       *result = NULL;
-
-       if (IS_CLASSREF(cls)) {
-               /* we must resolve this reference */
-
-               if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
-                                                                        mode, checkaccess, link, &c))
-                       goto return_exception;
-
-       } else {
-               /* cls has already been resolved */
-               c = cls.cls;
-               assert(c->state & CLASS_LOADED);
-       }
-       assert(c || (mode == resolveLazy));
-
-       if (!c)
-               return true; /* be lazy */
-       
-       assert(c);
-       assert(c->state & CLASS_LOADED);
-
-       if (link) {
-               if (!(c->state & CLASS_LINKED))
-                       if (!link_class(c))
-                               goto return_exception;
-
-               assert(c->state & CLASS_LINKED);
-       }
-
-       /* succeeded */
-       *result = c;
-       return true;
-
- return_exception:
-       *result = NULL;
-       return false;
-}
-
-
-/* resolve_class_from_typedesc *************************************************
-   Return a classinfo * for the given type descriptor
-  
-   IN:
-       d................type descriptor
-          checkaccess......if true, access rights to the class are checked
-          link.............if true, guarantee that the returned class, if any,
-                           has been linked
-   OUT:
-       *result..........set to result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-       false............an exception has been thrown
-
-   NOTE:
-       This function always resolves eagerly.
-   
-*******************************************************************************/
-
-bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
-{
-       classinfo *cls;
-       
-       assert(d);
-       assert(result);
-
-       *result = NULL;
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_class_from_typedesc(");
-       descriptor_debug_print_typedesc(stdout,d);
-       printf(",%i,%i)\n",(int)checkaccess,(int)link);
-#endif
-
-       if (d->type == TYPE_ADR) {
-               /* a reference type */
-               assert(d->classref);
-               if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
-                                                                                  resolveEager,checkaccess,link,&cls))
-                       return false; /* exception */
-       }
-       else {
-               /* a primitive type */
-               cls = primitivetype_table[d->decltype].class_primitive;
-               assert(cls->state & CLASS_LOADED);
-               if (!(cls->state & CLASS_LINKED))
-                       if (!link_class(cls))
-                               return false; /* exception */
-       }
-       assert(cls);
-       assert(cls->state & CLASS_LOADED);
-       assert(!link || (cls->state & CLASS_LINKED));
-
-#ifdef RESOLVE_VERBOSE
-       printf("    result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
-#endif
-
-       *result = cls;
-       return true;
-}
-
-/******************************************************************************/
-/* SUBTYPE SET CHECKS                                                         */
-/******************************************************************************/
-
-/* resolve_subtype_check *******************************************************
-   Resolve the given types lazily and perform a subtype check
-  
-   IN:
-       refmethod........the method triggering the resolution
-       subtype..........checked to be a subtype of supertype
-          supertype........the super type to check agaings
-          mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-       error............which type of exception to throw if
-                        the test fails. May be:
-                            resolveLinkageError, or
-                            resolveIllegalAccessError
-                                               IMPORTANT: If error==resolveIllegalAccessError,
-                                               then array types are not checked.
-
-   RETURN VALUE:
-       resolveSucceeded.....the check succeeded
-       resolveDeferred......the check could not be performed due to
-                               unresolved types. (This can only happen for
-                                                       mode == resolveLazy.)
-          resolveFailed........the check failed, an exception has been thrown.
-   
-   NOTE:
-          The types are resolved first, so any
-          exception which may occurr during resolution may
-          be thrown by this function.
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
-                                                                                     classref_or_classinfo subtype,
-                                                                                         classref_or_classinfo supertype,
-                                                                                         resolve_mode_t mode,
-                                                                                         resolve_err_t error)
-{
-       classinfo *subclass;
-       typeinfo subti;
-       typecheck_result r;
-
-       assert(refmethod);
-       assert(subtype.any);
-       assert(supertype.any);
-       assert(mode == resolveLazy || mode == resolveEager);
-       assert(error == resolveLinkageError || error == resolveIllegalAccessError);
-
-       /* resolve the subtype */
-
-       if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
-               /* the subclass could not be resolved. therefore we are sure that  */
-               /* no instances of this subclass will ever exist -> skip this test */
-               /* XXX this assumes that class loading has invariant results (as in JVM spec) */
-               *exceptionptr = NULL;
-               return resolveSucceeded;
-       }
-       if (!subclass)
-               return resolveDeferred; /* be lazy */
-
-       assert(subclass->state & CLASS_LINKED);
-
-       /* do not check access to protected members of arrays */
-
-       if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
-               return resolveSucceeded;
-       }
-
-       /* perform the subtype check */
-
-       typeinfo_init_classinfo(&subti,subclass);
-check_again:
-       r = typeinfo_is_assignable_to_class(&subti,supertype);
-       if (r == typecheck_FAIL)
-               return resolveFailed; /* failed, exception is already set */
-
-       if (r == typecheck_MAYBE) {
-               assert(IS_CLASSREF(supertype));
-               if (mode == resolveEager) {
-                       if (!resolve_classref_or_classinfo(refmethod,supertype,
-                                                                                          resolveEager,false,true,
-                                                                                          &supertype.cls))
-                       {
-                               return resolveFailed;
-                       }
-                       assert(supertype.cls);
-                       goto check_again;
-               }
-
-               return resolveDeferred; /* be lazy */
-       }
-
-       if (!r) {
-               /* sub class relationship is false */
-
-               char *message;
-               int msglen;
-
-#if defined(RESOLVE_VERBOSE)
-               printf("SUBTYPE CHECK FAILED!\n");
-#endif
-
-               msglen = utf_bytes(subclass->name) + utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype)) + 200;
-               message = MNEW(char, msglen);
-               strcpy(message, (error == resolveIllegalAccessError) ?
-                               "illegal access to protected member ("
-                               : "subtype constraint violated (");
-               utf_cat_classname(message, subclass->name);
-               strcat(message, " is not a subclass of ");
-               utf_cat_classname(message, CLASSREF_OR_CLASSINFO_NAME(supertype));
-               strcat(message, ")");
-               if (error == resolveIllegalAccessError)
-                       *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
-               else
-                       *exceptionptr = exceptions_new_linkageerror(message, NULL);
-               MFREE(message, char, msglen);
-               return resolveFailed; /* exception */
-       }
-
-       /* everything ok */
-
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-/* resolve_lazy_subtype_checks *************************************************
-   Resolve the types to check lazily and perform subtype checks
-  
-   IN:
-       refmethod........the method triggering the resolution
-       subtinfo.........the typeinfo containing the subtypes
-       supertype........the supertype to test againgst
-          mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-       error............which type of exception to throw if
-                        the test fails. May be:
-                            resolveLinkageError, or
-                            resolveIllegalAccessError
-                                               IMPORTANT: If error==resolveIllegalAccessError,
-                                               then array types in the set are skipped.
-
-   RETURN VALUE:
-       resolveSucceeded.....the check succeeded
-       resolveDeferred......the check could not be performed due to
-                               unresolved types
-          resolveFailed........the check failed, an exception has been thrown.
-   
-   NOTE:
-       The references in the set are resolved first, so any
-       exception which may occurr during resolution may
-       be thrown by this function.
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
-                                                                                                       typeinfo *subtinfo,
-                                                                                                       classref_or_classinfo supertype,
-                                                                                                       resolve_err_t error)
-{
-       int count;
-       int i;
-       resolve_result_t result;
-
-       assert(refmethod);
-       assert(subtinfo);
-       assert(supertype.any);
-       assert(error == resolveLinkageError || error == resolveIllegalAccessError);
-
-       /* returnAddresses are illegal here */
-
-       if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
-               exceptions_throw_verifyerror(refmethod,
-                               "Invalid use of returnAddress");
-               return resolveFailed;
-       }
-
-       /* uninitialized objects are illegal here */
-
-       if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
-               exceptions_throw_verifyerror(refmethod,
-                               "Invalid use of uninitialized object");
-               return resolveFailed;
-       }
-
-       /* the nulltype is always assignable */
-
-       if (TYPEINFO_IS_NULLTYPE(*subtinfo))
-               return resolveSucceeded;
-
-       /* every type is assignable to (BOOTSTRAP)java.lang.Object */
-
-       if (supertype.cls == class_java_lang_Object
-               || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
-                       && refmethod->class->classloader == NULL))
-       {
-               return resolveSucceeded;
-       }
-
-       if (subtinfo->merged) {
-
-               /* for a merged type we have to do a series of checks */
-
-               count = subtinfo->merged->count;
-               for (i=0; i<count; ++i) {
-                       classref_or_classinfo c = subtinfo->merged->list[i];
-                       if (subtinfo->dimension > 0) {
-                               /* a merge of array types */
-                               /* the merged list contains the possible _element_ types, */
-                               /* so we have to create array types with these elements.  */
-                               if (IS_CLASSREF(c)) {
-                                       c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
-                               }
-                               else {
-                                       c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
-                               }
-                       }
-
-                       /* do the subtype check against the type c */
-
-                       result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
-                       if (result != resolveSucceeded)
-                               return result;
-               }
-       }
-       else {
-
-               /* a single type, this is the common case, hopefully */
-
-               if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
-                       == CLASSREF_OR_CLASSINFO_NAME(supertype))
-               {
-                       /* the class names are the same */
-                   /* equality is guaranteed by the loading constraints */
-                       return resolveSucceeded;
-               }
-               else {
-
-                       /* some other type name, try to perform the check lazily */
-
-                       return resolve_subtype_check(refmethod,
-                                                                                subtinfo->typeclass,supertype,
-                                                                                resolveLazy,
-                                                                                error);
-               }
-       }
-
-       /* everything ok */
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-/* resolve_and_check_subtype_set ***********************************************
-   Resolve the references in the given set and test subtype relationships
-  
-   IN:
-       refmethod........the method triggering the resolution
-       ref..............a set of class/interface references
-                        (may be empty)
-       typeref..........the type to test against the set
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-       error............which type of exception to throw if
-                        the test fails. May be:
-                            resolveLinkageError, or
-                            resolveIllegalAccessError
-                                               IMPORTANT: If error==resolveIllegalAccessError,
-                                               then array types in the set are skipped.
-
-   RETURN VALUE:
-       resolveSucceeded.....the check succeeded
-       resolveDeferred......the check could not be performed due to
-                               unresolved types. (This can only happen if
-                                                       mode == resolveLazy.)
-          resolveFailed........the check failed, an exception has been thrown.
-   
-   NOTE:
-       The references in the set are resolved first, so any
-       exception which may occurr during resolution may
-       be thrown by this function.
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
-                                                                         unresolved_subtype_set *ref,
-                                                                         classref_or_classinfo typeref,
-                                                                         resolve_mode_t mode,
-                                                                         resolve_err_t error)
-{
-       classref_or_classinfo *setp;
-       typecheck_result checkresult;
-
-       assert(refmethod);
-       assert(ref);
-       assert(typeref.any);
-       assert(mode == resolveLazy || mode == resolveEager);
-       assert(error == resolveLinkageError || error == resolveIllegalAccessError);
-
-#if defined(RESOLVE_VERBOSE)
-       printf("resolve_and_check_subtype_set:\n");
-       unresolved_subtype_set_debug_dump(ref, stdout);
-       if (IS_CLASSREF(typeref))
-               class_classref_println(typeref.ref);
-       else
-               class_println(typeref.cls);
-#endif
-
-       setp = ref->subtyperefs;
-
-       /* an empty set of tests always succeeds */
-       if (!setp || !setp->any) {
-               return resolveSucceeded;
-       }
-
-       /* first resolve the type if necessary */
-       if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
-               return resolveFailed; /* exception */
-       if (!typeref.cls)
-               return resolveDeferred; /* be lazy */
-
-       assert(typeref.cls->state & CLASS_LINKED);
-
-       /* iterate over the set members */
-
-       for (; setp->any; ++setp) {
-               checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
-#if defined(RESOLVE_VERBOSE)
-               if (checkresult != resolveSucceeded)
-                       printf("SUBTYPE CHECK FAILED!\n");
-#endif
-               if (checkresult != resolveSucceeded)
-                       return checkresult;
-       }
-
-       /* check succeeds */
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-/******************************************************************************/
-/* CLASS RESOLUTION                                                           */
-/******************************************************************************/
-
-/* resolve_class ***************************************************************
-   Resolve an unresolved class reference. The class is also linked.
-  
-   IN:
-       ref..............struct containing the reference
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-          checkaccess......if true, access rights to the class are checked
-   
-   OUT:
-       *result..........set to the result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-                        (*result may still be NULL for resolveLazy)
-       false............an exception has been thrown
-   
-*******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-bool resolve_class(unresolved_class *ref,
-                                  resolve_mode_t mode,
-                                  bool checkaccess,
-                                  classinfo **result)
-{
-       classinfo *cls;
-       resolve_result_t checkresult;
-       
-       assert(ref);
-       assert(result);
-       assert(mode == resolveLazy || mode == resolveEager);
-
-       *result = NULL;
-
-#ifdef RESOLVE_VERBOSE
-       unresolved_class_debug_dump(ref,stdout);
-#endif
-
-       /* first we must resolve the class */
-       if (!resolve_classref(ref->referermethod,
-                                             ref->classref,mode,checkaccess,true,&cls))
-       {
-               /* the class reference could not be resolved */
-               return false; /* exception */
-       }
-       if (!cls)
-               return true; /* be lazy */
-
-       assert(cls);
-       assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
-
-       /* now we check the subtype constraints */
-       
-       checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                                                          &(ref->subtypeconstraints),
-                                                                          CLASSREF_OR_CLASSINFO(cls),
-                                                                          mode,
-                                                                          resolveLinkageError);
-       if (checkresult != resolveSucceeded)
-               return (bool) checkresult;
-
-       /* succeed */
-       *result = cls;
-       return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-/* resolve_classref_eager ******************************************************
-   Resolve an unresolved class reference eagerly. The class is also linked and
-   access rights to the class are checked.
-  
-   IN:
-       ref..............constant_classref to the class
-   
-   RETURN VALUE:
-       classinfo * to the class, or
-          NULL if an exception has been thrown
-   
-*******************************************************************************/
-
-classinfo * resolve_classref_eager(constant_classref *ref)
-{
-       classinfo *c;
-
-       if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
-               return NULL;
-
-       return c;
-}
-
-/* resolve_classref_eager_nonabstract ******************************************
-   Resolve an unresolved class reference eagerly. The class is also linked and
-   access rights to the class are checked. A check is performed that the class
-   is not abstract.
-  
-   IN:
-       ref..............constant_classref to the class
-   
-   RETURN VALUE:
-       classinfo * to the class, or
-          NULL if an exception has been thrown
-   
-*******************************************************************************/
-
-classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
-{
-       classinfo *c;
-
-       if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
-               return NULL;
-
-       /* ensure that the class is not abstract */
-
-       if (c->flags & ACC_ABSTRACT) {
-               exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
-               return NULL;
-       }
-
-       return c;
-}
-
-/* resolve_class_eager *********************************************************
-   Resolve an unresolved class reference eagerly. The class is also linked and
-   access rights to the class are checked.
-  
-   IN:
-       ref..............struct containing the reference
-   
-   RETURN VALUE:
-       classinfo * to the class, or
-          NULL if an exception has been thrown
-   
-*******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-classinfo * resolve_class_eager(unresolved_class *ref)
-{
-       classinfo *c;
-
-       if (!resolve_class(ref,resolveEager,true,&c))
-               return NULL;
-
-       return c;
-}
-#endif /* ENABLE_VERIFIER */
-
-/******************************************************************************/
-/* FIELD RESOLUTION                                                           */
-/******************************************************************************/
-
-/* resolve_field_verifier_checks *******************************************
-   Do the verifier checks necessary after field has been resolved.
-  
-   IN:
-       refmethod........the method containing the reference
-          fieldref.........the field reference
-          container........the class where the field was found
-          fi...............the fieldinfo of the resolved field
-          instanceti.......instance typeinfo, if available
-          valueti..........value typeinfo, if available
-          isstatic.........true if this is a *STATIC* instruction
-          isput............true if this is a PUT* instruction
-  
-   RETURN VALUE:
-       resolveSucceeded....everything ok
-          resolveDeferred.....tests could not be done, have been deferred
-       resolveFailed.......exception has been thrown
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
-                                                                                          constant_FMIref *fieldref,
-                                                                                          classinfo *container,
-                                                                                          fieldinfo *fi,
-                                                                                          typeinfo *instanceti,
-                                                                                          typeinfo *valueti,
-                                                                                          bool isstatic,
-                                                                                          bool isput)
-{
-       classinfo *declarer;
-       classinfo *referer;
-       resolve_result_t result;
-       constant_classref *fieldtyperef;
-
-       assert(refmethod);
-       assert(fieldref);
-       assert(container);
-       assert(fi);
-
-       /* get the classinfos and the field type */
-
-       referer = refmethod->class;
-       assert(referer);
-
-       declarer = fi->class;
-       assert(declarer);
-       assert(referer->state & CLASS_LINKED);
-
-       fieldtyperef = fieldref->parseddesc.fd->classref;
-
-       /* check static */
-
-#if true != 1
-#error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
-#endif
-
-       if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
-               /* a static field is accessed via an instance, or vice versa */
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IncompatibleClassChangeError,
-                               (fi->flags & ACC_STATIC) ? "static field accessed via instance"
-                                                        : "instance field  accessed without instance");
-               return resolveFailed;
-       }
-
-       /* check access rights */
-
-       if (!access_is_accessible_member(referer,declarer,fi->flags)) {
-               int msglen;
-               char *message;
-
-               msglen = utf_bytes(declarer->name) + utf_bytes(fi->name) + utf_bytes(referer->name) + 100;
-               message = MNEW(char, msglen);
-               strcpy(message, "field is not accessible (");
-               utf_cat_classname(message, declarer->name);
-               strcat(message, ".");
-               utf_cat(message, fi->name);
-               strcat(message, " from ");
-               utf_cat_classname(message, referer->name);
-               strcat(message, ")");
-               *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
-               MFREE(message,char,msglen);
-               return resolveFailed; /* exception */
-       }
-
-       /* for non-static methods we have to check the constraints on the         */
-       /* instance type                                                          */
-
-       if (instanceti) {
-               typeinfo *insttip;
-               typeinfo tinfo;
-
-               /* The instanceslot must contain a reference to a non-array type */
-
-               if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
-                       exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
-                       return resolveFailed;
-               }
-               if (TYPEINFO_IS_ARRAY(*instanceti)) {
-                       exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
-                       return resolveFailed;
-               }
-
-               if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
-               {
-                       /* The instruction writes a field in an uninitialized object. */
-                       /* This is only allowed when a field of an uninitialized 'this' object is */
-                       /* written inside an initialization method                                */
-
-                       classinfo *initclass;
-                       instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
-
-                       if (ins != NULL) {
-                               exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
-                               return resolveFailed;
-                       }
-
-                       /* XXX check that class of field == refmethod->class */
-                       initclass = referer; /* XXX classrefs */
-                       assert(initclass->state & CLASS_LINKED);
-
-                       typeinfo_init_classinfo(&tinfo, initclass);
-                       insttip = &tinfo;
-               }
-               else {
-                       insttip = instanceti;
-               }
-
-               result = resolve_lazy_subtype_checks(refmethod,
-                               insttip,
-                               CLASSREF_OR_CLASSINFO(container),
-                               resolveLinkageError);
-               if (result != resolveSucceeded)
-                       return result;
-
-               /* check protected access */
-
-               if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
-               {
-                       result = resolve_lazy_subtype_checks(refmethod,
-                                       instanceti,
-                                       CLASSREF_OR_CLASSINFO(referer),
-                                       resolveIllegalAccessError);
-                       if (result != resolveSucceeded)
-                               return result;
-               }
-
-       }
-
-       /* for PUT* instructions we have to check the constraints on the value type */
-
-       if (valueti) {
-               assert(fieldtyperef);
-
-               /* check subtype constraints */
-               result = resolve_lazy_subtype_checks(refmethod,
-                               valueti,
-                               CLASSREF_OR_CLASSINFO(fieldtyperef),
-                               resolveLinkageError);
-
-               if (result != resolveSucceeded)
-                       return result;
-       }
-
-       /* impose loading constraint on field type */
-
-       if (fi->type == TYPE_ADR) {
-               assert(fieldtyperef);
-               if (!classcache_add_constraint(declarer->classloader,
-                                                                          referer->classloader,
-                                                                          fieldtyperef->name))
-                       return resolveFailed;
-       }
-
-       /* XXX impose loading constraint on instance? */
-
-       /* everything ok */
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-/* resolve_field_lazy **********************************************************
-   Resolve an unresolved field reference lazily
-
-   NOTE: This function does NOT do any verification checks. In case of a
-         successful resolution, you must call resolve_field_verifier_checks
-                in order to perform the necessary checks!
-  
-   IN:
-          refmethod........the referer method
-          fieldref.........the field reference
-  
-   RETURN VALUE:
-       resolveSucceeded.....the reference has been resolved
-       resolveDeferred......the resolving could not be performed lazily
-          resolveFailed........resolving failed, an exception has been thrown.
-   
-*******************************************************************************/
-
-resolve_result_t resolve_field_lazy(methodinfo *refmethod,
-                                                                       constant_FMIref *fieldref)
-{
-       classinfo *referer;
-       classinfo *container;
-       fieldinfo *fi;
-
-       assert(refmethod);
-
-       /* the class containing the reference */
-
-       referer = refmethod->class;
-       assert(referer);
-
-       /* check if the field itself is already resolved */
-
-       if (IS_FMIREF_RESOLVED(fieldref))
-               return resolveSucceeded;
-
-       /* first we must resolve the class containg the field */
-
-       /* XXX can/may lazyResolving trigger linking? */
-
-       if (!resolve_class_from_name(referer, refmethod,
-                  fieldref->p.classref->name, resolveLazy, true, true, &container))
-       {
-               /* the class reference could not be resolved */
-               return resolveFailed; /* exception */
-       }
-       if (!container)
-               return resolveDeferred; /* be lazy */
-
-       assert(container->state & CLASS_LINKED);
-
-       /* now we must find the declaration of the field in `container`
-        * or one of its superclasses */
-
-       fi = class_resolvefield(container,
-                                                       fieldref->name, fieldref->descriptor,
-                                                       referer, true);
-       if (!fi) {
-               /* The field does not exist. But since we were called lazily, */
-               /* this error must not be reported now. (It will be reported   */
-               /* if eager resolving of this field is ever tried.)           */
-
-               *exceptionptr = NULL;
-               return resolveDeferred; /* be lazy */
-       }
-
-       /* cache the result of the resolution */
-
-       fieldref->p.field = fi;
-
-       /* everything ok */
-       return resolveSucceeded;
-}
-
-/* resolve_field ***************************************************************
-   Resolve an unresolved field reference
-  
-   IN:
-       ref..............struct containing the reference
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-  
-   OUT:
-       *result..........set to the result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-                        (*result may still be NULL for resolveLazy)
-       false............an exception has been thrown
-   
-*******************************************************************************/
-
-bool resolve_field(unresolved_field *ref,
-                                  resolve_mode_t mode,
-                                  fieldinfo **result)
-{
-       classinfo *referer;
-       classinfo *container;
-       classinfo *declarer;
-       constant_classref *fieldtyperef;
-       fieldinfo *fi;
-       resolve_result_t checkresult;
-
-       assert(ref);
-       assert(result);
-       assert(mode == resolveLazy || mode == resolveEager);
-
-       *result = NULL;
-
-#ifdef RESOLVE_VERBOSE
-       unresolved_field_debug_dump(ref,stdout);
-#endif
-
-       /* the class containing the reference */
-
-       referer = ref->referermethod->class;
-       assert(referer);
-
-       /* check if the field itself is already resolved */
-       if (IS_FMIREF_RESOLVED(ref->fieldref)) {
-               fi = ref->fieldref->p.field;
-               container = fi->class;
-               goto resolved_the_field;
-       }
-
-       /* first we must resolve the class containg the field */
-       if (!resolve_class_from_name(referer,ref->referermethod,
-                                          ref->fieldref->p.classref->name,mode,true,true,&container))
-       {
-               /* the class reference could not be resolved */
-               return false; /* exception */
-       }
-       if (!container)
-               return true; /* be lazy */
-
-       assert(container);
-       assert(container->state & CLASS_LOADED);
-       assert(container->state & CLASS_LINKED);
-
-       /* now we must find the declaration of the field in `container`
-        * or one of its superclasses */
-
-#ifdef RESOLVE_VERBOSE
-               printf("    resolving field in class...\n");
-#endif
-
-       fi = class_resolvefield(container,
-                                                       ref->fieldref->name,ref->fieldref->descriptor,
-                                                       referer,true);
-       if (!fi) {
-               if (mode == resolveLazy) {
-                       /* The field does not exist. But since we were called lazily, */
-                       /* this error must not be reported now. (It will be reported   */
-                       /* if eager resolving of this field is ever tried.)           */
-
-                       *exceptionptr = NULL;
-                       return true; /* be lazy */
-               }
-
-               return false; /* exception */
-       }
-
-       /* cache the result of the resolution */
-       ref->fieldref->p.field = fi;
-
-resolved_the_field:
-
-#ifdef ENABLE_VERIFIER
-       /* Checking opt_verify is ok here, because the NULL iptr guarantees */
-       /* that no missing parts of an instruction will be accessed.        */
-       if (opt_verify) {
-               checkresult = resolve_field_verifier_checks(
-                               ref->referermethod,
-                               ref->fieldref,
-                               container,
-                               fi,
-                               NULL, /* instanceti, handled by constraints below */
-                               NULL, /* valueti, handled by constraints below  */
-                               (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
-                               (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
-
-               if (checkresult != resolveSucceeded)
-                       return (bool) checkresult;
-
-               declarer = fi->class;
-               assert(declarer);
-               assert(declarer->state & CLASS_LOADED);
-               assert(declarer->state & CLASS_LINKED);
-
-               /* for non-static accesses we have to check the constraints on the */
-               /* instance type */
-
-               if (!(ref->flags & RESOLVE_STATIC)) {
-                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                       &(ref->instancetypes),
-                                       CLASSREF_OR_CLASSINFO(container),
-                                       mode, resolveLinkageError);
-                       if (checkresult != resolveSucceeded)
-                               return (bool) checkresult;
-               }
-
-               fieldtyperef = ref->fieldref->parseddesc.fd->classref;
-
-               /* for PUT* instructions we have to check the constraints on the value type */
-               if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
-                       assert(fieldtyperef);
-                       if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
-                               /* check subtype constraints */
-                               checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                               &(ref->valueconstraints),
-                                               CLASSREF_OR_CLASSINFO(fieldtyperef),
-                                               mode, resolveLinkageError);
-                               if (checkresult != resolveSucceeded)
-                                       return (bool) checkresult;
-                       }
-               }
-
-               /* check protected access */
-               if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
-                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                       &(ref->instancetypes),
-                                       CLASSREF_OR_CLASSINFO(referer),
-                                       mode,
-                                       resolveIllegalAccessError);
-                       if (checkresult != resolveSucceeded)
-                               return (bool) checkresult;
-               }
-
-       }
-#endif /* ENABLE_VERIFIER */
-
-       /* succeed */
-       *result = fi;
-
-       return true;
-}
-
-/* resolve_field_eager *********************************************************
-   Resolve an unresolved field reference eagerly.
-  
-   IN:
-       ref..............struct containing the reference
-   
-   RETURN VALUE:
-       fieldinfo * to the field, or
-          NULL if an exception has been thrown
-   
-*******************************************************************************/
-
-fieldinfo * resolve_field_eager(unresolved_field *ref)
-{
-       fieldinfo *fi;
-
-       if (!resolve_field(ref,resolveEager,&fi))
-               return NULL;
-
-       return fi;
-}
-
-/******************************************************************************/
-/* METHOD RESOLUTION                                                          */
-/******************************************************************************/
-
-/* resolve_method_invokespecial_lookup *****************************************
-   Do the special lookup for methods invoked by INVOKESPECIAL
-  
-   IN:
-       refmethod........the method containing the reference
-          mi...............the methodinfo of the resolved method
-  
-   RETURN VALUE:
-       a methodinfo *...the result of the lookup,
-          NULL.............an exception has been thrown
-   
-*******************************************************************************/
-
-methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
-                                                                                                methodinfo *mi)
-{
-       classinfo *declarer;
-       classinfo *referer;
-
-       assert(refmethod);
-       assert(mi);
-
-       /* get referer and declarer classes */
-
-       referer = refmethod->class;
-       assert(referer);
-
-       declarer = mi->class;
-       assert(declarer);
-       assert(referer->state & CLASS_LINKED);
-
-       /* checks for INVOKESPECIAL:                                       */
-       /* for <init> and methods of the current class we don't need any   */
-       /* special checks. Otherwise we must verify that the called method */
-       /* belongs to a super class of the current class                   */
-
-       if ((referer != declarer) && (mi->name != utf_init)) {
-               /* check that declarer is a super class of the current class   */
-
-               if (!class_issubclass(referer,declarer)) {
-                       exceptions_throw_verifyerror(refmethod,
-                                       "INVOKESPECIAL calling non-super class method");
-                       return NULL;
-               }
-
-               /* if the referer has ACC_SUPER set, we must do the special    */
-               /* lookup starting with the direct super class of referer      */
-
-               if ((referer->flags & ACC_SUPER) != 0) {
-                       mi = class_resolvemethod(referer->super.cls,
-                                                                        mi->name,
-                                                                        mi->descriptor);
-
-                       if (mi == NULL) {
-#if defined(ENABLE_JAVASE)
-                               /* the spec calls for an AbstractMethodError in this case */
-                               exceptions_throw_abstractmethoderror();
-#else
-                               exceptions_throw_virtualmachineerror();
-#endif
-                               return NULL;
-                       }
-               }
-       }
-
-       /* everything ok */
-       return mi;
-}
-
-/* resolve_method_verifier_checks ******************************************
-   Do the verifier checks necessary after a method has been resolved.
-  
-   IN:
-       refmethod........the method containing the reference
-          methodref........the method reference
-          mi...............the methodinfo of the resolved method
-          invokestatic.....true if the method is invoked by INVOKESTATIC
-  
-   RETURN VALUE:
-       resolveSucceeded....everything ok
-          resolveDeferred.....tests could not be done, have been deferred
-       resolveFailed.......exception has been thrown
-   
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
-                                                                                               constant_FMIref *methodref,
-                                                                                               methodinfo *mi,
-                                                                                               bool invokestatic)
-{
-       classinfo *declarer;
-       classinfo *referer;
-
-       assert(refmethod);
-       assert(methodref);
-       assert(mi);
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_method_verifier_checks\n");
-       printf("    flags: %02x\n",mi->flags);
-#endif
-
-       /* get the classinfos and the method descriptor */
-
-       referer = refmethod->class;
-       assert(referer);
-
-       declarer = mi->class;
-       assert(declarer);
-
-       /* check static */
-
-       if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
-               /* a static method is accessed via an instance, or vice versa */
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IncompatibleClassChangeError,
-                               (mi->flags & ACC_STATIC) ? "static method called via instance"
-                                                        : "instance method called without instance");
-               return resolveFailed;
-       }
-
-       /* check access rights */
-
-       if (!access_is_accessible_member(referer,declarer,mi->flags)) {
-               int msglen;
-               char *message;
-
-               /* XXX clean this up. this should be in exceptions.c */
-               msglen = utf_bytes(declarer->name) + utf_bytes(mi->name) +
-                       utf_bytes(mi->descriptor) + utf_bytes(referer->name) + 100;
-               message = MNEW(char, msglen);
-               strcpy(message, "method is not accessible (");
-               utf_cat_classname(message, declarer->name);
-               strcat(message, ".");
-               utf_cat(message, mi->name);
-               utf_cat(message, mi->descriptor);
-               strcat(message," from ");
-               utf_cat_classname(message, referer->name);
-               strcat(message,")");
-               *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException, message);
-               MFREE(message, char, msglen);
-               return resolveFailed; /* exception */
-       }
-
-       /* everything ok */
-
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* resolve_method_instance_type_checks *****************************************
-
-   Check the instance type of a method invocation.
-
-   IN:
-       refmethod........the method containing the reference
-          mi...............the methodinfo of the resolved method
-          instanceti.......typeinfo of the instance slot
-          invokespecial....true if the method is invoked by INVOKESPECIAL
-
-   RETURN VALUE:
-       resolveSucceeded....everything ok
-          resolveDeferred.....tests could not be done, have been deferred
-       resolveFailed.......exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
-                                                                                                        methodinfo *mi,
-                                                                                                        typeinfo *instanceti,
-                                                                                                        bool invokespecial)
-{
-       typeinfo         tinfo;
-       typeinfo        *tip;
-       resolve_result_t result;
-
-       if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
-       {   /* XXX clean up */
-               instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
-               classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
-                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
-               tip = &tinfo;
-               if (!typeinfo_init_class(tip, initclass))
-                       return false;
-       }
-       else {
-               tip = instanceti;
-       }
-
-       result = resolve_lazy_subtype_checks(refmethod,
-                                                                                tip,
-                                                                                CLASSREF_OR_CLASSINFO(mi->class),
-                                                                                resolveLinkageError);
-       if (result != resolveSucceeded)
-               return result;
-
-       /* check protected access */
-
-       /* XXX use other `declarer` than mi->class? */
-       if (((mi->flags & ACC_PROTECTED) != 0)
-                       && !SAME_PACKAGE(mi->class, refmethod->class))
-       {
-               result = resolve_lazy_subtype_checks(refmethod,
-                               tip,
-                               CLASSREF_OR_CLASSINFO(refmethod->class),
-                               resolveIllegalAccessError);
-               if (result != resolveSucceeded)
-                       return result;
-       }
-
-       /* everything ok */
-
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* resolve_method_param_type_checks ********************************************
-
-   Check non-instance parameter types of a method invocation.
-
-   IN:
-          jd...............jitdata of the method doing the call
-       refmethod........the method containing the reference
-          iptr.............the invoke instruction
-          mi...............the methodinfo of the resolved method
-          invokestatic.....true if the method is invoked by INVOKESTATIC
-
-   RETURN VALUE:
-       resolveSucceeded....everything ok
-          resolveDeferred.....tests could not be done, have been deferred
-       resolveFailed.......exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-resolve_result_t resolve_method_param_type_checks(jitdata *jd, 
-                                                                                                 methodinfo *refmethod,
-                                                                                                 instruction *iptr, 
-                                                                                                 methodinfo *mi,
-                                                                                                 bool invokestatic)
-{
-       varinfo         *param;
-       resolve_result_t result;
-       methoddesc      *md;
-       typedesc        *paramtypes;
-       s4               type;
-       s4               instancecount;
-       s4               i;
-
-       assert(jd);
-
-       instancecount = (invokestatic) ? 0 : 1;
-
-       /* check subtype constraints for TYPE_ADR parameters */
-
-       md = mi->parseddesc;
-       paramtypes = md->paramtypes;
-
-       for (i = md->paramcount-1-instancecount; i>=0; --i) {
-               param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
-               type = md->paramtypes[i+instancecount].type;
-
-               assert(param);
-               assert(type == param->type);
-
-               if (type == TYPE_ADR) {
-                       result = resolve_lazy_subtype_checks(refmethod,
-                                       &(param->typeinfo),
-                                       CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
-                                       resolveLinkageError);
-                       if (result != resolveSucceeded)
-                               return result;
-               }
-       }
-
-       /* everything ok */
-
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* resolve_method_param_type_checks_stackbased *********************************
-
-   Check non-instance parameter types of a method invocation.
-
-   IN:
-       refmethod........the method containing the reference
-          mi...............the methodinfo of the resolved method
-          invokestatic.....true if the method is invoked by INVOKESTATIC
-          stack............TOS before the INVOKE instruction
-
-   RETURN VALUE:
-       resolveSucceeded....everything ok
-          resolveDeferred.....tests could not be done, have been deferred
-       resolveFailed.......exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-resolve_result_t resolve_method_param_type_checks_stackbased(
-               methodinfo *refmethod, 
-               methodinfo *mi,
-               bool invokestatic, 
-               typedescriptor *stack)
-{
-       typedescriptor  *param;
-       resolve_result_t result;
-       methoddesc      *md;
-       typedesc        *paramtypes;
-       s4               type;
-       s4               instancecount;
-       s4               i;
-
-       instancecount = (invokestatic) ? 0 : 1;
-
-       /* check subtype constraints for TYPE_ADR parameters */
-
-       md = mi->parseddesc;
-       paramtypes = md->paramtypes;
-
-       param = stack - (md->paramslots - 1 - instancecount);
-
-       for (i = instancecount; i < md->paramcount; ++i) {
-               type = md->paramtypes[i].type;
-
-               assert(type == param->type);
-
-               if (type == TYPE_ADR) {
-                       result = resolve_lazy_subtype_checks(refmethod,
-                                       &(param->typeinfo),
-                                       CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
-                                       resolveLinkageError);
-                       if (result != resolveSucceeded)
-                               return result;
-               }
-
-               param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
-       }
-
-       /* everything ok */
-
-       return resolveSucceeded;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* resolve_method_loading_constraints ******************************************
-
-   Impose loading constraints on the parameters and return type of the
-   given method.
-
-   IN:
-       referer..........the class refering to the method
-          mi...............the method
-
-   RETURN VALUE:
-       true................everything ok
-          false...............an exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool resolve_method_loading_constraints(classinfo *referer,
-                                                                               methodinfo *mi)
-{
-       methoddesc *md;
-       typedesc   *paramtypes;
-       utf        *name;
-       s4          i;
-       s4          instancecount;
-
-       /* impose loading constraints on parameters (including instance) */
-
-       md = mi->parseddesc;
-       paramtypes = md->paramtypes;
-       instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
-
-       for (i = 0; i < md->paramcount; i++) {
-               if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
-                       if (i < instancecount) {
-                               /* The type of the 'this' pointer is the class containing */
-                               /* the method definition. Since container is the same as, */
-                               /* or a subclass of declarer, we also constrain declarer  */
-                               /* by transitivity of loading constraints.                */
-                               name = mi->class->name;
-                       }
-                       else {
-                               name = paramtypes[i].classref->name;
-                       }
-
-                       /* The caller (referer) and the callee (container) must agree */
-                       /* on the types of the parameters.                            */
-                       if (!classcache_add_constraint(referer->classloader,
-                                                                                  mi->class->classloader, name))
-                               return false; /* exception */
-               }
-       }
-
-       /* impose loading constraint onto return type */
-
-       if (md->returntype.type == TYPE_ADR) {
-               /* The caller (referer) and the callee (container) must agree */
-               /* on the return type.                                        */
-               if (!classcache_add_constraint(referer->classloader,
-                                       mi->class->classloader,
-                                       md->returntype.classref->name))
-                       return false; /* exception */
-       }
-
-       /* everything ok */
-
-       return true;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* resolve_method_lazy *********************************************************
-   Resolve an unresolved method reference lazily
-  
-   NOTE: This function does NOT do any verification checks. In case of a
-         successful resolution, you must call resolve_method_verifier_checks
-                in order to perform the necessary checks!
-  
-   IN:
-          refmethod........the referer method
-          methodref........the method reference
-          invokespecial....true if this is an INVOKESPECIAL instruction
-  
-   RETURN VALUE:
-       resolveSucceeded.....the reference has been resolved
-       resolveDeferred......the resolving could not be performed lazily
-          resolveFailed........resolving failed, an exception has been thrown.
-   
-*******************************************************************************/
-
-resolve_result_t resolve_method_lazy(methodinfo *refmethod,
-                                                                        constant_FMIref *methodref,
-                                                                        bool invokespecial)
-{
-       classinfo *referer;
-       classinfo *container;
-       methodinfo *mi;
-
-       assert(refmethod);
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_method_lazy\n");
-#endif
-
-       /* the class containing the reference */
-
-       referer = refmethod->class;
-       assert(referer);
-
-       /* check if the method itself is already resolved */
-
-       if (IS_FMIREF_RESOLVED(methodref))
-               return resolveSucceeded;
-
-       /* first we must resolve the class containg the method */
-
-       if (!resolve_class_from_name(referer, refmethod,
-                  methodref->p.classref->name, resolveLazy, true, true, &container))
-       {
-               /* the class reference could not be resolved */
-               return resolveFailed; /* exception */
-       }
-       if (!container)
-               return resolveDeferred; /* be lazy */
-
-       assert(container->state & CLASS_LINKED);
-
-       /* now we must find the declaration of the method in `container`
-        * or one of its superclasses */
-
-       if (container->flags & ACC_INTERFACE) {
-               mi = class_resolveinterfacemethod(container,
-                                                                             methodref->name,
-                                                                                 methodref->descriptor,
-                                                                             referer, true);
-
-       } else {
-               mi = class_resolveclassmethod(container,
-                                                                         methodref->name,
-                                                                         methodref->descriptor,
-                                                                         referer, true);
-       }
-
-       if (!mi) {
-               /* The method does not exist. But since we were called lazily, */
-               /* this error must not be reported now. (It will be reported   */
-               /* if eager resolving of this method is ever tried.)           */
-
-               *exceptionptr = NULL;
-               return resolveDeferred; /* be lazy */
-       }
-
-       if (invokespecial) {
-               mi = resolve_method_invokespecial_lookup(refmethod, mi);
-               if (!mi)
-                       return resolveFailed; /* exception */
-       }
-
-       /* have the method params already been parsed? no, do it. */
-
-       if (!mi->parseddesc->params)
-               if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
-                       return resolveFailed;
-
-       /* cache the result of the resolution */
-
-       methodref->p.method = mi;
-
-       /* succeed */
-
-       return resolveSucceeded;
-}
-
-/* resolve_method **************************************************************
-   Resolve an unresolved method reference
-  
-   IN:
-       ref..............struct containing the reference
-       mode.............mode of resolution:
-                            resolveLazy...only resolve if it does not
-                                          require loading classes
-                            resolveEager..load classes if necessary
-  
-   OUT:
-       *result..........set to the result of resolution, or to NULL if
-                        the reference has not been resolved
-                        In the case of an exception, *result is
-                        guaranteed to be set to NULL.
-  
-   RETURN VALUE:
-       true.............everything ok 
-                        (*result may still be NULL for resolveLazy)
-       false............an exception has been thrown
-   
-*******************************************************************************/
-
-bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
-{
-       classinfo *referer;
-       classinfo *container;
-       classinfo *declarer;
-       methodinfo *mi;
-       typedesc *paramtypes;
-       int instancecount;
-       int i;
-       resolve_result_t checkresult;
-
-       assert(ref);
-       assert(result);
-       assert(mode == resolveLazy || mode == resolveEager);
-
-#ifdef RESOLVE_VERBOSE
-       unresolved_method_debug_dump(ref,stdout);
-#endif
-
-       *result = NULL;
-
-       /* the class containing the reference */
-
-       referer = ref->referermethod->class;
-       assert(referer);
-
-       /* check if the method itself is already resolved */
-
-       if (IS_FMIREF_RESOLVED(ref->methodref)) {
-               mi = ref->methodref->p.method;
-               container = mi->class;
-               goto resolved_the_method;
-       }
-
-       /* first we must resolve the class containing the method */
-
-       if (!resolve_class_from_name(referer,ref->referermethod,
-                                          ref->methodref->p.classref->name,mode,true,true,&container))
-       {
-               /* the class reference could not be resolved */
-               return false; /* exception */
-       }
-       if (!container)
-               return true; /* be lazy */
-
-       assert(container);
-       assert(container->state & CLASS_LINKED);
-
-       /* now we must find the declaration of the method in `container`
-        * or one of its superclasses */
-
-       if (container->flags & ACC_INTERFACE) {
-               mi = class_resolveinterfacemethod(container,
-                                                                             ref->methodref->name,
-                                                                                 ref->methodref->descriptor,
-                                                                             referer, true);
-
-       } else {
-               mi = class_resolveclassmethod(container,
-                                                                         ref->methodref->name,
-                                                                         ref->methodref->descriptor,
-                                                                         referer, true);
-       }
-
-       if (!mi) {
-               if (mode == resolveLazy) {
-                       /* The method does not exist. But since we were called lazily, */
-                       /* this error must not be reported now. (It will be reported   */
-                       /* if eager resolving of this method is ever tried.)           */
-
-                       *exceptionptr = NULL;
-                       return true; /* be lazy */
-               }
-
-               return false; /* exception */ /* XXX set exceptionptr? */
-       }
-
-       /* { the method reference has been resolved } */
-
-       if (ref->flags & RESOLVE_SPECIAL) {
-               mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
-               if (!mi)
-                       return false; /* exception */
-       }
-
-       /* have the method params already been parsed? no, do it. */
-
-       if (!mi->parseddesc->params)
-               if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
-                       return false;
-
-       /* cache the resolution */
-
-       ref->methodref->p.method = mi;
-
-resolved_the_method:
-
-#ifdef ENABLE_VERIFIER
-       if (opt_verify) {
-
-               checkresult = resolve_method_verifier_checks(
-                               ref->referermethod,
-                               ref->methodref,
-                               mi,
-                               (ref->flags & RESOLVE_STATIC));
-
-               if (checkresult != resolveSucceeded)
-                       return (bool) checkresult;
-
-               /* impose loading constraints on params and return type */
-
-               if (!resolve_method_loading_constraints(referer, mi))
-                       return false;
-
-               declarer = mi->class;
-               assert(declarer);
-               assert(referer->state & CLASS_LINKED);
-
-               /* for non-static methods we have to check the constraints on the         */
-               /* instance type                                                          */
-
-               if (!(ref->flags & RESOLVE_STATIC)) {
-                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                       &(ref->instancetypes),
-                                       CLASSREF_OR_CLASSINFO(container),
-                                       mode,
-                                       resolveLinkageError);
-                       if (checkresult != resolveSucceeded)
-                               return (bool) checkresult;
-                       instancecount = 1;
-               }
-               else {
-                       instancecount = 0;
-               }
-
-               /* check subtype constraints for TYPE_ADR parameters */
-
-               assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
-               paramtypes = mi->parseddesc->paramtypes;
-
-               for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
-                       if (paramtypes[i+instancecount].type == TYPE_ADR) {
-                               if (ref->paramconstraints) {
-                                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                                       ref->paramconstraints + i,
-                                                       CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
-                                                       mode,
-                                                       resolveLinkageError);
-                                       if (checkresult != resolveSucceeded)
-                                               return (bool) checkresult;
-                               }
-                       }
-               }
-
-               /* check protected access */
-
-               if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
-               {
-                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
-                                       &(ref->instancetypes),
-                                       CLASSREF_OR_CLASSINFO(referer),
-                                       mode,
-                                       resolveIllegalAccessError);
-                       if (checkresult != resolveSucceeded)
-                               return (bool) checkresult;
-               }
-       }
-#endif /* ENABLE_VERIFIER */
-
-       /* succeed */
-       *result = mi;
-       return true;
-}
-
-/* resolve_method_eager ********************************************************
-   Resolve an unresolved method reference eagerly.
-  
-   IN:
-       ref..............struct containing the reference
-   
-   RETURN VALUE:
-       methodinfo * to the method, or
-          NULL if an exception has been thrown
-   
-*******************************************************************************/
-
-methodinfo * resolve_method_eager(unresolved_method *ref)
-{
-       methodinfo *mi;
-
-       if (!resolve_method(ref,resolveEager,&mi))
-               return NULL;
-
-       return mi;
-}
-
-/******************************************************************************/
-/* CREATING THE DATA STRUCTURES                                               */
-/******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
-                                                                                                methodinfo *refmethod,
-                                                                                                unresolved_subtype_set *stset,
-                                                                                                typeinfo *tinfo,
-                                                                                                utf *declaredclassname)
-{
-       int count;
-       int i;
-
-       assert(stset);
-       assert(tinfo);
-
-#ifdef RESOLVE_VERBOSE
-       printf("unresolved_subtype_set_from_typeinfo\n");
-#ifdef TYPEINFO_DEBUG
-       typeinfo_print(stdout,tinfo,4);
-#endif
-       printf("    declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
-       printf("\n");
-#endif
-
-       if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
-               exceptions_throw_verifyerror(refmethod,
-                               "Invalid use of returnAddress");
-               return false;
-       }
-
-       if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
-               exceptions_throw_verifyerror(refmethod,
-                               "Invalid use of uninitialized object");
-               return false;
-       }
-
-       /* the nulltype is always assignable */
-       if (TYPEINFO_IS_NULLTYPE(*tinfo))
-               goto empty_set;
-
-       /* every type is assignable to (BOOTSTRAP)java.lang.Object */
-       if (declaredclassname == utf_java_lang_Object
-                       && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
-       {
-               goto empty_set;
-       }
-
-       if (tinfo->merged) {
-               count = tinfo->merged->count;
-               stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
-               for (i=0; i<count; ++i) {
-                       classref_or_classinfo c = tinfo->merged->list[i];
-                       if (tinfo->dimension > 0) {
-                               /* a merge of array types */
-                               /* the merged list contains the possible _element_ types, */
-                               /* so we have to create array types with these elements.  */
-                               if (IS_CLASSREF(c)) {
-                                       c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
-                               }
-                               else {
-                                       c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
-                               }
-                       }
-                       stset->subtyperefs[i] = c;
-               }
-               stset->subtyperefs[count].any = NULL; /* terminate */
-       }
-       else {
-               if ((IS_CLASSREF(tinfo->typeclass)
-                                       ? tinfo->typeclass.ref->name
-                                       : tinfo->typeclass.cls->name) == declaredclassname)
-               {
-                       /* the class names are the same */
-                   /* equality is guaranteed by the loading constraints */
-                       goto empty_set;
-               }
-               else {
-                       stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
-                       stset->subtyperefs[0] = tinfo->typeclass;
-                       stset->subtyperefs[1].any = NULL; /* terminate */
-               }
-       }
-
-       return true;
-
-empty_set:
-       UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
-       return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-/* create_unresolved_class *****************************************************
-   Create an unresolved_class struct for the given class reference
-  
-   IN:
-          refmethod........the method triggering the resolution (if any)
-          classref.........the class reference
-          valuetype........value type to check against the resolved class
-                                               may be NULL, if no typeinfo is available
-
-   RETURN VALUE:
-       a pointer to a new unresolved_class struct, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-unresolved_class * create_unresolved_class(methodinfo *refmethod,
-                                                                                  constant_classref *classref,
-                                                                                  typeinfo *valuetype)
-{
-       unresolved_class *ref;
-
-#ifdef RESOLVE_VERBOSE
-       printf("create_unresolved_class\n");
-       printf("    referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
-       if (refmethod) {
-               printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
-               printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
-       }
-       printf("    name   : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
-#endif
-
-       ref = NEW(unresolved_class);
-       ref->classref = classref;
-       ref->referermethod = refmethod;
-
-       if (valuetype) {
-               if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
-                                       &(ref->subtypeconstraints),valuetype,classref->name))
-                       return NULL;
-       }
-       else {
-               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
-       }
-
-       return ref;
-}
-#endif /* ENABLE_VERIFIER */
-
-/* resolve_create_unresolved_field *********************************************
-   Create an unresolved_field struct for the given field access instruction
-  
-   IN:
-       referer..........the class containing the reference
-          refmethod........the method triggering the resolution (if any)
-          iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
-
-   RETURN VALUE:
-       a pointer to a new unresolved_field struct, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-unresolved_field * resolve_create_unresolved_field(classinfo *referer,
-                                                                                                  methodinfo *refmethod,
-                                                                                                  instruction *iptr)
-{
-       unresolved_field *ref;
-       constant_FMIref *fieldref = NULL;
-
-#ifdef RESOLVE_VERBOSE
-       printf("create_unresolved_field\n");
-       printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
-       printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
-       printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
-#endif
-
-       ref = NEW(unresolved_field);
-       ref->flags = 0;
-       ref->referermethod = refmethod;
-       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
-
-       switch (iptr->opc) {
-               case ICMD_PUTFIELD:
-                       ref->flags |= RESOLVE_PUTFIELD;
-                       break;
-
-               case ICMD_PUTFIELDCONST:
-                       ref->flags |= RESOLVE_PUTFIELD;
-                       break;
-
-               case ICMD_PUTSTATIC:
-                       ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
-                       break;
-
-               case ICMD_PUTSTATICCONST:
-                       ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
-                       break;
-
-               case ICMD_GETFIELD:
-                       break;
-
-               case ICMD_GETSTATIC:
-                       ref->flags |= RESOLVE_STATIC;
-                       break;
-
-#if !defined(NDEBUG)
-               default:
-                       assert(false);
-#endif
-       }
-
-       fieldref = iptr->sx.s23.s3.fmiref;
-
-       assert(fieldref);
-
-#ifdef RESOLVE_VERBOSE
-/*     printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
-       printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
-       printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
-       printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
-       fputc('\n',stdout);
-#endif
-
-       ref->fieldref = fieldref;
-
-       return ref;
-}
-
-/* resolve_constrain_unresolved_field ******************************************
-   Record subtype constraints for a field access.
-  
-   IN:
-       ref..............the unresolved_field structure of the access
-       referer..........the class containing the reference
-          refmethod........the method triggering the resolution (if any)
-          instanceti.......instance typeinfo, if available
-          valueti..........value typeinfo, if available
-
-   RETURN VALUE:
-       true.............everything ok
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool resolve_constrain_unresolved_field(unresolved_field *ref,
-                                                                               classinfo *referer, 
-                                                                               methodinfo *refmethod,
-                                                                           typeinfo *instanceti,
-                                                                           typeinfo *valueti)
-{
-       constant_FMIref *fieldref;
-       int type;
-       typeinfo tinfo;
-       typedesc *fd;
-
-       assert(ref);
-
-       fieldref = ref->fieldref;
-       assert(fieldref);
-
-#ifdef RESOLVE_VERBOSE
-       printf("constrain_unresolved_field\n");
-       printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
-       printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
-       printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
-/*     printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
-       printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
-       printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
-       printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
-       fputc('\n',stdout);
-#endif
-
-       assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
-       fd = fieldref->parseddesc.fd;
-       assert(fd);
-
-       /* record subtype constraints for the instance type, if any */
-       if (instanceti) {
-               typeinfo *insttip;
-
-               /* The instanceslot must contain a reference to a non-array type */
-               if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
-                       exceptions_throw_verifyerror(refmethod, 
-                                       "illegal instruction: field access on non-reference");
-                       return false;
-               }
-               if (TYPEINFO_IS_ARRAY(*instanceti)) {
-                       exceptions_throw_verifyerror(refmethod, 
-                                       "illegal instruction: field access on array");
-                       return false;
-               }
-
-               if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
-                               TYPEINFO_IS_NEWOBJECT(*instanceti))
-               {
-                       /* The instruction writes a field in an uninitialized object. */
-                       /* This is only allowed when a field of an uninitialized 'this' object is */
-                       /* written inside an initialization method                                */
-
-                       classinfo *initclass;
-                       instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
-
-                       if (ins != NULL) {
-                               exceptions_throw_verifyerror(refmethod, 
-                                               "accessing field of uninitialized object");
-                               return false;
-                       }
-                       /* XXX check that class of field == refmethod->class */
-                       initclass = refmethod->class; /* XXX classrefs */
-                       assert(initclass->state & CLASS_LOADED);
-                       assert(initclass->state & CLASS_LINKED);
-
-                       typeinfo_init_classinfo(&tinfo, initclass);
-                       insttip = &tinfo;
-               }
-               else {
-                       insttip = instanceti;
-               }
-               if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
-                                       &(ref->instancetypes), insttip, 
-                                       FIELDREF_CLASSNAME(fieldref)))
-                       return false;
-       }
-       else {
-               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
-       }
-
-       /* record subtype constraints for the value type, if any */
-       type = fd->type;
-       if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
-               assert(valueti);
-               if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
-                                       &(ref->valueconstraints), valueti, 
-                                       fieldref->parseddesc.fd->classref->name))
-                       return false;
-       }
-       else {
-               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
-       }
-
-       return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-/* resolve_create_unresolved_method ********************************************
-   Create an unresolved_method struct for the given method invocation
-  
-   IN:
-       referer..........the class containing the reference
-          refmethod........the method triggering the resolution (if any)
-          iptr.............the INVOKE* instruction
-
-   RETURN VALUE:
-       a pointer to a new unresolved_method struct, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-unresolved_method * resolve_create_unresolved_method(classinfo *referer,
-                                                                                                        methodinfo *refmethod,
-                                                                                                        constant_FMIref *methodref,
-                                                                                                        bool invokestatic,
-                                                                                                        bool invokespecial)
-{
-       unresolved_method *ref;
-
-       assert(methodref);
-
-#ifdef RESOLVE_VERBOSE
-       printf("create_unresolved_method\n");
-       printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
-       printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
-       printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
-       printf("    name   : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
-       printf("    desc   : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
-#endif
-
-       /* allocate params if necessary */
-       if (!methodref->parseddesc.md->params)
-               if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
-                                       (invokestatic) ? ACC_STATIC : ACC_NONE))
-                       return NULL;
-
-       /* create the data structure */
-       ref = NEW(unresolved_method);
-       ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
-                          | ((invokespecial) ? RESOLVE_SPECIAL : 0);
-       ref->referermethod = refmethod;
-       ref->methodref = methodref;
-       ref->paramconstraints = NULL;
-       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
-
-       return ref;
-}
-
-
-/* resolve_constrain_unresolved_method_instance ********************************
-   Record subtype constraints for the instance argument of a method call.
-  
-   IN:
-       ref..............the unresolved_method structure of the call
-       referer..........the class containing the reference
-          refmethod........the method triggering the resolution (if any)
-          iptr.............the INVOKE* instruction
-
-   RETURN VALUE:
-       true.............everything ok
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
-                                                                                                 methodinfo *refmethod,
-                                                                                                 typeinfo *instanceti,
-                                                                                                 bool invokespecial)
-{
-       constant_FMIref   *methodref;
-       constant_classref *instanceref;
-       typeinfo           tinfo;
-       typeinfo          *tip;
-
-       assert(ref);
-       methodref = ref->methodref;
-       assert(methodref);
-
-       /* XXX clean this up */
-       instanceref = IS_FMIREF_RESOLVED(methodref)
-               ? class_get_self_classref(methodref->p.method->class)
-               : methodref->p.classref;
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_constrain_unresolved_method_instance\n");
-       printf("    rmethod: "); method_println(refmethod);
-       printf("    mref   : "); method_methodref_println(methodref);
-#endif
-
-       /* record subtype constraints for the instance type, if any */
-
-       if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
-       {   /* XXX clean up */
-               instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
-               classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
-                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
-               tip = &tinfo;
-               if (!typeinfo_init_class(tip, initclass))
-                       return false;
-       }
-       else {
-               tip = instanceti;
-       }
-
-       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
-                               &(ref->instancetypes),tip,instanceref->name))
-               return false;
-
-       return true;
-}
-#endif /* defined(ENABLE_VERIFIER) */
-
-
-/* resolve_constrain_unresolved_method_params  *********************************
-   Record subtype constraints for the non-instance arguments of a method call.
-  
-   IN:
-       jd...............current jitdata (for looking up variables)
-       ref..............the unresolved_method structure of the call
-          refmethod........the method triggering the resolution (if any)
-          iptr.............the INVOKE* instruction
-
-   RETURN VALUE:
-       true.............everything ok
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool resolve_constrain_unresolved_method_params(jitdata *jd,
-                                                                                               unresolved_method *ref,
-                                                                                               methodinfo *refmethod,
-                                                                                               instruction *iptr)
-{
-       constant_FMIref *methodref;
-       varinfo *param;
-       methoddesc *md;
-       int i,j;
-       int type;
-       int instancecount;
-
-       assert(ref);
-       methodref = ref->methodref;
-       assert(methodref);
-       md = methodref->parseddesc.md;
-       assert(md);
-       assert(md->params != NULL);
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_constrain_unresolved_method_params\n");
-       printf("    rmethod: "); method_println(refmethod);
-       printf("    mref   : "); method_methodref_println(methodref);
-#endif
-
-       instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
-
-       /* record subtype constraints for the parameter types, if any */
-
-       for (i=md->paramcount-1-instancecount; i>=0; --i) {
-               param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
-               type = md->paramtypes[i+instancecount].type;
-
-               assert(param);
-               assert(type == param->type);
-
-               if (type == TYPE_ADR) {
-                       if (!ref->paramconstraints) {
-                               ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
-                               for (j=md->paramcount-1-instancecount; j>i; --j)
-                                       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
-                       }
-                       assert(ref->paramconstraints);
-                       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
-                                               ref->paramconstraints + i,&(param->typeinfo),
-                                               md->paramtypes[i+instancecount].classref->name))
-                               return false;
-               }
-               else {
-                       if (ref->paramconstraints)
-                               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
-               }
-       }
-
-       return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-
-/* resolve_constrain_unresolved_method_params_stackbased ***********************
-   Record subtype constraints for the non-instance arguments of a method call.
-  
-   IN:
-       ref..............the unresolved_method structure of the call
-          refmethod........the method triggering the resolution (if any)
-          stack............TOS before the INVOKE instruction
-
-   RETURN VALUE:
-       true.............everything ok
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-#if defined(ENABLE_VERIFIER)
-bool resolve_constrain_unresolved_method_params_stackbased(
-               unresolved_method *ref,
-               methodinfo *refmethod,
-               typedescriptor *stack)
-{
-       constant_FMIref *methodref;
-       typedescriptor *param;
-       methoddesc *md;
-       int i,j;
-       int type;
-       int instancecount;
-
-       assert(ref);
-       methodref = ref->methodref;
-       assert(methodref);
-       md = methodref->parseddesc.md;
-       assert(md);
-       assert(md->params != NULL);
-
-#ifdef RESOLVE_VERBOSE
-       printf("resolve_constrain_unresolved_method_params_stackbased\n");
-       printf("    rmethod: "); method_println(refmethod);
-       printf("    mref   : "); method_methodref_println(methodref);
-#endif
-
-       instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
-
-       /* record subtype constraints for the parameter types, if any */
-
-       param = stack - (md->paramslots - 1 - instancecount);
-
-       for (i = instancecount; i < md->paramcount; ++i) {
-               type = md->paramtypes[i].type;
-
-               assert(type == param->type);
-
-               if (type == TYPE_ADR) {
-                       if (!ref->paramconstraints) {
-                               ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
-                               for (j = 0; j < i - instancecount; ++j)
-                                       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
-                       }
-                       assert(ref->paramconstraints);
-                       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
-                                               ref->paramconstraints + i - instancecount,&(param->typeinfo),
-                                               md->paramtypes[i].classref->name))
-                               return false;
-               }
-               else {
-                       if (ref->paramconstraints)
-                               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
-               }
-
-               param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
-       }
-
-       return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-
-/******************************************************************************/
-/* FREEING MEMORY                                                             */
-/******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
-{
-       if (list) {
-               classref_or_classinfo *p = list;
-
-               /* this is silly. we *only* need to count the elements for MFREE */
-               while ((p++)->any)
-                       ;
-               MFREE(list,classref_or_classinfo,(p - list));
-       }
-}
-#endif /* ENABLE_VERIFIER */
-
-/* unresolved_class_free *******************************************************
-   Free the memory used by an unresolved_class
-  
-   IN:
-       ref..............the unresolved_class
-
-*******************************************************************************/
-
-void unresolved_class_free(unresolved_class *ref)
-{
-       assert(ref);
-
-#ifdef ENABLE_VERIFIER
-       unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
-#endif
-       FREE(ref,unresolved_class);
-}
-
-/* unresolved_field_free *******************************************************
-   Free the memory used by an unresolved_field
-  
-   IN:
-       ref..............the unresolved_field
-
-*******************************************************************************/
-
-void unresolved_field_free(unresolved_field *ref)
-{
-       assert(ref);
-
-#ifdef ENABLE_VERIFIER
-       unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
-       unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
-#endif
-       FREE(ref,unresolved_field);
-}
-
-/* unresolved_method_free ******************************************************
-   Free the memory used by an unresolved_method
-  
-   IN:
-       ref..............the unresolved_method
-
-*******************************************************************************/
-
-void unresolved_method_free(unresolved_method *ref)
-{
-       assert(ref);
-
-#ifdef ENABLE_VERIFIER
-       unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
-       if (ref->paramconstraints) {
-               int i;
-               int count = ref->methodref->parseddesc.md->paramcount;
-
-               for (i=0; i<count; ++i)
-                       unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
-               MFREE(ref->paramconstraints,unresolved_subtype_set,count);
-       }
-#endif
-       FREE(ref,unresolved_method);
-}
-
-/******************************************************************************/
-/* DEBUG DUMPS                                                                */
-/******************************************************************************/
-
-#if !defined(NDEBUG)
-
-/* unresolved_subtype_set_debug_dump *******************************************
-   Print debug info for unresolved_subtype_set to stream
-  
-   IN:
-       stset............the unresolved_subtype_set
-          file.............the stream
-
-*******************************************************************************/
-
-void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
-{
-       classref_or_classinfo *p;
-
-       if (SUBTYPESET_IS_EMPTY(*stset)) {
-               fprintf(file,"        (empty)\n");
-       }
-       else {
-               p = stset->subtyperefs;
-               for (;p->any; ++p) {
-                       if (IS_CLASSREF(*p)) {
-                               fprintf(file,"        ref: ");
-                               utf_fprint_printable_ascii(file,p->ref->name);
-                       }
-                       else {
-                               fprintf(file,"        cls: ");
-                               utf_fprint_printable_ascii(file,p->cls->name);
-                       }
-                       fputc('\n',file);
-               }
-       }
-}
-
-/* unresolved_class_debug_dump *************************************************
-   Print debug info for unresolved_class to stream
-  
-   IN:
-       ref..............the unresolved_class
-          file.............the stream
-
-*******************************************************************************/
-
-void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
-{
-       fprintf(file,"unresolved_class(%p):\n",(void *)ref);
-       if (ref) {
-               fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
-               fprintf(file,"    refmethod : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
-               fprintf(file,"    refmethodd: ");
-               utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
-               fprintf(file,"    classname : ");
-               utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
-               fprintf(file,"    subtypeconstraints:\n");
-               unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
-       }
-}
-
-/* unresolved_field_debug_dump *************************************************
-   Print debug info for unresolved_field to stream
-  
-   IN:
-       ref..............the unresolved_field
-          file.............the stream
-
-*******************************************************************************/
-
-void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
-{
-       fprintf(file,"unresolved_field(%p):\n",(void *)ref);
-       if (ref) {
-               fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
-               fprintf(file,"    refmethod : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
-               fprintf(file,"    refmethodd: ");
-               utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
-               fprintf(file,"    classname : ");
-               utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
-               fprintf(file,"    name      : ");
-               utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
-               fprintf(file,"    descriptor: ");
-               utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
-               fprintf(file,"    parseddesc: ");
-               descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
-               fprintf(file,"    flags     : %04x\n",ref->flags);
-               fprintf(file,"    instancetypes:\n");
-               unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
-               fprintf(file,"    valueconstraints:\n");
-               unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
-       }
-}
-
-/* unresolved_method_debug_dump ************************************************
-   Print debug info for unresolved_method to stream
-  
-   IN:
-       ref..............the unresolved_method
-          file.............the stream
-
-*******************************************************************************/
-
-void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
-{
-       int i;
-
-       fprintf(file,"unresolved_method(%p):\n",(void *)ref);
-       if (ref) {
-               fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
-               fprintf(file,"    refmethod : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
-               fprintf(file,"    refmethodd: ");
-               utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
-               fprintf(file,"    classname : ");
-               utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
-               fprintf(file,"    name      : ");
-               utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
-               fprintf(file,"    descriptor: ");
-               utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
-               fprintf(file,"    parseddesc: ");
-               descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
-               fprintf(file,"    flags     : %04x\n",ref->flags);
-               fprintf(file,"    instancetypes:\n");
-               unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
-               fprintf(file,"    paramconstraints:\n");
-               if (ref->paramconstraints) {
-                       for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
-                               fprintf(file,"      param %d:\n",i);
-                               unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
-                       }
-               }
-               else {
-                       fprintf(file,"      (empty)\n");
-               }
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-/*
- * 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:
- */
-
diff --git a/src/vm/resolve.h b/src/vm/resolve.h
deleted file mode 100644 (file)
index 5abc7dc..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/* src/vm/resolve.h - resolving classes/interfaces/fields/methods
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id: resolve.h 6241 2006-12-26 23:42:35Z twisti $
-
-*/
-
-
-#ifndef _RESOLVE_H
-#define _RESOLVE_H
-
-/* forward declarations *******************************************************/
-
-typedef struct unresolved_class unresolved_class;
-typedef struct unresolved_field unresolved_field;
-typedef struct unresolved_method unresolved_method;
-typedef struct unresolved_subtype_set unresolved_subtype_set;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/class.h"
-#include "vm/field.h"
-#include "vm/global.h"
-#include "vm/method.h"
-#include "vm/references.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/reg.h"
-#include "vm/jit/verify/typeinfo.h"
-
-
-/* constants ******************************************************************/
-
-#define RESOLVE_STATIC    0x0001  /* ref to static fields/methods             */
-#define RESOLVE_PUTFIELD  0x0002  /* field ref inside a PUT{FIELD,STATIC}...  */
-#define RESOLVE_SPECIAL   0x0004  /* method ref inside INVOKESPECIAL          */
-
-
-/* enums **********************************************************************/
-
-typedef enum {
-       resolveLazy,
-       resolveEager
-} resolve_mode_t;
-
-typedef enum {
-       resolveLinkageError,
-       resolveIllegalAccessError
-} resolve_err_t;
-
-typedef enum {
-       resolveFailed = false,  /* this must be a false value */
-       resolveDeferred = true, /* this must be a true value  */
-       resolveSucceeded
-} resolve_result_t;
-
-/* structs ********************************************************************/
-
-struct unresolved_subtype_set {
-       classref_or_classinfo *subtyperefs;     /* NULL terminated list */
-};
-
-struct unresolved_class {
-       constant_classref      *classref;
-       methodinfo                     *referermethod;
-       unresolved_subtype_set  subtypeconstraints;
-};
-
-/* XXX unify heads of unresolved_field and unresolved_method? */
-
-struct unresolved_field {
-       constant_FMIref *fieldref;
-       methodinfo      *referermethod;
-       s4               flags;
-       
-       unresolved_subtype_set  instancetypes;
-       unresolved_subtype_set  valueconstraints;
-};
-
-struct unresolved_method {
-       constant_FMIref *methodref;
-       methodinfo      *referermethod;
-       s4               flags;
-       
-       unresolved_subtype_set  instancetypes;
-       unresolved_subtype_set *paramconstraints;
-};
-
-#define SUBTYPESET_IS_EMPTY(stset) \
-       ((stset).subtyperefs == NULL)
-
-#define UNRESOLVED_SUBTYPE_SET_EMTPY(stset) \
-       do { (stset).subtyperefs = NULL; } while(0)
-
-/* function prototypes ********************************************************/
-
-bool resolve_class_from_name(classinfo* referer,methodinfo *refmethod,
-                                               utf *classname,
-                                               resolve_mode_t mode,
-                                               bool checkaccess,
-                                               bool link,
-                                               classinfo **result);
-
-bool resolve_classref(methodinfo *refmethod,
-                                constant_classref *ref,
-                                resolve_mode_t mode,
-                                bool checkaccess,
-                            bool link,
-                                classinfo **result);
-
-bool resolve_classref_or_classinfo(methodinfo *refmethod,
-                                                         classref_or_classinfo cls,
-                                                         resolve_mode_t mode,
-                                                         bool checkaccess,
-                                                         bool link,
-                                                         classinfo **result);
-
-bool resolve_class_from_typedesc(typedesc *d,bool checkaccess,bool link,classinfo **result);
-
-#ifdef ENABLE_VERIFIER
-bool resolve_class(unresolved_class *ref,
-                         resolve_mode_t mode,
-                         bool checkaccess,
-                         classinfo **result);
-
-classinfo * resolve_class_eager(unresolved_class *ref);
-#endif /* ENABLE_VERIFIER */
-
-bool resolve_field(unresolved_field *ref,
-                         resolve_mode_t mode,
-                         fieldinfo **result);
-
-bool resolve_method(unresolved_method *ref,
-                         resolve_mode_t mode,
-                          methodinfo **result);
-
-classinfo * resolve_classref_eager(constant_classref *ref);
-classinfo * resolve_classref_eager_nonabstract(constant_classref *ref);
-fieldinfo * resolve_field_eager(unresolved_field *ref);
-methodinfo * resolve_method_eager(unresolved_method *ref);
-
-#ifdef ENABLE_VERIFIER
-unresolved_class * create_unresolved_class(methodinfo *refmethod,
-                                               constant_classref *classref,
-                                               typeinfo *valuetype);
-#endif
-
-unresolved_field *resolve_create_unresolved_field(classinfo *referer,
-                                                                                         methodinfo *refmethod,
-                                                                                         instruction *iptr);
-
-unresolved_method * resolve_create_unresolved_method(classinfo *referer,
-                                                                                                        methodinfo *refmethod,
-                                                                                                        constant_FMIref *methodref,
-                                                                                                        bool invokestatic,
-                                                                                                        bool invokespecial);
-
-void unresolved_class_free(unresolved_class *ref);
-void unresolved_field_free(unresolved_field *ref);
-void unresolved_method_free(unresolved_method *ref);
-
-resolve_result_t resolve_method_lazy(methodinfo *refmethod,
-                                                                        constant_FMIref *methodref,
-                                                                        bool invokespecial);
-
-resolve_result_t resolve_field_lazy(methodinfo *refmethod,
-                                                                       constant_FMIref *fieldref);
-
-#if defined(ENABLE_VERIFIER)
-resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
-                                                                                          constant_FMIref *fieldref,
-                                                                                          classinfo *container,
-                                                                                          fieldinfo *fi,
-                                                                                          typeinfo *instanceti,
-                                                                                          typeinfo *valueti,
-                                                                                          bool isstatic,
-                                                                                          bool isput);
-
-bool resolve_constrain_unresolved_field(unresolved_field *ref,
-                                                                               classinfo *referer, 
-                                                                               methodinfo *refmethod,
-                                                                           typeinfo *instanceti,
-                                                                           typeinfo *valueti);
-
-resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
-                                                                                               constant_FMIref *methodref,
-                                                                                               methodinfo *mi,
-                                                                                               bool invokestatic);
-
-resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
-                                                                                                        methodinfo *mi,
-                                                                                                        typeinfo *instanceti,
-                                                                                                        bool invokespecial);
-
-resolve_result_t resolve_method_param_type_checks(jitdata *jd, 
-                                                                                                 methodinfo *refmethod,
-                                                                                                 instruction *iptr, 
-                                                                                                 methodinfo *mi,
-                                                                                                 bool invokestatic);
-
-resolve_result_t resolve_method_param_type_checks_stackbased(
-               methodinfo *refmethod, 
-               methodinfo *mi,
-               bool invokestatic, 
-               typedescriptor *stack);
-
-bool resolve_method_loading_constraints(classinfo *referer,
-                                                                               methodinfo *mi);
-
-bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
-                                                                                                 methodinfo *refmethod,
-                                                                                                 typeinfo *instanceti,
-                                                                                                 bool invokespecial);
-
-bool resolve_constrain_unresolved_method_params(jitdata *jd,
-                                                                                               unresolved_method *ref,
-                                                                                               methodinfo *refmethod,
-                                                                                               instruction *iptr);
-
-bool resolve_constrain_unresolved_method_params_stackbased(
-               unresolved_method *ref,
-               methodinfo *refmethod,
-               typedescriptor *stack);
-
-#endif /* defined(ENABLE_VERIFIER) */
-
-#ifndef NDEBUG
-void unresolved_class_debug_dump(unresolved_class *ref,FILE *file);
-void unresolved_field_debug_dump(unresolved_field *ref,FILE *file);
-void unresolved_method_debug_dump(unresolved_method *ref,FILE *file);
-void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file);
-#endif
-       
-#endif /* _RESOLVE_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
-
diff --git a/src/vm/rt-timing.c b/src/vm/rt-timing.c
deleted file mode 100644 (file)
index c16fbe0..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/* src/vm/rt-timing.c - POSIX real-time timing utilities
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id$
-
-*/
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "vm/rt-timing.h"
-#include "mm/memory.h"
-#include "vm/global.h"
-
-struct rt_timing_stat {
-       int index;
-       int totalindex;
-       const char *name;
-};
-
-static struct rt_timing_stat rt_timing_stat_defs[] = {
-    { RT_TIMING_JIT_CHECKS      ,RT_TIMING_JIT_TOTAL , "checks at beginning" },
-    { RT_TIMING_JIT_PARSE       ,RT_TIMING_JIT_TOTAL , "parse" },
-    { RT_TIMING_JIT_STACK       ,RT_TIMING_JIT_TOTAL , "analyse_stack" },
-    { RT_TIMING_JIT_TYPECHECK   ,RT_TIMING_JIT_TOTAL , "typecheck" },
-    { RT_TIMING_JIT_LOOP        ,RT_TIMING_JIT_TOTAL , "loop" },
-    { RT_TIMING_JIT_IFCONV      ,RT_TIMING_JIT_TOTAL , "if conversion" },
-    { RT_TIMING_JIT_ALLOC       ,RT_TIMING_JIT_TOTAL , "register allocation" },
-    { RT_TIMING_JIT_RPLPOINTS   ,RT_TIMING_JIT_TOTAL , "replacement point generation" },
-    { RT_TIMING_JIT_CODEGEN     ,RT_TIMING_JIT_TOTAL , "codegen" },
-    { RT_TIMING_JIT_TOTAL       ,-1                  , "total compile time" },
-    { -1                        ,-1                  , "" },
-
-    { RT_TIMING_LINK_RESOLVE    ,RT_TIMING_LINK_TOTAL, "link: resolve superclass/superinterfaces"},
-    { RT_TIMING_LINK_C_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute vftbl length"},
-    { RT_TIMING_LINK_ABSTRACT   ,RT_TIMING_LINK_TOTAL, "link: handle abstract methods"},
-    { RT_TIMING_LINK_C_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute interface table"},
-    { RT_TIMING_LINK_F_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill vftbl"},
-    { RT_TIMING_LINK_OFFSETS    ,RT_TIMING_LINK_TOTAL, "link: set offsets"},
-    { RT_TIMING_LINK_F_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill interface table"},
-    { RT_TIMING_LINK_FINALIZER  ,RT_TIMING_LINK_TOTAL, "link: set finalizer"},
-    { RT_TIMING_LINK_EXCEPTS    ,RT_TIMING_LINK_TOTAL, "link: resolve exception classes"},
-    { RT_TIMING_LINK_SUBCLASS   ,RT_TIMING_LINK_TOTAL, "link: re-calculate subclass indices"},
-    { RT_TIMING_LINK_TOTAL      ,-1                  , "total link time" },
-    { -1                        ,-1                  , "" },
-       
-       { RT_TIMING_LOAD_CHECKS     ,RT_TIMING_LOAD_TOTAL, "load: initial checks"},
-       { RT_TIMING_LOAD_NDPOOL     ,RT_TIMING_LOAD_TOTAL, "load: new descriptor pool"},
-       { RT_TIMING_LOAD_CPOOL      ,RT_TIMING_LOAD_TOTAL, "load: load constant pool"},
-       { RT_TIMING_LOAD_SETUP      ,RT_TIMING_LOAD_TOTAL, "load: class setup"},
-       { RT_TIMING_LOAD_FIELDS     ,RT_TIMING_LOAD_TOTAL, "load: load fields"},
-       { RT_TIMING_LOAD_METHODS    ,RT_TIMING_LOAD_TOTAL, "load: load methods"},
-       { RT_TIMING_LOAD_CLASSREFS  ,RT_TIMING_LOAD_TOTAL, "load: create classrefs"},
-       { RT_TIMING_LOAD_DESCS      ,RT_TIMING_LOAD_TOTAL, "load: allocate descriptors"},
-       { RT_TIMING_LOAD_SETREFS    ,RT_TIMING_LOAD_TOTAL, "load: set classrefs"},
-       { RT_TIMING_LOAD_PARSEFDS   ,RT_TIMING_LOAD_TOTAL, "load: parse field descriptors"},
-       { RT_TIMING_LOAD_PARSEMDS   ,RT_TIMING_LOAD_TOTAL, "load: parse method descriptors"},
-       { RT_TIMING_LOAD_PARSECP    ,RT_TIMING_LOAD_TOTAL, "load: parse descriptors in constant pool"},
-       { RT_TIMING_LOAD_VERIFY     ,RT_TIMING_LOAD_TOTAL, "load: verifier checks"},
-       { RT_TIMING_LOAD_ATTRS      ,RT_TIMING_LOAD_TOTAL, "load: load attributes"},
-       { RT_TIMING_LOAD_TOTAL      ,-1                  , "total load time (from classbuffer)"},
-    { -1                        ,-1                  , "" },
-
-       { RT_TIMING_LOAD_BOOT_LOOKUP,-1                       , "boot: lookup in classcache"},
-       { RT_TIMING_LOAD_BOOT_ARRAY ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load array classes"},
-       { RT_TIMING_LOAD_BOOT_SUCK  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: suck class files"},
-       { RT_TIMING_LOAD_BOOT_LOAD  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load from class buffer"},
-       { RT_TIMING_LOAD_BOOT_CACHE ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: store in classcache"},
-       { RT_TIMING_LOAD_BOOT_TOTAL ,-1                       , "total bootstrap loader time"},
-    { -1                        ,-1                       , "" },
-
-       { RT_TIMING_LOAD_CL_LOOKUP  ,-1                       , "classloader: lookup in classcache" },
-       { RT_TIMING_LOAD_CL_PREPARE ,-1                       , "classloader: prepare loader call" },
-       { RT_TIMING_LOAD_CL_JAVA    ,-1                       , "classloader: loader Java code" },
-       { RT_TIMING_LOAD_CL_CACHE   ,-1                       , "classloader: store in classcache" },
-    { -1                        ,-1                       , "" },
-
-       { RT_TIMING_NEW_OBJECT      ,-1                       , "builtin_new time" },
-       { RT_TIMING_NEW_ARRAY       ,-1                       , "builtin_newarray time" },
-    { -1                        ,-1                       , "" },
-
-    { 0                         ,-1                       , NULL }
-};
-
-static long long rt_timing_sum[RT_TIMING_N] = { 0 };
-
-void rt_timing_gettime(struct timespec *ts)
-{
-       if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,ts) != 0) {
-               fprintf(stderr,"could not get time by clock_gettime: %s\n",strerror(errno));
-               abort();
-       }
-}
-
-long rt_timing_diff_usec(struct timespec *a,struct timespec *b)
-{
-       long diff;
-       time_t atime;
-
-       diff = (b->tv_nsec - a->tv_nsec) / 1000;
-       atime = a->tv_sec;
-       while (atime < b->tv_sec) {
-               atime++;
-               diff += 1000000;
-       }
-       return diff;
-}
-
-void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index)
-{
-       long diff;
-
-       diff = rt_timing_diff_usec(a,b);
-       rt_timing_sum[index] += diff;
-}
-
-void rt_timing_print_time_stats(FILE *file)
-{
-       struct rt_timing_stat *stats;
-       double total;
-
-       for (stats = rt_timing_stat_defs; stats->name; ++stats) {
-               if (stats->index < 0) {
-                       fprintf(file,"%s\n",stats->name);
-                       continue;
-               }
-               
-               if (stats->totalindex >= 0) {
-                       total = rt_timing_sum[stats->totalindex];
-                       fprintf(file,"%12lld usec %3.0f%% %s\n",
-                                       rt_timing_sum[stats->index],
-                                       (total != 0.0) ? rt_timing_sum[stats->index] / total * 100.0 : 0.0,
-                                       stats->name);
-               }
-               else {
-                       fprintf(file,"%12lld usec      %s\n",
-                                       rt_timing_sum[stats->index],
-                                       stats->name);
-               }
-       }
-}
-
-/*
- * 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:
- */
diff --git a/src/vm/rt-timing.h b/src/vm/rt-timing.h
deleted file mode 100644 (file)
index 432f656..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* src/vm/rt-timing.h - POSIX real-time timing utilities
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes:
-
-   $Id$
-
-*/
-
-#ifndef _RT_TIMING_H
-#define _RT_TIMING_H
-
-#include "config.h"
-
-#if defined(ENABLE_RT_TIMING)
-
-#include "vm/types.h"
-
-#include <time.h>
-
-#include "mm/memory.h"
-#include "vm/global.h"
-
-#define RT_TIMING_GET_TIME(ts) \
-       rt_timing_gettime(&(ts));
-
-#define RT_TIMING_TIME_DIFF(a,b,index) \
-       rt_timing_time_diff(&(a),&(b),(index));
-
-#define RT_TIMING_JIT_CHECKS       0
-#define RT_TIMING_JIT_PARSE        1
-#define RT_TIMING_JIT_STACK        2
-#define RT_TIMING_JIT_TYPECHECK    3
-#define RT_TIMING_JIT_LOOP         4
-#define RT_TIMING_JIT_IFCONV       5
-#define RT_TIMING_JIT_ALLOC        6
-#define RT_TIMING_JIT_RPLPOINTS    7
-#define RT_TIMING_JIT_CODEGEN      8
-#define RT_TIMING_JIT_TOTAL        9
-
-#define RT_TIMING_LINK_RESOLVE     10
-#define RT_TIMING_LINK_C_VFTBL     11
-#define RT_TIMING_LINK_ABSTRACT    12
-#define RT_TIMING_LINK_C_IFTBL     13
-#define RT_TIMING_LINK_F_VFTBL     14
-#define RT_TIMING_LINK_OFFSETS     15
-#define RT_TIMING_LINK_F_IFTBL     16
-#define RT_TIMING_LINK_FINALIZER   17
-#define RT_TIMING_LINK_EXCEPTS     18
-#define RT_TIMING_LINK_SUBCLASS    19
-#define RT_TIMING_LINK_TOTAL       20
-
-#define RT_TIMING_LOAD_CHECKS      21
-#define RT_TIMING_LOAD_NDPOOL      22
-#define RT_TIMING_LOAD_CPOOL       23
-#define RT_TIMING_LOAD_SETUP       24
-#define RT_TIMING_LOAD_FIELDS      25
-#define RT_TIMING_LOAD_METHODS     26
-#define RT_TIMING_LOAD_CLASSREFS   27
-#define RT_TIMING_LOAD_DESCS       28
-#define RT_TIMING_LOAD_SETREFS     29
-#define RT_TIMING_LOAD_PARSEFDS    30
-#define RT_TIMING_LOAD_PARSEMDS    31
-#define RT_TIMING_LOAD_PARSECP     32
-#define RT_TIMING_LOAD_VERIFY      33
-#define RT_TIMING_LOAD_ATTRS       34
-#define RT_TIMING_LOAD_TOTAL       35
-
-#define RT_TIMING_LOAD_BOOT_LOOKUP 36
-#define RT_TIMING_LOAD_BOOT_ARRAY  37
-#define RT_TIMING_LOAD_BOOT_SUCK   38
-#define RT_TIMING_LOAD_BOOT_LOAD   39
-#define RT_TIMING_LOAD_BOOT_CACHE  40
-#define RT_TIMING_LOAD_BOOT_TOTAL  41
-
-#define RT_TIMING_LOAD_CL_LOOKUP   42
-#define RT_TIMING_LOAD_CL_PREPARE  43
-#define RT_TIMING_LOAD_CL_JAVA     44
-#define RT_TIMING_LOAD_CL_CACHE    45
-
-#define RT_TIMING_NEW_OBJECT       46
-#define RT_TIMING_NEW_ARRAY        47
-
-#define RT_TIMING_N                48
-
-void rt_timing_gettime(struct timespec *ts);
-
-void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index);
-
-long rt_timing_diff_usec(struct timespec *a,struct timespec *b);
-
-void rt_timing_print_time_stats(FILE *file);
-
-#else /* !defined(ENABLE_RT_TIMING) */
-
-#define RT_TIMING_GET_TIME(ts)
-#define RT_TIMING_TIME_DIFF(a,b,index)
-
-#endif /* defined(ENABLE_RT_TIMING) */
-
-#endif /* _RT_TIMING_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
index c8e5a31dbbdf7368601310fc8adff4db5a4361ea..17279a70c89877aac7c316a86b9d5addc1aa5471 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/signal.c - machine independent signal functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: signal.c 6256 2006-12-28 12:30:09Z twisti $
+   $Id: signal.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "vm/types.h"
 
+#include "mm/memory.h"
+
+#include "native/jni.h"
+#include "native/include/java_lang_Thread.h"
+
+#if defined(WITH_CLASSPATH_GNU)
+# include "native/include/java_lang_VMThread.h"
+#endif
+
 #if defined(ENABLE_THREADS)
 # include "threads/native/threads.h"
 #endif
 
-#include "mm/memory.h"
+#include "vm/builtin.h"
 #include "vm/signallocal.h"
-#include "vm/options.h"
+#include "vm/stringlocal.h"
 #include "vm/vm.h"
 #include "vm/jit/stacktrace.h"
 
+#include "vmcore/options.h"
+
+
+/* global variables ***********************************************************/
+
+#if defined(ENABLE_THREADS)
+static threadobject *thread_signal;
+#endif
+
 
 /* function prototypes ********************************************************/
 
 void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p);
-void signal_handler_sigint(int sig, siginfo_t *siginfo, void *_p);
-void signal_handler_sigquit(int sig, siginfo_t *siginfo, void *_p);
 
 
 /* signal_init *****************************************************************
@@ -76,6 +88,7 @@ void signal_init(void)
 #if !defined(__CYGWIN__)
        int              pagesize;
        struct sigaction act;
+       sigset_t         mask;
 
        /* mmap a memory page at address 0x0, so our hardware-exceptions
           work. */
@@ -91,7 +104,8 @@ void signal_init(void)
        (void) GCNEW(u1);
 #endif
 
-       /* install signal handlers we need to convert to exceptions */
+       /* Install signal handlers for signals we want to catch in all
+          threads. */
 
        sigemptyset(&act.sa_mask);
 
@@ -99,7 +113,7 @@ void signal_init(void)
 # if defined(ENABLE_INTRP)
        if (!opt_intrp) {
 # endif
-               /* catch NullPointerException/StackOverFlowException */
+               /* SIGSEGV handler */
 
                act.sa_sigaction = md_signal_handler_sigsegv;
                act.sa_flags     = SA_NODEFER | SA_SIGINFO;
@@ -112,9 +126,9 @@ void signal_init(void)
                sigaction(SIGBUS, &act, NULL);
 #endif
 
-               /* catch ArithmeticException */
-
 #if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
+               /* SIGFPE handler */
+
                act.sa_sigaction = md_signal_handler_sigfpe;
                act.sa_flags     = SA_NODEFER | SA_SIGINFO;
                sigaction(SIGFPE, &act, NULL);
@@ -125,93 +139,149 @@ void signal_init(void)
 #endif /* !defined(ENABLE_INTRP) */
 
 #if defined(ENABLE_THREADS)
-       /* catch SIGHUP for threads_thread_interrupt */
+       /* SIGHUP handler for threads_thread_interrupt */
 
        act.sa_sigaction = signal_handler_sighup;
        act.sa_flags     = 0;
        sigaction(SIGHUP, &act, NULL);
 #endif
 
-       /* catch SIGINT for exiting properly on <ctrl>-c */
-
-       act.sa_sigaction = signal_handler_sigint;
-       act.sa_flags     = SA_NODEFER | SA_SIGINFO;
-       sigaction(SIGINT, &act, NULL);
-
-#if defined(ENABLE_THREADS)
-       /* catch SIGQUIT for thread dump */
-
-# if !defined(__FREEBSD__)
-       act.sa_sigaction = signal_handler_sigquit;
-       act.sa_flags     = SA_SIGINFO;
-       sigaction(SIGQUIT, &act, NULL);
-# endif
-#endif
-
 #if defined(ENABLE_THREADS) && defined(ENABLE_PROFILING)
-       /* install signal handler for profiling sampling */
+       /* SIGUSR2 handler for profiling sampling */
 
        act.sa_sigaction = md_signal_handler_sigusr2;
        act.sa_flags     = SA_SIGINFO;
        sigaction(SIGUSR2, &act, NULL);
 #endif
 
+       /* Block the following signals (SIGINT for <ctrl>-c, SIGQUIT for
+          <ctrl>-\).  We enable them later in signal_thread, but only for
+          this thread. */
+
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGINT);
+#if !defined(__FREEBSD__)
+       sigaddset(&mask, SIGQUIT);
+#endif
+       sigprocmask(SIG_BLOCK, &mask, NULL);
+
 #endif /* !defined(__CYGWIN__) */
 }
 
 
-/* signal_handler_sighup *******************************************************
+/* signal_thread ************************************************************
 
-   This handler is required by threads_thread_interrupt and does
-   nothing.
+   This thread sets the signal mask to catch the user input signals
+   (SIGINT, SIGQUIT).  We use such a thread, so we don't get the
+   signals on every single thread running.  Especially, this makes
+   problems on slow machines.
 
 *******************************************************************************/
 
-#if defined(ENABLE_THREADS)
-void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p)
+static void signal_thread(void)
 {
-       /* do nothing */
-}
+       sigset_t mask;
+       int      sig;
+
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGINT);
+#if !defined(__FREEBSD__)
+       sigaddset(&mask, SIGQUIT);
 #endif
 
+       while (true) {
+               /* just wait for a signal */
 
-/* signal_handler_sigquit ******************************************************
+               sigwait(&mask, &sig);
 
-   Handle for SIGQUIT (<ctrl>-\) which print a stacktrace for every
-   running thread.
+               switch (sig) {
+               case SIGINT:
+                       /* exit the vm properly */
 
-*******************************************************************************/
+                       vm_exit(0);
+                       break;
 
-#if defined(ENABLE_THREADS)
-void signal_handler_sigquit(int sig, siginfo_t *siginfo, void *_p)
-{
-       /* do thread dump */
+               case SIGQUIT:
+                       /* print a thread dump */
 
-       threads_dump();
-}
+                       threads_dump();
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               statistics_print_memory_usage();
 #endif
+                       break;
+               }
+       }
+
+       /* this should not happen */
+
+       vm_abort("signal_thread: this thread should not exit!");
+}
 
 
-/* signal_handler_sigint *******************************************************
+/* signal_start_thread *********************************************************
 
-   Handler for SIGINT (<ctrl>-c) which shuts down CACAO properly with
-   Runtime.exit(I)V.
+   Starts the signal handler thread.
 
 *******************************************************************************/
 
-void signal_handler_sigint(int sig, siginfo_t *siginfo, void *_p)
+bool signal_start_thread(void)
 {
-       /* if we are already in Runtime.exit(), just do it hardcore */
+#if defined(ENABLE_THREADS)
+#if defined(WITH_CLASSPATH_GNU)
+       java_lang_VMThread *vmt;
+#endif
 
-       if (vm_exiting) {
-               fprintf(stderr, "Caught SIGINT while already shutting down. Shutdown aborted...\n");
-               exit(0);
-       }
+       /* create the finalizer object */
+
+       thread_signal = (threadobject *) builtin_new(class_java_lang_Thread);
+
+       if (thread_signal == NULL)
+               return false;
+
+#if defined(WITH_CLASSPATH_GNU)
+       vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+
+       vmt->thread = (java_lang_Thread *) thread_signal;
+
+       thread_signal->o.vmThread = vmt;
+#endif
+
+       thread_signal->flags      = THREAD_FLAG_DAEMON;
+
+       thread_signal->o.name     = javastring_new_from_ascii("Signal Handler");
+#if defined(ENABLE_JAVASE)
+       thread_signal->o.daemon   = true;
+#endif
+       thread_signal->o.priority = 5;
 
-       /* exit the vm properly */
+       /* actually start the finalizer thread */
 
-       vm_exit(0);
+       threads_start_thread(thread_signal, signal_thread);
+
+       /* everything's ok */
+
+       return true;
+#else
+#error FIX ME!
+#endif
+}
+
+
+/* signal_handler_sighup *******************************************************
+
+   This handler is required by threads_thread_interrupt and does
+   nothing.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p)
+{
+       /* do nothing */
 }
+#endif
 
 
 /*
index f10a4dd10fc9e4a59b51627840c6195be0b5e5b6..0ee51976b0d7c03cf6880c210cfe475a2e2a995b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/signallocal.h - machine independent signal functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: signallocal.h 6172 2006-12-11 19:43:41Z twisti $
+   $Id: signallocal.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -42,6 +38,7 @@
 /* function prototypes ********************************************************/
 
 void signal_init(void);
+bool signal_start_thread(void);
 
 /* machine dependent signal handler */
 
diff --git a/src/vm/stackmap.c b/src/vm/stackmap.c
deleted file mode 100644 (file)
index 93c1b70..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/* src/vm/stackmap.c - class attribute StackMapTable
-
-   Copyright (C) 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
-
-*/
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "vm/class.h"
-#include "vm/exceptions.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/stackmap.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-#include "vm/suck.h"
-
-
-/* stackmap_get_verification_type_info *****************************************
-
-   union verification_type_info {
-       Top_variable_info;
-          Integer_variable_info;
-          Float_variable_info;
-          Long_variable_info;
-          Double_variable_info;
-          Null_variable_info;
-          UninitializedThis_variable_info;
-          Object_variable_info;
-          Uninitialized_variable_info;
-   }
-
-   Top_variable_info {
-       u1 tag = ITEM_Top;  // 0
-   }
-
-   Integer_variable_info {
-       u1 tag = ITEM_Integer;  // 1
-   }
-
-   Float_variable_info {
-       u1 tag = ITEM_Float;  // 2
-   }
-
-   Long_variable_info {
-       u1 tag = ITEM_Long;  // 4
-   }
-
-   Double_variable_info {
-       u1 tag = ITEM_Double;  // 3
-   }
-
-   Null_variable_info {
-       u1 tag = ITEM_Null;  // 5
-   }
-
-   UninitializedThis_variable_info {
-       u1 tag = ITEM_UninitializedThis;  // 6
-   }
-
-   Object_variable_info {
-       u1 tag = ITEM_Object;  // 7
-          u2 cpool_index;
-   }
-
-   Uninitialized_variable_info {
-       u1 tag = ITEM_Uninitialized;  // 8
-          u2 offset;
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
-{
-       /* get verification type */
-
-       if (!suck_check_classbuffer_size(cb, 1))
-               return false;
-
-       verification_type_info->tag = suck_u1(cb);
-
-       /* process the tag */
-
-       switch (verification_type_info->tag) {
-       case ITEM_Top:
-       case ITEM_Integer:
-       case ITEM_Float:
-       case ITEM_Long:
-       case ITEM_Double:
-       case ITEM_Null:
-       case ITEM_UninitializedThis:
-               break;
-
-       case ITEM_Object:
-               /* get constant pool index */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
-               break;
-
-       case ITEM_Uninitialized:
-               /* get offset */
-
-               if (!suck_check_classbuffer_size(cb, 2))
-                       return false;
-
-               verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
-               break;
-       }
-
-       return true;
-}
-
-
-/* stackmap_get_same_locals_1_stack_item_frame *********************************
-
-   same_locals_1_stack_item_frame {
-       u1 frame_type = SAME_LOCALS_1_STACK_ITEM;  // 64-127
-          verification_type_info stack[1];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
-{
-       same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
-
-       /* for convenience */
-
-       same_locals_1_stack_item_frame =
-               &(stack_map_frame->same_locals_1_stack_item_frame);
-
-       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
-               return false;
-
-       return true;
-}
-
-
-/* stackmap_get_same_locals_1_stack_item_frame_extended ************************
-
-   same_locals_1_stack_item_frame_extended {
-       u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED;  // 247
-          u2 offset_delta;
-          verification_type_info stack[1];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
-{
-       same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
-
-       /* for convenience */
-
-       same_locals_1_stack_item_frame_extended =
-               &(stack_map_frame->same_locals_1_stack_item_frame_extended);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
-
-       /* process stack */
-
-       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
-               return false;
-
-       return true;
-}
-
-
-/* stackmap_get_chop_frame *****************************************************
-
-   chop_frame {
-       u1 frame_type = CHOP_FRAME;  // 248-250
-          u2 offset_delta;
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_chop_frame(classbuffer *cb,
-                                                                       stack_map_frame_t *stack_map_frame)
-{
-       chop_frame_t *chop_frame;
-
-       /* for convenience */
-
-       chop_frame = &(stack_map_frame->chop_frame);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       chop_frame->offset_delta = suck_u2(cb);
-
-       return true;
-}
-
-
-/* stackmap_get_same_frame_extended ********************************************
-
-   same_frame_extended {
-       u1 frame_type = SAME_FRAME_EXTENDED;  // 251
-          u2 offset_delta;
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_same_frame_extended(classbuffer *cb,
-                                                                                        stack_map_frame_t *stack_map_frame)
-{
-       same_frame_extended_t *same_frame_extended;
-
-       /* for convenience */
-
-       same_frame_extended = &(stack_map_frame->same_frame_extended);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       same_frame_extended->offset_delta = suck_u2(cb);
-
-       return true;
-}
-
-
-/* stackmap_get_append_frame ***************************************************
-
-   append_frame {
-       u1 frame_type = APPEND_FRAME;  // 252-254
-          u2 offset_delta;
-          verification_type_info locals[frame_Type - 251];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_append_frame(classbuffer *cb,
-                                                                         stack_map_frame_t *stack_map_frame)
-{
-       append_frame_t *append_frame;
-       s4              number_of_locals;
-       s4              i;
-
-       /* for convenience */
-
-       append_frame = &(stack_map_frame->append_frame);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       /* get offset delta */
-
-       append_frame->offset_delta = suck_u2(cb);
-
-       /* allocate locals array */
-
-       number_of_locals = append_frame->frame_type - 251;
-
-       append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
-
-       /* process all locals */
-
-       for (i = 0; i < number_of_locals; i++)
-               if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
-                       return false;
-
-       return true;
-}
-
-
-/* stackmap_get_full_frame *****************************************************
-
-   full_frame {
-       u1 frame_type = FULL_FRAME;
-          u2 offset_delta;
-          u2 number_of_locals;
-          verification_type_info locals[number_of_locals];
-          u2 number_of_stack_items;
-          verification_type_info stack[number_of_stack_items];
-   }
-
-*******************************************************************************/
-
-static bool stackmap_get_full_frame(classbuffer *cb,
-                                                                       stack_map_frame_t *stack_map_frame)
-{
-       full_frame_t *full_frame;
-       s4 i;
-
-       /* for convenience */
-
-       full_frame = &(stack_map_frame->full_frame);
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 2 + 2))
-               return false;
-
-       /*  get offset delta */
-
-       stack_map_frame->full_frame.offset_delta = suck_u2(cb);
-
-       /* get number of locals */
-
-       full_frame->number_of_locals = suck_u2(cb);
-
-       /* allocate locals array */
-
-       full_frame->locals =
-               DMNEW(verification_type_info_t, full_frame->number_of_locals);
-
-       /* process all locals */
-
-       for (i = 0; i < full_frame->number_of_locals; i++)
-               if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
-                       return false;
-
-       /* get number of stack items */
-
-       if (!suck_check_classbuffer_size(cb, 2))
-               return false;
-
-       full_frame->number_of_stack_items = suck_u2(cb);
-
-       /* allocate stack array */
-
-       full_frame->stack =
-               DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
-
-       /* process all stack items */
-
-       for (i = 0; i < full_frame->number_of_stack_items; i++)
-               if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
-                       return false;
-
-       return true;
-}
-
-
-/* stackmap_load_attribute_stackmaptable ***************************************
-
-   stack_map {
-          u2 attribute_name_index;
-          u4 attribute_length;
-          u2 number_of_entries;
-          stack_map_frame entries[number_of_entries];
-   }
-
-   union stack_map_frame {
-       same_frame;
-          same_locals_1_stack_item_frame;
-          same_locals_1_stack_item_frame_extended;
-          chop_frame;
-          same_frame_extended;
-          append_frame;
-          full_frame;
-   }
-
-   same_frame {
-       u1 frame_type = SAME;  // 0-63
-   }
-
-*******************************************************************************/
-
-bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
-{
-       classinfo       *c;
-       stack_map_t     *stack_map;
-       s4               i;
-       u1               frame_type;
-
-       /* get classinfo */
-
-       c = cb->class;
-
-       /* allocate stack map structure */
-
-       stack_map = DNEW(stack_map_t);
-
-       STATISTICS(size_stack_map += sizeof(stack_map_t));
-
-       /* check buffer size */
-
-       if (!suck_check_classbuffer_size(cb, 4 + 2))
-               return false;
-
-       /* attribute_length */
-
-       stack_map->attribute_length = suck_u4(cb);
-
-       if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
-               return false;
-
-       /* get number of entries */
-
-       stack_map->number_of_entries = suck_u2(cb);
-
-       /* process all entries */
-
-       stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
-
-       for (i = 0; i < stack_map->number_of_entries; i++) {
-               /* get the frame type */
-
-               frame_type = suck_u1(cb);
-
-               stack_map->entries[i].frame_type = frame_type;
-
-               /* process frame */
-
-               if (frame_type <= FRAME_TYPE_SAME) {
-                       /* same_frame */
-               }
-               else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
-                       /* same_locals_1_stack_item_frame */
-
-                       if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type <= FRAME_TYPE_RESERVED) {
-                       /* reserved */
-
-                       exceptions_throw_classformaterror(c, "reserved frame type");
-                       return false;
-               }
-               else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
-                       /* same_locals_1_stack_item_frame_extended */
-
-                       if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type <= FRAME_TYPE_CHOP) {
-                       /* chop_frame */
-
-                       if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
-                       /* same_frame_extended */
-
-                       if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type <= FRAME_TYPE_APPEND) {
-                       /* append_frame */
-
-                       if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-               else if (frame_type == FRAME_TYPE_FULL_FRAME) {
-                       /* full_frame */
-
-                       if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
-                               return false;
-               }
-       }
-
-       /* store stack map in method structure */
-
-#if 0
-       /* currently not used */
-
-       m->stack_map = stack_map;
-#endif
-
-       return true;
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/stackmap.h b/src/vm/stackmap.h
deleted file mode 100644 (file)
index e86c743..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/* src/vm/stackmap.h - class attribute StackMapTable
-
-   Copyright (C) 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
-
-*/
-
-
-#ifndef _STACKMAP_H
-#define _STACKMAP_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct stack_map_t                       stack_map_t;
-typedef union  stack_map_frame_t                 stack_map_frame_t;
-typedef struct same_locals_1_stack_item_frame_t  same_locals_1_stack_item_frame_t;
-typedef struct same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended_t;
-typedef struct chop_frame_t                      chop_frame_t;
-typedef struct same_frame_extended_t             same_frame_extended_t;
-typedef struct append_frame_t                    append_frame_t;
-typedef struct full_frame_t                      full_frame_t;
-
-typedef union  verification_type_info_t          verification_type_info_t;
-typedef struct Top_variable_info_t                  Top_variable_info_t;
-typedef struct Integer_variable_info_t           Integer_variable_info_t;
-typedef struct Float_variable_info_t             Float_variable_info_t;
-typedef struct Long_variable_info_t              Long_variable_info_t;
-typedef struct Double_variable_info_t            Double_variable_info_t;
-typedef struct Null_variable_info_t              Null_variable_info_t;
-typedef struct UninitializedThis_variable_info_t UninitializedThis_variable_info_t;
-typedef struct Object_variable_info_t            Object_variable_info_t;
-typedef struct Uninitialized_variable_info_t     Uninitialized_variable_info_t;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/method.h"
-
-
-/* verification_type_info *****************************************************/
-
-#define ITEM_Top                  0
-#define ITEM_Integer              1
-#define ITEM_Float                2
-#define ITEM_Double               3
-#define ITEM_Long                 4
-#define ITEM_Null                 5
-#define ITEM_UninitializedThis    6
-#define ITEM_Object               7
-#define ITEM_Uninitialized        8
-
-struct Top_variable_info_t {
-       u1 tag;
-};
-
-struct Integer_variable_info_t {
-       u1 tag;
-};
-
-struct Float_variable_info_t {
-       u1 tag;
-};
-
-struct Long_variable_info_t {
-       u1 tag;
-};
-
-struct Double_variable_info_t {
-       u1 tag;
-};
-
-struct Null_variable_info_t {
-       u1 tag;
-};
-
-struct UninitializedThis_variable_info_t {
-       u1 tag;
-};
-
-struct Object_variable_info_t {
-       u1 tag;
-       u2 cpool_index;
-};
-
-struct Uninitialized_variable_info_t {
-       u1 tag;
-       u2 offset;
-};
-
-union verification_type_info_t {
-       u1 tag;
-       Top_variable_info_t                   Top_variable_info;
-       Integer_variable_info_t           Integer_variable_info;
-       Float_variable_info_t             Float_variable_info;
-       Long_variable_info_t              Long_variable_info;
-       Double_variable_info_t            Double_variable_info;
-       Null_variable_info_t              Null_variable_info;
-       UninitializedThis_variable_info_t UninitializedThis_variable_info;
-       Object_variable_info_t            Object_variable_info;
-       Uninitialized_variable_info_t     Uninitialized_variable_info;
-};
-
-
-/* stack_map_t ****************************************************************/
-
-struct stack_map_t {
-       u2                 attribute_name_index;
-       u4                 attribute_length;
-       u2                 number_of_entries;
-       stack_map_frame_t *entries;
-};
-
-
-/* same_locals_1_stack_item_frame_t *******************************************/
-
-struct same_locals_1_stack_item_frame_t {
-       u1                       frame_type;
-       verification_type_info_t stack[1];
-};
-
-
-/* same_locals_1_stack_item_frame_extended_t **********************************/
-
-struct same_locals_1_stack_item_frame_extended_t {
-       u1                       frame_type;
-       u2                       offset_delta;
-       verification_type_info_t stack[1];
-};
-
-
-/* chop_frame_t ***************************************************************/
-
-struct chop_frame_t {
-       u1 frame_type;
-       u2 offset_delta;
-};
-
-
-/* same_frame_extended_t ******************************************************/
-
-struct same_frame_extended_t {
-       u1 frame_type;
-       u2 offset_delta;
-};
-
-
-/* append_frame_t *************************************************************/
-
-struct append_frame_t {
-       u1                        frame_type;
-       u2                        offset_delta;
-       verification_type_info_t *locals;
-};
-
-
-/* full_frame_t ***************************************************************/
-
-struct full_frame_t {
-       u1                        frame_type;
-       u2                        offset_delta;
-       u2                        number_of_locals;
-       verification_type_info_t *locals;
-       u2                        number_of_stack_items;
-       verification_type_info_t *stack;
-};
-
-
-/* stack_map_frame_t **********************************************************/
-
-#define FRAME_TYPE_SAME                                 63   /* 0-63          */
-#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM             127  /* 0-127         */
-#define FRAME_TYPE_RESERVED                             246  /* 128-246       */
-#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED    247  /* 247           */
-#define FRAME_TYPE_CHOP                                 250  /* 248-250       */
-#define FRAME_TYPE_SAME_FRAME_EXTENDED                  251  /* 251           */
-#define FRAME_TYPE_APPEND                               254  /* 252-254       */
-#define FRAME_TYPE_FULL_FRAME                           255  /* 255           */
-
-union stack_map_frame_t {
-       u1                                        frame_type;
-       same_locals_1_stack_item_frame_t          same_locals_1_stack_item_frame;
-       same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended;
-       chop_frame_t                              chop_frame;
-       same_frame_extended_t                     same_frame_extended;
-       append_frame_t                            append_frame;
-       full_frame_t                              full_frame;
-};
-
-
-/* function prototypes ********************************************************/
-
-bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m);
-
-#endif /* _STACKMAP_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
diff --git a/src/vm/statistics.c b/src/vm/statistics.c
deleted file mode 100644 (file)
index 0f142ea..0000000
+++ /dev/null
@@ -1,632 +0,0 @@
-/* src/vm/statistics.c - global varables for statistics
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: statistics.c 6216 2006-12-18 18:21:37Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <string.h> 
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include "vm/types.h"
-
-#include "toolbox/logging.h"
-#include "vm/global.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
-
-
-/* global variables ***********************************************************/
-
-static s8 loadingtime = 0;              /* accumulated loading time           */
-static s8 loadingstarttime = 0;
-static s8 loadingstoptime = 0;
-static s4 loadingtime_recursion = 0;
-
-static s8 compilingtime = 0;            /* accumulated compile time           */
-static s8 compilingstarttime = 0;
-static s8 compilingstoptime = 0;
-static s4 compilingtime_recursion = 0;
-
-s4 codememusage = 0;
-s4 maxcodememusage = 0;
-
-s4 memoryusage = 0;
-s4 maxmemusage = 0;
-
-s4 maxdumpsize = 0;
-
-s4 globalallocateddumpsize = 0;
-s4 globaluseddumpsize = 0;
-
-
-/* variables for measurements *************************************************/
-
-s4 size_classinfo  = 0;
-s4 size_fieldinfo  = 0;
-s4 size_methodinfo = 0;
-s4 size_codeinfo   = 0;
-
-s4 size_stack_map  = 0;
-
-int count_const_pool_len = 0;
-int count_classref_len = 0;
-int count_parsed_desc_len = 0;
-int count_vftbl_len = 0;
-int count_all_methods = 0;
-int count_methods_marked_used = 0;  /* RTA */
-
-int count_vmcode_len = 0;
-int count_extable_len = 0;
-int count_class_loads = 0;
-int count_class_inits = 0;
-
-int count_utf_len = 0;                  /* size of utf hash                   */
-int count_utf_new = 0;                  /* calls of utf_new                   */
-int count_utf_new_found  = 0;           /* calls of utf_new with fast return  */
-
-int count_locals_conflicts = 0;         /* register allocator statistics */
-int count_locals_spilled = 0;
-int count_locals_register = 0;
-int count_ss_spilled = 0;
-int count_ss_register = 0;
-int count_methods_allocated_by_lsra = 0;
-int count_mem_move_bb = 0;
-int count_interface_size = 0;
-int count_argument_mem_ss = 0;
-int count_argument_reg_ss = 0;
-int count_method_in_register = 0;
-int count_mov_reg_reg = 0;
-int count_mov_mem_reg = 0;
-int count_mov_reg_mem = 0;
-int count_mov_mem_mem = 0;
-
-int count_jit_calls = 0;
-int count_methods = 0;
-int count_spills = 0;
-int count_spills_read = 0;
-int count_pcmd_activ = 0;
-int count_pcmd_drop = 0;
-int count_pcmd_zero = 0;
-int count_pcmd_const_store = 0;
-int count_pcmd_const_alu = 0;
-int count_pcmd_const_bra = 0;
-int count_pcmd_load = 0;
-int count_pcmd_move = 0;
-int count_load_instruction = 0;
-int count_pcmd_store = 0;
-int count_pcmd_store_comb = 0;
-int count_dup_instruction = 0;
-int count_pcmd_op = 0;
-int count_pcmd_mem = 0;
-int count_pcmd_met = 0;
-int count_pcmd_bra = 0;
-int count_pcmd_table = 0;
-int count_pcmd_return = 0;
-int count_pcmd_returnx = 0;
-int count_check_null = 0;
-int count_check_bound = 0;
-int count_max_basic_blocks = 0;
-int count_basic_blocks = 0;
-int count_javainstr = 0;
-int count_max_javainstr = 0;
-int count_javacodesize = 0;
-int count_javaexcsize = 0;
-int count_calls = 0;
-int count_tryblocks = 0;
-int count_code_len = 0;
-int count_data_len = 0;
-int count_cstub_len = 0;
-int count_nstub_len = 0;
-int count_max_new_stack = 0;
-int count_upper_bound_new_stack = 0;
-
-s4 count_branches_resolved   = 0;
-s4 count_branches_unresolved = 0;
-
-u8 count_native_function_calls=0;
-u8 count_jni_callXmethod_calls=0;
-u8 count_jni_calls=0;
-
-
-static int count_block_stack_init[11] = {
-       0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 
-       0
-};
-int *count_block_stack = count_block_stack_init;
-static int count_analyse_iterations_init[5] = {
-       0, 0, 0, 0, 0
-};
-int *count_analyse_iterations = count_analyse_iterations_init;
-static int count_method_bb_distribution_init[9] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0
-};
-int *count_method_bb_distribution = count_method_bb_distribution_init;
-static int count_block_size_distribution_init[18] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0
-};
-int *count_block_size_distribution = count_block_size_distribution_init;
-static int count_store_length_init[21] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0
-};
-int *count_store_length = count_store_length_init;
-static int count_store_depth_init[11] = {
-       0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0,
-       0
-};
-int *count_store_depth = count_store_depth_init;
-
-
-/* instruction scheduler statistics *******************************************/
-
-s4 count_schedule_basic_blocks = 0;
-s4 count_schedule_nodes = 0;
-s4 count_schedule_leaders = 0;
-s4 count_schedule_max_leaders = 0;
-s4 count_schedule_critical_path = 0;
-
-
-/* nativeinvokation ***********************************************************
-
-   increments the native invokation count by one
-       
-*******************************************************************************/
-
-void nativeinvokation(void)
-{
-       /* XXX do locking here */
-       count_native_function_calls++;
-}
-
-
-/* jnicallXmethodinvokation ***************************************************
-
-   increments the jni CallXMethod invokation count by one
-       
-*******************************************************************************/
-
-void jnicallXmethodnvokation(void)
-{
-       /* XXX do locking here */
-       count_jni_callXmethod_calls++;
-}
-
-
-/* jniinvokation *************************************************************
-
-   increments the jni overall  invokation count by one
-       
-*******************************************************************************/
-
-void jniinvokation(void)
-{
-       /* XXX do locking here */
-       count_jni_calls++;
-}
-
-
-/* getcputime *********************************** ******************************
-
-   Returns the used CPU time in microseconds
-       
-*******************************************************************************/
-
-s8 getcputime(void)
-{
-       struct rusage ru;
-       int sec, usec;
-
-       getrusage(RUSAGE_SELF, &ru);
-       sec = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
-       usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
-
-       return sec * 1000000 + usec;
-}
-
-
-/* loadingtime_stop ************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void loadingtime_start(void)
-{
-       loadingtime_recursion++;
-
-       if (loadingtime_recursion == 1)
-               loadingstarttime = getcputime();
-}
-
-
-/* loadingtime_stop ************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void loadingtime_stop(void)
-{
-       if (loadingtime_recursion == 1) {
-               loadingstoptime = getcputime();
-               loadingtime += (loadingstoptime - loadingstarttime);
-       }
-
-       loadingtime_recursion--;
-}
-
-
-/* compilingtime_stop **********************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void compilingtime_start(void)
-{
-       compilingtime_recursion++;
-
-       if (compilingtime_recursion == 1)
-               compilingstarttime = getcputime();
-}
-
-
-/* compilingtime_stop **********************************************************
-
-   XXX
-
-*******************************************************************************/
-
-void compilingtime_stop(void)
-{
-       if (compilingtime_recursion == 1) {
-               compilingstoptime = getcputime();
-               compilingtime += (compilingstoptime - compilingstarttime);
-       }
-
-       compilingtime_recursion--;
-}
-
-
-/* print_times *****************************************************************
-
-   Prints a summary of CPU time usage.
-
-*******************************************************************************/
-
-void print_times(void)
-{
-       s8 totaltime;
-       s8 runtime;
-
-       totaltime = getcputime();
-       runtime = totaltime - loadingtime - compilingtime;
-
-#if SIZEOF_VOID_P == 8
-       dolog("Time for loading classes: %6ld ms", loadingtime / 1000);
-       dolog("Time for compiling code:  %6ld ms", compilingtime / 1000);
-       dolog("Time for running program: %6ld ms", runtime / 1000);
-       dolog("Total time:               %6ld ms", totaltime / 1000);
-#else
-       dolog("Time for loading classes: %6lld ms", loadingtime / 1000);
-       dolog("Time for compiling code:  %6lld ms", compilingtime / 1000);
-       dolog("Time for running program: %6lld ms", runtime / 1000);
-       dolog("Total time:               %6lld ms", totaltime / 1000);
-#endif
-}
-
-
-/* print_stats *****************************************************************
-
-   outputs detailed compiler statistics
-
-*******************************************************************************/
-
-void print_stats(void)
-{
-       s4    i;
-       float f;
-       s4    sum;
-
-
-       dolog("Number of JIT compiler calls: %6d", count_jit_calls);
-       dolog("Number of compiled methods:   %6d", count_methods);
-
-       dolog("Number of compiled basic blocks:               %6d",
-                 count_basic_blocks);
-       dolog("Number of max. basic blocks per method:        %6d",
-                 count_max_basic_blocks);
-
-       dolog("Number of compiled JavaVM instructions:        %6d",
-                 count_javainstr);
-       dolog("Number of max. JavaVM instructions per method: %6d",
-                 count_max_javainstr);
-       dolog("Size of compiled JavaVM instructions:          %6d(%d)",
-                 count_javacodesize, count_javacodesize - count_methods * 18);
-
-       dolog("Size of compiled Exception Tables:      %d", count_javaexcsize);
-       dolog("Number of Machine-Instructions: %d", count_code_len >> 2);
-       dolog("Number of Spills (write to memory): %d", count_spills);
-       dolog("Number of Spills (read from memory): %d", count_spills_read);
-       dolog("Number of Activ    Pseudocommands: %6d", count_pcmd_activ);
-       dolog("Number of Drop     Pseudocommands: %6d", count_pcmd_drop);
-       dolog("Number of Const    Pseudocommands: %6d (zero:%5d)",
-                 count_pcmd_load, count_pcmd_zero);
-       dolog("Number of ConstAlu Pseudocommands: %6d (cmp: %5d, store:%5d)",
-                 count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
-       dolog("Number of Move     Pseudocommands: %6d", count_pcmd_move);
-       dolog("Number of Load     Pseudocommands: %6d", count_load_instruction);
-       dolog("Number of Store    Pseudocommands: %6d (combined: %5d)",
-                 count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
-       dolog("Number of OP       Pseudocommands: %6d", count_pcmd_op);
-       dolog("Number of DUP      Pseudocommands: %6d", count_dup_instruction);
-       dolog("Number of Mem      Pseudocommands: %6d", count_pcmd_mem);
-       dolog("Number of Method   Pseudocommands: %6d", count_pcmd_met);
-       dolog("Number of Branch   Pseudocommands: %6d (rets:%5d, Xrets: %5d)",
-                 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
-       log_println("                resolved branches: %6d", count_branches_resolved);
-       log_println("              unresolved branches: %6d", count_branches_unresolved);
-       dolog("Number of Table    Pseudocommands: %6d", count_pcmd_table);
-       dolog("Number of Useful   Pseudocommands: %6d", count_pcmd_table +
-                 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
-       dolog("Number of Null Pointer Checks:     %6d", count_check_null);
-       dolog("Number of Array Bound Checks:      %6d", count_check_bound);
-       dolog("Number of Try-Blocks: %d", count_tryblocks);
-       dolog("Maximal count of stack elements:   %d", count_max_new_stack);
-       dolog("Upper bound of max stack elements: %d", count_upper_bound_new_stack);
-       dolog("Distribution of stack sizes at block boundary");
-       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_block_stack[0], count_block_stack[1], count_block_stack[2],
-                 count_block_stack[3], count_block_stack[4], count_block_stack[5],
-                 count_block_stack[6], count_block_stack[7], count_block_stack[8],
-                 count_block_stack[9], count_block_stack[10]);
-       dolog("Distribution of store stack depth");
-       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_store_depth[0], count_store_depth[1], count_store_depth[2],
-                 count_store_depth[3], count_store_depth[4], count_store_depth[5],
-                 count_store_depth[6], count_store_depth[7], count_store_depth[8],
-                 count_store_depth[9], count_store_depth[10]);
-       dolog("Distribution of store creator chains first part");
-       dolog("     0     1     2     3     4     5     6     7     8     9");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_store_length[0], count_store_length[1], count_store_length[2],
-                 count_store_length[3], count_store_length[4], count_store_length[5],
-                 count_store_length[6], count_store_length[7], count_store_length[8],
-                 count_store_length[9]);
-       dolog("Distribution of store creator chains second part");
-       dolog("    10    11    12    13    14    15    16    17    18    19  >=20");
-       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
-                 count_store_length[10], count_store_length[11],
-                 count_store_length[12], count_store_length[13],
-                 count_store_length[14], count_store_length[15],
-                 count_store_length[16], count_store_length[17],
-                 count_store_length[18], count_store_length[19],
-                 count_store_length[20]);
-       dolog("Distribution of analysis iterations");
-       dolog("     1     2     3     4   >=5");
-       dolog("%6d%6d%6d%6d%6d",
-                 count_analyse_iterations[0], count_analyse_iterations[1],
-                 count_analyse_iterations[2], count_analyse_iterations[3],
-                 count_analyse_iterations[4]);
-
-
-       /* Distribution of basic blocks per method ********************************/
-
-       log_println("Distribution of basic blocks per method:");
-       log_println("   <=5  <=10  <=15  <=20  <=30  <=40  <=50  <=75   >75");
-
-       log_start();
-       for (i = 0; i <= 8; i++)
-               log_print("%6d", count_method_bb_distribution[i]);
-       log_finish();
-
-       /* print ratio */
-
-       f = (float) count_methods;
-
-       log_start();
-       for (i = 0; i <= 8; i++)
-               log_print("%6.2f", (float) count_method_bb_distribution[i] / f);
-       log_finish();
-
-       /* print cumulated ratio */
-
-       log_start();
-       for (i = 0, sum = 0; i <= 8; i++) {
-               sum += count_method_bb_distribution[i];
-               log_print("%6.2f", (float) sum / f);
-       }
-       log_finish();
-
-
-       /* Distribution of basic block sizes **************************************/
-
-       log_println("Distribution of basic block sizes:");
-       log_println("     0     1     2     3     4     5     6     7     8     9   <13   <15   <17   <19   <21   <26   <31   >30");
-
-       /* print block sizes */
-
-       log_start();
-       for (i = 0; i <= 17; i++)
-               log_print("%6d", count_block_size_distribution[i]);
-       log_finish();
-
-       /* print ratio */
-
-       f = (float) count_basic_blocks;
-
-       log_start();
-       for (i = 0; i <= 17; i++)
-               log_print("%6.2f", (float) count_block_size_distribution[i] / f);
-       log_finish();
-
-       /* print cumulated ratio */
-
-       log_start();
-       for (i = 0, sum = 0; i <= 17; i++) {
-               sum += count_block_size_distribution[i];
-               log_print("%6.2f", (float) sum / f);
-       }
-       log_finish();
-
-       log_println("Size of Code Area:          %10.3f kB", (float) count_code_len / 1024);
-       log_println("Size of Data Area:          %10.3f kB", (float) count_data_len / 1024);
-
-       log_println("Size of classinfo  (%3d B): %10.3f kB", sizeof(classinfo), (float) size_classinfo / 1024);
-       log_println("Size of fieldinfo  (%3d B): %10.3f kB", sizeof(fieldinfo), (float) size_fieldinfo / 1024);
-       log_println("Size of methodinfo (%3d B): %10.3f kB", sizeof(methodinfo), (float) size_methodinfo / 1024);
-       log_println("Size of codeinfo   (%3d B): %10.3f kB", sizeof(codeinfo), (float) size_codeinfo / 1024);
-
-       log_println("Size of Const Pool:         %10.3f kB", (float) (count_const_pool_len + count_utf_len) / 1024);
-       log_println("Size of Class refs:         %10.3f kB", (float) count_classref_len / 1024);
-       log_println("Size of descriptors:        %10.3f kB", (float) count_parsed_desc_len / 1024);
-       log_println("Size of vftbl:              %10.3f kB", (float) count_vftbl_len / 1024);
-       log_println("Size of compiler stubs:     %10.3f kB", (float) count_cstub_len / 1024);
-       log_println("Size of native stubs:       %10.3f kB", (float) count_nstub_len / 1024);
-       log_println("Size of utf:                %10.3f kB", (float) count_utf_len / 1024);
-       log_println("Size of VMCode:             %10.3f kB", (float) count_vmcode_len / 1024);
-       log_println("Size of exception tables:   %10.3f kB", (float) count_extable_len / 1024);
-        log_println("size of stack map:          %10.3f kb\n", (float) size_stack_map / 1024);
-
-       dolog("Number of class loads:    %6d", count_class_loads);
-       dolog("Number of class inits:    %6d", count_class_inits);
-       dolog("Number of loaded Methods: %6d\n", count_all_methods);
-
-       dolog("Calls of utf_new:                 %6d", count_utf_new);
-       dolog("Calls of utf_new (element found): %6d\n", count_utf_new_found);
-
-
-       /* LSRA statistics ********************************************************/
-
-       dolog("Moves reg -> reg:     %6d", count_mov_reg_reg);
-       dolog("Moves mem -> reg:     %6d", count_mov_mem_reg);
-       dolog("Moves reg -> mem:     %6d", count_mov_reg_mem);
-       dolog("Moves mem -> mem:     %6d", count_mov_mem_mem);
-
-       dolog("Methods allocated by LSRA:         %6d",
-                 count_methods_allocated_by_lsra);
-       dolog("Conflicts between local Variables: %6d", count_locals_conflicts);
-       dolog("Local Variables held in Memory:    %6d", count_locals_spilled);
-       dolog("Local Variables held in Registers: %6d", count_locals_register);
-       dolog("Stackslots held in Memory:         %6d", count_ss_spilled);
-       dolog("Stackslots held in Registers:      %6d", count_ss_register);
-       dolog("Memory moves at BB Boundaries:     %6d", count_mem_move_bb);
-       dolog("Number of interface slots:         %6d\n", count_interface_size);
-       dolog("Number of Argument stack slots in register:  %6d",
-                 count_argument_reg_ss);
-       dolog("Number of Argument stack slots in memory:    %6d\n",
-                 count_argument_mem_ss);
-       dolog("Number of Methods kept in registers:         %6d\n",
-                 count_method_in_register);
-
-
-       /* instruction scheduler statistics ***************************************/
-
-#if defined(USE_SCHEDULER)
-       dolog("Instruction scheduler statistics:");
-       dolog("Number of basic blocks:       %7d", count_schedule_basic_blocks);
-       dolog("Number of nodes:              %7d", count_schedule_nodes);
-       dolog("Number of leaders nodes:      %7d", count_schedule_leaders);
-       dolog("Number of max. leaders nodes: %7d", count_schedule_max_leaders);
-       dolog("Length of critical path:      %7d\n", count_schedule_critical_path);
-#endif
-
-
-       /* call statistics ********************************************************/
-
-       dolog("Function call statistics:");
-       dolog("Number of native function invokations:           %ld",
-                 count_native_function_calls);
-       dolog("Number of jni->CallXMethod function invokations: %ld",
-                 count_jni_callXmethod_calls);
-       dolog("Overall number of jni invokations:               %ld",
-                 count_jni_calls);
-
-
-       /* now print other statistics ********************************************/
-
-#if defined(ENABLE_INTRP)
-       print_dynamic_super_statistics();
-#endif
-}
-
-
-/* mem_usagelog ****************************************************************
-
-   prints some memory related infos
-
-*******************************************************************************/
-
-void mem_usagelog(bool givewarnings)
-{
-       if ((memoryusage != 0) && givewarnings) {
-               dolog("Allocated memory not returned: %9d", (s4) memoryusage);
-       }
-
-       if ((globalallocateddumpsize != 0) && givewarnings) {
-               dolog("Dump memory not returned:      %9d",
-                         (s4) globalallocateddumpsize);
-       }
-
-       dolog("Code - max. memory usage:      %9d kB",
-                 (s4) ((maxcodememusage + 1023) / 1024));
-       dolog("Random - max. memory usage:    %9d kB",
-                 (s4) ((maxmemusage + 1023) / 1024));
-       dolog("Dump - max. memory usage:      %9d kB",
-                 (s4) ((maxdumpsize + 1023) / 1024));
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/statistics.h b/src/vm/statistics.h
deleted file mode 100644 (file)
index a19e788..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/* src/vm/statistics.h - exports global varables for statistics
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: statistics.h 6216 2006-12-18 18:21:37Z twisti $
-
-*/
-
-
-#ifndef _STATISTICS_H
-#define _STATISTICS_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-
-/* statistic macros ***********************************************************/
-
-#if defined(ENABLE_STATISTICS)
-#define STATISTICS(x) \
-    do { \
-        if (opt_stat) { \
-            x; \
-        } \
-    } while (0)
-#else
-#define STATISTICS(x)    /* nothing */
-#endif
-
-/* in_  inline statistics */
-
-#define IN_MAX                  9
-#define IN_UNIQUEVIRT           0x0000 
-#define IN_UNIQUE_INTERFACE     0x0001
-#define IN_OUTSIDERS            0x0004
-#define IN_MAXDEPTH             0x0008
-#define IN_MAXCODE              0x0010
-#define IN_JCODELENGTH          0x0020
-#define IN_EXCEPTION            0x0040
-#define IN_NOT_UNIQUE_VIRT      0x0080
-#define IN_NOT_UNIQUE_INTERFACE 0x0100
-
-#define N_UNIQUEVIRT            0
-#define N_UNIQUE_INTERFACE      1
-#define N_OUTSIDERS             2
-#define N_MAXDEPTH             3       
-#define N_MAXCODE               4 
-#define N_JCODELENGTH           5 
-#define N_EXCEPTION            6 
-#define N_NOT_UNIQUE_VIRT       7 
-#define N_NOT_UNIQUE_INTERFACE  8 
-
-
-/* global variables ***********************************************************/
-
-extern s4 codememusage;
-extern s4 maxcodememusage;
-
-extern s4 memoryusage;
-extern s4 maxmemusage;
-
-extern s4 maxdumpsize;
-
-extern s4 globalallocateddumpsize;
-extern s4 globaluseddumpsize;
-
-
-/* variables for measurements *************************************************/
-
-extern s4 size_classinfo;
-extern s4 size_fieldinfo;
-extern s4 size_methodinfo;
-extern s4 size_codeinfo;
-
-extern s4 size_stack_map;
-
-extern int count_const_pool_len;
-extern int count_classref_len;
-extern int count_parsed_desc_len;
-extern int count_vftbl_len;
-extern int count_all_methods;
-extern int count_methods_marked_used;  /*RTA*/
-extern int count_vmcode_len;
-extern int count_extable_len;
-extern int count_class_loads;
-extern int count_class_inits;
-
-extern int count_utf_len;               /* size of utf hash                   */
-extern int count_utf_new;
-extern int count_utf_new_found;
-
-extern int count_locals_conflicts;
-extern int count_locals_spilled;
-extern int count_locals_register;
-extern int count_ss_spilled;
-extern int count_ss_register;
-extern int count_methods_allocated_by_lsra;
-extern int count_mem_move_bb;
-extern int count_interface_size;
-extern int count_argument_mem_ss;
-extern int count_argument_reg_ss;
-extern int count_method_in_register;
-extern int count_mov_reg_reg;
-extern int count_mov_mem_reg;
-extern int count_mov_reg_mem;
-extern int count_mov_mem_mem;
-
-extern int count_jit_calls;
-extern int count_methods;
-extern int count_spills;
-extern int count_spills_read;
-extern int count_pcmd_activ;
-extern int count_pcmd_drop;
-extern int count_pcmd_zero;
-extern int count_pcmd_const_store;
-extern int count_pcmd_const_alu;
-extern int count_pcmd_const_bra;
-extern int count_pcmd_load;
-extern int count_pcmd_move;
-extern int count_load_instruction;
-extern int count_pcmd_store;
-extern int count_pcmd_store_comb;
-extern int count_dup_instruction;
-extern int count_pcmd_op;
-extern int count_pcmd_mem;
-extern int count_pcmd_met;
-extern int count_pcmd_bra;
-extern int count_pcmd_table;
-extern int count_pcmd_return;
-extern int count_pcmd_returnx;
-extern int count_check_null;
-extern int count_check_bound;
-extern int count_max_basic_blocks;
-extern int count_basic_blocks;
-extern int count_max_javainstr;
-extern int count_javainstr;
-extern int count_javacodesize;
-extern int count_javaexcsize;
-extern int count_calls;
-extern int count_tryblocks;
-extern int count_code_len;
-extern int count_data_len;
-extern int count_cstub_len;
-extern int count_nstub_len;
-extern int count_max_new_stack;
-extern int count_upper_bound_new_stack;
-
-extern s4 count_branches_resolved;
-extern s4 count_branches_unresolved;
-
-extern int *count_block_stack;
-extern int *count_analyse_iterations;
-extern int *count_method_bb_distribution;
-extern int *count_block_size_distribution;
-extern int *count_store_length;
-extern int *count_store_depth;
-                                /* in_  inline statistics */
-extern int count_in;
-extern int count_in_uniqVirt;
-extern int count_in_uniqIntf;
-extern int count_in_rejected;
-extern int count_in_rejected_mult;
-extern int count_in_outsiders;
-extern int count_in_uniqueVirt_not_inlined;
-extern int count_in_uniqueInterface_not_inlined;
-extern int count_in_maxDepth;
-extern int count_in_maxMethods;
-
-extern u2 count_in_not   [512];
-
-/* instruction scheduler statistics *******************************************/
-
-extern s4 count_schedule_basic_blocks;
-extern s4 count_schedule_nodes;
-extern s4 count_schedule_leaders;
-extern s4 count_schedule_max_leaders;
-extern s4 count_schedule_critical_path;
-
-
-/* function prototypes ********************************************************/
-
-s8 getcputime(void);
-
-void loadingtime_start(void);
-void loadingtime_stop(void);
-void compilingtime_start(void);
-void compilingtime_stop(void);
-
-void print_times(void);
-void print_stats(void);
-
-void mem_usagelog(bool givewarnings);
-
-
-void nativeinvokation(void);
-void compiledinvokation(void);
-void jnicallXmethodnvokation(void);
-void jniinvokation(void);
-
-#endif /* _STATISTICS_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:
- */
index 9c26afa89eb080942650b594c9cbf46ecfb0fb97..d01801818a82889dcc2e8edce6be0c696629c61b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/string.c - java.lang.String related functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Roman Obermaisser
-            Andreas Krall
-
-   Changes: Christian Thalinger
-                       Edwin Steiner
-
-   $Id: string.c 5823 2006-10-24 23:24:19Z edwin $
+   $Id: string.c 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
-#include "vm/utf8.h"
+
+#include "vmcore/options.h"
+#include "vmcore/utf8.h"
 
 
 /* global variables ***********************************************************/
@@ -74,134 +65,6 @@ static java_objectheader *lock_hashtable_string;
 #endif
 
 
-/* global string definitions **************************************************/
-
-/* exception/error super class */
-
-const char *string_java_lang_Throwable =
-    "java/lang/Throwable";
-
-const char *string_java_lang_VMThrowable =
-    "java/lang/VMThrowable";
-
-
-/* specify some exception strings for code generation */
-
-const char *string_java_lang_ArithmeticException =
-    "java/lang/ArithmeticException";
-
-const char *string_java_lang_ArithmeticException_message =
-    "/ by zero";
-
-const char *string_java_lang_ArrayIndexOutOfBoundsException =
-    "java/lang/ArrayIndexOutOfBoundsException";
-
-const char *string_java_lang_ArrayStoreException =
-    "java/lang/ArrayStoreException";
-
-const char *string_java_lang_ClassCastException =
-    "java/lang/ClassCastException";
-
-const char *string_java_lang_ClassNotFoundException =
-       "java/lang/ClassNotFoundException";
-
-const char *string_java_lang_CloneNotSupportedException =
-    "java/lang/CloneNotSupportedException";
-
-const char *string_java_lang_Exception =
-    "java/lang/Exception";
-
-const char *string_java_lang_IllegalAccessException =
-    "java/lang/IllegalAccessException";
-
-const char *string_java_lang_IllegalArgumentException =
-    "java/lang/IllegalArgumentException";
-
-const char *string_java_lang_IllegalMonitorStateException =
-    "java/lang/IllegalMonitorStateException";
-
-const char *string_java_lang_IndexOutOfBoundsException =
-    "java/lang/IndexOutOfBoundsException";
-
-const char *string_java_lang_InstantiationException =
-    "java/lang/InstantiationException";
-
-const char *string_java_lang_InterruptedException =
-    "java/lang/InterruptedException";
-
-const char *string_java_lang_NegativeArraySizeException =
-    "java/lang/NegativeArraySizeException";
-
-const char *string_java_lang_NoSuchFieldException =
-       "java/lang/NoSuchFieldException";
-
-const char *string_java_lang_NoSuchMethodException =
-       "java/lang/NoSuchMethodException";
-
-const char *string_java_lang_NullPointerException =
-    "java/lang/NullPointerException";
-
-const char *string_java_lang_StringIndexOutOfBoundsException =
-    "java/lang/StringIndexOutOfBoundsException";
-
-const char *string_java_lang_reflect_InvocationTargetException =
-    "java/lang/reflect/InvocationTargetException";
-
-
-/* specify some error strings for code generation */
-
-const char *string_java_lang_AbstractMethodError =
-    "java/lang/AbstractMethodError";
-
-const char *string_java_lang_ClassCircularityError =
-    "java/lang/ClassCircularityError";
-
-const char *string_java_lang_ClassFormatError =
-    "java/lang/ClassFormatError";
-
-const char *string_java_lang_Error =
-    "java/lang/Error";
-
-const char *string_java_lang_ExceptionInInitializerError =
-    "java/lang/ExceptionInInitializerError";
-
-const char *string_java_lang_IncompatibleClassChangeError =
-    "java/lang/IncompatibleClassChangeError";
-
-const char *string_java_lang_InstantiationError =
-    "java/lang/InstantiationError";
-
-const char *string_java_lang_InternalError =
-    "java/lang/InternalError";
-
-const char *string_java_lang_LinkageError =
-    "java/lang/LinkageError";
-
-const char *string_java_lang_NoClassDefFoundError =
-    "java/lang/NoClassDefFoundError";
-
-const char *string_java_lang_NoSuchFieldError =
-       "java/lang/NoSuchFieldError";
-
-const char *string_java_lang_NoSuchMethodError =
-       "java/lang/NoSuchMethodError";
-
-const char *string_java_lang_OutOfMemoryError =
-    "java/lang/OutOfMemoryError";
-
-const char *string_java_lang_UnsatisfiedLinkError =
-    "java/lang/UnsatisfiedLinkError";
-
-const char *string_java_lang_UnsupportedClassVersionError =
-    "java/lang/UnsupportedClassVersionError";
-
-const char *string_java_lang_VerifyError =
-    "java/lang/VerifyError";
-
-const char *string_java_lang_VirtualMachineError =
-    "java/lang/VirtualMachineError";
-
-
 /* string_init *****************************************************************
 
    Initialize the string hashtable lock.
@@ -289,36 +152,43 @@ void stringtable_update(void)
 
 *******************************************************************************/
 
-java_lang_String *javastring_new_from_utf_buffer(const char *buffer, u4 blength)
+java_objectheader *javastring_new_from_utf_buffer(const char *buffer, u4 blength)
 {
        const char *utf_ptr;            /* current utf character in utf string    */
        u4 utflength;                   /* length of utf-string if uncompressed   */
-       java_lang_String *s;            /* result-string                          */
-       java_chararray *a;
+       java_objectheader *o;
+       java_lang_String  *s;           /* result-string                          */
+       java_chararray    *a;
        u4 i;
 
        assert(buffer);
 
        utflength = utf_get_number_of_u2s_for_buffer(buffer,blength);
 
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
+       o = builtin_new(class_java_lang_String);
        a = builtin_newarray_char(utflength);
 
        /* javastring or character-array could not be created */
-       if (!a || !s)
+
+       if ((o == NULL) || (a == NULL))
                return NULL;
 
        /* decompress utf-string */
+
        utf_ptr = buffer;
+
        for (i = 0; i < utflength; i++)
-               a->data[i] = utf_nextu2((char **)&utf_ptr);
+               a->data[i] = utf_nextu2((char **) &utf_ptr);
        
        /* set fields of the javastring-object */
+
+       s = (java_lang_String *) o;
+
        s->value  = a;
        s->offset = 0;
        s->count  = utflength;
 
-       return s;
+       return o;
 }
 
 
@@ -337,10 +207,11 @@ java_lang_String *javastring_new_from_utf_buffer(const char *buffer, u4 blength)
 
 *******************************************************************************/
 
-java_lang_String *javastring_safe_new_from_utf8(const char *text)
+java_objectheader *javastring_safe_new_from_utf8(const char *text)
 {
-       java_lang_String *s;            /* result-string                          */
-       java_chararray *a;
+       java_objectheader *o;
+       java_chararray    *a;
+       java_lang_String  *s;
        s4 nbytes;
        s4 len;
 
@@ -357,12 +228,12 @@ java_lang_String *javastring_safe_new_from_utf8(const char *text)
 
        /* allocate the String object and the char array */
 
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
+       o = builtin_new(class_java_lang_String);
        a = builtin_newarray_char(len);
 
        /* javastring or character-array could not be created? */
 
-       if (!a || !s)
+       if ((o == NULL) || (a == NULL))
                return NULL;
 
        /* decompress UTF-8 string */
@@ -371,11 +242,13 @@ java_lang_String *javastring_safe_new_from_utf8(const char *text)
 
        /* set fields of the String object */
 
+       s = (java_lang_String *) o;
+
        s->value  = a;
        s->offset = 0;
        s->count  = len;
 
-       return s;
+       return o;
 }
 
 
@@ -394,7 +267,7 @@ java_lang_String *javastring_safe_new_from_utf8(const char *text)
 
 *******************************************************************************/
 
-java_lang_String *javastring_new_from_utf_string(const char *utfstr)
+java_objectheader *javastring_new_from_utf_string(const char *utfstr)
 {
        assert(utfstr);
 
@@ -411,15 +284,16 @@ java_lang_String *javastring_new_from_utf_string(const char *utfstr)
 
 *******************************************************************************/
 
-java_lang_String *javastring_new(utf *u)
+java_objectheader *javastring_new(utf *u)
 {
        char *utf_ptr;                  /* current utf character in utf string    */
        u4 utflength;                   /* length of utf-string if uncompressed   */
-       java_lang_String *s;            /* result-string                          */
-       java_chararray *a;
+       java_objectheader *o;
+       java_chararray    *a;
+       java_lang_String  *s;
        s4 i;
 
-       if (!u) {
+       if (u == NULL) {
                exceptions_throw_nullpointerexception();
                return NULL;
        }
@@ -427,25 +301,31 @@ java_lang_String *javastring_new(utf *u)
        utf_ptr = u->text;
        utflength = utf_get_number_of_u2s(u);
 
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
+       o = builtin_new(class_java_lang_String);
        a = builtin_newarray_char(utflength);
 
        /* javastring or character-array could not be created */
-       if (!a || !s)
+
+       if ((o == NULL) || (a == NULL))
                return NULL;
 
        /* decompress utf-string */
+
        for (i = 0; i < utflength; i++)
                a->data[i] = utf_nextu2(&utf_ptr);
        
        /* set fields of the javastring-object */
+
+       s = (java_lang_String *) o;
+
        s->value  = a;
        s->offset = 0;
        s->count  = utflength;
 
-       return s;
+       return o;
 }
 
+
 /* javastring_new_slash_to_dot *************************************************
 
    creates a new object of type java/lang/String with the text of 
@@ -455,16 +335,17 @@ java_lang_String *javastring_new(utf *u)
 
 *******************************************************************************/
 
-java_lang_String *javastring_new_slash_to_dot(utf *u)
+java_objectheader *javastring_new_slash_to_dot(utf *u)
 {
        char *utf_ptr;                  /* current utf character in utf string    */
        u4 utflength;                   /* length of utf-string if uncompressed   */
-       java_lang_String *s;            /* result-string                          */
-       java_chararray *a;
+       java_objectheader *o;
+       java_chararray    *a;
+       java_lang_String  *s;
        s4 i;
        u2 ch;
 
-       if (!u) {
+       if (u == NULL) {
                exceptions_throw_nullpointerexception();
                return NULL;
        }
@@ -472,14 +353,15 @@ java_lang_String *javastring_new_slash_to_dot(utf *u)
        utf_ptr = u->text;
        utflength = utf_get_number_of_u2s(u);
 
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
+       o = builtin_new(class_java_lang_String);
        a = builtin_newarray_char(utflength);
 
        /* javastring or character-array could not be created */
-       if (!a || !s)
+       if ((o == NULL) || (a == NULL))
                return NULL;
 
        /* decompress utf-string */
+
        for (i = 0; i < utflength; i++) {
                ch = utf_nextu2(&utf_ptr);
                if (ch == '/')
@@ -488,11 +370,14 @@ java_lang_String *javastring_new_slash_to_dot(utf *u)
        }
        
        /* set fields of the javastring-object */
+
+       s = (java_lang_String *) o;
+
        s->value  = a;
        s->offset = 0;
        s->count  = utflength;
 
-       return s;
+       return o;
 }
 
 
@@ -510,37 +395,43 @@ java_lang_String *javastring_new_slash_to_dot(utf *u)
 
 *******************************************************************************/
 
-java_lang_String *javastring_new_from_ascii(const char *text)
+java_objectheader *javastring_new_from_ascii(const char *text)
 {
        s4 i;
        s4 len;                             /* length of the string               */
-       java_lang_String *s;                /* result-string                      */
-       java_chararray *a;
+       java_objectheader *o;
+       java_lang_String  *s;
+       java_chararray    *a;
 
-       if (!text) {
+       if (text == NULL) {
                exceptions_throw_nullpointerexception();
                return NULL;
        }
 
        len = strlen(text);
 
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
+       o = builtin_new(class_java_lang_String);
        a = builtin_newarray_char(len);
 
        /* javastring or character-array could not be created */
-       if (!a || !s)
+
+       if ((o == NULL) || (a == NULL))
                return NULL;
 
        /* copy text */
+
        for (i = 0; i < len; i++)
                a->data[i] = text[i];
        
        /* set fields of the javastring-object */
+
+       s = (java_lang_String *) o;
+
        s->value  = a;
        s->offset = 0;
        s->count  = len;
 
-       return s;
+       return o;
 }
 
 
@@ -586,27 +477,16 @@ char *javastring_tochar(java_objectheader *so)
 
 *******************************************************************************/
 
-utf *javastring_toutf(java_lang_String *s, bool isclassname)
+utf *javastring_toutf(java_objectheader *string, bool isclassname)
 {
-       if (s == NULL)
-               return utf_null;
-
-       return utf_new_u2(s->value->data + s->offset, s->count, isclassname);
-}
-
-
-/* javastring_strlen ***********************************************************
+       java_lang_String *s;
 
-   Returns the length of the Java string.
-       
-*******************************************************************************/
+       s = (java_lang_String *) string;
 
-s4 javastring_strlen(java_lang_String *s)
-{
        if (s == NULL)
-               return 0;
+               return utf_null;
 
-       return s->count;
+       return utf_new_u2(s->value->data + s->offset, s->count, isclassname);
 }
 
 
@@ -794,12 +674,12 @@ java_objectheader *literalstring_new(utf *u)
 
 *******************************************************************************/
 
-void literalstring_free(java_objectheader* sobj)
+void literalstring_free(java_objectheader* string)
 {
        java_lang_String *s;
        java_chararray *a;
 
-       s = (java_lang_String *) sobj;
+       s = (java_lang_String *) string;
        a = s->value;
 
        /* dispose memory of java.lang.String object */
index 99fee6bda7c13462cadc6fda6cc6d158098ffd00..b7faec3c28c732ace9b68d5d831cc8293f2fec31 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/stringlocal.h - string header
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Edwin Steiner
-
-   $Id: stringlocal.h 5821 2006-10-24 16:41:54Z edwin $
+   $Id: stringlocal.h 7246 2007-01-29 18:49:05Z twisti $
 
 */
 
@@ -42,11 +36,11 @@ typedef struct literalstring literalstring;
 #include "config.h"
 #include "vm/types.h"
 
-#include "vm/global.h"                  /* required before java_lang_String.h */
-#include "native/include/java_lang_String.h"
+#include "toolbox/hashtable.h"
+
+#include "vm/global.h"
 
-#include "vm/hashtable.h"
-#include "vm/utf8.h"
+#include "vmcore/utf8.h"
 
 
 /* data structure of internal javastrings stored in global hashtable **********/
@@ -61,59 +55,6 @@ struct literalstring {
 extern hashtable hashtable_string;
 
 
-/* global string definitions **************************************************/
-
-/* exception/error super class */
-
-extern const char *string_java_lang_Throwable;
-extern const char *string_java_lang_VMThrowable;
-
-
-/* specify some exception strings for code generation */
-
-extern const char *string_java_lang_ArithmeticException;
-extern const char *string_java_lang_ArithmeticException_message;
-extern const char *string_java_lang_ArrayIndexOutOfBoundsException;
-extern const char *string_java_lang_ArrayStoreException;
-extern const char *string_java_lang_ClassCastException;
-extern const char *string_java_lang_ClassNotFoundException;
-extern const char *string_java_lang_CloneNotSupportedException;
-extern const char *string_java_lang_Exception;
-extern const char *string_java_lang_IllegalAccessException;
-extern const char *string_java_lang_IllegalArgumentException;
-extern const char *string_java_lang_IllegalMonitorStateException;
-extern const char *string_java_lang_IndexOutOfBoundsException;
-extern const char *string_java_lang_InstantiationException;
-extern const char *string_java_lang_InterruptedException;
-extern const char *string_java_lang_NegativeArraySizeException;
-extern const char *string_java_lang_NoSuchFieldException;
-extern const char *string_java_lang_NoSuchMethodException;
-extern const char *string_java_lang_NullPointerException;
-extern const char *string_java_lang_StringIndexOutOfBoundsException;
-extern const char *string_java_lang_reflect_InvocationTargetException;
-
-
-/* specify some error strings for code generation */
-
-extern const char *string_java_lang_AbstractMethodError;
-extern const char *string_java_lang_ClassCircularityError;
-extern const char *string_java_lang_ClassFormatError;
-extern const char *string_java_lang_Error;
-extern const char *string_java_lang_ExceptionInInitializerError;
-extern const char *string_java_lang_IncompatibleClassChangeError;
-extern const char *string_java_lang_InternalError;
-extern const char *string_java_lang_InstantiationError;
-extern const char *string_java_lang_LinkageError;
-extern const char *string_java_lang_NoClassDefFoundError;
-extern const char *string_java_lang_NoSuchFieldError;
-extern const char *string_java_lang_NoSuchMethodError;
-extern const char *string_java_lang_OutOfMemoryError;
-extern const char *string_java_lang_UnsatisfiedLinkError;
-extern const char *string_java_lang_UnsupportedClassVersionError;
-extern const char *string_java_lang_VerifyError;
-extern const char *string_java_lang_VirtualMachineError;
-
-
 /* function prototypes ********************************************************/
 
 /* initialize string subsystem */
@@ -122,29 +63,26 @@ bool string_init(void);
 void stringtable_update(void);
 
 /* creates a new object of type java/lang/String from a utf-text */
-java_lang_String *javastring_new(utf *text);
+java_objectheader *javastring_new(utf *text);
 
 /* creates a new object of type java/lang/String from a utf-text, changes slashes to dots */
-java_lang_String *javastring_new_slash_to_dot(utf *text);
+java_objectheader *javastring_new_slash_to_dot(utf *text);
 
 /* creates a new object of type java/lang/String from an ASCII c-string */
-java_lang_String *javastring_new_from_ascii(const char *text);
+java_objectheader *javastring_new_from_ascii(const char *text);
 
 /* creates a new object of type java/lang/String from UTF-8 */
-java_lang_String *javastring_new_from_utf_buffer(const char *buffer, u4 blength);
-java_lang_String *javastring_new_from_utf_string(const char *utfstr);
+java_objectheader *javastring_new_from_utf_buffer(const char *buffer, u4 blength);
+java_objectheader *javastring_new_from_utf_string(const char *utfstr);
 
 /* creates a new object of type java/lang/String from (possibly invalid) UTF-8 */
-java_lang_String *javastring_safe_new_from_utf8(const char *text);
+java_objectheader *javastring_safe_new_from_utf8(const char *text);
 
 /* make c-string from a javastring (debugging) */
-char *javastring_tochar(java_objectheader *s);
+char *javastring_tochar(java_objectheader *string);
 
 /* make utf symbol from javastring */
-utf *javastring_toutf(java_lang_String *string, bool isclassname);
-
-/* returns length of javastring */
-s4 javastring_strlen(java_lang_String *s);
+utf *javastring_toutf(java_objectheader *string, bool isclassname);
 
 /* creates a new javastring with the text of the u2-array */
 java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset,
diff --git a/src/vm/suck.c b/src/vm/suck.c
deleted file mode 100644 (file)
index 859c890..0000000
+++ /dev/null
@@ -1,650 +0,0 @@
-/* src/vm/suck.c - functions to read LE ordered types from a buffer
-
-   Copyright (C) 1996-2005, 2006, 2007 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   $Id: suck.c 6286 2007-01-10 10:03:38Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
-
-#include "toolbox/list.h"
-#include "toolbox/logging.h"
-#include "toolbox/util.h"
-#include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/properties.h"
-#include "vm/stringlocal.h"
-#include "vm/suck.h"
-#include "vm/vm.h"
-#include "vm/zip.h"
-
-
-/* global variables ***********************************************************/
-
-list *list_classpath_entries;
-
-
-/* suck_init *******************************************************************
-
-   Initializes the suck subsystem like initializing the classpath
-   entries list.
-
-*******************************************************************************/
-
-bool suck_init(void)
-{
-       list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* scandir_filter **************************************************************
-
-   Filters for zip/jar files.
-
-*******************************************************************************/
-
-#if defined(__LINUX__)
-static int scandir_filter(const struct dirent *a)
-#else
-static int scandir_filter(struct dirent *a)
-#endif
-{
-       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(char *key)
-{
-       char           *value;
-       char           *start;
-       char           *end;
-       char           *path;
-       s4              pathlen;
-       struct dirent **namelist;
-       s4              n;
-       s4              i;
-       s4              namlen;
-       char           *tmpbootclasspath;
-
-       /* 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 = 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
-
-                                       /* reallocate memory for bootclasspath */
-
-                                       tmpbootclasspath = MNEW(char,
-                                                                                       pathlen + strlen("/") + namlen +
-                                                                                       strlen(":") +
-                                                                                       strlen(_Jv_bootclasspath) +
-                                                                                       strlen("0"));
-
-                                       /* prepend the file found to bootclasspath */
-
-                                       strcpy(tmpbootclasspath, path);
-                                       strcat(tmpbootclasspath, "/");
-                                       strcat(tmpbootclasspath, namelist[i]->d_name);
-                                       strcat(tmpbootclasspath, ":");
-
-                                       strcat(tmpbootclasspath, _Jv_bootclasspath);
-
-                                       /* free old bootclasspath memory */
-
-                                       MFREE(_Jv_bootclasspath, u1, strlen(_Jv_bootclasspath));
-
-                                       /* and set the new bootclasspath */
-
-                                       _Jv_bootclasspath = tmpbootclasspath;
-
-                                       /* 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) {
-               *exceptionptr =
-                       new_classformaterror((cb)->class, "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
-
-       if (sizeof(float) != 4) {
-               exceptions_throw_internalerror("Incompatible float-format");
-
-               /* XXX should we exit in such a case? */
-               throw_exception_exit();
-       }
-       
-       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
-
-       if (sizeof(double) != 8) {
-               exceptions_throw_internalerror("Incompatible double-format");
-
-               /* XXX should we exit in such a case? */
-               throw_exception_exit();
-       }
-       
-       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 */
-
-                       LOCK_MONITOR_ENTER(lce);
-
-                       /* try to get the file in current archive */
-
-                       cb = zip_get(lce, c);
-
-                       /* leave the monitor */
-
-                       LOCK_MONITOR_EXIT(lce);
-
-               } else {
-#endif /* defined(ENABLE_ZLIB) */
-                       path = MNEW(char, lce->pathlen + filenamelen);
-                       strcpy(path, lce->path);
-                       strcat(path, filename);
-
-                       classfile = fopen(path, "r");
-
-                       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;
-                                       cb->path  = lce->path;
-
-                                       /* read class data */
-
-                                       len = fread(cb->data, 1, cb->size, classfile);
-
-                                       if (len != buffer.st_size) {
-                                               suck_stop(cb);
-/*                                             if (ferror(classfile)) { */
-/*                                             } */
-                                       }
-
-                                       /* close the class file */
-
-                                       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:
- */
diff --git a/src/vm/suck.h b/src/vm/suck.h
deleted file mode 100644 (file)
index f8eca84..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/* src/vm/suck.h - functions to read LE ordered types from a buffer
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: suck.h 5810 2006-10-20 13:54:54Z twisti $
-
-*/
-
-
-#ifndef _SUCK_H
-#define _SUCK_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/class.h"
-#include "vm/hashtable.h"
-#include "vm/loader.h"
-
-
-/* list_classpath_entry *******************************************************/
-
-enum {
-       CLASSPATH_PATH,
-       CLASSPATH_ARCHIVE
-};
-
-typedef struct list_classpath_entry list_classpath_entry;
-
-struct list_classpath_entry {
-#if defined(ENABLE_THREADS)
-       java_objectheader  header;              /* monitor locking on zip/jar files   */
-#endif
-       s4                 type;
-       char              *path;
-       s4                 pathlen;
-#if defined(ENABLE_ZLIB)
-       hashtable         *htclasses;
-#endif
-       listnode           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 *list_classpath_entries;
-
-
-/* function prototypes ********************************************************/
-
-bool suck_init(void);
-
-void suck_add(char *classpath);
-void suck_add_from_property(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);
-
-#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:
- */
diff --git a/src/vm/utf8.c b/src/vm/utf8.c
deleted file mode 100644 (file)
index 2619b0c..0000000
+++ /dev/null
@@ -1,1795 +0,0 @@
-/* src/vm/utf8.c - utf8 string functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Mark Probst
-            Andreas Krall
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: utf8.c 6286 2007-01-10 10:03:38Z twisti $
-
-*/
-
-
-#include "config.h"
-
-#include <string.h>
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
-
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "vm/hashtable.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/utf8.h"
-
-
-/* global variables ***********************************************************/
-
-/* hashsize must be power of 2 */
-
-#define HASHTABLE_UTF_SIZE    16384     /* initial size of utf-hash           */
-
-hashtable *hashtable_utf;               /* hashtable for utf8-symbols         */
-
-
-/* utf-symbols for pointer comparison of frequently used strings **************/
-
-utf *utf_java_lang_Object;
-
-utf *utf_java_lang_Class;
-utf *utf_java_lang_ClassLoader;
-utf *utf_java_lang_Cloneable;
-utf *utf_java_lang_SecurityManager;
-utf *utf_java_lang_String;
-utf *utf_java_lang_System;
-utf *utf_java_lang_ThreadGroup;
-utf *utf_java_io_Serializable;
-
-utf *utf_java_lang_Throwable;
-utf *utf_java_lang_Error;
-utf *utf_java_lang_LinkageError;
-utf *utf_java_lang_NoClassDefFoundError;
-utf *utf_java_lang_OutOfMemoryError;
-utf *utf_java_lang_VirtualMachineError;
-
-#if defined(ENABLE_JAVASE)
-utf *utf_java_lang_AbstractMethodError;
-utf *utf_java_lang_NoSuchMethodError;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-utf *utf_java_lang_VMThrowable;
-#endif
-
-utf *utf_java_lang_Exception;
-utf *utf_java_lang_ClassCastException;
-utf *utf_java_lang_ClassNotFoundException;
-utf *utf_java_lang_IllegalArgumentException;
-utf *utf_java_lang_IllegalMonitorStateException;
-
-utf *utf_java_lang_NullPointerException;
-
-#if defined(ENABLE_JAVASE)
-utf* utf_java_lang_Void;
-#endif
-
-utf* utf_java_lang_Boolean;
-utf* utf_java_lang_Byte;
-utf* utf_java_lang_Character;
-utf* utf_java_lang_Short;
-utf* utf_java_lang_Integer;
-utf* utf_java_lang_Long;
-utf* utf_java_lang_Float;
-utf* utf_java_lang_Double;
-
-#if defined(ENABLE_JAVASE)
-utf *utf_java_lang_StackTraceElement;
-utf *utf_java_lang_reflect_Constructor;
-utf *utf_java_lang_reflect_Field;
-utf *utf_java_lang_reflect_Method;
-utf *utf_java_util_Vector;
-#endif
-
-utf *utf_InnerClasses;                  /* InnerClasses                       */
-utf *utf_ConstantValue;                 /* ConstantValue                      */
-utf *utf_Code;                          /* Code                               */
-utf *utf_Exceptions;                    /* Exceptions                         */
-utf *utf_LineNumberTable;               /* LineNumberTable                    */
-utf *utf_SourceFile;                    /* SourceFile                         */
-
-#if defined(ENABLE_JAVASE)
-utf *utf_EnclosingMethod;
-utf *utf_Signature;
-utf *utf_RuntimeVisibleAnnotations;
-utf *utf_StackMapTable;
-#endif
-
-utf *utf_init;                          /* <init>                             */
-utf *utf_clinit;                        /* <clinit>                           */
-utf *utf_clone;                         /* clone                              */
-utf *utf_finalize;                      /* finalize                           */
-utf *utf_run;                           /* run                                */
-
-utf *utf_add;
-utf *utf_remove;
-utf *utf_addThread;
-utf *utf_removeThread;
-utf *utf_put;
-utf *utf_get;
-utf *utf_value;
-
-utf *utf_fillInStackTrace;
-utf *utf_getSystemClassLoader;
-utf *utf_loadClass;
-utf *utf_printStackTrace;
-
-utf *utf_Z;                             /* Z                                  */
-utf *utf_B;                             /* B                                  */
-utf *utf_C;                             /* C                                  */
-utf *utf_S;                             /* S                                  */
-utf *utf_I;                             /* I                                  */
-utf *utf_J;                             /* J                                  */
-utf *utf_F;                             /* F                                  */
-utf *utf_D;                             /* D                                  */
-
-utf *utf_void__void;                    /* ()V                                */
-utf *utf_boolean__void;                 /* (Z)V                               */
-utf *utf_byte__void;                    /* (B)V                               */
-utf *utf_char__void;                    /* (C)V                               */
-utf *utf_short__void;                   /* (S)V                               */
-utf *utf_int__void;                     /* (I)V                               */
-utf *utf_long__void;                    /* (J)V                               */
-utf *utf_float__void;                   /* (F)V                               */
-utf *utf_double__void;                  /* (D)V                               */
-
-utf *utf_void__java_lang_ClassLoader;   /* ()Ljava/lang/ClassLoader;          */
-utf *utf_void__java_lang_Object;        /* ()Ljava/lang/Object;               */
-utf *utf_void__java_lang_Throwable;     /* ()Ljava/lang/Throwable;            */
-utf *utf_java_lang_Object__java_lang_Object;
-utf *utf_java_lang_String__void;        /* (Ljava/lang/String;)V              */
-utf *utf_java_lang_String__java_lang_Class;
-utf *utf_java_lang_Thread__V;           /* (Ljava/lang/Thread;)V              */
-utf *utf_java_lang_Throwable__void;     /* (Ljava/lang/Throwable;)V           */
-
-utf *utf_not_named_yet;                 /* special name for unnamed classes   */
-utf *utf_null;
-utf *array_packagename;
-
-
-/* utf_init ********************************************************************
-
-   Initializes the utf8 subsystem.
-
-*******************************************************************************/
-
-bool utf8_init(void)
-{
-       /* create utf8 hashtable */
-
-       hashtable_utf = NEW(hashtable);
-
-       hashtable_create(hashtable_utf, HASHTABLE_UTF_SIZE);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_utf_len += sizeof(utf*) * hashtable_utf->size;
-#endif
-
-       /* create utf-symbols for pointer comparison of frequently used strings */
-
-       utf_java_lang_Object           = utf_new_char("java/lang/Object");
-
-       utf_java_lang_Class            = utf_new_char("java/lang/Class");
-       utf_java_lang_ClassLoader      = utf_new_char("java/lang/ClassLoader");
-       utf_java_lang_Cloneable        = utf_new_char("java/lang/Cloneable");
-       utf_java_lang_SecurityManager  = utf_new_char("java/lang/SecurityManager");
-       utf_java_lang_String           = utf_new_char("java/lang/String");
-       utf_java_lang_System           = utf_new_char("java/lang/System");
-       utf_java_lang_ThreadGroup      = utf_new_char("java/lang/ThreadGroup");
-       utf_java_io_Serializable       = utf_new_char("java/io/Serializable");
-
-       utf_java_lang_Throwable        = utf_new_char(string_java_lang_Throwable);
-       utf_java_lang_Error            = utf_new_char(string_java_lang_Error);
-
-       utf_java_lang_LinkageError =
-               utf_new_char(string_java_lang_LinkageError);
-
-       utf_java_lang_NoClassDefFoundError =
-               utf_new_char(string_java_lang_NoClassDefFoundError);
-
-       utf_java_lang_OutOfMemoryError =
-               utf_new_char(string_java_lang_OutOfMemoryError);
-
-       utf_java_lang_VirtualMachineError =
-               utf_new_char(string_java_lang_VirtualMachineError);
-
-#if defined(ENABLE_JAVASE)
-       utf_java_lang_AbstractMethodError =
-               utf_new_char(string_java_lang_AbstractMethodError);
-
-       utf_java_lang_NoSuchMethodError =
-               utf_new_char(string_java_lang_NoSuchMethodError);
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-       utf_java_lang_VMThrowable      = utf_new_char(string_java_lang_VMThrowable);
-#endif
-
-       utf_java_lang_Exception        = utf_new_char(string_java_lang_Exception);
-
-       utf_java_lang_ClassCastException =
-               utf_new_char(string_java_lang_ClassCastException);
-
-       utf_java_lang_ClassNotFoundException =
-               utf_new_char(string_java_lang_ClassNotFoundException);
-
-       utf_java_lang_IllegalArgumentException =
-               utf_new_char(string_java_lang_IllegalArgumentException);
-
-       utf_java_lang_IllegalMonitorStateException =
-               utf_new_char(string_java_lang_IllegalMonitorStateException);
-
-       utf_java_lang_NullPointerException =
-               utf_new_char(string_java_lang_NullPointerException);
-
-#if defined(ENABLE_JAVASE)
-       utf_java_lang_Void             = utf_new_char("java/lang/Void");
-#endif
-
-       utf_java_lang_Boolean          = utf_new_char("java/lang/Boolean");
-       utf_java_lang_Byte             = utf_new_char("java/lang/Byte");
-       utf_java_lang_Character        = utf_new_char("java/lang/Character");
-       utf_java_lang_Short            = utf_new_char("java/lang/Short");
-       utf_java_lang_Integer          = utf_new_char("java/lang/Integer");
-       utf_java_lang_Long             = utf_new_char("java/lang/Long");
-       utf_java_lang_Float            = utf_new_char("java/lang/Float");
-       utf_java_lang_Double           = utf_new_char("java/lang/Double");
-
-#if defined(ENABLE_JAVASE)
-       utf_java_lang_StackTraceElement =
-               utf_new_char("java/lang/StackTraceElement");
-
-       utf_java_lang_reflect_Constructor =
-               utf_new_char("java/lang/reflect/Constructor");
-
-       utf_java_lang_reflect_Field    = utf_new_char("java/lang/reflect/Field");
-       utf_java_lang_reflect_Method   = utf_new_char("java/lang/reflect/Method");
-       utf_java_util_Vector           = utf_new_char("java/util/Vector");
-#endif
-
-       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");
-
-#if defined(ENABLE_JAVASE)
-       utf_EnclosingMethod            = utf_new_char("EnclosingMethod");
-       utf_Signature                  = utf_new_char("Signature");
-       utf_RuntimeVisibleAnnotations  = utf_new_char("RuntimeVisibleAnnotations");
-       utf_StackMapTable              = utf_new_char("StackMapTable");
-#endif
-
-       utf_init                           = utf_new_char("<init>");
-       utf_clinit                         = utf_new_char("<clinit>");
-       utf_clone                      = utf_new_char("clone");
-       utf_finalize                   = utf_new_char("finalize");
-       utf_run                        = utf_new_char("run");
-
-       utf_add                        = utf_new_char("add");
-       utf_remove                     = utf_new_char("remove");
-       utf_addThread                  = utf_new_char("addThread");
-       utf_removeThread               = utf_new_char("removeThread");
-       utf_put                        = utf_new_char("put");
-       utf_get                        = utf_new_char("get");
-       utf_value                      = utf_new_char("value");
-
-       utf_printStackTrace            = utf_new_char("printStackTrace");
-       utf_fillInStackTrace           = utf_new_char("fillInStackTrace");
-       utf_loadClass                  = utf_new_char("loadClass");
-       utf_getSystemClassLoader       = utf_new_char("getSystemClassLoader");
-
-       utf_Z                          = utf_new_char("Z");
-       utf_B                          = utf_new_char("B");
-       utf_C                          = utf_new_char("C");
-       utf_S                          = utf_new_char("S");
-       utf_I                          = utf_new_char("I");
-       utf_J                          = utf_new_char("J");
-       utf_F                          = utf_new_char("F");
-       utf_D                          = utf_new_char("D");
-
-       utf_void__void                 = utf_new_char("()V");
-       utf_boolean__void              = utf_new_char("(Z)V");
-       utf_byte__void                 = utf_new_char("(B)V");
-       utf_char__void                 = utf_new_char("(C)V");
-       utf_short__void                = utf_new_char("(S)V");
-       utf_int__void                  = utf_new_char("(I)V");
-       utf_long__void                 = utf_new_char("(J)V");
-       utf_float__void                = utf_new_char("(F)V");
-       utf_double__void               = utf_new_char("(D)V");
-       utf_void__java_lang_Object     = utf_new_char("()Ljava/lang/Object;");
-       utf_void__java_lang_Throwable  = utf_new_char("()Ljava/lang/Throwable;");
-
-       utf_void__java_lang_ClassLoader =
-               utf_new_char("()Ljava/lang/ClassLoader;");
-
-       utf_java_lang_Object__java_lang_Object =
-               utf_new_char("(Ljava/lang/Object;)Ljava/lang/Object;");
-
-       utf_java_lang_String__void     = utf_new_char("(Ljava/lang/String;)V");
-
-       utf_java_lang_String__java_lang_Class =
-               utf_new_char("(Ljava/lang/String;)Ljava/lang/Class;");
-
-       utf_java_lang_Thread__V        = utf_new_char("(Ljava/lang/Thread;)V");
-       utf_java_lang_Throwable__void  = utf_new_char("(Ljava/lang/Throwable;)V");
-
-       utf_null                       = utf_new_char("null");
-       utf_not_named_yet              = utf_new_char("\t<not_named_yet>");
-       array_packagename              = utf_new_char("\t<the array package>");
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* utf_hashkey *****************************************************************
-
-   The hashkey is computed from the utf-text by using up to 8
-   characters.  For utf-symbols longer than 15 characters 3 characters
-   are taken from the beginning and the end, 2 characters are taken
-   from the middle.
-
-*******************************************************************************/
-
-#define nbs(val) ((u4) *(++text) << val) /* get next byte, left shift by val  */
-#define fbs(val) ((u4) *(  text) << val) /* get first byte, left shift by val */
-
-u4 utf_hashkey(const char *text, u4 length)
-{
-       const char *start_pos = text;       /* pointer to utf text                */
-       u4 a;
-
-       switch (length) {
-       case 0: /* empty string */
-               return 0;
-
-       case 1: return fbs(0);
-       case 2: return fbs(0) ^ nbs(3);
-       case 3: return fbs(0) ^ nbs(3) ^ nbs(5);
-       case 4: return fbs(0) ^ nbs(2) ^ nbs(4) ^ nbs(6);
-       case 5: return fbs(0) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(6);
-       case 6: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(5) ^ nbs(6);
-       case 7: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6);
-       case 8: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7);
-
-       case 9:
-               a = fbs(0);
-               a ^= nbs(1);
-               a ^= nbs(2);
-               text++;
-               return a ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7) ^ nbs(8);
-
-       case 10:
-               a = fbs(0);
-               text++;
-               a ^= nbs(2);
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text++;
-               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9);
-
-       case 11:
-               a = fbs(0);
-               text++;
-               a ^= nbs(2);
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text++;
-               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9) ^ nbs(10);
-
-       case 12:
-               a = fbs(0);
-               text += 2;
-               a ^= nbs(2);
-               a ^= nbs(3);
-               text++;
-               a ^= nbs(5);
-               a ^= nbs(6);
-               a ^= nbs(7);
-               text++;
-               return a ^ nbs(9) ^ nbs(10);
-
-       case 13:
-               a = fbs(0);
-               a ^= nbs(1);
-               text++;
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text += 2;      
-               a ^= nbs(7);
-               a ^= nbs(8);
-               text += 2;
-               return a ^ nbs(9) ^ nbs(10);
-
-       case 14:
-               a = fbs(0);
-               text += 2;      
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text += 2;      
-               a ^= nbs(7);
-               a ^= nbs(8);
-               text += 2;
-               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
-
-       case 15:
-               a = fbs(0);
-               text += 2;      
-               a ^= nbs(3);
-               a ^= nbs(4);
-               text += 2;      
-               a ^= nbs(7);
-               a ^= nbs(8);
-               text += 2;
-               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
-
-       default:  /* 3 characters from beginning */
-               a = fbs(0);
-               text += 2;
-               a ^= nbs(3);
-               a ^= nbs(4);
-
-               /* 2 characters from middle */
-               text = start_pos + (length / 2);
-               a ^= fbs(5);
-               text += 2;
-               a ^= nbs(6);    
-
-               /* 3 characters from end */
-               text = start_pos + length - 4;
-
-               a ^= fbs(7);
-               text++;
-
-               return a ^ nbs(10) ^ nbs(11);
-    }
-}
-
-/* utf_full_hashkey ************************************************************
-
-   This function computes a hash value using all bytes in the string.
-
-   The algorithm is the "One-at-a-time" algorithm as published
-   by Bob Jenkins on http://burtleburtle.net/bob/hash/doobs.html.
-
-*******************************************************************************/
-
-u4 utf_full_hashkey(const char *text, u4 length)
-{
-       register const unsigned char *p = (const unsigned char *) text;
-       register u4 hash;
-       register u4 i;
-
-       hash = 0;
-       for (i=length; i--;)
-       {
-           hash += *p++;
-           hash += (hash << 10);
-           hash ^= (hash >> 6);
-       }
-       hash += (hash << 3);
-       hash ^= (hash >> 11);
-       hash += (hash << 15);
-
-       return hash;
-}
-
-/* unicode_hashkey *************************************************************
-
-   Compute the hashkey of a unicode string.
-
-*******************************************************************************/
-
-u4 unicode_hashkey(u2 *text, u2 len)
-{
-       return utf_hashkey((char *) text, len);
-}
-
-
-/* utf_new *********************************************************************
-
-   Creates a new utf-symbol, the text of the symbol is passed as a
-   u1-array. The function searches the utf-hashtable for a utf-symbol
-   with this text. On success the element returned, otherwise a new
-   hashtable element is created.
-
-   If the number of entries in the hashtable exceeds twice the size of
-   the hashtable slots a reorganization of the hashtable is done and
-   the utf symbols are copied to a new hashtable with doubled size.
-
-*******************************************************************************/
-
-utf *utf_new(const char *text, u2 length)
-{
-       u4 key;                             /* hashkey computed from utf-text     */
-       u4 slot;                            /* slot in hashtable                  */
-       utf *u;                             /* hashtable element                  */
-       u2 i;
-
-       LOCK_MONITOR_ENTER(hashtable_utf->header);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_utf_new++;
-#endif
-
-       key  = utf_hashkey(text, length);
-       slot = key & (hashtable_utf->size - 1);
-       u    = hashtable_utf->ptr[slot];
-
-       /* search external hash chain for utf-symbol */
-
-       while (u) {
-               if (u->blength == length) {
-                       /* compare text of hashtable elements */
-
-                       for (i = 0; i < length; i++)
-                               if (text[i] != u->text[i])
-                                       goto nomatch;
-                       
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_utf_new_found++;
-#endif
-
-                       /* symbol found in hashtable */
-
-                       LOCK_MONITOR_EXIT(hashtable_utf->header);
-
-                       return u;
-               }
-
-       nomatch:
-               u = u->hashlink; /* next element in external chain */
-       }
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_utf_len += sizeof(utf) + length + 1;
-#endif
-
-       /* location in hashtable found, create new utf element */
-       u = NEW(utf);
-       u->blength  = length;               /* length in bytes of utfstring       */
-       u->hashlink = hashtable_utf->ptr[slot]; /* link in external hashchain     */
-       u->text     = mem_alloc(length + 1);/* allocate memory for utf-text       */
-
-       memcpy(u->text, text, length);      /* copy utf-text                      */
-       u->text[length] = '\0';
-
-       hashtable_utf->ptr[slot] = u;       /* insert symbol into table           */
-       hashtable_utf->entries++;           /* update number of entries           */
-
-       if (hashtable_utf->entries > (hashtable_utf->size * 2)) {
-
-        /* reorganization of hashtable, average length of the external
-           chains is approx. 2 */
-
-               hashtable *newhash;                              /* the new hashtable */
-               u4         i;
-               utf       *u;
-               utf       *nextu;
-               u4         slot;
-
-               /* create new hashtable, double the size */
-
-               newhash = hashtable_resize(hashtable_utf, hashtable_utf->size * 2);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_utf_len += sizeof(utf*) * hashtable_utf->size;
-#endif
-
-               /* transfer elements to new hashtable */
-
-               for (i = 0; i < hashtable_utf->size; i++) {
-                       u = hashtable_utf->ptr[i];
-
-                       while (u) {
-                               nextu = u->hashlink;
-                               slot  = utf_hashkey(u->text, u->blength) & (newhash->size - 1);
-                                               
-                               u->hashlink = (utf *) newhash->ptr[slot];
-                               newhash->ptr[slot] = u;
-
-                               /* follow link in external hash chain */
-
-                               u = nextu;
-                       }
-               }
-       
-               /* dispose old table */
-
-               hashtable_free(hashtable_utf);
-
-               hashtable_utf = newhash;
-       }
-
-       LOCK_MONITOR_EXIT(hashtable_utf->header);
-
-       return u;
-}
-
-
-/* utf_new_u2 ******************************************************************
-
-   Make utf symbol from u2 array, if isclassname is true '.' is
-   replaced by '/'.
-
-*******************************************************************************/
-
-utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
-{
-       char *buffer;                   /* memory buffer for  unicode characters  */
-       char *pos;                      /* pointer to current position in buffer  */
-       u4 left;                        /* unicode characters left                */
-       u4 buflength;                   /* utf length in bytes of the u2 array    */
-       utf *result;                    /* resulting utf-string                   */
-       int i;          
-
-       /* determine utf length in bytes and allocate memory */
-
-       buflength = u2_utflength(unicode_pos, unicode_length); 
-       buffer    = MNEW(char, buflength);
-       left = buflength;
-       pos  = buffer;
-
-       for (i = 0; i++ < unicode_length; unicode_pos++) {
-               /* next unicode character */
-               u2 c = *unicode_pos;
-               
-               if ((c != 0) && (c < 0x80)) {
-                       /* 1 character */       
-                       left--;
-               if ((int) left < 0) break;
-                       /* convert classname */
-                       if (isclassname && c == '.')
-                               *pos++ = '/';
-                       else
-                               *pos++ = (char) c;
-
-               } else if (c < 0x800) {             
-                       /* 2 characters */                              
-               unsigned char high = c >> 6;
-               unsigned char low  = c & 0x3F;
-                       left = left - 2;
-               if ((int) left < 0) break;
-               *pos++ = high | 0xC0; 
-               *pos++ = low  | 0x80;     
-
-               } else {         
-               /* 3 characters */                              
-               char low  = c & 0x3f;
-               char mid  = (c >> 6) & 0x3F;
-               char high = c >> 12;
-                       left = left - 3;
-               if ((int) left < 0) break;
-               *pos++ = high | 0xE0; 
-               *pos++ = mid  | 0x80;  
-               *pos++ = low  | 0x80;   
-               }
-       }
-       
-       /* insert utf-string into symbol-table */
-       result = utf_new(buffer,buflength);
-
-       MFREE(buffer, char, buflength);
-
-       return result;
-}
-
-
-/* utf_new_char ****************************************************************
-
-   Creates a new utf symbol, the text for this symbol is passed as a
-   c-string ( = char* ).
-
-*******************************************************************************/
-
-utf *utf_new_char(const char *text)
-{
-       return utf_new(text, strlen(text));
-}
-
-
-/* utf_new_char_classname ******************************************************
-
-   Creates a new utf symbol, the text for this symbol is passed as a
-   c-string ( = char* ) "." characters are going to be replaced by
-   "/". Since the above function is used often, this is a separte
-   function, instead of an if.
-
-*******************************************************************************/
-
-utf *utf_new_char_classname(const char *text)
-{
-       if (strchr(text, '.')) {
-               char *txt = strdup(text);
-               char *end = txt + strlen(txt);
-               char *c;
-               utf *tmpRes;
-
-               for (c = txt; c < end; c++)
-                       if (*c == '.') *c = '/';
-
-               tmpRes = utf_new(txt, strlen(txt));
-               FREE(txt, 0);
-
-               return tmpRes;
-
-       } else
-               return utf_new(text, strlen(text));
-}
-
-
-/* utf_nextu2 ******************************************************************
-
-   Read the next unicode character from the utf string and increment
-   the utf-string pointer accordingly.
-
-   CAUTION: This function is unsafe for input that was not checked 
-            by is_valid_utf!
-
-*******************************************************************************/
-
-u2 utf_nextu2(char **utf_ptr)
-{
-    /* uncompressed unicode character */
-    u2 unicode_char = 0;
-    /* current position in utf text */ 
-    unsigned char *utf = (unsigned char *) (*utf_ptr);
-    /* bytes representing the unicode character */
-    unsigned char ch1, ch2, ch3;
-    /* number of bytes used to represent the unicode character */
-    int len = 0;
-       
-    switch ((ch1 = utf[0]) >> 4) {
-       default: /* 1 byte */
-               (*utf_ptr)++;
-               return (u2) ch1;
-       case 0xC: 
-       case 0xD: /* 2 bytes */
-               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
-                       unsigned char high = ch1 & 0x1F;
-                       unsigned char low  = ch2 & 0x3F;
-                       unicode_char = (high << 6) + low;
-                       len = 2;
-               }
-               break;
-
-       case 0xE: /* 2 or 3 bytes */
-               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
-                       if (((ch3 = utf[2]) & 0xC0) == 0x80) {
-                               unsigned char low  = ch3 & 0x3f;
-                               unsigned char mid  = ch2 & 0x3f;
-                               unsigned char high = ch1 & 0x0f;
-                               unicode_char = (((high << 6) + mid) << 6) + low;
-                               len = 3;
-                       } else
-                               len = 2;                                           
-               }
-               break;
-    }
-
-    /* update position in utf-text */
-    *utf_ptr = (char *) (utf + len);
-
-    return unicode_char;
-}
-
-
-/* utf_bytes *******************************************************************
-
-   Determine number of bytes (aka. octets) in the utf string.
-
-   IN:
-      u............utf string
-
-   OUT:
-      The number of octets of this utf string.
-         There is _no_ terminating zero included in this count.
-
-*******************************************************************************/
-
-u4 utf_bytes(utf *u)
-{
-       return u->blength;
-}
-
-/* utf_get_number_of_u2s_for_buffer ********************************************
-
-   Determine number of UTF-16 u2s in the given UTF-8 buffer
-
-   CAUTION: This function is unsafe for input that was not checked 
-            by is_valid_utf!
-
-   CAUTION: Use this function *only* when you want to convert an UTF-8 buffer
-   to an array of u2s (UTF-16) and want to know how many of them you will get.
-   All other uses of this function are probably wrong.
-
-   IN:
-      buffer........points to first char in buffer
-         blength.......number of _bytes_ in the buffer
-
-   OUT:
-      the number of u2s needed to hold this string in UTF-16 encoding.
-         There is _no_ terminating zero included in this count.
-
-   NOTE: Unlike utf_get_number_of_u2s, this function never throws an
-   exception.
-
-*******************************************************************************/
-
-u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength)
-{
-       const char *endpos;                 /* points behind utf string           */
-       const char *utf_ptr;                /* current position in utf text       */
-       u4 len = 0;                         /* number of unicode characters       */
-
-       utf_ptr = buffer;
-       endpos = utf_ptr + blength;
-
-       while (utf_ptr < endpos) {
-               len++;
-               /* next unicode character */
-               utf_nextu2((char **)&utf_ptr);
-       }
-
-       assert(utf_ptr == endpos);
-
-       return len;
-}
-
-
-/* utf_get_number_of_u2s *******************************************************
-
-   Determine number of UTF-16 u2s in the utf string.
-
-   CAUTION: This function is unsafe for input that was not checked 
-            by is_valid_utf!
-
-   CAUTION: Use this function *only* when you want to convert a utf string
-   to an array of u2s and want to know how many of them you will get.
-   All other uses of this function are probably wrong.
-
-   IN:
-      u............utf string
-
-   OUT:
-      the number of u2s needed to hold this string in UTF-16 encoding.
-         There is _no_ terminating zero included in this count.
-         XXX 0 if a NullPointerException has been thrown (see below)
-
-*******************************************************************************/
-
-u4 utf_get_number_of_u2s(utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-       u4 len = 0;                         /* number of unicode characters       */
-
-       /* XXX this is probably not checked by most callers! Review this after */
-       /* the invalid uses of this function have been eliminated */
-       if (u == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               len++;
-               /* next unicode character */
-               utf_nextu2(&utf_ptr);
-       }
-
-       if (utf_ptr != endpos) {
-               /* string ended abruptly */
-               exceptions_throw_internalerror("Illegal utf8 string");
-               return NULL;
-       }
-
-       return len;
-}
-
-
-/* utf8_safe_number_of_u2s *****************************************************
-
-   Determine number of UTF-16 u2s needed for decoding the given UTF-8 string.
-   (For invalid UTF-8 the U+fffd replacement character will be counted.)
-
-   This function is safe even for invalid UTF-8 strings.
-
-   IN:
-      text..........zero-terminated(!) UTF-8 string (may be invalid)
-                       must NOT be NULL
-         nbytes........strlen(text). (This is needed to completely emulate
-                       the RI).
-
-   OUT:
-      the number of u2s needed to hold this string in UTF-16 encoding.
-         There is _no_ terminating zero included in this count.
-
-*******************************************************************************/
-
-s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes) {
-       register const unsigned char *t;
-       register s4 byte;
-       register s4 len;
-       register const unsigned char *tlimit;
-       s4 byte1;
-       s4 byte2;
-       s4 byte3;
-       s4 value;
-       s4 skip;
-
-       assert(text);
-       assert(nbytes >= 0);
-
-       len = 0;
-       t = (const unsigned char *) text;
-       tlimit = t + nbytes;
-
-       /* CAUTION: Keep this code in sync with utf8_safe_convert_to_u2s! */
-
-       while (1) {
-               byte = *t++;
-
-               if (byte & 0x80) {
-                       /* highest bit set, non-ASCII character */
-
-                       if ((byte & 0xe0) == 0xc0) {
-                               /* 2-byte: should be 110..... 10...... ? */
-
-                               if ((*t++ & 0xc0) == 0x80)
-                                       ; /* valid 2-byte */
-                               else
-                                       t--; /* invalid */
-                       }
-                       else if ((byte & 0xf0) == 0xe0) {
-                               /* 3-byte: should be 1110.... 10...... 10...... */
-                               /*                            ^t                */
-
-                               if (t + 2 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               if ((*t++ & 0xc0) == 0x80) {
-                                       if ((*t++ & 0xc0) == 0x80)
-                                               ; /* valid 3-byte */
-                                       else
-                                               t--; /* invalid */
-                               }
-                               else
-                                       t--; /* invalid */
-                       }
-                       else if ((byte & 0xf8) == 0xf0) {
-                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
-                               /*                            ^t                         */
-
-                               if (t + 3 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
-                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
-                                                       /* valid 4-byte UTF-8? */
-                                                       value = ((byte  & 0x07) << 18)
-                                                                 | ((byte1 & 0x3f) << 12)
-                                                                 | ((byte2 & 0x3f) <<  6)
-                                                                 | ((byte3 & 0x3f)      );
-
-                                                       if (value > 0x10FFFF)
-                                                               ; /* invalid */
-                                                       else if (value > 0xFFFF)
-                                                               len += 1; /* we need surrogates */
-                                                       else
-                                                               ; /* 16bit suffice */
-                                               }
-                                               else
-                                                       t--; /* invalid */
-                                       }
-                                       else
-                                               t--; /* invalid */
-                               }
-                               else
-                                       t--; /* invalid */
-                       }
-                       else if ((byte & 0xfc) == 0xf8) {
-                               /* invalid 5-byte */
-                               if (t + 4 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               skip = 4;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                       }
-                       else if ((byte & 0xfe) == 0xfc) {
-                               /* invalid 6-byte */
-                               if (t + 5 > tlimit)
-                                       return len + 1; /* invalid, stop here */
-
-                               skip = 5;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                       }
-                       else
-                               ; /* invalid */
-               }
-               else {
-                       /* NUL */
-
-                       if (byte == 0)
-                               break;
-
-                       /* ASCII character, common case */
-               }
-
-               len++;
-       }
-
-       return len;
-}
-
-
-/* utf8_safe_convert_to_u2s ****************************************************
-
-   Convert the given UTF-8 string to UTF-16 into a pre-allocated buffer.
-   (Invalid UTF-8 will be replaced with the U+fffd replacement character.)
-   Use utf8_safe_number_of_u2s to determine the number of u2s to allocate.
-
-   This function is safe even for invalid UTF-8 strings.
-
-   IN:
-      text..........zero-terminated(!) UTF-8 string (may be invalid)
-                       must NOT be NULL
-         nbytes........strlen(text). (This is needed to completely emulate
-                                       the RI).
-         buffer........a preallocated array of u2s to receive the decoded
-                       string. Use utf8_safe_number_of_u2s to get the
-                                       required number of u2s for allocating this.
-
-*******************************************************************************/
-
-#define UNICODE_REPLACEMENT  0xfffd
-
-void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer) {
-       register const unsigned char *t;
-       register s4 byte;
-       register const unsigned char *tlimit;
-       s4 byte1;
-       s4 byte2;
-       s4 byte3;
-       s4 value;
-       s4 skip;
-
-       assert(text);
-       assert(nbytes >= 0);
-
-       t = (const unsigned char *) text;
-       tlimit = t + nbytes;
-
-       /* CAUTION: Keep this code in sync with utf8_safe_number_of_u2s! */
-
-       while (1) {
-               byte = *t++;
-
-               if (byte & 0x80) {
-                       /* highest bit set, non-ASCII character */
-
-                       if ((byte & 0xe0) == 0xc0) {
-                               /* 2-byte: should be 110..... 10...... */
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       /* valid 2-byte UTF-8 */
-                                       *buffer++ = ((byte  & 0x1f) << 6)
-                                                         | ((byte1 & 0x3f)     );
-                               }
-                               else {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       t--;
-                               }
-                       }
-                       else if ((byte & 0xf0) == 0xe0) {
-                               /* 3-byte: should be 1110.... 10...... 10...... */
-
-                               if (t + 2 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
-                                               /* valid 3-byte UTF-8 */
-                                               *buffer++ = ((byte  & 0x0f) << 12)
-                                                                 | ((byte1 & 0x3f) <<  6)
-                                                                 | ((byte2 & 0x3f)      );
-                                       }
-                                       else {
-                                               *buffer++ = UNICODE_REPLACEMENT;
-                                               t--;
-                                       }
-                               }
-                               else {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       t--;
-                               }
-                       }
-                       else if ((byte & 0xf8) == 0xf0) {
-                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
-
-                               if (t + 3 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               if (((byte1 = *t++) & 0xc0) == 0x80) {
-                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
-                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
-                                                       /* valid 4-byte UTF-8? */
-                                                       value = ((byte  & 0x07) << 18)
-                                                                 | ((byte1 & 0x3f) << 12)
-                                                                 | ((byte2 & 0x3f) <<  6)
-                                                                 | ((byte3 & 0x3f)      );
-
-                                                       if (value > 0x10FFFF) {
-                                                               *buffer++ = UNICODE_REPLACEMENT;
-                                                       }
-                                                       else if (value > 0xFFFF) {
-                                                               /* we need surrogates */
-                                                               *buffer++ = 0xd800 | ((value >> 10) - 0x40);
-                                                               *buffer++ = 0xdc00 | (value & 0x03ff);
-                                                       }
-                                                       else
-                                                               *buffer++ = value; /* 16bit suffice */
-                                               }
-                                               else {
-                                                       *buffer++ = UNICODE_REPLACEMENT;
-                                                       t--;
-                                               }
-                                       }
-                                       else {
-                                               *buffer++ = UNICODE_REPLACEMENT;
-                                               t--;
-                                       }
-                               }
-                               else {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       t--;
-                               }
-                       }
-                       else if ((byte & 0xfc) == 0xf8) {
-                               if (t + 4 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               skip = 4;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                               *buffer++ = UNICODE_REPLACEMENT;
-                       }
-                       else if ((byte & 0xfe) == 0xfc) {
-                               if (t + 5 > tlimit) {
-                                       *buffer++ = UNICODE_REPLACEMENT;
-                                       return;
-                               }
-
-                               skip = 5;
-                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
-                                       t++;
-                               *buffer++ = UNICODE_REPLACEMENT;
-                       }
-                       else
-                               *buffer++ = UNICODE_REPLACEMENT;
-               }
-               else {
-                       /* NUL */
-
-                       if (byte == 0)
-                               break;
-
-                       /* ASCII character, common case */
-
-                       *buffer++ = byte;
-               }
-       }
-}
-
-
-/* u2_utflength ****************************************************************
-
-   Returns the utf length in bytes of a u2 array.
-
-*******************************************************************************/
-
-u4 u2_utflength(u2 *text, u4 u2_length)
-{
-       u4 result_len = 0;                  /* utf length in bytes                */
-       u2 ch;                              /* current unicode character          */
-       u4 len;
-       
-       for (len = 0; len < u2_length; len++) {
-               /* next unicode character */
-               ch = *text++;
-         
-               /* determine bytes required to store unicode character as utf */
-               if (ch && (ch < 0x80)) 
-                       result_len++;
-               else if (ch < 0x800)
-                       result_len += 2;        
-               else 
-                       result_len += 3;        
-       }
-
-    return result_len;
-}
-
-
-/* utf_copy ********************************************************************
-
-   Copy the given utf string byte-for-byte to a buffer.
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_copy(char *buffer, utf *u)
-{
-       /* our utf strings are zero-terminated (done by utf_new) */
-       MCOPY(buffer, u->text, char, u->blength + 1);
-}
-
-
-/* utf_cat *********************************************************************
-
-   Append the given utf string byte-for-byte to a buffer.
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_cat(char *buffer, utf *u)
-{
-       /* our utf strings are zero-terminated (done by utf_new) */
-       MCOPY(buffer + strlen(buffer), u->text, char, u->blength + 1);
-}
-
-
-/* utf_copy_classname **********************************************************
-
-   Copy the given utf classname byte-for-byte to a buffer.
-   '/' is replaced by '.'
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_copy_classname(char *buffer, utf *u)
-{
-       char *bufptr;
-       char *srcptr;
-       char *endptr;
-       char ch;
-
-       bufptr = buffer;
-       srcptr = u->text;
-       endptr = UTF_END(u) + 1; /* utfs are zero-terminared by utf_new */
-
-       while (srcptr != endptr) {
-               ch = *srcptr++;
-               if (ch == '/')
-                       ch = '.';
-               *bufptr++ = ch;
-       }
-}
-
-
-/* utf_cat *********************************************************************
-
-   Append the given utf classname byte-for-byte to a buffer.
-   '/' is replaced by '.'
-
-   IN:
-      buffer.......the buffer
-         u............the utf string
-
-*******************************************************************************/
-
-void utf_cat_classname(char *buffer, utf *u)
-{
-       utf_copy_classname(buffer + strlen(buffer), u);
-}
-
-/* utf_display_printable_ascii *************************************************
-
-   Write utf symbol to stdout (for debugging purposes).
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_display_printable_ascii(utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-       if (u == NULL) {
-               printf("NULL");
-               fflush(stdout);
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               /* read next unicode character */
-
-               u2 c = utf_nextu2(&utf_ptr);
-
-               if ((c >= 32) && (c <= 127))
-                       printf("%c", c);
-               else
-                       printf("?");
-       }
-
-       fflush(stdout);
-}
-
-
-/* utf_display_printable_ascii_classname ***************************************
-
-   Write utf symbol to stdout with `/' converted to `.' (for debugging
-   purposes).
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_display_printable_ascii_classname(utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-       if (u == NULL) {
-               printf("NULL");
-               fflush(stdout);
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               /* read next unicode character */
-
-               u2 c = utf_nextu2(&utf_ptr);
-
-               if (c == '/')
-                       c = '.';
-
-               if ((c >= 32) && (c <= 127))
-                       printf("%c", c);
-               else
-                       printf("?");
-       }
-
-       fflush(stdout);
-}
-
-
-/* utf_sprint_convert_to_latin1 ************************************************
-       
-   Write utf symbol into c-string (for debugging purposes).
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_sprint_convert_to_latin1(char *buffer, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-       u2 pos = 0;                         /* position in c-string               */
-
-       if (!u) {
-               strcpy(buffer, "NULL");
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) 
-               /* copy next unicode character */       
-               buffer[pos++] = utf_nextu2(&utf_ptr);
-
-       /* terminate string */
-       buffer[pos] = '\0';
-}
-
-
-/* utf_sprint_convert_to_latin1_classname **************************************
-       
-   Write utf symbol into c-string with `/' converted to `.' (for debugging
-   purposes).
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-       u2 pos = 0;                         /* position in c-string               */
-
-       if (!u) {
-               strcpy(buffer, "NULL");
-               return;
-       }
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) {
-               /* copy next unicode character */       
-               u2 c = utf_nextu2(&utf_ptr);
-               if (c == '/') c = '.';
-               buffer[pos++] = c;
-       }
-
-       /* terminate string */
-       buffer[pos] = '\0';
-}
-
-
-/* utf_strcat_convert_to_latin1 ************************************************
-       
-   Like libc strcat, but uses an utf8 string.
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_strcat_convert_to_latin1(char *buffer, utf *u)
-{
-       utf_sprint_convert_to_latin1(buffer + strlen(buffer), u);
-}
-
-
-/* utf_strcat_convert_to_latin1_classname **************************************
-       
-   Like libc strcat, but uses an utf8 string.
-   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
-   invalid results.
-
-*******************************************************************************/
-
-void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u)
-{
-       utf_sprint_convert_to_latin1_classname(buffer + strlen(buffer), u);
-}
-
-
-/* utf_fprint_printable_ascii **************************************************
-       
-   Write utf symbol into file.
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_fprint_printable_ascii(FILE *file, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-       if (!u)
-               return;
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) { 
-               /* read next unicode character */                
-               u2 c = utf_nextu2(&utf_ptr);                            
-
-               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
-               else fprintf(file, "?");
-       }
-}
-
-
-/* utf_fprint_printable_ascii_classname ****************************************
-       
-   Write utf symbol into file with `/' converted to `.'.
-   Non-printable and non-ASCII characters are printed as '?'.
-
-*******************************************************************************/
-
-void utf_fprint_printable_ascii_classname(FILE *file, utf *u)
-{
-       char *endpos;                       /* points behind utf string           */
-       char *utf_ptr;                      /* current position in utf text       */
-
-    if (!u)
-               return;
-
-       endpos = UTF_END(u);
-       utf_ptr = u->text;
-
-       while (utf_ptr < endpos) { 
-               /* read next unicode character */                
-               u2 c = utf_nextu2(&utf_ptr);                            
-               if (c == '/') c = '.';
-
-               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
-               else fprintf(file, "?");
-       }
-}
-
-
-/* is_valid_utf ****************************************************************
-
-   Return true if the given string is a valid UTF-8 string.
-
-   utf_ptr...points to first character
-   end_pos...points after last character
-
-*******************************************************************************/
-
-/*  static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26}; */
-
-bool is_valid_utf(char *utf_ptr, char *end_pos)
-{
-       int bytes;
-       int len,i;
-       char c;
-       unsigned long v;
-
-       if (end_pos < utf_ptr) return false;
-       bytes = end_pos - utf_ptr;
-       while (bytes--) {
-               c = *utf_ptr++;
-
-               if (!c) return false;                     /* 0x00 is not allowed */
-               if ((c & 0x80) == 0) continue;            /* ASCII */
-
-               if      ((c & 0xe0) == 0xc0) len = 1;     /* 110x xxxx */
-               else if ((c & 0xf0) == 0xe0) len = 2;     /* 1110 xxxx */
-               else if ((c & 0xf8) == 0xf0) len = 3;     /* 1111 0xxx */
-               else if ((c & 0xfc) == 0xf8) len = 4;     /* 1111 10xx */
-               else if ((c & 0xfe) == 0xfc) len = 5;     /* 1111 110x */
-               else return false;                        /* invalid leading byte */
-
-               if (len > 2) return false;                /* Java limitation */
-
-               v = (unsigned long)c & (0x3f >> len);
-               
-               if ((bytes -= len) < 0) return false;     /* missing bytes */
-
-               for (i = len; i--; ) {
-                       c = *utf_ptr++;
-                       if ((c & 0xc0) != 0x80)               /* 10xx xxxx */
-                               return false;
-                       v = (v << 6) | (c & 0x3f);
-               }
-
-               if (v == 0) {
-                       if (len != 1) return false;           /* Java special */
-
-               } else {
-                       /* Sun Java seems to allow overlong UTF-8 encodings */
-                       
-                       /* if (v < min_codepoint[len]) */
-                               /* XXX throw exception? */
-               }
-
-               /* surrogates in UTF-8 seem to be allowed in Java classfiles */
-               /* if (v >= 0xd800 && v <= 0xdfff) return false; */ /* surrogates */
-
-               /* even these seem to be allowed */
-               /* if (v == 0xfffe || v == 0xffff) return false; */ /* invalid codepoints */
-       }
-
-       return true;
-}
-
-
-/* is_valid_name ***************************************************************
-
-   Return true if the given string may be used as a class/field/method
-   name. (Currently this only disallows empty strings and control
-   characters.)
-
-   NOTE: The string is assumed to have passed is_valid_utf!
-
-   utf_ptr...points to first character
-   end_pos...points after last character
-
-*******************************************************************************/
-
-bool is_valid_name(char *utf_ptr, char *end_pos)
-{
-       if (end_pos <= utf_ptr) return false; /* disallow empty names */
-
-       while (utf_ptr < end_pos) {
-               unsigned char c = *utf_ptr++;
-
-               if (c < 0x20) return false; /* disallow control characters */
-               if (c == 0xc0 && (unsigned char) *utf_ptr == 0x80)  /* disallow zero */
-                       return false;
-       }
-
-       return true;
-}
-
-bool is_valid_name_utf(utf *u)
-{
-       return is_valid_name(u->text, UTF_END(u));
-}
-
-
-/* utf_show ********************************************************************
-
-   Writes the utf symbols in the utfhash to stdout and displays the
-   number of external hash chains grouped according to the chainlength
-   (for debugging purposes).
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void utf_show(void)
-{
-
-#define CHAIN_LIMIT 20               /* limit for seperated enumeration */
-
-       u4 chain_count[CHAIN_LIMIT]; /* numbers of chains */
-       u4 max_chainlength = 0;      /* maximum length of the chains */
-       u4 sum_chainlength = 0;      /* sum of the chainlengths */
-       u4 beyond_limit = 0;         /* number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
-       u4 i;
-
-       printf("UTF-HASH:\n");
-
-       /* show element of utf-hashtable */
-
-       for (i = 0; i < hashtable_utf->size; i++) {
-               utf *u = hashtable_utf->ptr[i];
-
-               if (u) {
-                       printf("SLOT %d: ", (int) i);
-
-                       while (u) {
-                               printf("'");
-                               utf_display_printable_ascii(u);
-                               printf("' ");
-                               u = u->hashlink;
-                       }       
-                       printf("\n");
-               }
-       }
-
-       printf("UTF-HASH: %d slots for %d entries\n", 
-                  (int) hashtable_utf->size, (int) hashtable_utf->entries );
-
-       if (hashtable_utf->entries == 0)
-               return;
-
-       printf("chains:\n  chainlength    number of chains    %% of utfstrings\n");
-
-       for (i=0;i<CHAIN_LIMIT;i++)
-               chain_count[i]=0;
-
-       /* count numbers of hashchains according to their length */
-       for (i=0; i<hashtable_utf->size; i++) {
-                 
-               utf *u = (utf*) hashtable_utf->ptr[i];
-               u4 chain_length = 0;
-
-               /* determine chainlength */
-               while (u) {
-                       u = u->hashlink;
-                       chain_length++;
-               }
-
-               /* update sum of all chainlengths */
-               sum_chainlength+=chain_length;
-
-               /* determine the maximum length of the chains */
-               if (chain_length>max_chainlength)
-                       max_chainlength = chain_length;
-
-               /* update number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
-               if (chain_length>=CHAIN_LIMIT) {
-                       beyond_limit+=chain_length;
-                       chain_length=CHAIN_LIMIT-1;
-               }
-
-               /* update number of hashchains of current length */
-               chain_count[chain_length]++;
-       }
-
-       /* display results */  
-       for (i=1;i<CHAIN_LIMIT-1;i++) 
-               printf("       %2d %17d %18.2f%%\n",i,chain_count[i],(((float) chain_count[i]*i*100)/hashtable_utf->entries));
-         
-       printf("     >=%2d %17d %18.2f%%\n",CHAIN_LIMIT-1,chain_count[CHAIN_LIMIT-1],((float) beyond_limit*100)/hashtable_utf->entries);
-
-
-       printf("max. chainlength:%5d\n",max_chainlength);
-
-       /* avg. chainlength = sum of chainlengths / number of chains */
-       printf("avg. chainlength:%5.2f\n",(float) sum_chainlength / (hashtable_utf->size-chain_count[0]));
-}
-#endif /* !defined(NDEBUG) */
-
-
-/*
- * 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:
- */
diff --git a/src/vm/utf8.h b/src/vm/utf8.h
deleted file mode 100644 (file)
index a4f2e10..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/* src/vm/utf8.h - utf8 string functions
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-            Edwin Steiner
-
-   $Id: utf8.h 6244 2006-12-27 15:15:31Z twisti $
-
-*/
-
-
-#ifndef _UTF_H
-#define _UTF_H
-
-#include "config.h"
-
-#include <stdio.h>
-
-/* forward typedefs ***********************************************************/
-
-typedef struct utf utf;
-
-#include "vm/types.h"
-#include "vm/global.h"
-
-
-/* data structure for utf8 symbols ********************************************/
-
-struct utf {
-       utf  *hashlink;                     /* link for external hash chain       */
-       s4    blength;                      /* text length in bytes               */
-       char *text;                         /* pointer to text                    */
-};
-
-/* to determine the end of utf strings */
-
-#define UTF_END(u)    ((char *) u->text + u->blength)
-
-
-/* utf-symbols for pointer comparison of frequently used strings **************/
-
-extern utf *utf_java_lang_Object;
-
-extern utf *utf_java_lang_Class;
-extern utf *utf_java_lang_ClassLoader;
-extern utf *utf_java_lang_Cloneable;
-extern utf *utf_java_lang_SecurityManager;
-extern utf *utf_java_lang_String;
-extern utf *utf_java_lang_System;
-extern utf *utf_java_lang_ThreadGroup;
-extern utf *utf_java_io_Serializable;
-
-extern utf *utf_java_lang_Throwable;
-extern utf *utf_java_lang_Error;
-extern utf *utf_java_lang_LinkageError;
-extern utf *utf_java_lang_NoClassDefFoundError;
-extern utf *utf_java_lang_OutOfMemoryError;
-extern utf *utf_java_lang_VirtualMachineError;
-
-#if defined(ENABLE_JAVASE)
-extern utf *utf_java_lang_AbstractMethodError;
-extern utf *utf_java_lang_NoSuchMethodError;
-#endif
-
-#if defined(WITH_CLASSPATH_GNU)
-extern utf *utf_java_lang_VMThrowable;
-#endif
-
-extern utf *utf_java_lang_Exception;
-extern utf *utf_java_lang_ClassCastException;
-extern utf *utf_java_lang_ClassNotFoundException;
-extern utf *utf_java_lang_IllegalArgumentException;
-extern utf *utf_java_lang_IllegalMonitorStateException;
-
-extern utf *utf_java_lang_NullPointerException;
-
-#if defined(ENABLE_JAVASE)
-extern utf* utf_java_lang_Void;
-#endif
-
-extern utf* utf_java_lang_Boolean;
-extern utf* utf_java_lang_Byte;
-extern utf* utf_java_lang_Character;
-extern utf* utf_java_lang_Short;
-extern utf* utf_java_lang_Integer;
-extern utf* utf_java_lang_Long;
-extern utf* utf_java_lang_Float;
-extern utf* utf_java_lang_Double;
-
-#if defined(ENABLE_JAVASE)
-extern utf *utf_java_lang_StackTraceElement;
-extern utf *utf_java_lang_reflect_Constructor;
-extern utf *utf_java_lang_reflect_Field;
-extern utf *utf_java_lang_reflect_Method;
-extern utf *utf_java_util_Vector;
-#endif
-
-extern utf *utf_InnerClasses;
-extern utf *utf_ConstantValue;
-extern utf *utf_Code;
-extern utf *utf_Exceptions;
-extern utf *utf_LineNumberTable;
-extern utf *utf_SourceFile;
-
-#if defined(ENABLE_JAVASE)
-extern utf *utf_EnclosingMethod;
-extern utf *utf_Signature;
-extern utf *utf_RuntimeVisibleAnnotations;
-extern utf *utf_StackMapTable;
-#endif
-
-extern utf *utf_init;
-extern utf *utf_clinit;
-extern utf *utf_clone;
-extern utf *utf_finalize;
-extern utf *utf_run;
-
-extern utf *utf_add;
-extern utf *utf_remove;
-extern utf *utf_addThread;
-extern utf *utf_removeThread;
-extern utf *utf_put;
-extern utf *utf_get;
-extern utf *utf_value;
-
-extern utf *utf_fillInStackTrace;
-extern utf *utf_getSystemClassLoader;
-extern utf *utf_loadClass;
-extern utf *utf_printStackTrace;
-
-extern utf *utf_Z;
-extern utf *utf_B;
-extern utf *utf_C;
-extern utf *utf_S;
-extern utf *utf_I;
-extern utf *utf_J;
-extern utf *utf_F;
-extern utf *utf_D;
-
-extern utf *utf_void__void;
-extern utf *utf_boolean__void;
-extern utf *utf_byte__void;
-extern utf *utf_char__void;
-extern utf *utf_short__void;
-extern utf *utf_int__void;
-extern utf *utf_long__void;
-extern utf *utf_float__void;
-extern utf *utf_double__void;
-
-extern utf *utf_void__java_lang_ClassLoader;
-extern utf *utf_void__java_lang_Object;
-extern utf *utf_void__java_lang_Throwable;
-extern utf *utf_java_lang_Object__java_lang_Object;
-extern utf *utf_java_lang_String__void;
-extern utf *utf_java_lang_String__java_lang_Class;
-extern utf *utf_java_lang_Thread__V;
-extern utf *utf_java_lang_Throwable__void;
-
-extern utf *utf_not_named_yet;
-extern utf *utf_null;
-extern utf *array_packagename;
-
-
-/* function prototypes ********************************************************/
-
-/* initialize the utf8 subsystem */
-bool utf8_init(void);
-
-u4 utf_hashkey(const char *text, u4 length);
-u4 utf_full_hashkey(const char *text, u4 length);
-
-/* determine hashkey of a unicode-symbol */
-u4 unicode_hashkey(u2 *text, u2 length);
-
-/* create new utf-symbol */
-utf *utf_new(const char *text, u2 length);
-
-/* make utf symbol from u2 array */
-utf *utf_new_u2(u2 *unicodedata, u4 unicodelength, bool isclassname);
-
-utf *utf_new_char(const char *text);
-utf *utf_new_char_classname(const char *text);
-
-/* get number of bytes */
-u4 utf_bytes(utf *u);
-
-/* get next unicode character of a utf-string */
-u2 utf_nextu2(char **utf);
-
-/* get (number of) unicode characters of a utf string (safe) */
-s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes);
-void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer);
-
-/* get (number of) unicode characters of a utf string (UNSAFE!) */
-u4 utf_get_number_of_u2s(utf *u);
-u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength);
-
-/* determine utf length in bytes of a u2 array */
-u4 u2_utflength(u2 *text, u4 u2_length);
-
-void utf_copy(char *buffer, utf *u);
-void utf_cat(char *buffer, utf *u);
-void utf_copy_classname(char *buffer, utf *u);
-void utf_cat_classname(char *buffer, utf *u);
-
-/* write utf symbol to file/buffer */
-void utf_display_printable_ascii(utf *u);
-void utf_display_printable_ascii_classname(utf *u);
-
-void utf_sprint_convert_to_latin1(char *buffer, utf *u);
-void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u);
-
-void utf_strcat_convert_to_latin1(char *buffer, utf *u);
-void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u);
-
-void utf_fprint_printable_ascii(FILE *file, utf *u);
-void utf_fprint_printable_ascii_classname(FILE *file, utf *u);
-
-/* check if a UTF-8 string is valid */
-bool is_valid_utf(char *utf_ptr, char *end_pos);
-
-/* check if a UTF-8 string may be used as a class/field/method name */
-bool is_valid_name(char *utf_ptr, char *end_pos);
-bool is_valid_name_utf(utf *u);
-
-/* show utf-table */
-void utf_show(void);
-
-#endif /* _UTF_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:
- * vim:noexpandtab:sw=4:ts=4:
- */
index 4997ee10ed46052938cda56f431cbd2b1390ab4d..69aded785afbd132392fd1f64344cc71cc3124d1 100644 (file)
 
 #include "mm/gc-common.h"
 #include "mm/memory.h"
+
 #include "native/jni.h"
 #include "native/native.h"
+#include "native/include/java_lang_String.h"
 
 #if defined(ENABLE_THREADS)
 # include "threads/native/threads.h"
 #endif
 
-#include "vm/classcache.h"
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/finalizer.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/options.h"
 #include "vm/properties.h"
-#include "vm/rt-timing.h"
 #include "vm/signallocal.h"
 #include "vm/stringlocal.h"
-#include "vm/suck.h"
 #include "vm/vm.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/md.h"
 #include "vm/jit/asmpart.h"
 
 #include "vm/jit/optimizing/recompile.h"
 
+#include "vmcore/classcache.h"
+#include "vmcore/options.h"
+#include "vmcore/suck.h"
+
 #if defined(ENABLE_JVMTI)
 # include "native/jvmti/cacaodbg.h"
 #endif
@@ -565,7 +571,7 @@ static void version(bool opt_exit)
        puts("java version \""JAVA_VERSION"\"");
        puts("CACAO version "VERSION"");
 
-       puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
+       puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
        puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
        puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
        puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
@@ -1495,7 +1501,7 @@ bool vm_create(JavaVMInitArgs *vm_args)
        if (!finalizer_init())
                throw_main_exception_exit();
 
-       /* install architecture dependent signal handler used for exceptions */
+       /* install architecture dependent signal handlers */
 
        signal_init();
 
@@ -1564,7 +1570,12 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
        if (!recompile_init())
                throw_main_exception_exit();
-               
+
+       /* start the signal handler thread */
+
+       if (!signal_start_thread())
+               throw_main_exception_exit();
+
        /* finally, start the finalizer thread */
 
        if (!finalizer_start_thread())
@@ -1614,15 +1625,15 @@ bool vm_create(JavaVMInitArgs *vm_args)
 
 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
 {
-       utf              *mainutf;
-       classinfo        *mainclass;
-       methodinfo       *m;
-       java_objectarray *oa; 
-       s4                oalength;
-       utf              *u;
-       java_lang_String *s;
-       s4                status;
-       s4                i;
+       utf               *mainutf;
+       classinfo         *mainclass;
+       methodinfo        *m;
+       java_objectarray  *oa; 
+       s4                 oalength;
+       utf               *u;
+       java_objectheader *s;
+       s4                 status;
+       s4                 i;
 
 #if !defined(NDEBUG)
        if (compileall) {
@@ -1654,16 +1665,14 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
        mainutf = utf_new_char(mainstring);
 
 #if defined(ENABLE_JAVAME_CLDC1_1)
-       if (!(mainclass = load_class_bootstrap(mainutf)))
-               throw_main_exception_exit();
+       mainclass = load_class_bootstrap(mainutf);
 #else
-       if (!(mainclass = load_class_from_sysloader(mainutf)))
-               throw_main_exception_exit();
+       mainclass = load_class_from_sysloader(mainutf);
 #endif
 
        /* error loading class */
 
-       if ((*exceptionptr != NULL) || (mainclass == NULL))
+       if ((exceptions_get_exception() != NULL) || (mainclass == NULL))
                throw_main_exception_exit();
 
        if (!link_class(mainclass))
@@ -1684,10 +1693,11 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
        /* there is no main method or it isn't static */
 
        if ((m == NULL) || !(m->flags & ACC_STATIC)) {
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
+               exceptions_throw_nosuchmethoderror(mainclass,
+                                                                                  utf_new_char("main"), 
+                                                                                  utf_new_char("([Ljava/lang/String;)V"));
 
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NoSuchMethodError, "main");
                throw_main_exception_exit();
        }
 
@@ -1701,7 +1711,7 @@ void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
                u = utf_new_char(vm_args->options[opt_index + i].optionString);
                s = javastring_new(u);
 
-               oa->data[i] = (java_objectheader *) s;
+               oa->data[i] = s;
        }
 
 #ifdef TYPEINFO_DEBUG_TEST
@@ -1899,8 +1909,6 @@ void vm_exit_handler(void)
 #endif
                }
 
-               mem_usagelog(1);
-
                if (opt_getcompilingtime)
                        print_times();
 #endif /* defined(ENABLE_STATISTICS) */
@@ -2080,7 +2088,7 @@ static void vm_compile_all(void)
 
                                                /* print out exception and cause */
 
-                                               exceptions_print_exception(*exceptionptr);
+                                               exceptions_print_current_exception();
 
                                                /* goto next class */
 
@@ -2104,7 +2112,7 @@ static void vm_compile_all(void)
 
                                                        /* print out exception and cause */
 
-                                                       exceptions_print_exception(*exceptionptr);
+                                                       exceptions_print_current_exception();
                                                }
                                        }
                                }
@@ -2149,17 +2157,9 @@ static void vm_compile_method(void)
                                                                         false);
        }
 
-       if (m == NULL) {
-               char message[MAXLOGTEXT];
-               sprintf(message, "%s%s", opt_method,
-                               opt_signature ? opt_signature : "");
-
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NoSuchMethodException,
-                                                                 message);
-                                                                                
-               throw_main_exception_exit();
-       }
+       if (m == NULL)
+               vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
+                                opt_method, opt_signature ? opt_signature : "");
                
        jit_compile(m);
 }
diff --git a/src/vm/zip.c b/src/vm/zip.c
deleted file mode 100644 (file)
index 233c1a5..0000000
+++ /dev/null
@@ -1,499 +0,0 @@
-/* src/vm/zip.c - ZIP file handling for bootstrap classloader
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Edwin Steiner
-
-   $Id: zip.c 4888 2006-05-06 00:11:18Z edwin $
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <zlib.h>
-#include <sys/mman.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/suck.h"
-#include "vm/utf8.h"
-#include "vm/zip.h"
-
-
-/* start size for classes hashtable *******************************************/
-
-#define HASHTABLE_CLASSES_SIZE    (1 << 10)
-
-
-/* info taken from:
-   http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
-*/
-
-/* all signatures in the ZIP file have a length of 4 bytes ********************/
-
-#define SIGNATURE_LENGTH    4
-
-
-/* Local file header ***********************************************************
-
-   local file header signature     4 bytes  (0x04034b50)
-   version needed to extract       2 bytes
-   general purpose bit flag        2 bytes
-   compression method              2 bytes
-   last mod file time              2 bytes
-   last mod file date              2 bytes
-   crc-32                          4 bytes
-   compressed size                 4 bytes
-   uncompressed size               4 bytes
-   file name length                2 bytes
-   extra field length              2 bytes
-
-   file name (variable size)
-   extra field (variable size)
-
-*******************************************************************************/
-
-#define LFH_HEADER_SIZE              30
-
-#define LFH_SIGNATURE                0x04034b50
-#define LFH_FILE_NAME_LENGTH         26
-#define LFH_EXTRA_FIELD_LENGTH       28
-
-typedef struct lfh lfh;
-
-struct lfh {
-       u2 compressionmethod;
-       u4 compressedsize;
-       u4 uncompressedsize;
-       u2 filenamelength;
-       u2 extrafieldlength;
-};
-
-
-/* Central directory structure *************************************************
-
-   [file header 1]
-   .
-   .
-   . 
-   [file header n]
-   [digital signature] 
-   
-   File header:
-   
-     central file header signature   4 bytes  (0x02014b50)
-     version made by                 2 bytes
-     version needed to extract       2 bytes
-     general purpose bit flag        2 bytes
-     compression method              2 bytes
-     last mod file time              2 bytes
-     last mod file date              2 bytes
-     crc-32                          4 bytes
-     compressed size                 4 bytes
-     uncompressed size               4 bytes
-     file name length                2 bytes
-     extra field length              2 bytes
-     file comment length             2 bytes
-     disk number start               2 bytes
-     internal file attributes        2 bytes
-     external file attributes        4 bytes
-     relative offset of local header 4 bytes
-   
-     file name (variable size)
-     extra field (variable size)
-     file comment (variable size)
-
-   Digital signature:
-   
-     header signature                4 bytes  (0x05054b50)
-     size of data                    2 bytes
-     signature data (variable size)
-
-*******************************************************************************/
-
-#define CDSFH_HEADER_SIZE            46
-
-#define CDSFH_SIGNATURE              0x02014b50
-#define CDSFH_COMPRESSION_METHOD     10
-#define CDSFH_COMPRESSED_SIZE        20
-#define CDSFH_UNCOMPRESSED_SIZE      24
-#define CDSFH_FILE_NAME_LENGTH       28
-#define CDSFH_EXTRA_FIELD_LENGTH     30
-#define CDSFH_FILE_COMMENT_LENGTH    32
-#define CDSFH_RELATIVE_OFFSET        42
-#define CDSFH_FILENAME               46
-
-typedef struct cdsfh cdsfh;
-
-struct cdsfh {
-       u2 compressionmethod;
-       u4 compressedsize;
-       u4 uncompressedsize;
-       u2 filenamelength;
-       u2 extrafieldlength;
-       u2 filecommentlength;
-       u4 relativeoffset;
-};
-
-
-/* End of central directory record *********************************************
-
-   end of central dir signature    4 bytes  (0x06054b50)
-   number of this disk             2 bytes
-   number of the disk with the
-   start of the central directory  2 bytes
-   total number of entries in the
-   central directory on this disk  2 bytes
-   total number of entries in
-   the central directory           2 bytes
-   size of the central directory   4 bytes
-   offset of start of central
-   directory with respect to
-   the starting disk number        4 bytes
-   .ZIP file comment length        2 bytes
-   .ZIP file comment       (variable size)
-
-*******************************************************************************/
-
-#define EOCDR_SIGNATURE              0x06054b50
-#define EOCDR_ENTRIES                10
-#define EOCDR_OFFSET                 16
-
-typedef struct eocdr eocdr;
-
-struct eocdr {
-       u2 entries;
-       u4 offset;
-};
-
-
-/* zip_open ********************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-hashtable *zip_open(char *path)
-{
-       hashtable               *ht;
-       hashtable_zipfile_entry *htzfe;
-       int                      fd;
-       u1                       lfh_signature[SIGNATURE_LENGTH];
-       off_t                    len;
-       u1                      *filep;
-       s4                       i;
-       u1                      *p;
-       eocdr                    eocdr;
-       cdsfh                    cdsfh;
-       const char              *filename;
-       const char              *classext;
-       utf                     *u;
-       u4                       key;       /* hashkey computed from utf-text     */
-       u4                       slot;      /* slot in hashtable                  */
-
-       /* first of all, open the file */
-
-       if ((fd = open(path, O_RDONLY)) == -1)
-               return NULL;
-
-       /* check for signature in first local file header */
-
-       if (read(fd, lfh_signature, SIGNATURE_LENGTH) != SIGNATURE_LENGTH)
-               return NULL;
-
-       if (SUCK_LE_U4(lfh_signature) != LFH_SIGNATURE)
-               return NULL;
-
-       /* get the file length */
-
-       if ((len = lseek(fd, 0, SEEK_END)) == -1)
-               return NULL;
-
-       /* we better mmap the file */
-
-       filep = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
-
-       /* some older compilers, like DEC OSF cc, don't like comparisons
-       on void* types */
-
-       if ((ptrint) filep == (ptrint) MAP_FAILED)
-               return NULL;
-
-       /* find end of central directory record */
-
-       for (p = filep + len; p >= filep; p--)
-               if (SUCK_LE_U4(p) == EOCDR_SIGNATURE)
-                       break;
-
-       /* get number of entries in central directory */
-
-       eocdr.entries = SUCK_LE_U2(p + EOCDR_ENTRIES);
-       eocdr.offset  = SUCK_LE_U4(p + EOCDR_OFFSET);
-
-       /* create hashtable for filenames */
-
-       ht = NEW(hashtable);
-
-       hashtable_create(ht, HASHTABLE_CLASSES_SIZE);
-
-       /* add all file entries into the hashtable */
-
-       for (i = 0, p = filep + eocdr.offset; i < eocdr.entries; i++) {
-               /* check file header signature */
-
-               if (SUCK_LE_U4(p) != CDSFH_SIGNATURE)
-                       return NULL;
-
-               /* we found an entry */
-
-               cdsfh.compressionmethod = SUCK_LE_U2(p + CDSFH_COMPRESSION_METHOD);
-               cdsfh.compressedsize    = SUCK_LE_U4(p + CDSFH_COMPRESSED_SIZE);
-               cdsfh.uncompressedsize  = SUCK_LE_U4(p + CDSFH_UNCOMPRESSED_SIZE);
-               cdsfh.filenamelength    = SUCK_LE_U2(p + CDSFH_FILE_NAME_LENGTH);
-               cdsfh.extrafieldlength  = SUCK_LE_U2(p + CDSFH_EXTRA_FIELD_LENGTH);
-               cdsfh.filecommentlength = SUCK_LE_U2(p + CDSFH_FILE_COMMENT_LENGTH);
-               cdsfh.relativeoffset    = SUCK_LE_U4(p + CDSFH_RELATIVE_OFFSET);
-
-               /* create utf8 string of filename, strip .class from classes */
-
-               filename = (const char *) (p + CDSFH_FILENAME);
-               classext = filename + cdsfh.filenamelength - strlen(".class");
-
-               /* skip directory entries */
-
-               if (filename[cdsfh.filenamelength - 1] != '/') {
-                       if (strncmp(classext, ".class", strlen(".class")) == 0)
-                               u = utf_new(filename, cdsfh.filenamelength - strlen(".class"));
-                       else
-                               u = utf_new(filename, cdsfh.filenamelength);
-
-                       /* insert class into hashtable */
-
-                       htzfe = NEW(hashtable_zipfile_entry);
-
-                       htzfe->filename          = u;
-                       htzfe->compressionmethod = cdsfh.compressionmethod;
-                       htzfe->compressedsize    = cdsfh.compressedsize;
-                       htzfe->uncompressedsize  = cdsfh.uncompressedsize;
-                       htzfe->data              = filep + cdsfh.relativeoffset;
-
-                       /* get hashtable slot */
-
-                       key  = utf_hashkey(u->text, u->blength);
-                       slot = key & (ht->size - 1);
-
-                       /* insert into external chain */
-
-                       htzfe->hashlink = ht->ptr[slot];
-
-                       /* insert hashtable zipfile entry */
-
-                       ht->ptr[slot] = htzfe;
-                       ht->entries++;
-               }
-
-               /* move to next central directory structure file header */
-
-               p = p +
-                       CDSFH_HEADER_SIZE +
-                       cdsfh.filenamelength +
-                       cdsfh.extrafieldlength +
-                       cdsfh.filecommentlength;
-       }
-
-       /* return pointer to hashtable */
-
-       return ht;
-}
-
-
-/* zip_find ********************************************************************
-
-   Search for the given filename in the classpath entries of a zip file.
-
-   NOTE: The '.class' extension is stripped when reading a zip file, so if
-   you want to find a .class file, you must search for its name _without_
-   the '.class' extension. 
-   XXX I dont like that, it makes foo and foo.class ambiguous. -Edwin
-
-   IN:
-      lce..........the classpath entries for the zip file
-         u............the filename to look for
-
-   RETURN VALUE:
-      hashtable_zipfile_entry * of the entry if found, or
-         NULL if not found
-
-*******************************************************************************/
-
-hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u)
-{
-       hashtable               *ht;
-       u4                       key;       /* hashkey computed from utf-text     */
-       u4                       slot;      /* slot in hashtable                  */
-       hashtable_zipfile_entry *htzfe;     /* hashtable element                  */
-
-       /* get classes hashtable from the classpath entry */
-
-       ht = lce->htclasses;
-
-       /* get the hashtable slot of the name searched */
-
-       key   = utf_hashkey(u->text, u->blength);
-       slot  = key & (ht->size - 1);
-       htzfe = ht->ptr[slot];
-
-       /* search external hash chain for utf-symbol */
-
-       while (htzfe) {
-               if (htzfe->filename == u)
-                       return htzfe;
-
-               /* next element in external chain */
-
-               htzfe = htzfe->hashlink;
-       }
-
-       /* file not found in this archive */
-
-       return NULL;
-}
-
-
-/* zip_get ********************************************************************
-
-   XXX
-
-*******************************************************************************/
-
-classbuffer *zip_get(list_classpath_entry *lce, classinfo *c)
-{
-       hashtable_zipfile_entry *htzfe;
-       lfh                      lfh;
-       u1                      *indata;
-       u1                      *outdata;
-       z_stream                 zs;
-       int                      err;
-       classbuffer             *cb;
-
-       /* try to find the class in the current archive */
-
-       if ((htzfe = zip_find(lce, c->name)) == NULL)
-               return NULL;
-
-       /* read stuff from local file header */
-
-       lfh.filenamelength   = SUCK_LE_U2(htzfe->data + LFH_FILE_NAME_LENGTH);
-       lfh.extrafieldlength = SUCK_LE_U2(htzfe->data + LFH_EXTRA_FIELD_LENGTH);
-
-       indata = htzfe->data +
-               LFH_HEADER_SIZE +
-               lfh.filenamelength +
-               lfh.extrafieldlength;
-
-       /* allocate buffer for uncompressed data */
-
-       outdata = MNEW(u1, htzfe->uncompressedsize);
-
-       /* how is the file stored? */
-
-       switch (htzfe->compressionmethod) {
-       case Z_DEFLATED:
-               /* fill z_stream structure */
-
-               zs.next_in   = indata;
-               zs.avail_in  = htzfe->compressedsize;
-               zs.next_out  = outdata;
-               zs.avail_out = htzfe->uncompressedsize;
-
-               zs.zalloc = Z_NULL;
-               zs.zfree  = Z_NULL;
-               zs.opaque = Z_NULL;
-
-               /* initialize this inflate run */
-
-               if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
-                       assert(0);
-
-               /* decompress the file into buffer */
-
-               err = inflate(&zs, Z_SYNC_FLUSH);
-
-               if ((err != Z_STREAM_END) && (err != Z_OK))
-                       assert(0);
-
-               /* finish this inflate run */
-
-               if (inflateEnd(&zs) != Z_OK)
-                       assert(0);
-               break;
-
-       case 0:
-               /* uncompressed file, just copy the data */
-               MCOPY(outdata, indata, u1, htzfe->compressedsize);
-               break;
-
-       default:
-               assert(0);
-       }
-       
-       /* allocate classbuffer */
-
-       cb = NEW(classbuffer);
-
-       cb->class = c;
-       cb->size  = htzfe->uncompressedsize;
-       cb->data  = outdata;
-       cb->pos   = outdata;
-       cb->path  = lce->path;
-
-       /* return the filled classbuffer structure */
-
-       return cb;
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/zip.h b/src/vm/zip.h
deleted file mode 100644 (file)
index babca6d..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* src/vm/zip.c - ZIP file handling for bootstrap classloader
-
-   Copyright (C) 1996-2005, 2006 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.
-
-   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.
-
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: zip.h 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-
-#ifndef _ZIP_H
-#define _ZIP_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/class.h"
-#include "vm/global.h"
-#include "vm/hashtable.h"
-#include "vm/loader.h"
-#include "vm/suck.h"
-#include "vm/utf8.h"
-
-
-/* hashtable_zipfile_entry ****************************************************/
-
-typedef struct hashtable_zipfile_entry hashtable_zipfile_entry;
-
-struct hashtable_zipfile_entry {
-       utf                     *filename;
-       u2                       compressionmethod;
-       u4                       compressedsize;
-       u4                       uncompressedsize;
-       u1                      *data;
-       hashtable_zipfile_entry *hashlink;
-};
-
-
-/* function prototypes ********************************************************/
-
-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);
-
-#endif /* _ZIP_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:
- */
diff --git a/src/vmcore/.cvsignore b/src/vmcore/.cvsignore
new file mode 100644 (file)
index 0000000..8f719f9
--- /dev/null
@@ -0,0 +1,9 @@
+*.a
+*.o
+*.la
+*.lo
+.deps
+.libs
+Makefile
+Makefile.in
+TAGS
diff --git a/src/vmcore/Makefile.am b/src/vmcore/Makefile.am
new file mode 100644 (file)
index 0000000..7c5e353
--- /dev/null
@@ -0,0 +1,101 @@
+## src/vmcore/Makefile.am
+##
+## Copyright (C) 2007 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.
+##
+## 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.
+##
+## $Id: Makefile.am 6216 2006-12-18 18:21:37Z twisti $
+
+## Process this file with automake to produce Makefile.in
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR) -I$(top_srcdir)/src/vm/jit/$(ARCH_DIR)/$(OS_DIR)
+
+LIBS =
+
+if ENABLE_JAVASE
+ANNOTATION_SOURCES = \
+       annotation.c \
+       annotation.h
+
+STACKMAP_SOURCES = \
+       stackmap.c \
+       stackmap.h
+endif
+
+if ENABLE_RT_TIMING
+RT_TIMING_SOURCES = \
+       rt-timing.c \
+       rt-timing.h
+endif
+
+if ENABLE_STATISTICS
+STATISTICS_SOURCES = \
+       statistics.c \
+       statistics.h
+endif
+
+if ENABLE_ZLIB
+ZLIB_SOURCES = \
+       zip.c \
+       zip.h
+endif
+
+noinst_LTLIBRARIES = \
+       libvmcore.la
+
+libvmcore_la_SOURCES = \
+       $(ANNOTATION_SOURCES) \
+       class.c \
+       class.h \
+       classcache.c \
+       classcache.h \
+       descriptor.c \
+       descriptor.h \
+       field.c \
+       field.h \
+       linker.c \
+       linker.h \
+       loader.c \
+       loader.h \
+       method.c \
+       method.h \
+       options.c \
+       options.h \
+       references.h \
+       resolve.c \
+       resolve.h \
+       $(RT_TIMING_SOURCES) \
+       $(STACKMAP_SOURCES) \
+       $(STATISTICS_SOURCES) \
+       suck.c \
+       suck.h \
+       utf8.c \
+       utf8.h \
+       $(ZLIB_SOURCES)
+
+
+## Local variables:
+## mode: Makefile
+## indent-tabs-mode: t
+## c-basic-offset: 4
+## tab-width: 8
+## compile-command: "automake --add-missing"
+## End:
diff --git a/src/vmcore/annotation.c b/src/vmcore/annotation.c
new file mode 100644 (file)
index 0000000..fa2fb11
--- /dev/null
@@ -0,0 +1,178 @@
+/* src/vmcore/annotation.c - class annotations
+
+   Copyright (C) 2006, 2007 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.
+
+   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.
+
+   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+
+*/
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vmcore/annotation.h"
+#include "vmcore/class.h"
+#include "vmcore/suck.h"
+
+
+/* annotation_load_attribute_runtimevisibleannotations *************************
+
+   RuntimeVisibleAnnotations_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u2 num_annotations;
+       annotation annotations[num_annotations];
+   }
+
+   annotation {
+       u2 type_index;
+       u2 num_element_value_pairs;
+       {
+            u2            element_name_index;
+            element_value element;
+       } element_value_pairs[num_element_value_pairs];
+   }
+
+   element_value {
+       u1 tag;
+       union {
+           u2 const_value_index;
+           {
+               u2 type_name_index;
+               u2 const_name_index;
+           } enum_const_value;
+           u2 class_info_index;
+           annotation annotation_value;
+           {
+               u2 num_values;
+               element_value values[num_values];
+           } array_value;
+       } value;
+   }
+
+*******************************************************************************/
+
+bool annotation_load_attribute_runtimevisibleannotations(classbuffer *cb)
+{
+       classinfo       *c;
+       u4               attribute_length;
+       u2               num_annotations;
+       annotation_t    *aa;
+       element_value_t *element_value;
+       u2               type_index;
+       u2               num_element_value_pairs;
+       u2               element_name_index;
+       u4               i, j;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* attribute_length */
+
+       attribute_length = suck_u4(cb);
+
+       if (!suck_check_classbuffer_size(cb, attribute_length))
+               return false;
+
+       /* get number of annotations */
+
+       num_annotations = suck_u2(cb);
+
+       printf("num_annotations: %d\n", num_annotations);
+
+       /* allocate annotations-array */
+
+       aa = MNEW(annotation_t, num_annotations);
+
+       /* parse all annotations */
+
+       for (i = 0; i < num_annotations; i++) {
+               /* get annotation type */
+
+               type_index = suck_u2(cb);
+
+               if (!(aa[i].type = class_getconstant(c, type_index, CONSTANT_Utf8)))
+                       return false;
+
+               printf("type: ");
+               utf_display_printable_ascii(aa[i].type);
+               printf("\n");
+
+               /* get number of element values */
+
+               num_element_value_pairs = suck_u2(cb);
+
+               printf("num_element_value_pairs: %d\n", num_element_value_pairs);
+
+               element_value = MNEW(element_value_t, num_element_value_pairs);
+
+               /* parse all element values */
+
+               for (j = 0; j < num_element_value_pairs; j++) {
+                       /* get element name */
+
+                       element_name_index = suck_u2(cb);
+
+                       if (!(element_value[j].name =
+                                 class_getconstant(c, element_name_index, CONSTANT_Utf8)))
+                               return false;
+
+                       /* get element tag */
+
+                       element_value[i].tag = suck_u1(cb);
+               }
+
+               /* store element value data */
+
+               aa[i].element_valuescount = num_element_value_pairs;
+               aa[i].element_values      = element_value;
+       }
+
+       /* store annotation variables */
+
+       c->runtimevisibleannotationscount = num_annotations;
+       c->runtimevisibleannotations      = aa;
+
+       return true;
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/annotation.h b/src/vmcore/annotation.h
new file mode 100644 (file)
index 0000000..cafa190
--- /dev/null
@@ -0,0 +1,83 @@
+/* src/vmcore/annotation.h - class annotations
+
+   Copyright (C) 2006, 2007 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.
+
+   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.
+
+   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+
+*/
+
+
+#ifndef _ANNOTATION_H
+#define _ANNOTATION_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct annotation_t    annotation_t;
+typedef struct element_value_t element_value_t;
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/utf8.h"
+
+
+/* annotation *****************************************************************/
+
+struct annotation_t {
+       utf             *type;
+       s4               element_valuescount;
+       element_value_t *element_values;
+};
+
+
+/* element_value **************************************************************/
+
+struct element_value_t {
+       utf *name;
+       u1   tag;
+};
+
+
+/* function prototypes ********************************************************/
+
+bool annotation_load_attribute_runtimevisibleannotations(classbuffer *cb);
+
+#endif /* _ANNOTATION_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/class.c b/src/vmcore/class.c
new file mode 100644 (file)
index 0000000..d370ceb
--- /dev/null
@@ -0,0 +1,1676 @@
+/* src/vmcore/class.c - class related functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: class.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
+#include "toolbox/logging.h"
+
+#include "vm/exceptions.h"
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+#include "vmcore/classcache.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/suck.h"
+#include "vmcore/utf8.h"
+
+
+/* global variables ***********************************************************/
+
+list unlinkedclasses;                   /* this is only used for eager class  */
+                                        /* loading                            */
+
+
+/* frequently used classes ****************************************************/
+
+/* important system classes */
+
+classinfo *class_java_lang_Object;
+classinfo *class_java_lang_Class;
+classinfo *class_java_lang_ClassLoader;
+classinfo *class_java_lang_Cloneable;
+classinfo *class_java_lang_SecurityManager;
+classinfo *class_java_lang_String;
+classinfo *class_java_lang_System;
+classinfo *class_java_lang_Thread;
+classinfo *class_java_lang_ThreadGroup;
+classinfo *class_java_lang_VMSystem;
+classinfo *class_java_lang_VMThread;
+classinfo *class_java_io_Serializable;
+
+
+/* system exception classes required in cacao */
+
+classinfo *class_java_lang_Throwable;
+classinfo *class_java_lang_Error;
+classinfo *class_java_lang_LinkageError;
+classinfo *class_java_lang_NoClassDefFoundError;
+classinfo *class_java_lang_OutOfMemoryError;
+classinfo *class_java_lang_VirtualMachineError;
+
+#if defined(WITH_CLASSPATH_GNU)
+classinfo *class_java_lang_VMThrowable;
+#endif
+
+classinfo *class_java_lang_Exception;
+classinfo *class_java_lang_ClassCastException;
+classinfo *class_java_lang_ClassNotFoundException;
+
+#if defined(ENABLE_JAVASE)
+classinfo *class_java_lang_Void;
+#endif
+classinfo *class_java_lang_Boolean;
+classinfo *class_java_lang_Byte;
+classinfo *class_java_lang_Character;
+classinfo *class_java_lang_Short;
+classinfo *class_java_lang_Integer;
+classinfo *class_java_lang_Long;
+classinfo *class_java_lang_Float;
+classinfo *class_java_lang_Double;
+
+
+/* some runtime exception */
+
+classinfo *class_java_lang_NullPointerException;
+
+
+/* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+classinfo *class_java_lang_StackTraceElement;
+classinfo *class_java_lang_reflect_Constructor;
+classinfo *class_java_lang_reflect_Field;
+classinfo *class_java_lang_reflect_Method;
+classinfo *class_java_security_PrivilegedAction;
+classinfo *class_java_util_Vector;
+
+classinfo *arrayclass_java_lang_Object;
+#endif
+
+
+/* pseudo classes for the typechecker */
+
+classinfo *pseudo_class_Arraystub;
+classinfo *pseudo_class_Null;
+classinfo *pseudo_class_New;
+
+
+/* class_set_packagename *******************************************************
+
+   Derive the package name from the class name and store it in the struct.
+
+*******************************************************************************/
+
+void class_set_packagename(classinfo *c)
+{
+       char *p = UTF_END(c->name) - 1;
+       char *start = c->name->text;
+
+       /* set the package name */
+       /* classes in the unnamed package keep packagename == NULL */
+
+       if (c->name->text[0] == '[') {
+               /* set packagename of arrays to the element's package */
+
+               for (; *start == '['; start++);
+
+               /* skip the 'L' in arrays of references */
+               if (*start == 'L')
+                       start++;
+
+               for (; (p > start) && (*p != '/'); --p);
+
+               c->packagename = utf_new(start, p - start);
+
+       } else {
+               for (; (p > start) && (*p != '/'); --p);
+
+               c->packagename = utf_new(start, p - start);
+       }
+}
+
+
+/* class_create_classinfo ******************************************************
+
+   Create a new classinfo struct. The class name is set to the given utf *,
+   most other fields are initialized to zero.
+
+   Note: classname may be NULL. In this case a not-yet-named classinfo is
+         created. The name must be filled in later and class_set_packagename
+                must be called after that.
+
+*******************************************************************************/
+
+classinfo *class_create_classinfo(utf *classname)
+{
+       classinfo *c;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_classinfo += sizeof(classinfo);
+#endif
+
+       /* we use a safe name for temporarily unnamed classes */
+       if (!classname)
+               classname = utf_not_named_yet;
+
+#if !defined(NDEBUG)
+       if (initverbose)
+               log_message_utf("Creating class: ", classname);
+#endif
+
+       /* GCNEW_UNCOLLECTABLE clears the allocated memory */
+
+       c = GCNEW_UNCOLLECTABLE(classinfo, 1);
+       /*c=NEW(classinfo);*/
+       c->name = classname;
+
+       /* Set the header.vftbl of all loaded classes to the one of
+       java.lang.Class, so Java code can use a class as object. */
+
+       if (class_java_lang_Class)
+               if (class_java_lang_Class->vftbl)
+                       c->object.header.vftbl = class_java_lang_Class->vftbl;
+       
+       if (classname != utf_not_named_yet)
+               class_set_packagename(c);
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&c->object.header);
+#endif
+
+       return c;
+}
+
+
+/* class_postset_header_vftbl **************************************************
+
+   Set the header.vftbl of all classes created before java.lang.Class
+   was linked.  This is necessary that Java code can use a class as
+   object.
+
+*******************************************************************************/
+
+void class_postset_header_vftbl(void)
+{
+       classinfo *c;
+       u4 slot;
+       classcache_name_entry *nmen;
+       classcache_class_entry *clsen;
+
+       assert(class_java_lang_Class);
+
+       for (slot = 0; slot < hashtable_classcache.size; slot++) {
+               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+               for (; nmen; nmen = nmen->hashlink) {
+                       /* iterate over all class entries */
+
+                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+                               c = clsen->classobj;
+
+                               /* now set the the vftbl */
+
+                               if (c->object.header.vftbl == NULL)
+                                       c->object.header.vftbl = class_java_lang_Class->vftbl;
+                       }
+               }
+       }
+}
+
+
+/* class_load_attribute_sourcefile *********************************************
+
+   SourceFile_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+          u2 sourcefile_index;
+   }
+
+*******************************************************************************/
+
+static bool class_load_attribute_sourcefile(classbuffer *cb)
+{
+       classinfo *c;
+       u4         attribute_length;
+       u2         sourcefile_index;
+       utf       *sourcefile;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       /* there can be no more than one SourceFile attribute */
+
+       if (c->sourcefile != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
+               return false;
+       }
+
+       /* get sourcefile */
+
+       sourcefile_index = suck_u2(cb);
+       sourcefile = class_getconstant(c, sourcefile_index, CONSTANT_Utf8);
+
+       if (sourcefile == NULL)
+               return false;
+
+       /* store sourcefile */
+
+       c->sourcefile = sourcefile;
+
+       return true;
+}
+
+
+/* class_load_attribute_enclosingmethod ****************************************
+
+   EnclosingMethod_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+          u2 class_index;
+          u2 method_index;
+   }
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+static bool class_load_attribute_enclosingmethod(classbuffer *cb)
+{
+       classinfo             *c;
+       u4                     attribute_length;
+       u2                     class_index;
+       u2                     method_index;
+       classref_or_classinfo  cr;
+       constant_nameandtype  *cn;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 4) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       /* there can be no more than one EnclosingMethod attribute */
+
+       if (c->enclosingmethod != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple EnclosingMethod attributes");
+               return false;
+       }
+
+       /* get class index */
+
+       class_index = suck_u2(cb);
+       cr.ref = innerclass_getconstant(c, class_index, CONSTANT_Class);
+
+       /* get method index */
+
+       method_index = suck_u2(cb);
+       cn = innerclass_getconstant(c, method_index, CONSTANT_NameAndType);
+
+       /* store info in classinfo */
+
+       c->enclosingclass.any = cr.any;
+       c->enclosingmethod    = cn;
+
+       return true;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
+/* class_load_attributes *******************************************************
+
+   Read attributes from ClassFile.
+
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
+   InnerClasses_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+   }
+
+*******************************************************************************/
+
+bool class_load_attributes(classbuffer *cb)
+{
+       classinfo *c;
+       u4         i, j;
+       u2         attributes_count;
+       u2         attribute_name_index;
+       utf       *attribute_name;
+
+       c = cb->class;
+
+       /* get attributes count */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       attributes_count = suck_u2(cb);
+
+       for (i = 0; i < attributes_count; i++) {
+               /* get attribute name */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               attribute_name_index = suck_u2(cb);
+               attribute_name =
+                       class_getconstant(c, attribute_name_index, CONSTANT_Utf8);
+
+               if (attribute_name == NULL)
+                       return false;
+
+               if (attribute_name == utf_InnerClasses) {
+                       /* InnerClasses */
+
+                       if (c->innerclass != NULL) {
+                               exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
+                               return false;
+                       }
+                               
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* skip attribute length */
+                       suck_u4(cb);
+
+                       /* number of records */
+                       c->innerclasscount = suck_u2(cb);
+
+                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
+                               return false;
+
+                       /* allocate memory for innerclass structure */
+                       c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
+
+                       for (j = 0; j < c->innerclasscount; j++) {
+                               /* The innerclass structure contains a class with an encoded
+                                  name, its defining scope, its simple name and a bitmask of
+                                  the access flags. If an inner class is not a member, its
+                                  outer_class is NULL, if a class is anonymous, its name is
+                                  NULL. */
+                                                               
+                               innerclassinfo *info = c->innerclass + j;
+
+                               info->inner_class.ref =
+                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               info->outer_class.ref =
+                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
+                               info->name =
+                                       innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
+                               info->flags = suck_u2(cb);
+                       }
+               }
+               else if (attribute_name == utf_SourceFile) {
+                       /* SourceFile */
+
+                       if (!class_load_attribute_sourcefile(cb))
+                               return false;
+               }
+#if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_EnclosingMethod) {
+                       /* EnclosingMethod */
+
+                       if (!class_load_attribute_enclosingmethod(cb))
+                               return false;
+               }
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(c->signature)))
+                               return false;
+               }
+               else if (attribute_name == utf_RuntimeVisibleAnnotations) {
+                       /* RuntimeVisibleAnnotations */
+
+                       if (!annotation_load_attribute_runtimevisibleannotations(cb))
+                               return false;
+               }
+#endif
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       return true;
+}
+
+
+/* class_freepool **************************************************************
+
+       Frees all resources used by this classes Constant Pool.
+
+*******************************************************************************/
+
+static void class_freecpool(classinfo *c)
+{
+       u4 idx;
+       u4 tag;
+       voidptr info;
+       
+       if (c->cptags && c->cpinfos) {
+               for (idx = 0; idx < c->cpcount; idx++) {
+                       tag = c->cptags[idx];
+                       info = c->cpinfos[idx];
+               
+                       if (info != NULL) {
+                               switch (tag) {
+                               case CONSTANT_Fieldref:
+                               case CONSTANT_Methodref:
+                               case CONSTANT_InterfaceMethodref:
+                                       FREE(info, constant_FMIref);
+                                       break;
+                               case CONSTANT_Integer:
+                                       FREE(info, constant_integer);
+                                       break;
+                               case CONSTANT_Float:
+                                       FREE(info, constant_float);
+                                       break;
+                               case CONSTANT_Long:
+                                       FREE(info, constant_long);
+                                       break;
+                               case CONSTANT_Double:
+                                       FREE(info, constant_double);
+                                       break;
+                               case CONSTANT_NameAndType:
+                                       FREE(info, constant_nameandtype);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if (c->cptags)
+               MFREE(c->cptags, u1, c->cpcount);
+
+       if (c->cpinfos)
+               MFREE(c->cpinfos, voidptr, c->cpcount);
+}
+
+
+/* class_getconstant ***********************************************************
+
+   Retrieves the value at position 'pos' of the constantpool of a
+   class. If the type of the value is other than 'ctype', an error is
+   thrown.
+
+*******************************************************************************/
+
+voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
+{
+       /* check index and type of constantpool entry */
+       /* (pos == 0 is caught by type comparison) */
+
+       if ((pos >= c->cpcount) || (c->cptags[pos] != ctype)) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+
+       return c->cpinfos[pos];
+}
+
+
+/* innerclass_getconstant ******************************************************
+
+   Like class_getconstant, but if cptags is ZERO, null is returned.
+       
+*******************************************************************************/
+
+voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
+{
+       /* invalid position in constantpool */
+
+       if (pos >= c->cpcount) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+
+       /* constantpool entry of type 0 */      
+
+       if (c->cptags[pos] == 0)
+               return NULL;
+
+       /* check type of constantpool entry */
+
+       if (c->cptags[pos] != ctype) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool index");
+               return NULL;
+       }
+               
+       return c->cpinfos[pos];
+}
+
+
+/* class_free ******************************************************************
+
+   Frees all resources used by the class.
+
+*******************************************************************************/
+
+void class_free(classinfo *c)
+{
+       s4 i;
+       vftbl_t *v;
+               
+       class_freecpool(c);
+
+       if (c->interfaces)
+               MFREE(c->interfaces, classinfo*, c->interfacescount);
+
+       if (c->fields) {
+               for (i = 0; i < c->fieldscount; i++)
+                       field_free(&(c->fields[i]));
+#if defined(ENABLE_CACAO_GC)
+               MFREE(c->fields, fieldinfo, c->fieldscount);
+#endif
+       }
+       
+       if (c->methods) {
+               for (i = 0; i < c->methodscount; i++)
+                       method_free(&(c->methods[i]));
+               MFREE(c->methods, methodinfo, c->methodscount);
+       }
+
+       if ((v = c->vftbl) != NULL) {
+               if (v->arraydesc)
+                       mem_free(v->arraydesc,sizeof(arraydescriptor));
+               
+               for (i = 0; i < v->interfacetablelength; i++) {
+                       MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
+               }
+               MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
+
+               i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
+                   sizeof(methodptr*) * (v->interfacetablelength -
+                                        (v->interfacetablelength > 0));
+               v = (vftbl_t*) (((methodptr*) v) -
+                                               (v->interfacetablelength - 1) * (v->interfacetablelength > 1));
+               mem_free(v, i);
+       }
+
+       if (c->innerclass)
+               MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
+
+       /*      if (c->classvftbl)
+               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
+       
+/*     GCFREE(c); */
+}
+
+
+/* get_array_class *************************************************************
+
+   Returns the array class with the given name for the given
+   classloader, or NULL if an exception occurred.
+
+   Note: This function does eager loading. 
+
+*******************************************************************************/
+
+static classinfo *get_array_class(utf *name,java_objectheader *initloader,
+                                                                                       java_objectheader *defloader,bool link)
+{
+       classinfo *c;
+       
+       /* lookup this class in the classcache */
+       c = classcache_lookup(initloader,name);
+       if (!c)
+               c = classcache_lookup_defined(defloader,name);
+
+       if (!c) {
+               /* we have to create it */
+               c = class_create_classinfo(name);
+               c = load_newly_created_array(c,initloader);
+               if (c == NULL)
+                       return NULL;
+       }
+
+       assert(c);
+       assert(c->state & CLASS_LOADED);
+       assert(c->classloader == defloader);
+
+       if (link && !(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
+
+       assert(!link || (c->state & CLASS_LINKED));
+
+       return c;
+}
+
+
+/* class_array_of **************************************************************
+
+   Returns an array class with the given component class. The array
+   class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_array_of(classinfo *component, bool link)
+{
+    s4 namelen;
+    char *namebuf;
+       s4 dumpsize;
+       classinfo *c;
+
+       dumpsize = dump_size();
+
+    /* Assemble the array class name */
+    namelen = component->name->blength;
+    
+    if (component->name->text[0] == '[') {
+        /* the component is itself an array */
+        namebuf = DMNEW(char, namelen + 1);
+        namebuf[0] = '[';
+        MCOPY(namebuf + 1, component->name->text, char, namelen);
+        namelen++;
+
+    } else {
+        /* the component is a non-array class */
+        namebuf = DMNEW(char, namelen + 3);
+        namebuf[0] = '[';
+        namebuf[1] = 'L';
+        MCOPY(namebuf + 2, component->name->text, char, namelen);
+        namebuf[2 + namelen] = ';';
+        namelen += 3;
+    }
+
+       c = get_array_class(utf_new(namebuf, namelen),
+                                               component->classloader,
+                                               component->classloader,
+                                               link);
+
+       dump_release(dumpsize);
+
+       return c;
+}
+
+
+/* class_multiarray_of *********************************************************
+
+   Returns an array class with the given dimension and element class.
+   The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
+{
+    s4 namelen;
+    char *namebuf;
+       s4 dumpsize;
+       classinfo *c;
+
+       dumpsize = dump_size();
+
+       if (dim < 1) {
+               log_text("Invalid array dimension requested");
+               assert(0);
+       }
+
+    /* Assemble the array class name */
+    namelen = element->name->blength;
+    
+    if (element->name->text[0] == '[') {
+        /* the element is itself an array */
+        namebuf = DMNEW(char, namelen + dim);
+        memcpy(namebuf + dim, element->name->text, namelen);
+        namelen += dim;
+    }
+    else {
+        /* the element is a non-array class */
+        namebuf = DMNEW(char, namelen + 2 + dim);
+        namebuf[dim] = 'L';
+        memcpy(namebuf + dim + 1, element->name->text, namelen);
+        namelen += (2 + dim);
+        namebuf[namelen - 1] = ';';
+    }
+       memset(namebuf, '[', dim);
+
+       c = get_array_class(utf_new(namebuf, namelen),
+                                               element->classloader,
+                                               element->classloader,
+                                               link);
+
+       dump_release(dumpsize);
+
+       return c;
+}
+
+
+/* class_lookup_classref *******************************************************
+
+   Looks up the constant_classref for a given classname in the classref
+   tables of a class.
+
+   IN:
+       cls..............the class containing the reference
+          name.............the name of the class refered to
+
+    RETURN VALUE:
+          a pointer to a constant_classref, or 
+          NULL if the reference was not found
+   
+*******************************************************************************/
+
+constant_classref *class_lookup_classref(classinfo *cls, utf *name)
+{
+       constant_classref *ref;
+       extra_classref *xref;
+       int count;
+
+       assert(cls);
+       assert(name);
+       assert(!cls->classrefcount || cls->classrefs);
+       
+       /* first search the main classref table */
+       count = cls->classrefcount;
+       ref = cls->classrefs;
+       for (; count; --count, ++ref)
+               if (ref->name == name)
+                       return ref;
+
+       /* next try the list of extra classrefs */
+       for (xref = cls->extclassrefs; xref; xref = xref->next) {
+               if (xref->classref.name == name)
+                       return &(xref->classref);
+       }
+
+       /* not found */
+       return NULL;
+}
+
+
+/* class_get_classref **********************************************************
+
+   Returns the constant_classref for a given classname.
+
+   IN:
+       cls..............the class containing the reference
+          name.............the name of the class refered to
+
+   RETURN VALUE:
+       a pointer to a constant_classref (never NULL)
+
+   NOTE:
+       The given name is not checked for validity!
+   
+*******************************************************************************/
+
+constant_classref *class_get_classref(classinfo *cls, utf *name)
+{
+       constant_classref *ref;
+       extra_classref *xref;
+
+       assert(cls);
+       assert(name);
+
+       ref = class_lookup_classref(cls,name);
+       if (ref)
+               return ref;
+
+       xref = NEW(extra_classref);
+       CLASSREF_INIT(xref->classref,cls,name);
+
+       xref->next = cls->extclassrefs;
+       cls->extclassrefs = xref;
+
+       return &(xref->classref);
+}
+
+
+/* class_get_self_classref *****************************************************
+
+   Returns the constant_classref to the class itself.
+
+   IN:
+       cls..............the class containing the reference
+
+   RETURN VALUE:
+       a pointer to a constant_classref (never NULL)
+
+*******************************************************************************/
+
+constant_classref *class_get_self_classref(classinfo *cls)
+{
+       /* XXX this should be done in a faster way. Maybe always make */
+       /* the classref of index 0 a self reference.                  */
+       return class_get_classref(cls,cls->name);
+}
+
+/* class_get_classref_multiarray_of ********************************************
+
+   Returns an array type reference with the given dimension and element class
+   reference.
+
+   IN:
+       dim..............the requested dimension
+                           dim must be in [1;255]. This is NOT checked!
+          ref..............the component class reference
+
+   RETURN VALUE:
+       a pointer to the class reference for the array type
+
+   NOTE:
+       The referer of `ref` is used as the referer for the new classref.
+
+*******************************************************************************/
+
+constant_classref *class_get_classref_multiarray_of(s4 dim, constant_classref *ref)
+{
+    s4 namelen;
+    char *namebuf;
+       s4 dumpsize;
+       constant_classref *cr;
+
+       assert(ref);
+       assert(dim >= 1 && dim <= 255);
+
+       dumpsize = dump_size();
+
+    /* Assemble the array class name */
+    namelen = ref->name->blength;
+    
+    if (ref->name->text[0] == '[') {
+        /* the element is itself an array */
+        namebuf = DMNEW(char, namelen + dim);
+        memcpy(namebuf + dim, ref->name->text, namelen);
+        namelen += dim;
+    }
+    else {
+        /* the element is a non-array class */
+        namebuf = DMNEW(char, namelen + 2 + dim);
+        namebuf[dim] = 'L';
+        memcpy(namebuf + dim + 1, ref->name->text, namelen);
+        namelen += (2 + dim);
+        namebuf[namelen - 1] = ';';
+    }
+       memset(namebuf, '[', dim);
+
+    cr = class_get_classref(ref->referer,utf_new(namebuf, namelen));
+
+       dump_release(dumpsize);
+
+       return cr;
+}
+
+
+/* class_get_classref_component_of *********************************************
+
+   Returns the component classref of a given array type reference
+
+   IN:
+       ref..............the array type reference
+
+   RETURN VALUE:
+       a reference to the component class, or
+          NULL if `ref` is not an object array type reference
+
+   NOTE:
+       The referer of `ref` is used as the referer for the new classref.
+
+*******************************************************************************/
+
+constant_classref *class_get_classref_component_of(constant_classref *ref)
+{
+       s4 namelen;
+       char *name;
+       
+       assert(ref);
+
+       name = ref->name->text;
+       if (*name++ != '[')
+               return NULL;
+       
+       namelen = ref->name->blength - 1;
+       if (*name == 'L') {
+               name++;
+               namelen -= 2;
+       }
+       else if (*name != '[') {
+               return NULL;
+       }
+
+    return class_get_classref(ref->referer, utf_new(name, namelen));
+}
+
+
+/* class_findmethod ************************************************************
+       
+   Searches a 'classinfo' structure for a method having the given name
+   and descriptor. If descriptor is NULL, it is ignored.
+
+*******************************************************************************/
+
+methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
+{
+       methodinfo *m;
+       s4          i;
+
+       for (i = 0; i < c->methodscount; i++) {
+               m = &(c->methods[i]);
+
+               if ((m->name == name) && ((desc == NULL) || (m->descriptor == desc)))
+                       return m;
+       }
+
+       return NULL;
+}
+
+
+/* class_resolvemethod *********************************************************
+       
+   Searches a class and it's super classes for a method.
+
+   Superinterfaces are *not* searched.
+
+*******************************************************************************/
+
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
+{
+       methodinfo *m;
+
+       while (c) {
+               m = class_findmethod(c, name, desc);
+
+               if (m)
+                       return m;
+
+               /* JVM Specification bug: 
+
+                  It is important NOT to resolve special <init> and <clinit>
+                  methods to super classes or interfaces; yet, this is not
+                  explicited in the specification.  Section 5.4.3.3 should be
+                  updated appropriately.  */
+
+               if (name == utf_init || name == utf_clinit)
+                       return NULL;
+
+               c = c->super.cls;
+       }
+
+       return NULL;
+}
+
+
+/* class_resolveinterfacemethod_intern *****************************************
+
+   Internally used helper function. Do not use this directly.
+
+*******************************************************************************/
+
+static methodinfo *class_resolveinterfacemethod_intern(classinfo *c,
+                                                                                                          utf *name, utf *desc)
+{
+       methodinfo *m;
+       s4          i;
+
+       /* try to find the method in the class */
+
+       m = class_findmethod(c, name, desc);
+
+       if (m != NULL)
+               return m;
+
+       /* no method found? try the superinterfaces */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
+                                                                                                       name, desc);
+
+               if (m != NULL)
+                       return m;
+       }
+
+       /* no method found */
+
+       return NULL;
+}
+
+
+/* class_resolveclassmethod ****************************************************
+       
+   Resolves a reference from REFERER to a method with NAME and DESC in
+   class C.
+
+   If the method cannot be resolved the return value is NULL. If
+   EXCEPT is true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
+                                                                        classinfo *referer, bool throwexception)
+{
+       classinfo  *cls;
+       methodinfo *m;
+       s4          i;
+
+/*     if (c->flags & ACC_INTERFACE) { */
+/*             if (throwexception) */
+/*                     *exceptionptr = */
+/*                             new_exception(string_java_lang_IncompatibleClassChangeError); */
+/*             return NULL; */
+/*     } */
+
+       /* try class c and its superclasses */
+
+       cls = c;
+
+       m = class_resolvemethod(cls, name, desc);
+
+       if (m != NULL)
+               goto found;
+
+       /* try the superinterfaces */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               m = class_resolveinterfacemethod_intern(c->interfaces[i].cls,
+                                                                                               name, desc);
+
+               if (m != NULL)
+                       goto found;
+       }
+       
+       if (throwexception) {
+#if defined(ENABLE_JAVASE)
+               exceptions_throw_nosuchmethoderror(c, name, desc);
+#else
+               exceptions_throw_virtualmachineerror();
+#endif
+       }
+
+       return NULL;
+
+ found:
+       if ((m->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
+               if (throwexception) {
+#if defined(ENABLE_JAVASE)
+                       exceptions_throw_abstractmethoderror();
+#else
+                       exceptions_throw_virtualmachineerror();
+#endif
+               }
+
+               return NULL;
+       }
+
+       /* XXX check access rights */
+
+       return m;
+}
+
+
+/* class_resolveinterfacemethod ************************************************
+
+   Resolves a reference from REFERER to a method with NAME and DESC in
+   interface C.
+
+   If the method cannot be resolved the return value is NULL. If
+   EXCEPT is true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
+                                                                                classinfo *referer, bool throwexception)
+{
+       methodinfo *mi;
+
+       if (!(c->flags & ACC_INTERFACE)) {
+               if (throwexception)
+                       exceptions_throw_incompatibleclasschangeerror(c, "Not an interface");
+
+               return NULL;
+       }
+
+       mi = class_resolveinterfacemethod_intern(c, name, desc);
+
+       if (mi != NULL)
+               return mi;
+
+       /* try class java.lang.Object */
+
+       mi = class_findmethod(class_java_lang_Object, name, desc);
+
+       if (mi != NULL)
+               return mi;
+
+       if (throwexception) {
+#if defined(ENABLE_JAVASE)
+               exceptions_throw_nosuchmethoderror(c, name, desc);
+#else
+               exceptions_throw_virtualmachineerror();
+#endif
+       }
+
+       return NULL;
+}
+
+
+/* class_findfield *************************************************************
+       
+   Searches for field with specified name and type in a classinfo
+   structure. If no such field is found NULL is returned.
+
+*******************************************************************************/
+
+fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
+{
+       s4 i;
+
+       for (i = 0; i < c->fieldscount; i++)
+               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
+                       return &(c->fields[i]);
+
+       if (c->super.cls)
+               return class_findfield(c->super.cls, name, desc);
+
+       return NULL;
+}
+
+
+/* class_findfield_approx ******************************************************
+       
+   Searches in 'classinfo'-structure for a field with the specified
+   name.
+
+*******************************************************************************/
+fieldinfo *class_findfield_by_name(classinfo *c, utf *name)
+{
+       s4 i;
+
+       /* get field index */
+
+       i = class_findfield_index_by_name(c, name);
+
+       /* field was not found, return */
+
+       if (i == -1)
+               return NULL;
+
+       /* return field address */
+
+       return &(c->fields[i]);
+}
+
+
+s4 class_findfield_index_by_name(classinfo *c, utf *name)
+{
+       s4 i;
+
+       for (i = 0; i < c->fieldscount; i++) {
+               /* compare field names */
+
+               if ((c->fields[i].name == name))
+                       return i;
+       }
+
+       /* field was not found, raise exception */      
+
+       exceptions_throw_nosuchfielderror(c, name);
+
+       return -1;
+}
+
+
+/****************** Function: class_resolvefield_int ***************************
+
+    This is an internally used helper function. Do not use this directly.
+
+       Tries to resolve a field having the given name and type.
+    If the field cannot be resolved, NULL is returned.
+
+*******************************************************************************/
+
+static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
+{
+       fieldinfo *fi;
+       s4         i;
+
+       /* search for field in class c */
+
+       for (i = 0; i < c->fieldscount; i++) { 
+               if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
+                       return &(c->fields[i]);
+               }
+    }
+
+       /* try superinterfaces recursively */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               fi = class_resolvefield_int(c->interfaces[i].cls, name, desc);
+               if (fi)
+                       return fi;
+       }
+
+       /* try superclass */
+
+       if (c->super.cls)
+               return class_resolvefield_int(c->super.cls, name, desc);
+
+       /* not found */
+
+       return NULL;
+}
+
+
+/********************* Function: class_resolvefield ***************************
+       
+       Resolves a reference from REFERER to a field with NAME and DESC in class C.
+
+    If the field cannot be resolved the return value is NULL. If EXCEPT is
+    true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
+                                                         classinfo *referer, bool throwexception)
+{
+       fieldinfo *fi;
+
+       fi = class_resolvefield_int(c, name, desc);
+
+       if (!fi) {
+               if (throwexception)
+                       exceptions_throw_nosuchfielderror(c, name);
+
+               return NULL;
+       }
+
+       /* XXX check access rights */
+
+       return fi;
+}
+
+
+/* class_issubclass ************************************************************
+
+   Checks if sub is a descendant of super.
+       
+*******************************************************************************/
+
+bool class_issubclass(classinfo *sub, classinfo *super)
+{
+       for (;;) {
+               if (!sub)
+                       return false;
+
+               if (sub == super)
+                       return true;
+
+               sub = sub->super.cls;
+       }
+}
+
+
+/* class_printflags ************************************************************
+
+   Prints flags of a class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_printflags(classinfo *c)
+{
+       if (c == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (c->flags & ACC_PUBLIC)       printf(" PUBLIC");
+       if (c->flags & ACC_PRIVATE)      printf(" PRIVATE");
+       if (c->flags & ACC_PROTECTED)    printf(" PROTECTED");
+       if (c->flags & ACC_STATIC)       printf(" STATIC");
+       if (c->flags & ACC_FINAL)        printf(" FINAL");
+       if (c->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+       if (c->flags & ACC_VOLATILE)     printf(" VOLATILE");
+       if (c->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
+       if (c->flags & ACC_NATIVE)       printf(" NATIVE");
+       if (c->flags & ACC_INTERFACE)    printf(" INTERFACE");
+       if (c->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
+}
+#endif
+
+
+/* class_print *****************************************************************
+
+   Prints classname plus flags.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_print(classinfo *c)
+{
+       if (c == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       utf_display_printable_ascii(c->name);
+       class_printflags(c);
+}
+#endif
+
+
+/* class_classref_print ********************************************************
+
+   Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_print(constant_classref *cr)
+{
+       if (cr == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       utf_display_printable_ascii(cr->name);
+       printf("(ref.by ");
+       if (cr->referer)
+               class_print(cr->referer);
+       else
+               printf("NULL");
+       printf(")");
+}
+#endif
+
+
+/* class_println ***************************************************************
+
+   Prints classname plus flags and new line.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_println(classinfo *c)
+{
+       class_print(c);
+       printf("\n");
+}
+#endif
+
+
+/* class_classref_println ******************************************************
+
+   Prints classname plus referer class and new line.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_println(constant_classref *cr)
+{
+       class_classref_print(cr);
+       printf("\n");
+}
+#endif
+
+
+/* class_classref_or_classinfo_print *******************************************
+
+   Prints classname plus referer class.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_classref_or_classinfo_print(classref_or_classinfo c)
+{
+       if (c.any == NULL) {
+               printf("(classref_or_classinfo) NULL");
+               return;
+       }
+       if (IS_CLASSREF(c))
+               class_classref_print(c.ref);
+       else
+               class_print(c.cls);
+}
+#endif
+
+
+/* class_classref_or_classinfo_println *****************************************
+
+   Prints classname plus referer class and a newline.
+
+*******************************************************************************/
+
+void class_classref_or_classinfo_println(classref_or_classinfo c)
+{
+       class_classref_or_classinfo_println(c);
+       printf("\n");
+}
+
+
+/* class_showconstantpool ******************************************************
+
+   Dump the constant pool of the given class to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_showconstantpool (classinfo *c) 
+{
+       u4 i;
+       voidptr e;
+
+       printf ("---- dump of constant pool ----\n");
+
+       for (i=0; i<c->cpcount; i++) {
+               printf ("#%d:  ", (int) i);
+               
+               e = c -> cpinfos [i];
+               if (e) {
+                       
+                       switch (c -> cptags [i]) {
+                       case CONSTANT_Class:
+                               printf ("Classreference -> ");
+                               utf_display_printable_ascii ( ((constant_classref*)e) -> name );
+                               break;
+                       case CONSTANT_Fieldref:
+                               printf ("Fieldref -> ");
+                               field_fieldref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_Methodref:
+                               printf ("Methodref -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_InterfaceMethodref:
+                               printf ("InterfaceMethod -> ");
+                               method_methodref_print((constant_FMIref *) e);
+                               break;
+                       case CONSTANT_String:
+                               printf ("String -> ");
+                               utf_display_printable_ascii (e);
+                               break;
+                       case CONSTANT_Integer:
+                               printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
+                               break;
+                       case CONSTANT_Float:
+                               printf ("Float -> %f", ((constant_float*)e) -> value);
+                               break;
+                       case CONSTANT_Double:
+                               printf ("Double -> %f", ((constant_double*)e) -> value);
+                               break;
+                       case CONSTANT_Long:
+                               {
+                                       u8 v = ((constant_long*)e) -> value;
+#if U8_AVAILABLE
+                                       printf ("Long -> %ld", (long int) v);
+#else
+                                       printf ("Long -> HI: %ld, LO: %ld\n", 
+                                                       (long int) v.high, (long int) v.low);
+#endif 
+                               }
+                               break;
+                       case CONSTANT_NameAndType:
+                               {
+                                       constant_nameandtype *cnt = e;
+                                       printf ("NameAndType: ");
+                                       utf_display_printable_ascii (cnt->name);
+                                       printf (" ");
+                                       utf_display_printable_ascii (cnt->descriptor);
+                               }
+                               break;
+                       case CONSTANT_Utf8:
+                               printf ("Utf8 -> ");
+                               utf_display_printable_ascii (e);
+                               break;
+                       default: 
+                               log_text("Invalid type of ConstantPool-Entry");
+                               assert(0);
+                       }
+               }
+
+               printf ("\n");
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* class_showmethods ***********************************************************
+
+   Dump info about the fields and methods of the given class to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void class_showmethods (classinfo *c)
+{
+       s4 i;
+       
+       printf("--------- Fields and Methods ----------------\n");
+       printf("Flags: ");
+       class_printflags(c);
+       printf("\n");
+
+       printf("This: ");
+       utf_display_printable_ascii(c->name);
+       printf("\n");
+
+       if (c->super.cls) {
+               printf("Super: ");
+               utf_display_printable_ascii(c->super.cls->name);
+               printf ("\n");
+       }
+
+       printf("Index: %d\n", c->index);
+       
+       printf("Interfaces:\n");        
+       for (i = 0; i < c->interfacescount; i++) {
+               printf("   ");
+               utf_display_printable_ascii(c->interfaces[i].cls->name);
+               printf (" (%d)\n", c->interfaces[i].cls->index);
+       }
+
+       printf("Fields:\n");
+       for (i = 0; i < c->fieldscount; i++)
+               field_println(&(c->fields[i]));
+
+       printf("Methods:\n");
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               if (!(m->flags & ACC_STATIC))
+                       printf("vftblindex: %d   ", m->vftblindex);
+
+               method_println(m);
+       }
+
+       printf ("Virtual function table:\n");
+       for (i = 0; i < c->vftbl->vftbllength; i++)
+               printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]));
+}
+#endif /* !defined(NDEBUG) */
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/class.h b/src/vmcore/class.h
new file mode 100644 (file)
index 0000000..4f51a5f
--- /dev/null
@@ -0,0 +1,356 @@
+/* src/vmcore/class.h - class related functions header
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: class.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _CLASS_H
+#define _CLASS_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct classinfo      classinfo; 
+typedef struct innerclassinfo innerclassinfo;
+typedef struct extra_classref extra_classref;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "toolbox/list.h"
+
+#include "vm/global.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vmcore/annotation.h"
+#endif
+
+#include "vmcore/field.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+#include "vmcore/utf8.h"
+
+
+/* class state defines ********************************************************/
+
+#define CLASS_LOADING         0x0001
+#define CLASS_LOADED          0x0002
+#define CLASS_LINKING         0x0004
+#define CLASS_LINKED          0x0008
+#define CLASS_INITIALIZING    0x0010
+#define CLASS_INITIALIZED     0x0020
+#define CLASS_ERROR           0x0040
+
+
+/* some macros ****************************************************************/
+
+#define CLASS_IS_OR_ALMOST_INITIALIZED(c) \
+    (((c)->state & CLASS_INITIALIZING) || ((c)->state & CLASS_INITIALIZED))
+
+
+/* classinfo ******************************************************************/
+
+struct classinfo {                /* class structure                          */
+       struct {
+               java_objectheader header;
+               ptrint            padding[4];
+       } object;
+
+       s4          flags;            /* ACC flags                                */
+       utf        *name;             /* class name                               */
+
+       s4          cpcount;          /* number of entries in constant pool       */
+       u1         *cptags;           /* constant pool tags                       */
+       voidptr    *cpinfos;          /* pointer to constant pool info structures */
+
+       s4          classrefcount;    /* number of symbolic class references      */
+       constant_classref *classrefs; /* table of symbolic class references       */
+       extra_classref *extclassrefs; /* additional classrefs                     */
+       s4          parseddescsize;   /* size of the parsed descriptors block     */
+       u1         *parseddescs;      /* parsed descriptors                       */
+
+       classref_or_classinfo super;  /* super class                              */
+       classinfo  *sub;              /* sub class pointer                        */
+       classinfo  *nextsub;          /* pointer to next class in sub class list  */
+
+       s4          interfacescount;  /* number of interfaces                     */
+       classref_or_classinfo *interfaces; /* superinterfaces                     */
+
+       s4          fieldscount;      /* number of fields                         */
+       fieldinfo  *fields;           /* field table                              */
+
+       s4          methodscount;     /* number of methods                        */
+       methodinfo *methods;          /* method table                             */
+
+       listnode    listnode;         /* linkage                                  */
+
+       s4          state;            /* current class state                      */
+       s4          index;            /* hierarchy depth (classes) or index       */
+                                     /* (interfaces)                             */
+       s4          instancesize;     /* size of an instance of this class        */
+
+       vftbl_t    *vftbl;            /* pointer to virtual function table        */
+
+       methodinfo *finalizer;        /* finalizer method                         */
+
+       u2          innerclasscount;  /* number of inner classes                  */
+       innerclassinfo *innerclass;
+
+#if defined(ENABLE_JAVASE)
+       classref_or_classinfo  enclosingclass;  /* enclosing class                */
+       constant_nameandtype  *enclosingmethod; /* enclosing method               */
+#endif
+
+       utf        *packagename;      /* full name of the package                 */
+       utf        *sourcefile;       /* SourceFile attribute                     */
+#if defined(ENABLE_JAVASE)
+       utf        *signature;        /* Signature attribute                      */
+       s4            runtimevisibleannotationscount;
+       annotation_t *runtimevisibleannotations;
+#endif
+       java_objectheader *classloader; /* NULL for bootstrap classloader         */
+};
+
+
+/* innerclassinfo *************************************************************/
+
+struct innerclassinfo {
+       classref_or_classinfo inner_class; /* inner class pointer                 */
+       classref_or_classinfo outer_class; /* outer class pointer                 */
+       utf                  *name;        /* innerclass name                     */
+       s4                    flags;       /* ACC flags                           */
+};
+
+
+/* extra_classref **************************************************************
+
+   for classrefs not occurring within descriptors
+
+*******************************************************************************/
+
+struct extra_classref {
+       extra_classref    *next;
+       constant_classref  classref;
+};
+
+
+/* global variables ***********************************************************/
+
+extern list unlinkedclasses;   /* this is only used for eager class loading   */
+
+
+/* frequently used classes ****************************************************/
+
+/* important system classes */
+
+extern classinfo *class_java_lang_Object;
+extern classinfo *class_java_lang_Class;
+extern classinfo *class_java_lang_ClassLoader;
+extern classinfo *class_java_lang_Cloneable;
+extern classinfo *class_java_lang_SecurityManager;
+extern classinfo *class_java_lang_String;
+extern classinfo *class_java_lang_System;
+extern classinfo *class_java_lang_Thread;
+extern classinfo *class_java_lang_ThreadGroup;
+extern classinfo *class_java_lang_VMSystem;
+extern classinfo *class_java_lang_VMThread;
+extern classinfo *class_java_io_Serializable;
+
+
+/* system exception classes required in cacao */
+
+extern classinfo *class_java_lang_Throwable;
+extern classinfo *class_java_lang_Error;
+extern classinfo *class_java_lang_LinkageError;
+extern classinfo *class_java_lang_NoClassDefFoundError;
+extern classinfo *class_java_lang_OutOfMemoryError;
+extern classinfo *class_java_lang_VirtualMachineError;
+
+#if defined(WITH_CLASSPATH_GNU)
+extern classinfo *class_java_lang_VMThrowable;
+#endif
+
+extern classinfo *class_java_lang_Exception;
+extern classinfo *class_java_lang_ClassCastException;
+extern classinfo *class_java_lang_ClassNotFoundException;
+
+#if defined(ENABLE_JAVASE)
+extern classinfo *class_java_lang_Void;
+#endif
+
+extern classinfo *class_java_lang_Boolean;
+extern classinfo *class_java_lang_Byte;
+extern classinfo *class_java_lang_Character;
+extern classinfo *class_java_lang_Short;
+extern classinfo *class_java_lang_Integer;
+extern classinfo *class_java_lang_Long;
+extern classinfo *class_java_lang_Float;
+extern classinfo *class_java_lang_Double;
+
+
+/* some runtime exception */
+
+extern classinfo *class_java_lang_NullPointerException;
+
+
+/* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+extern classinfo *class_java_lang_StackTraceElement;
+extern classinfo *class_java_lang_reflect_Constructor;
+extern classinfo *class_java_lang_reflect_Field;
+extern classinfo *class_java_lang_reflect_Method;
+extern classinfo *class_java_security_PrivilegedAction;
+extern classinfo *class_java_util_Vector;
+
+extern classinfo *arrayclass_java_lang_Object;
+#endif
+
+
+/* pseudo classes for the type checker ****************************************/
+
+/*
+ * pseudo_class_Arraystub
+ *     (extends Object implements Cloneable, java.io.Serializable)
+ *
+ *     If two arrays of incompatible component types are merged,
+ *     the resulting reference has no accessible components.
+ *     The result does, however, implement the interfaces Cloneable
+ *     and java.io.Serializable. This pseudo class is used internally
+ *     to represent such results. (They are *not* considered arrays!)
+ *
+ * pseudo_class_Null
+ *
+ *     This pseudo class is used internally to represent the
+ *     null type.
+ *
+ * pseudo_class_New
+ *
+ *     This pseudo class is used internally to represent the
+ *     the 'uninitialized object' type.
+ */
+
+extern classinfo *pseudo_class_Arraystub;
+extern classinfo *pseudo_class_Null;
+extern classinfo *pseudo_class_New;
+
+
+/* function prototypes ********************************************************/
+
+/* create a new classinfo struct */
+classinfo *class_create_classinfo(utf *u);
+
+/* postset's the header.vftbl */
+void class_postset_header_vftbl(void);
+
+/* set the package name after the name has been set */
+void class_set_packagename(classinfo *c);
+
+bool class_load_attributes(classbuffer *cb);
+
+/* retrieve constantpool element */
+voidptr class_getconstant(classinfo *class, u4 pos, u4 ctype);
+voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype);
+
+/* frees all resources used by the class */
+void class_free(classinfo *);
+
+/* return an array class with the given component class */
+classinfo *class_array_of(classinfo *component,bool link);
+
+/* return an array class with the given dimension and element class */
+classinfo *class_multiarray_of(s4 dim, classinfo *element,bool link);
+
+/* return a classref for the given class name */
+/* (does a linear search!)                    */
+constant_classref *class_lookup_classref(classinfo *cls,utf *name);
+
+/* return a classref for the given class name */
+/* (does a linear search!)                    */
+constant_classref *class_get_classref(classinfo *cls,utf *name);
+
+/* return a classref to the class itself */
+/* (does a linear search!)                    */
+constant_classref *class_get_self_classref(classinfo *cls);
+
+/* return a classref for an array with the given dimension of with the */
+/* given component type */
+constant_classref *class_get_classref_multiarray_of(s4 dim,constant_classref *ref);
+
+/* return a classref for the component type of the given array type */
+constant_classref *class_get_classref_component_of(constant_classref *ref);
+
+/* get a class' field by name and descriptor */
+fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc);
+
+/* search 'classinfo'-structure for a field with the specified name */
+fieldinfo *class_findfield_by_name(classinfo *c, utf *name);
+s4 class_findfield_index_by_name(classinfo *c, utf *name);
+
+/* search class for a field */
+fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc, classinfo *referer, bool throwexception);
+
+/* search for a method with a specified name and descriptor */
+methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc);
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *dest);
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *dest, classinfo *referer, bool throwexception);
+
+bool class_issubclass(classinfo *sub, classinfo *super);
+
+/* some debugging functions */
+
+#if !defined(NDEBUG)
+void class_printflags(classinfo *c);
+void class_print(classinfo *c);
+void class_println(classinfo *c);
+void class_classref_print(constant_classref *cr);
+void class_classref_println(constant_classref *cr);
+void class_classref_or_classinfo_print(classref_or_classinfo c);
+void class_classref_or_classinfo_println(classref_or_classinfo c);
+#endif
+
+/* debug purposes */
+void class_showmethods(classinfo *c);
+void class_showconstantpool(classinfo *c);
+
+#endif /* _CLASS_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:
+ */
diff --git a/src/vmcore/classcache.c b/src/vmcore/classcache.c
new file mode 100644 (file)
index 0000000..c2d53ed
--- /dev/null
@@ -0,0 +1,1583 @@
+/* src/vmcore/classcache.c - loaded class cache and loading constraints
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: classcache.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
+#include "toolbox/hashtable.h"
+
+#include "vm/exceptions.h"
+
+#include "vmcore/classcache.h"
+#include "vmcore/utf8.h"
+
+
+/*************************************************************************
+
+  Class Cache
+
+  The classcache has two functions:
+  
+       1) caching the resolution of class references
+       2) storing and checking loading constraints
+
+  We will use the following terms in this description:
+
+       N          a class name: a utf string
+       (N,L)      a class reference with initiating loader L and class name N
+       C          a class (object): the result of resolving a reference (N,L)
+               We will write resultion as
+                               C = *(N,L)
+       (N,L1,L2)  a loading constraint indicating that (N,L1) and (N,L2) must
+                  resolve to the same class C. So (N,L1,L2) means
+                               *(N,L1) = *(N,L2)
+
+  The functions of the classcache require:
+
+    1) a mapping (N,L) |--> C for looking up prior resolution results.
+       2) storing the current set of loading constraints { (N,L1,L2) }
+
+  These functions can be rearranged like that:
+
+    a mapping N |--> (a mapping L |--> C or NULL, 
+                         a set of constraints {(L1,L2)})
+
+  Thus we can treat the mapping and constraints for each name N
+  separately. The implementation does this by keeping a hash table
+  mapping a name N to a `classcache_name_entry` which contains all
+  info with respect to N.
+
+  For a class name N we can define an equivalence relation ~N~ on
+  class loaders:
+
+       L1 ~N~ L2  <==>  *(N,L1) = *(N,L2)
+
+  A loading constraint (N,L1,L2) implies L1 ~N~ L2.
+
+  Also, if two references (N,L1) and (N,L2) resolve to the same class C
+  we have L1 ~N~ L2 because class loaders are required to return
+  consistent resolutions for a name N [XXX].
+
+  A `classcache_name_entry` keeps a set of tuples { (Cx,IL,CL) },
+  where
+               Cx...is a class C or NULL
+               IL...is the set of initiating loaders
+               CL...is the set of constrained loaders
+               
+  Such a tuple is called `classcache_class_entry` in the source code.
+
+  The following holds for each tuple (Cx,IL,CL):
+
+    .  (Cx is NULL) implies IL = {}.
+          
+       .  If Cx is a class, IL is the set of loaders that have been
+          recorded as initiating loaders for Cx. IL may be the
+          empty set {} in case Cx has already been defined but no
+          initiating loader has been recorded, yet.
+  
+    .  (IL u CL) is a subset of an equivalence class of ~N~.
+
+                (This means that all loaders in IL and CL must resolve
+                the name N to the same class.)
+
+  The following holds for the set of tuples { (Cx,IL,CL) }:
+
+    .  For a given class C there is at most one tuple with Cx = C
+          in the set. (There may be an arbitrary number of tuples
+          with Cx = NULL, however.)
+
+       .  For a given loader L there is at most one tuple with
+          L in (IL u CL).
+
+  The implementation stores sets of loaders as linked lists of
+  `classcache_loader_entry`s.
+
+  Comments about manipulating the classcache can be found in the
+  individual functions below.
+*************************************************************************/
+
+
+/* initial number of slots in the classcache hash table */
+#define CLASSCACHE_INIT_SIZE  2048
+
+/*============================================================================*/
+/* DEBUG HELPERS                                                              */
+/*============================================================================*/
+
+/*#define CLASSCACHE_VERBOSE*/
+
+/*============================================================================*/
+/* STATISTICS                                                                 */
+/*============================================================================*/
+
+/*#define CLASSCACHE_STATS*/
+
+#ifdef CLASSCACHE_STATS
+static int stat_classnames_stored = 0;
+static int stat_classes_stored = 0;
+static int stat_trivial_constraints = 0;
+static int stat_nontriv_constraints = 0;
+static int stat_nontriv_constraints_both = 0;
+static int stat_nontriv_constraints_merged = 0;
+static int stat_nontriv_constraints_one = 0;
+static int stat_nontriv_constraints_none = 0;
+static int stat_new_loader_entry = 0;
+static int stat_merge_class_entries = 0;
+static int stat_merge_loader_entries = 0;
+static int stat_lookup = 0;
+static int stat_lookup_class_entry_checked = 0;
+static int stat_lookup_loader_checked = 0;
+static int stat_lookup_name = 0;
+static int stat_lookup_name_entry = 0;
+static int stat_lookup_name_notfound = 0;
+static int stat_lookup_new_name = 0;
+static int stat_lookup_new_name_entry = 0;
+static int stat_lookup_new_name_collisions = 0;
+static int stat_rehash_names = 0;
+static int stat_rehash_names_collisions = 0;
+
+#define CLASSCACHE_COUNT(cnt)  (cnt)++
+#define CLASSCACHE_COUNTIF(cond,cnt)  do{if(cond) (cnt)++;} while(0)
+
+void classcache_print_statistics(FILE *file) {
+       fprintf(file,"classnames stored   : %8d\n",stat_classnames_stored);
+       fprintf(file,"classes stored      : %8d\n",stat_classes_stored);
+       fprintf(file,"trivial constraints : %8d\n",stat_trivial_constraints);
+       fprintf(file,"non-triv constraints: %8d\n",stat_nontriv_constraints);
+       fprintf(file,"   both loaders rec.: %8d\n",stat_nontriv_constraints_both);
+       fprintf(file,"       merged       : %8d\n",stat_nontriv_constraints_merged);
+       fprintf(file,"   one loader rec.  : %8d\n",stat_nontriv_constraints_one);
+       fprintf(file,"   no loaders rec.  : %8d\n",stat_nontriv_constraints_none);
+       fprintf(file,"new loader entries  : %8d\n",stat_new_loader_entry);
+       fprintf(file,"merge class entries : %8d\n",stat_merge_class_entries);
+       fprintf(file,"merge loader entries: %8d\n",stat_merge_loader_entries);
+       fprintf(file,"lookups             : %8d\n",stat_lookup);
+       fprintf(file,"   class entries ckd: %8d\n",stat_lookup_class_entry_checked);
+       fprintf(file,"   loader checked   : %8d\n",stat_lookup_loader_checked);
+       fprintf(file,"lookup name         : %8d\n",stat_lookup_name);
+       fprintf(file,"   entries checked  : %8d\n",stat_lookup_name_entry);
+       fprintf(file,"   not found        : %8d\n",stat_lookup_name_notfound);
+       fprintf(file,"lookup (new) name   : %8d\n",stat_lookup_new_name);
+       fprintf(file,"   entries checked  : %8d\n",stat_lookup_new_name_entry);
+       fprintf(file,"   new collisions   : %8d\n",stat_lookup_new_name_collisions);
+       fprintf(file,"names rehashed      : %8d times\n",stat_rehash_names);
+       fprintf(file,"    collisions      : %8d\n",stat_rehash_names_collisions);
+}
+#else
+#define CLASSCACHE_COUNT(cnt)
+#define CLASSCACHE_COUNTIF(cond,cnt)
+#endif
+
+/*============================================================================*/
+/* THREAD-SAFE LOCKING                                                        */
+/*============================================================================*/
+
+       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+       /* CAUTION: The static functions below are */
+       /*          NOT synchronized!              */
+       /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+#if defined(ENABLE_THREADS)
+# define CLASSCACHE_LOCK()      LOCK_MONITOR_ENTER(lock_hashtable_classcache)
+# define CLASSCACHE_UNLOCK()    LOCK_MONITOR_EXIT(lock_hashtable_classcache)
+#else
+# define CLASSCACHE_LOCK()
+# define CLASSCACHE_UNLOCK()
+#endif
+
+/*============================================================================*/
+/* GLOBAL VARIABLES                                                           */
+/*============================================================================*/
+
+hashtable hashtable_classcache;
+
+#if defined(ENABLE_THREADS)
+static java_objectheader *lock_hashtable_classcache;
+#endif
+
+
+/*============================================================================*/
+/*                                                                            */
+/*============================================================================*/
+
+/* prototypes */
+
+static void classcache_free_class_entry(classcache_class_entry *clsen);
+static void classcache_remove_class_entry(classcache_name_entry *en,
+                                                                                 classcache_class_entry *clsen);
+
+/* hash function to use */
+
+#define CLASSCACHE_HASH utf_full_hashkey
+
+/* classcache_init *************************************************************
+   Initialize the class cache
+
+   Note: NOT synchronized!
+  
+*******************************************************************************/
+
+bool classcache_init(void)
+{
+       /* create the hashtable */
+
+       hashtable_create(&hashtable_classcache, CLASSCACHE_INIT_SIZE);
+
+#if defined(ENABLE_THREADS)
+       /* create utf hashtable lock object */
+
+       lock_hashtable_classcache = NEW(java_objectheader);
+
+       lock_init_object_lock(lock_hashtable_classcache);
+#endif
+
+       /* everything's ok */
+
+       return true;
+}
+
+/* classcache_new_loader_entry *************************************************
+   Create a new classcache_loader_entry struct
+   (internally used helper function)
+  
+   IN:
+       loader...........the ClassLoader object
+          next.............the next classcache_loader_entry
+
+   RETURN VALUE:
+       the new classcache_loader_entry
+  
+*******************************************************************************/
+
+static classcache_loader_entry * classcache_new_loader_entry(
+                                                                       classloader * loader,
+                                                                       classcache_loader_entry * next)
+{
+       classcache_loader_entry *lden;
+
+       lden = NEW(classcache_loader_entry);
+       lden->loader = loader;
+       lden->next = next;
+       CLASSCACHE_COUNT(stat_new_loader_entry);
+
+       return lden;
+}
+
+/* classcache_merge_loaders ****************************************************
+   Merge two lists of loaders into one
+   (internally used helper function)
+  
+   IN:
+       lista............first list (may be NULL)
+          listb............second list (may be NULL)
+
+   RETURN VALUE:
+       the merged list (may be NULL)
+
+   NOTE:
+       The lists given as arguments are destroyed!
+  
+*******************************************************************************/
+
+static classcache_loader_entry * classcache_merge_loaders(
+                                                                       classcache_loader_entry * lista,
+                                                                       classcache_loader_entry * listb)
+{
+       classcache_loader_entry *result;
+       classcache_loader_entry *ldenA;
+       classcache_loader_entry *ldenB;
+       classcache_loader_entry **chain;
+
+       CLASSCACHE_COUNT(stat_merge_loader_entries);
+
+       /* XXX This is a quadratic algorithm. If this ever
+        * becomes a problem, the loader lists should be
+        * stored as sorted lists and merged in linear time. */
+
+       result = NULL;
+       chain = &result;
+
+       for (ldenA = lista; ldenA; ldenA = ldenA->next) {
+
+               for (ldenB = listb; ldenB; ldenB = ldenB->next) {
+                       if (ldenB->loader == ldenA->loader)
+                               goto common_element;
+               }
+
+               /* this loader is only in lista */
+               *chain = ldenA;
+               chain = &(ldenA->next);
+
+         common_element:
+               /* XXX free the duplicated element */
+               ;
+       }
+
+       /* concat listb to the result */
+       *chain = listb;
+
+       return result;
+}
+
+/* classcache_merge_class_entries **********************************************
+   Merge two `classcache_class_entry`s into one.
+   (internally used helper function)
+  
+   IN:
+       en...............the classcache_name_entry containing both class entries
+       clsenA...........first class entry, will receive the result
+          clsenB...........second class entry
+
+   PRE-CONDITION:
+       Either both entries must have the same classobj, or one of them has
+          classobj == NULL.
+
+   NOTE:
+       clsenB is freed by this function!
+  
+*******************************************************************************/
+
+static void classcache_merge_class_entries(classcache_name_entry *en,
+                                                                                  classcache_class_entry *clsenA,
+                                                                                  classcache_class_entry *clsenB)
+{
+#ifdef CLASSCACHE_VERBOSE
+       char logbuffer[1024];
+#endif
+       
+       assert(en);
+       assert(clsenA);
+       assert(clsenB);
+       assert(!clsenA->classobj || !clsenB->classobj || clsenA->classobj == clsenB->classobj);
+
+#ifdef CLASSCACHE_VERBOSE
+       sprintf(logbuffer,"classcache_merge_class_entries(%p,%p->%p,%p->%p) ", 
+                       (void*)en,(void*)clsenA,(void*)clsenA->classobj,(void*)clsenB,(void*)clsenB->classobj);
+       if (clsenA->classobj)
+               utf_cat_classname(logbuffer, clsenA->classobj->name);
+       if (clsenB->classobj)
+               utf_cat_classname(logbuffer, clsenB->classobj->name);
+       log_text(logbuffer);
+#endif
+
+       CLASSCACHE_COUNT(stat_merge_class_entries);
+
+       /* clsenB will be merged into clsenA */
+       clsenA->loaders = classcache_merge_loaders(clsenA->loaders, clsenB->loaders);
+       clsenB->loaders = NULL; /* these have been freed or reused */
+
+       clsenA->constraints = classcache_merge_loaders(clsenA->constraints,
+                                                                                                  clsenB->constraints);
+       clsenB->constraints = NULL; /* these have been freed or reused */
+
+       if (!clsenA->classobj)
+               clsenA->classobj = clsenB->classobj;
+
+       /* remove clsenB from the list of class entries */
+       classcache_remove_class_entry(en, clsenB);
+}
+
+
+/* classcache_lookup_name ******************************************************
+   Lookup a name in the first level of the cache
+   (internally used helper function)
+   
+   IN:
+       name.............the name to look up
+  
+   RETURN VALUE:
+       a pointer to the classcache_name_entry for this name, or
+       null if no entry was found.
+          
+*******************************************************************************/
+
+static classcache_name_entry *classcache_lookup_name(utf *name)
+{
+       classcache_name_entry *c;           /* hash table element                 */
+       u4 key;                             /* hashkey computed from classname    */
+       u4 slot;                            /* slot in hashtable                  */
+
+       CLASSCACHE_COUNT(stat_lookup_name);
+
+       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
+       slot = key & (hashtable_classcache.size - 1);
+       c    = hashtable_classcache.ptr[slot];
+
+       /* search external hash chain for the entry */
+
+       while (c) {
+               /* entry found in hashtable */
+               CLASSCACHE_COUNT(stat_lookup_name_entry);
+
+               if (c->name == name)
+                       return c;
+
+               c = c->hashlink;                    /* next element in external chain */
+       }
+
+       /* not found */
+
+       CLASSCACHE_COUNT(stat_lookup_name_notfound);
+       return NULL;
+}
+
+
+/* classcache_new_name *********************************************************
+   Return a classcache_name_entry for the given name. The entry is created
+   if it is not already in the cache.
+   (internally used helper function)
+   
+   IN:
+       name.............the name to look up / create an entry for
+  
+   RETURN VALUE:
+       a pointer to the classcache_name_entry for this name
+          
+*******************************************************************************/
+
+static classcache_name_entry *classcache_new_name(utf *name)
+{
+       classcache_name_entry *c;       /* hash table element */
+       u4 key;                                         /* hashkey computed from classname */
+       u4 slot;                                        /* slot in hashtable               */
+       u4 i;
+
+       CLASSCACHE_COUNT(stat_lookup_new_name);
+
+       key  = CLASSCACHE_HASH(name->text, (u4) name->blength);
+       slot = key & (hashtable_classcache.size - 1);
+       c    = hashtable_classcache.ptr[slot];
+
+       /* search external hash chain for the entry */
+
+       while (c) {
+               /* entry found in hashtable */
+               CLASSCACHE_COUNT(stat_lookup_new_name_entry);
+
+               if (c->name == name)
+                       return c;
+
+               c = c->hashlink;                    /* next element in external chain */
+       }
+
+       /* location in hashtable found, create new entry */
+
+       c = NEW(classcache_name_entry);
+
+       c->name = name;
+       c->classes = NULL;
+
+       /* insert entry into hashtable */
+       c->hashlink = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+       CLASSCACHE_COUNTIF(c->hashlink,stat_lookup_new_name_collisions);
+       hashtable_classcache.ptr[slot] = c;
+
+       /* update number of hashtable-entries */
+       hashtable_classcache.entries++;
+       CLASSCACHE_COUNT(stat_classnames_stored);
+
+       if ((hashtable_classcache.entries*2) > hashtable_classcache.size) {
+               /* reorganization of hashtable */ 
+
+               classcache_name_entry *c2;
+               hashtable newhash;              /* the new hashtable */
+
+               CLASSCACHE_COUNT(stat_rehash_names);
+
+               /* create new hashtable, double the size */
+
+               hashtable_create(&newhash, hashtable_classcache.size * 2);
+               newhash.entries = hashtable_classcache.entries;
+
+               /* transfer elements to new hashtable */
+
+               for (i = 0; i < hashtable_classcache.size; i++) {
+                       c2 = (classcache_name_entry *) hashtable_classcache.ptr[i];
+                       while (c2) {
+                               classcache_name_entry *nextc = c2->hashlink;
+                               u4 newslot =
+                                       (CLASSCACHE_HASH(c2->name->text, (u4) c2->name->blength)) & (newhash.size - 1);
+
+                               c2->hashlink = (classcache_name_entry *) newhash.ptr[newslot];
+                               CLASSCACHE_COUNTIF(c2->hashlink,stat_rehash_names_collisions);
+                               newhash.ptr[newslot] = c2;
+
+                               c2 = nextc;
+                       }
+               }
+
+               /* dispose old table */
+
+               MFREE(hashtable_classcache.ptr, void *, hashtable_classcache.size);
+               hashtable_classcache = newhash;
+       }
+
+       return c;
+}
+
+
+/* classcache_lookup ***********************************************************
+   Lookup a possibly loaded class
+  
+   IN:
+       initloader.......initiating loader for resolving the class name
+       classname........class name to look up
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+classinfo *classcache_lookup(classloader *initloader, utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       CLASSCACHE_COUNT(stat_lookup);
+       en = classcache_lookup_name(classname);
+
+       if (en) {
+               /* iterate over all class entries */
+
+               for (clsen = en->classes; clsen; clsen = clsen->next) {
+                       CLASSCACHE_COUNT(stat_lookup_class_entry_checked);
+                       /* check if this entry has been loaded by initloader */
+
+                       for (lden = clsen->loaders; lden; lden = lden->next) {
+                               CLASSCACHE_COUNT(stat_lookup_loader_checked);
+                               if (lden->loader == initloader) {
+                                       /* found the loaded class entry */
+
+                                       assert(clsen->classobj);
+                                       cls = clsen->classobj;
+                                       goto found;
+                               }
+                       }
+               }
+       }
+
+  found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+
+/* classcache_lookup_defined ***************************************************
+   Lookup a class with the given name and defining loader
+  
+   IN:
+       defloader........defining loader
+       classname........class name
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+   
+*******************************************************************************/
+
+classinfo *classcache_lookup_defined(classloader *defloader, utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_lookup_name(classname);
+
+       if (en) {
+               /* iterate over all class entries */
+               for (clsen = en->classes; clsen; clsen = clsen->next) {
+                       if (!clsen->classobj)
+                               continue;
+
+                       /* check if this entry has been defined by defloader */
+                       if (clsen->classobj->classloader == defloader) {
+                               cls = clsen->classobj;
+                               goto found;
+                       }
+               }
+       }
+
+  found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+
+/* classcache_lookup_defined_or_initiated **************************************
+   Lookup a class that has been defined or initiated by the given loader
+  
+   IN:
+       loader...........defining or initiating loader
+       classname........class name to look up
+  
+   RETURN VALUE:
+       The return value is a pointer to the cached class object,
+       or NULL, if the class is not in the cache.
+
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+classinfo *classcache_lookup_defined_or_initiated(classloader *loader, 
+                                                                                                 utf *classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       classinfo *cls = NULL;
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_lookup_name(classname);
+
+       if (en) {
+               /* iterate over all class entries */
+
+               for (clsen = en->classes; clsen; clsen = clsen->next) {
+
+                       /* check if this entry has been defined by loader */
+                       if (clsen->classobj && clsen->classobj->classloader == loader) {
+                               cls = clsen->classobj;
+                               goto found;
+                       }
+                       
+                       /* check if this entry has been initiated by loader */
+                       for (lden = clsen->loaders; lden; lden = lden->next) {
+                               if (lden->loader == loader) {
+                                       /* found the loaded class entry */
+
+                                       assert(clsen->classobj);
+                                       cls = clsen->classobj;
+                                       goto found;
+                               }
+                       }
+               }
+       }
+
+  found:
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+
+/* classcache_store ************************************************************
+   
+   Store a loaded class. If a class of the same name has already been stored
+   with the same initiating loader, then the given class CLS is freed (if
+   possible) and the previously stored class is returned.
+  
+   IN:
+       initloader.......initiating loader used to load the class
+                           (may be NULL indicating the bootstrap loader)
+       cls..............class object to cache
+          mayfree..........true if CLS may be freed in case another class is
+                           returned
+  
+   RETURN VALUE:
+       cls..............everything ok, the class was stored in the cache,
+          other classinfo..another class with the same (initloader,name) has been
+                           stored earlier. CLS has been freed[1] and the earlier
+                                               stored class is returned.
+       NULL.............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+
+   [1]...in case MAYFREE is true
+   
+*******************************************************************************/
+
+classinfo *classcache_store(classloader *initloader, classinfo *cls,
+                                                       bool mayfree)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+       classcache_class_entry *clsenB;
+       classcache_loader_entry *lden;
+#ifdef CLASSCACHE_VERBOSE
+       char logbuffer[1024];
+#endif
+       
+       assert(cls);
+       assert(cls->state & CLASS_LOADED);
+
+       CLASSCACHE_LOCK();
+
+#ifdef CLASSCACHE_VERBOSE
+       sprintf(logbuffer,"classcache_store (%p,%d,%p=", (void*)initloader,mayfree,(void*)cls);
+       utf_cat_classname(logbuffer, cls->name);
+       strcat(logbuffer,")");
+       log_text(logbuffer);
+#endif
+
+       en = classcache_new_name(cls->name);
+
+       assert(en);
+
+       /* iterate over all class entries */
+       for (clsen = en->classes; clsen; clsen = clsen->next) {
+
+               /* check if this entry has already been loaded by initloader */
+               for (lden = clsen->loaders; lden; lden = lden->next) {
+                       if (lden->loader == initloader) {
+                          if (clsen->classobj != cls) {
+                                       /* A class with the same (initloader,name) pair has been stored already. */
+                                       /* We free the given class and return the earlier one.                   */
+#ifdef CLASSCACHE_VERBOSE
+                                       dolog("replacing %p with earlier loaded class %p",cls,clsen->classobj);
+#endif
+                                       assert(clsen->classobj);
+                                       if (mayfree)
+                                               class_free(cls);
+                                       cls = clsen->classobj;
+                          }
+                          goto return_success;
+                       }
+               }
+
+               /* {This entry has not been resolved with initloader} */
+
+               /* check if initloader is constrained to this entry */
+               for (lden = clsen->constraints; lden; lden = lden->next) {
+                       if (lden->loader == initloader) {
+                               /* we have to use this entry. check if it has been resolved */
+                               if (clsen->classobj) {
+                                       /* check if is has already been resolved to another class */
+                                       if (clsen->classobj != cls) {
+                                               /* a loading constraint is violated */
+                                               exceptions_throw_linkageerror("loading constraint violated: ", cls);
+                                               goto return_exception;
+                                       }
+
+                                       /* record initloader as initiating loader */
+                                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
+                                       goto return_success;
+                               }
+
+                               /* {this is the first resolution for this entry} */
+                               /* record initloader as initiating loader */
+                               clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
+
+                               /* maybe we can merge this entry with another one */
+                               for (clsenB = en->classes; clsenB; clsenB = clsenB->next) {
+                                       /* we dont want the entry that we have already */
+                                       if (clsenB->classobj == cls) {
+                                               /* this entry has the same classobj. let's merge them */
+                                               classcache_merge_class_entries(en,clsen,clsenB);
+                                               goto return_success;
+                                       }
+                               }
+
+                               /* record the loaded class object */
+                               clsen->classobj = cls;
+                               CLASSCACHE_COUNT(stat_classes_stored);
+
+                               /* done */
+                               goto return_success;
+                       }
+               }
+
+       }
+
+       /* {There is no class entry containing initloader as initiating 
+        *  or constrained loader.} */
+
+       /* we look for a class entry with the same classobj we want to store */
+       for (clsen = en->classes; clsen; clsen = clsen->next) {
+               if (clsen->classobj == cls) {
+                       /* this entry is about the same classobj. let's use it */
+                       /* check if this entry has already been loaded by initloader */
+                       for (lden = clsen->loaders; lden; lden = lden->next) {
+                               if (lden->loader == initloader)
+                                       goto return_success;
+                       }
+                       clsen->loaders = classcache_new_loader_entry(initloader, clsen->loaders);
+                       goto return_success;
+               }
+       }
+
+       /* create a new class entry for this class object with */
+       /* initiating loader initloader                        */
+
+       clsen = NEW(classcache_class_entry);
+       clsen->classobj = cls;
+       clsen->loaders = classcache_new_loader_entry(initloader, NULL);
+       clsen->constraints = NULL;
+
+       clsen->next = en->classes;
+       en->classes = clsen;
+       CLASSCACHE_COUNT(stat_classes_stored);
+
+  return_success:
+#ifdef CLASSCACHE_VERBOSE
+       classcache_debug_dump(stderr,cls->name);
+#endif
+       CLASSCACHE_UNLOCK();
+       return cls;
+
+  return_exception:
+       CLASSCACHE_UNLOCK();
+       return NULL;                            /* exception */
+}
+
+/* classcache_store_unique *****************************************************
+   
+   Store a loaded class as loaded by the bootstrap loader. This is a wrapper 
+   aroung classcache_store that throws an exception if a class with the same 
+   name has already been loaded by the bootstrap loader.
+
+   This function is used to register a few special classes during startup.
+   It should not be used otherwise.
+  
+   IN:
+       cls..............class object to cache
+  
+   RETURN VALUE:
+       true.............everything ok, the class was stored.
+       false............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+bool classcache_store_unique(classinfo *cls)
+{
+       classinfo *result;
+
+       result = classcache_store(NULL,cls,false);
+       if (result == NULL)
+               return false;
+
+       if (result != cls) {
+               exceptions_throw_internalerror("class already stored in the class cache");
+               return false;
+       }
+
+       return true;
+}
+
+/* classcache_store_defined ****************************************************
+   
+   Store a loaded class after it has been defined. If the class has already
+   been defined by the same defining loader in another thread, free the given
+   class and returned the one which has been defined earlier.
+  
+   IN:
+       cls..............class object to store. classloader must be set
+                           (classloader may be NULL, for bootloader)
+  
+   RETURN VALUE:
+       cls..............everything ok, the class was stored the cache,
+          other classinfo..the class had already been defined, CLS was freed, the
+                           class which was defined earlier is returned,
+       NULL.............an exception has been thrown.
+   
+*******************************************************************************/
+
+classinfo *classcache_store_defined(classinfo *cls)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsen;
+#ifdef CLASSCACHE_VERBOSE
+       char logbuffer[1024];
+#endif
+
+       assert(cls);
+       assert(cls->state & CLASS_LOADED);
+
+       CLASSCACHE_LOCK();
+
+#ifdef CLASSCACHE_VERBOSE
+       sprintf(logbuffer,"classcache_store_defined (%p,", (void*)cls->classloader);
+       utf_cat_classname(logbuffer, cls->name);
+       strcat(logbuffer,")");
+       log_text(logbuffer);
+#endif
+
+       en = classcache_new_name(cls->name);
+
+       assert(en);
+
+       /* iterate over all class entries */
+       for (clsen = en->classes; clsen; clsen = clsen->next) {
+               
+               /* check if this class has been defined by the same classloader */
+               if (clsen->classobj && clsen->classobj->classloader == cls->classloader) {
+                       /* we found an earlier definition, delete the newer one */
+                       /* (if it is a different classinfo)                     */
+                       if (clsen->classobj != cls) {
+#ifdef CLASSCACHE_VERBOSE
+                               dolog("replacing %p with earlier defined class %p",cls,clsen->classobj);
+#endif
+                               class_free(cls);
+                               cls = clsen->classobj;
+                       }
+                       goto return_success;
+               }
+       }
+
+       /* create a new class entry for this class object */
+       /* the list of initiating loaders is empty at this point */
+
+       clsen = NEW(classcache_class_entry);
+       clsen->classobj = cls;
+       clsen->loaders = NULL;
+       clsen->constraints = NULL;
+
+       clsen->next = en->classes;
+       en->classes = clsen;
+       CLASSCACHE_COUNT(stat_classes_stored);
+
+return_success:
+#ifdef CLASSCACHE_VERBOSE
+       classcache_debug_dump(stderr,cls->name);
+#endif
+       CLASSCACHE_UNLOCK();
+       return cls;
+}
+
+/* classcache_find_loader ******************************************************
+   Find the class entry loaded by or constrained to a given loader
+   (internally used helper function)
+  
+   IN:
+       entry............the classcache_name_entry
+       loader...........the loader to look for
+  
+   RETURN VALUE:
+       the classcache_class_entry for the given loader, or
+          NULL if no entry was found
+   
+*******************************************************************************/
+
+static classcache_class_entry * classcache_find_loader(
+                                                                       classcache_name_entry * entry,
+                                                                       classloader * loader)
+{
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+
+       assert(entry);
+
+       /* iterate over all class entries */
+       for (clsen = entry->classes; clsen; clsen = clsen->next) {
+
+               /* check if this entry has already been loaded by initloader */
+               for (lden = clsen->loaders; lden; lden = lden->next) {
+                       if (lden->loader == loader)
+                               return clsen;   /* found */
+               }
+
+               /* check if loader is constrained to this entry */
+               for (lden = clsen->constraints; lden; lden = lden->next) {
+                       if (lden->loader == loader)
+                               return clsen;   /* found */
+               }
+       }
+
+       /* not found */
+       return NULL;
+}
+
+/* classcache_free_class_entry *************************************************
+   Free the memory used by a class entry
+  
+   IN:
+       clsen............the classcache_class_entry to free  
+          
+*******************************************************************************/
+
+static void classcache_free_class_entry(classcache_class_entry * clsen)
+{
+       classcache_loader_entry *lden;
+       classcache_loader_entry *next;
+
+       assert(clsen);
+
+       for (lden = clsen->loaders; lden; lden = next) {
+               next = lden->next;
+               FREE(lden, classcache_loader_entry);
+       }
+       for (lden = clsen->constraints; lden; lden = next) {
+               next = lden->next;
+               FREE(lden, classcache_loader_entry);
+       }
+
+       FREE(clsen, classcache_class_entry);
+}
+
+/* classcache_remove_class_entry ***********************************************
+   Remove a classcache_class_entry from the list of possible resolution of
+   a name entry
+   (internally used helper function)
+  
+   IN:
+       entry............the classcache_name_entry
+       clsen............the classcache_class_entry to remove
+  
+*******************************************************************************/
+
+static void classcache_remove_class_entry(classcache_name_entry * entry,
+                                                                                 classcache_class_entry * clsen)
+{
+       classcache_class_entry **chain;
+
+       assert(entry);
+       assert(clsen);
+
+       chain = &(entry->classes);
+       while (*chain) {
+               if (*chain == clsen) {
+                       *chain = clsen->next;
+                       classcache_free_class_entry(clsen);
+                       return;
+               }
+               chain = &((*chain)->next);
+       }
+}
+
+/* classcache_free_name_entry **************************************************
+   Free the memory used by a name entry
+  
+   IN:
+       entry............the classcache_name_entry to free  
+          
+*******************************************************************************/
+
+static void classcache_free_name_entry(classcache_name_entry * entry)
+{
+       classcache_class_entry *clsen;
+       classcache_class_entry *next;
+
+       assert(entry);
+
+       for (clsen = entry->classes; clsen; clsen = next) {
+               next = clsen->next;
+               classcache_free_class_entry(clsen);
+       }
+
+       FREE(entry, classcache_name_entry);
+}
+
+/* classcache_free *************************************************************
+   Free the memory used by the class cache
+
+   NOTE:
+       The class cache may not be used any more after this call, except
+          when it is reinitialized with classcache_init.
+  
+   Note: NOT synchronized!
+  
+*******************************************************************************/
+
+void classcache_free(void)
+{
+       u4 slot;
+       classcache_name_entry *entry;
+       classcache_name_entry *next;
+
+       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
+               for (entry = (classcache_name_entry *) hashtable_classcache.ptr[slot]; entry; entry = next) {
+                       next = entry->hashlink;
+                       classcache_free_name_entry(entry);
+               }
+       }
+
+       MFREE(hashtable_classcache.ptr, voidptr, hashtable_classcache.size);
+       hashtable_classcache.size = 0;
+       hashtable_classcache.entries = 0;
+       hashtable_classcache.ptr = NULL;
+}
+
+/* classcache_add_constraint ***************************************************
+   Add a loading constraint
+  
+   IN:
+       a................first initiating loader
+       b................second initiating loader
+       classname........class name
+  
+   RETURN VALUE:
+       true.............everything ok, the constraint has been added,
+       false............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool classcache_add_constraint(classloader * a,
+                                                          classloader * b,
+                                                          utf * classname)
+{
+       classcache_name_entry *en;
+       classcache_class_entry *clsenA;
+       classcache_class_entry *clsenB;
+
+       assert(classname);
+
+#ifdef CLASSCACHE_VERBOSE
+       fprintf(stderr, "classcache_add_constraint(%p,%p,", (void *) a, (void *) b);
+       utf_fprint_printable_ascii_classname(stderr, classname);
+       fprintf(stderr, ")\n");
+#endif
+
+       /* a constraint with a == b is trivially satisfied */
+       if (a == b) {
+               CLASSCACHE_COUNT(stat_trivial_constraints);
+               return true;
+       }
+
+       CLASSCACHE_LOCK();
+
+       en = classcache_new_name(classname);
+
+       assert(en);
+       CLASSCACHE_COUNT(stat_nontriv_constraints);
+
+       /* find the entry loaded by / constrained to each loader */
+       clsenA = classcache_find_loader(en, a);
+       clsenB = classcache_find_loader(en, b);
+
+       if (clsenA && clsenB) {
+               /* { both loaders have corresponding entries } */
+               CLASSCACHE_COUNT(stat_nontriv_constraints_both);
+
+               /* if the entries are the same, the constraint is already recorded */
+               if (clsenA == clsenB)
+                       goto return_success;
+
+               /* check if the entries can be merged */
+               if (clsenA->classobj && clsenB->classobj
+                       && clsenA->classobj != clsenB->classobj) {
+                       /* no, the constraint is violated */
+                       exceptions_throw_linkageerror("loading constraint violated: ",
+                                                                                 clsenA->classobj);
+                       goto return_exception;
+               }
+
+               /* yes, merge the entries */
+               classcache_merge_class_entries(en,clsenA,clsenB);
+               CLASSCACHE_COUNT(stat_nontriv_constraints_merged);
+       }
+       else {
+               /* { at most one of the loaders has a corresponding entry } */
+
+               /* set clsenA to the single class entry we have */
+               if (!clsenA)
+                       clsenA = clsenB;
+
+               if (!clsenA) {
+                       /* { no loader has a corresponding entry } */
+                       CLASSCACHE_COUNT(stat_nontriv_constraints_none);
+
+                       /* create a new class entry with the constraint (a,b,en->name) */
+                       clsenA = NEW(classcache_class_entry);
+                       clsenA->classobj = NULL;
+                       clsenA->loaders = NULL;
+                       clsenA->constraints = classcache_new_loader_entry(b, NULL);
+                       clsenA->constraints = classcache_new_loader_entry(a, clsenA->constraints);
+
+                       clsenA->next = en->classes;
+                       en->classes = clsenA;
+               }
+               else {
+                       CLASSCACHE_COUNT(stat_nontriv_constraints_one);
+
+                       /* make b the loader that has no corresponding entry */
+                       if (clsenB)
+                               b = a;
+
+                       /* loader b must be added to entry clsenA */
+                       clsenA->constraints = classcache_new_loader_entry(b, clsenA->constraints);
+               }
+       }
+
+  return_success:
+       CLASSCACHE_UNLOCK();
+       return true;
+
+  return_exception:
+       CLASSCACHE_UNLOCK();
+       return false;                           /* exception */
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+/* classcache_add_constraints_for_params ***************************************
+   Add loading constraints for the parameters and return type of 
+   the given method.
+  
+   IN:
+       a................first initiating loader
+       b................second initiating loader
+       m................methodinfo 
+  
+   RETURN VALUE:
+       true.............everything ok, the constraints have been added,
+       false............an exception has been thrown.
+   
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool classcache_add_constraints_for_params(classloader * a,
+                                                                                  classloader * b,
+                                                                                  methodinfo *m)
+{
+       methoddesc *md;
+       typedesc *td;
+       s4 i;
+
+       /* a constraint with a == b is trivially satisfied */
+
+       if (a == b) {
+               return true;
+       }
+
+       /* get the parsed descriptor */
+
+       assert(m);
+       md = m->parseddesc;
+       assert(md);
+
+       /* constrain the return type */
+
+       if (md->returntype.type == TYPE_ADR) {
+               if (!classcache_add_constraint(a, b, md->returntype.classref->name))
+                       return false; /* exception */
+       }
+
+       /* constrain each reference type used in the parameters */
+
+       td = md->paramtypes;
+       i = md->paramcount;
+       for (; i--; td++) {
+               if (td->type != TYPE_ADR)
+                       continue;
+
+               if (!classcache_add_constraint(a, b, td->classref->name))
+                       return false; /* exception */
+       }
+
+       /* everything ok */
+       return true;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* classcache_number_of_loaded_classes *****************************************
+
+   Counts the number of loaded classes and returns it.
+
+   Note: This function assumes that the CLASSCACHE_LOCK is held by the
+   caller!
+
+*******************************************************************************/
+
+static s4 classcache_number_of_loaded_classes(void)
+{
+       classcache_name_entry  *en;
+       classcache_class_entry *clsen;
+       s4                      number;
+       s4                      i;
+
+       /* initialize class counter */
+
+       number = 0;
+
+       for (i = 0; i < hashtable_classcache.size; i++) {
+               /* iterate over hashlink */
+
+               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
+                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
+
+                       if (en->name->text[0] == '$')
+                               continue;
+
+                       /* iterate over classes with same name */
+
+                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
+                               /* get only loaded classes */
+
+                               if (clsen->classobj != NULL)
+                                       number++;
+                       }
+               }
+       }
+
+       return number;
+}
+
+
+/* classcache_get_loaded_class_count *******************************************
+
+   Counts the number of loaded classes and returns it.
+
+*******************************************************************************/
+
+s4 classcache_get_loaded_class_count(void)
+{
+       s4 count;
+
+       CLASSCACHE_LOCK();
+
+       count = classcache_number_of_loaded_classes();
+       
+       CLASSCACHE_UNLOCK();
+
+       return count;
+}
+
+
+/* classcache_get_loaded_classes ***********************************************
+
+   Returns an array of all loaded classes as array.  The array is
+   allocaed on the Java heap.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JVMTI)
+void classcache_get_loaded_classes(s4 *class_count_ptr,
+                                                                  classinfo ***classes_ptr)
+{
+       classinfo              **classes;
+       s4                       class_count;
+       classcache_name_entry   *en;
+       classcache_class_entry  *clsen;
+       s4                       i;
+       s4                       j;
+
+       CLASSCACHE_LOCK();
+
+       /* get the number of loaded classes and allocate the array */
+
+       class_count = classcache_number_of_loaded_classes();
+
+       classes = GCMNEW(classinfo*, class_count);
+
+       /* look in every slot of the hashtable */
+
+       for (i = 0, j = 0; i < hashtable_classcache.size; i++) {
+               /* iterate over hashlink */
+
+               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
+                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
+
+                       if (en->name->text[0] == '$')
+                               continue;
+
+                       /* iterate over classes with same name */
+
+                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
+                               /* get only loaded classes */
+
+                               if (clsen->classobj != NULL) {
+                                       classes[j] = clsen->classobj;
+                                       j++;
+                               }
+                       }
+               }
+       }
+
+       /* pass the return values */
+
+       *class_count_ptr = class_count;
+       *classes_ptr     = classes;
+
+       CLASSCACHE_UNLOCK();
+}
+#endif /* defined(ENABLE_JVMTI) */
+
+
+/* classcache_foreach_loaded_class *********************************************
+
+   Calls the given function for each loaded class.
+
+*******************************************************************************/
+
+void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
+                                                                        void *data)
+{
+       classcache_name_entry   *en;
+       classcache_class_entry  *clsen;
+       s4                       i;
+
+       CLASSCACHE_LOCK();
+
+       /* look in every slot of the hashtable */
+
+       for (i = 0; i < hashtable_classcache.size; i++) {
+               /* iterate over hashlink */
+
+               for (en = hashtable_classcache.ptr[i]; en != NULL; en = en->hashlink) {
+                       /* filter pseudo classes $NEW$, $NULL$, $ARRAYSTUB$ out */
+
+                       if (en->name->text[0] == '$')
+                               continue;
+
+                       /* iterate over classes with same name */
+
+                       for (clsen = en->classes; clsen != NULL; clsen = clsen->next) {
+                               /* get only loaded classes */
+
+                               if (clsen->classobj != NULL) {
+                                       (*func)(clsen->classobj, data);
+                               }
+                       }
+               }
+       }
+
+       CLASSCACHE_UNLOCK();
+}
+
+
+/*============================================================================*/
+/* DEBUG DUMPS                                                                */
+/*============================================================================*/
+
+/* classcache_debug_dump *******************************************************
+   Print the contents of the loaded class cache to a stream
+  
+   IN:
+       file.............output stream
+          only.............if != NULL, only print entries for this name
+                           (Currently we print also the rest of the hash chain to
+                                                get a feel for the average length of hash chains.)
+  
+   Note: synchronized with global tablelock
+   
+*******************************************************************************/
+
+#ifndef NDEBUG
+void classcache_debug_dump(FILE * file,utf *only)
+{
+       classcache_name_entry *c;
+       classcache_class_entry *clsen;
+       classcache_loader_entry *lden;
+       u4 slot;
+
+       CLASSCACHE_LOCK();
+
+       fprintf(file, "\n=== [loaded class cache] =====================================\n\n");
+       fprintf(file, "hash size   : %d\n", (int) hashtable_classcache.size);
+       fprintf(file, "hash entries: %d\n", (int) hashtable_classcache.entries);
+       fprintf(file, "\n");
+
+       if (only) {
+               c = classcache_lookup_name(only);
+               slot = 0; /* avoid compiler warning */
+               goto dump_it;
+       }
+
+       for (slot = 0; slot < hashtable_classcache.size; ++slot) {
+               c = (classcache_name_entry *) hashtable_classcache.ptr[slot];
+
+dump_it:
+               for (; c; c = c->hashlink) {
+                       utf_fprint_printable_ascii_classname(file, c->name);
+                       fprintf(file, "\n");
+
+                       /* iterate over all class entries */
+                       for (clsen = c->classes; clsen; clsen = clsen->next) {
+                               if (clsen->classobj) {
+                                       fprintf(file, "    loaded %p\n", (void *) clsen->classobj);
+                               }
+                               else {
+                                       fprintf(file, "    unresolved\n");
+                               }
+                               fprintf(file, "        loaders:");
+                               for (lden = clsen->loaders; lden; lden = lden->next) {
+                                       fprintf(file, "<%p> %p", (void *) lden, (void *) lden->loader);
+                               }
+                               fprintf(file, "\n        constraints:");
+                               for (lden = clsen->constraints; lden; lden = lden->next) {
+                                       fprintf(file, "<%p> %p", (void *) lden, (void *) lden->loader);
+                               }
+                               fprintf(file, "\n");
+                       }
+               }
+
+               if (only)
+                       break;
+       }
+       fprintf(file, "\n==============================================================\n\n");
+
+       CLASSCACHE_UNLOCK();
+}
+#endif /* NDEBUG */
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/classcache.h b/src/vmcore/classcache.h
new file mode 100644 (file)
index 0000000..4fcb868
--- /dev/null
@@ -0,0 +1,178 @@
+/* src/vmcore/classcache.h - loaded class cache and loading constraints
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: classcache.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _CLASSCACHE_H
+#define _CLASSCACHE_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#include <stdio.h>  /* for FILE */
+
+#if defined(ENABLE_JVMTI)
+# include "native/jni.h"
+#endif
+
+#include "toolbox/hashtable.h"
+
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+#include "vmcore/references.h"
+
+
+/* forward declarations *******************************************************/
+
+typedef struct classcache_name_entry classcache_name_entry;
+typedef struct classcache_class_entry classcache_class_entry;
+typedef struct classcache_loader_entry classcache_loader_entry;
+
+typedef java_objectheader classloader;
+
+/* global variables ***********************************************************/
+
+extern hashtable hashtable_classcache;
+
+
+/* structs ********************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* The Loaded Class Cache                                                     */
+/*                                                                            */
+/* The loaded class cache is implemented as a two-level data structure.       */
+/*                                                                            */
+/* The first level is a hash table indexed by class names. For each class     */
+/* name in the cache there is a classcache_name_entry, which collects all     */
+/* information about classes with this class name.                            */
+/*                                                                            */
+/* Second level: For each classcache_name_entry there is a list of            */
+/* classcache_class_entry:s representing the possible different resolutions   */
+/* of the class name.                                                         */
+/*                                                                            */
+/* A classcache_class_entry records the following:                            */
+/*                                                                            */
+/* - the loaded class object, if this entry has been resolved, otherwise NULL */
+/* - the list of initiating loaders which have resolved the class name to     */
+/*   this class object                                                        */
+/* - the list of initiating loaders which are constrained to resolve this     */
+/*   class name to this class object in the future                            */
+/*                                                                            */
+/* The classcache_class_entry:s approximate the equivalence classes created   */
+/* by the loading constraints and the equivalence of loaded classes.          */
+/*                                                                            */
+/* When a loading constraint (loaderA,loaderB,NAME) is added, then the        */
+/* classcache_class_entry:s for NAME containing loaderA and loaderB resp.     */
+/* must be merged into one entry. If this is impossible, because the entries  */
+/* have already been resolved to different class objects, then the constraint */
+/* is violated and an expception must be thrown.                              */
+/*----------------------------------------------------------------------------*/
+
+
+/* classcache_name_entry
+ *
+ * For each classname a classcache_name_entry struct is created.
+ */
+
+struct classcache_name_entry
+{
+       utf                     *name;        /* class name                       */
+       classcache_name_entry   *hashlink;    /* link for external chaining       */
+       classcache_class_entry  *classes;     /* equivalence classes for this name*/
+};
+
+struct classcache_class_entry
+{
+       classinfo               *classobj;    /* the loaded class object, or NULL */
+       classcache_loader_entry *loaders;
+       classcache_loader_entry *constraints;
+       classcache_class_entry  *next;        /* next class entry for same name   */
+};
+
+struct classcache_loader_entry
+{
+       classloader              *loader;     /* class loader object              */
+       classcache_loader_entry  *next;       /* next loader entry in the list    */
+};
+
+
+/* callback function type for  classcache_foreach_loaded_class */
+
+typedef void (*classcache_foreach_functionptr_t)(classinfo *, void *);
+
+
+/* function prototypes ********************************************************/
+
+/* initialize the loaded class cache */
+bool classcache_init(void);
+void classcache_free(void);
+
+classinfo * classcache_lookup(classloader *initloader,utf *classname);
+classinfo * classcache_lookup_defined(classloader *defloader,utf *classname);
+classinfo * classcache_lookup_defined_or_initiated(classloader *loader,utf *classname);
+
+bool classcache_store_unique(classinfo *cls);
+classinfo * classcache_store(classloader *initloader,classinfo *cls,bool mayfree);
+classinfo * classcache_store_defined(classinfo *cls);
+
+#if defined(ENABLE_VERIFIER)
+bool classcache_add_constraint(classloader *a,classloader *b,utf *classname);
+bool classcache_add_constraints_for_params(classloader *a,classloader *b,
+                                                                                  methodinfo *m);
+#endif
+
+s4 classcache_get_loaded_class_count(void);
+
+void classcache_foreach_loaded_class(classcache_foreach_functionptr_t func,
+                                                                        void *data);
+
+#if defined(ENABLE_JVMTI)
+void classcache_get_loaded_classes(s4 *class_count_ptr,
+                                                                  classinfo ***classes_ptr);
+#endif
+
+#ifndef NDEBUG
+void classcache_debug_dump(FILE *file,utf *only);
+#endif
+       
+#endif /* _CLASSCACHE_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+
diff --git a/src/vmcore/descriptor.c b/src/vmcore/descriptor.c
new file mode 100644 (file)
index 0000000..4b1c0e8
--- /dev/null
@@ -0,0 +1,1361 @@
+/* src/vmcore/descriptor.c - checking and parsing of field / method descriptors
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: descriptor.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "md-abi.h"
+
+#include "mm/memory.h"
+
+#include "vm/exceptions.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
+
+/* constants (private to descriptor.c) ****************************************/
+
+/* initial number of entries for the classrefhash of a descriptor_pool */
+/* (currently the hash is never grown!) */
+#define CLASSREFHASH_INIT_SIZE  64
+
+/* initial number of entries for the descriptorhash of a descriptor_pool */
+/* (currently the hash is never grown!) */
+#define DESCRIPTORHASH_INIT_SIZE  128
+
+/* data structures (private to descriptor.c) **********************************/
+
+typedef struct classref_hash_entry classref_hash_entry;
+typedef struct descriptor_hash_entry descriptor_hash_entry;
+
+/* entry struct for the classrefhash of descriptor_pool */
+struct classref_hash_entry {
+       classref_hash_entry *hashlink;  /* for hash chaining            */
+       utf                 *name;      /* name of the class refered to */
+       u2                   index;     /* index into classref table    */
+};
+
+/* entry struct for the descriptorhash of descriptor_pool */
+struct descriptor_hash_entry {
+       descriptor_hash_entry *hashlink;
+       utf                   *desc;
+       parseddesc             parseddesc;
+       s2                     paramslots; /* number of params, LONG/DOUBLE counted as 2 */
+};
+
+
+/****************************************************************************/
+/* MACROS FOR DESCRIPTOR PARSING (private to descriptor.c)                  */
+/****************************************************************************/
+
+/* SKIP_FIELDDESCRIPTOR:
+ * utf_ptr must point to the first character of a field descriptor.
+ * After the macro call utf_ptr points to the first character after
+ * the field descriptor.
+ *
+ * CAUTION: This macro does not check for an unexpected end of the
+ * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
+ */
+#define SKIP_FIELDDESCRIPTOR(utf_ptr)                                                  \
+       do { while (*(utf_ptr)=='[') (utf_ptr)++;                                       \
+               if (*(utf_ptr)++=='L')                                                                  \
+                       while(*(utf_ptr)++ != ';') /* skip */; } while(0)
+
+/* SKIP_FIELDDESCRIPTOR_SAFE:
+ * utf_ptr must point to the first character of a field descriptor.
+ * After the macro call utf_ptr points to the first character after
+ * the field descriptor.
+ *
+ * Input:
+ *     utf_ptr....points to first char of descriptor
+ *     end_ptr....points to first char after the end of the string
+ *     errorflag..must be initialized (to false) by the caller!
+ * Output:
+ *     utf_ptr....points to first char after the descriptor
+ *     errorflag..set to true if the string ended unexpectedly
+ */
+#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                   \
+       do { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;     \
+               if ((utf_ptr) == (end_ptr))                                                                             \
+                       (errorflag) = true;                                                                                     \
+               else                                                                                                                    \
+                       if (*(utf_ptr)++=='L') {                                                                        \
+                               while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';')    \
+                                       /* skip */;                                                                                     \
+                               if ((utf_ptr)[-1] != ';')                                                               \
+                                       (errorflag) = true; }} while(0)
+
+
+/****************************************************************************/
+/* DEBUG HELPERS                                                            */
+/****************************************************************************/
+
+/*#define DESCRIPTOR_VERBOSE*/
+
+/****************************************************************************/
+/* FUNCTIONS                                                                */
+/****************************************************************************/
+
+/* descriptor_to_basic_type ****************************************************
+
+   Return the basic type to use for a value with this descriptor.
+
+   IN:
+       utf..............descriptor utf string
+
+   OUT:
+       A TYPE_* constant.
+
+   PRECONDITIONS:
+       This function assumes that the descriptor has passed 
+          descriptor_pool_add checks and that it does not start with '('.
+
+*******************************************************************************/
+
+u2 descriptor_to_basic_type(utf *descriptor)
+{
+       assert(descriptor->blength >= 1);
+       
+       switch (descriptor->text[0]) {
+               case 'B': 
+               case 'C':
+               case 'I':
+               case 'S':  
+               case 'Z':  return TYPE_INT;
+               case 'D':  return TYPE_DBL;
+               case 'F':  return TYPE_FLT;
+               case 'J':  return TYPE_LNG;
+               case 'L':
+               case '[':  return TYPE_ADR;
+       }
+                       
+       assert(0);
+
+       return 0; /* keep the compiler happy */
+}
+
+/* descriptor_typesize**** ****************************************************
+
+   Return the size in bytes needed for the given type.
+
+   IN:
+       td..............typedesc describing the type
+
+   OUT:
+       The number of bytes
+
+*******************************************************************************/
+
+u2 descriptor_typesize(typedesc *td)
+{
+       assert(td);
+
+       switch (td->type) {
+               case TYPE_INT: return 4;
+               case TYPE_LNG: return 8;
+               case TYPE_FLT: return 4;
+               case TYPE_DBL: return 8;
+               case TYPE_ADR: return sizeof(voidptr);
+       }
+
+       assert(0);
+
+       return 0; /* keep the compiler happy */
+}
+
+/* name_from_descriptor ********************************************************
+
+   Return the class name indicated by the given descriptor
+   (Internally used helper function)
+
+   IN:
+       c................class containing the descriptor
+       utf_ptr..........first character of descriptor
+       end_ptr..........first character after the end of the string
+       mode.............a combination (binary or) of the following flags:
+
+               (Flags marked with * are the default settings.)
+
+               How to handle "V" descriptors:
+
+                            * DESCRIPTOR_VOID.....handle it like other primitive types
+                   DESCRIPTOR_NOVOID...treat it as an error
+
+               How to deal with extra characters after the end of the
+               descriptor:
+
+                            * DESCRIPTOR_NOCHECKEND...ignore (useful for parameter lists)
+                   DESCRIPTOR_CHECKEND.....treat them as an error
+
+   OUT:
+       *next............if non-NULL, *next is set to the first character after
+                        the descriptor. (Undefined if an error occurs.)
+       *name............set to the utf name of the class
+
+   RETURN VALUE:
+       true.............descriptor parsed successfully
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+#define DESCRIPTOR_VOID          0      /* default */
+#define DESCRIPTOR_NOVOID        0x0040
+#define DESCRIPTOR_NOCHECKEND    0      /* default */
+#define DESCRIPTOR_CHECKEND      0x1000
+
+static bool 
+name_from_descriptor(classinfo *c,
+                                        char *utf_ptr, char *end_ptr,
+                                        char **next, int mode, utf **name)
+{
+       char *start = utf_ptr;
+       bool error = false;
+
+       assert(c);
+       assert(utf_ptr);
+       assert(end_ptr);
+       assert(name);
+       
+       *name = NULL;           
+       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
+
+       if (mode & DESCRIPTOR_CHECKEND)
+               error |= (utf_ptr != end_ptr);
+       
+       if (!error) {
+               if (next) *next = utf_ptr;
+               
+               switch (*start) {
+                 case 'V':
+                         if (mode & DESCRIPTOR_NOVOID)
+                                 break;
+                         /* FALLTHROUGH! */
+                 case 'I':
+                 case 'J':
+                 case 'F':
+                 case 'D':
+                 case 'B':
+                 case 'C':
+                 case 'S':
+                 case 'Z':
+                         return true;
+                         
+                 case 'L':
+                         start++;
+                         utf_ptr--;
+                         /* FALLTHROUGH! */
+                 case '[':
+                         *name = utf_new(start, utf_ptr - start);
+                         return true;
+               }
+       }
+
+       exceptions_throw_classformaterror(c, "Invalid descriptor");
+       return false;
+}
+
+
+/* descriptor_to_typedesc ******************************************************
+   Parse the given type descriptor and fill a typedesc struct
+   (Internally used helper function)
+
+   IN:
+       pool.............the descriptor pool
+          utf_ptr..........points to first character of type descriptor
+          end_pos..........points after last character of the whole descriptor
+
+   OUT:
+       *next............set to next character after type descriptor
+          *d...............filled with parsed information
+
+   RETURN VALUE:
+       true.............parsing succeeded  
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+static bool
+descriptor_to_typedesc(descriptor_pool *pool, char *utf_ptr, char *end_pos,
+                                          char **next, typedesc *td)
+{
+       utf *name;
+       
+       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, next, 0, &name))
+               return false;
+
+       if (name) {
+               /* a reference type */
+               td->type = TYPE_ADR;
+               td->decltype = TYPE_ADR;
+               td->arraydim = 0;
+               for (utf_ptr = name->text; *utf_ptr == '['; ++utf_ptr)
+                       td->arraydim++;
+               td->classref = descriptor_pool_lookup_classref(pool, name);
+
+       } else {
+               /* a primitive type */
+               switch (*utf_ptr) {
+               case 'B': 
+                       td->decltype = PRIMITIVETYPE_BYTE;
+                       td->type = TYPE_INT;
+                       break;
+               case 'C':
+                       td->decltype = PRIMITIVETYPE_CHAR;
+                       td->type = TYPE_INT;
+                       break;
+               case 'S':  
+                       td->decltype = PRIMITIVETYPE_SHORT;
+                       td->type = TYPE_INT;
+                       break;
+               case 'Z':
+                       td->decltype = PRIMITIVETYPE_BOOLEAN;
+                       td->type = TYPE_INT;
+                       break;
+               case 'I':
+                       td->decltype = PRIMITIVETYPE_INT;
+                       td->type = TYPE_INT;
+                       break;
+               case 'D':
+                       td->decltype = PRIMITIVETYPE_DOUBLE;
+                       td->type = TYPE_DBL;
+                       break;
+               case 'F':
+                       td->decltype = PRIMITIVETYPE_FLOAT;
+                       td->type = TYPE_FLT;
+                       break;
+               case 'J':
+                       td->decltype = PRIMITIVETYPE_LONG;
+                       td->type = TYPE_LNG;
+                       break;
+               case 'V':
+                       td->decltype = PRIMITIVETYPE_VOID;
+                       td->type = TYPE_VOID;
+                       break;
+               default:
+                       assert(false);
+               }
+
+               td->arraydim = 0;
+               td->classref = NULL;
+       }
+
+       return true;
+}
+
+
+/* descriptor_pool_new *********************************************************
+   Allocate a new descriptor_pool
+
+   IN:
+       referer..........class for which to create the pool
+
+   RETURN VALUE:
+       a pointer to the new descriptor_pool
+
+*******************************************************************************/
+
+descriptor_pool * 
+descriptor_pool_new(classinfo *referer)
+{
+       descriptor_pool *pool;
+       u4 hashsize;
+       u4 slot;
+
+       pool = DNEW(descriptor_pool);
+       assert(pool);
+
+       pool->referer = referer;
+       pool->fieldcount = 0;
+       pool->methodcount = 0;
+       pool->paramcount = 0;
+       pool->descriptorsize = 0;
+       pool->descriptors = NULL;
+       pool->descriptors_next = NULL;
+       pool->classrefs = NULL;
+       pool->descriptor_kind = NULL;
+       pool->descriptor_kind_next = NULL;
+
+       hashsize = CLASSREFHASH_INIT_SIZE;
+       pool->classrefhash.size = hashsize;
+       pool->classrefhash.entries = 0;
+       pool->classrefhash.ptr = DMNEW(voidptr,hashsize);
+       for (slot=0; slot<hashsize; ++slot)
+               pool->classrefhash.ptr[slot] = NULL;
+
+       hashsize = DESCRIPTORHASH_INIT_SIZE;
+       pool->descriptorhash.size = hashsize;
+       pool->descriptorhash.entries = 0;
+       pool->descriptorhash.ptr = DMNEW(voidptr,hashsize);
+       for (slot=0; slot<hashsize; ++slot)
+               pool->descriptorhash.ptr[slot] = NULL;
+
+       return pool;
+}
+
+
+/* descriptor_pool_add_class ***************************************************
+   Add the given class reference to the pool
+
+   IN:
+       pool.............the descriptor_pool
+          name.............the class reference to add
+
+   RETURN VALUE:
+       true.............reference has been added
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+bool 
+descriptor_pool_add_class(descriptor_pool *pool, utf *name)
+{
+       u4 key,slot;
+       classref_hash_entry *c;
+       
+       assert(pool);
+       assert(name);
+
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_add_class(%p,",(void*)pool);
+       utf_fprint_printable_ascii(stderr,name);fprintf(stderr,")\n");
+#endif
+
+       /* find a place in the hashtable */
+
+       key = utf_hashkey(name->text, name->blength);
+       slot = key & (pool->classrefhash.size - 1);
+       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+
+       while (c) {
+               if (c->name == name)
+                       return true; /* already stored */
+               c = c->hashlink;
+       }
+
+       /* check if the name is a valid classname */
+
+       if (!is_valid_name(name->text,UTF_END(name))) {
+               exceptions_throw_classformaterror(pool->referer, "Invalid class name");
+               return false; /* exception */
+       }
+
+       /* XXX check maximum array dimension */
+       
+       c = DNEW(classref_hash_entry);
+       c->name = name;
+       c->index = pool->classrefhash.entries++;
+       c->hashlink = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+       pool->classrefhash.ptr[slot] = c;
+
+       return true;
+}
+
+
+/* descriptor_pool_add *********************************************************
+   Check the given descriptor and add it to the pool
+
+   IN:
+       pool.............the descriptor_pool
+          desc.............the descriptor to add. Maybe a field or method desc.
+
+   OUT:
+       *paramslots......if non-NULL, set to the number of parameters.
+                           LONG and DOUBLE are counted twice
+
+   RETURN VALUE:
+       true.............descriptor has been added
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+bool 
+descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
+{
+       u4 key,slot;
+       descriptor_hash_entry *d;
+       char *utf_ptr;
+       char *end_pos;
+       utf *name;
+       s4 argcount = 0;
+       
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_add(%p,",(void*)pool);
+       utf_fprint_printable_ascii(stderr,desc);fprintf(stderr,")\n");
+#endif
+
+       assert(pool);
+       assert(desc);
+
+       /* find a place in the hashtable */
+
+       key = utf_hashkey(desc->text, desc->blength);
+       slot = key & (pool->descriptorhash.size - 1);
+       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+
+       /* Save all method descriptors in the hashtable, since the parsed         */
+       /* descriptor may vary between differenf methods (static vs. non-static). */
+
+       utf_ptr = desc->text;
+
+       if (*utf_ptr != '(') {
+               while (d) {
+                       if (d->desc == desc) {
+                               if (paramslots)
+                                       *paramslots = d->paramslots;
+                               return true; /* already stored */
+                       }
+                       d = d->hashlink;
+               }
+       }
+
+       /* add the descriptor to the pool */
+
+       d = DNEW(descriptor_hash_entry);
+       d->desc = desc;
+       d->parseddesc.any = NULL;
+       d->hashlink = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+       pool->descriptorhash.ptr[slot] = d;
+
+       /* now check the descriptor */
+
+       end_pos = UTF_END(desc);
+       
+       if (*utf_ptr == '(') {
+               /* a method descriptor */
+
+               pool->methodcount++;
+               utf_ptr++;
+
+               /* check arguments */
+
+               while ((utf_ptr != end_pos) && (*utf_ptr != ')')) {
+                       pool->paramcount++;
+
+                       /* We cannot count the `this' argument here because
+                        * we don't know if the method is static. */
+
+                       if (*utf_ptr == 'J' || *utf_ptr == 'D')
+                               argcount += 2;
+                       else
+                               argcount++;
+
+                       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, &utf_ptr,
+                                                                     DESCRIPTOR_NOVOID, &name))
+                               return false;
+
+                       if (name)
+                               if (!descriptor_pool_add_class(pool, name))
+                                       return false;
+               }
+
+               if (utf_ptr == end_pos) {
+                       exceptions_throw_classformaterror(pool->referer,
+                                                                                         "Missing ')' in method descriptor");
+                       return false;
+               }
+
+               utf_ptr++; /* skip ')' */
+
+               if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
+                                                                 DESCRIPTOR_CHECKEND, &name))
+                       return false;
+
+               if (name)
+                       if (!descriptor_pool_add_class(pool,name))
+                               return false;
+
+               if (argcount > 255) {
+                       exceptions_throw_classformaterror(pool->referer,
+                                                                                         "Too many arguments in signature");
+                       return false;
+               }
+
+       } else {
+               /* a field descriptor */
+
+               pool->fieldcount++;
+               
+           if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
+                                                         DESCRIPTOR_NOVOID | DESCRIPTOR_CHECKEND,
+                                                                 &name))
+                       return false;
+
+               if (name)
+                       if (!descriptor_pool_add_class(pool,name))
+                               return false;
+       }
+
+       d->paramslots = argcount;
+
+       if (paramslots)
+               *paramslots = argcount;
+
+       return true;
+}
+
+
+/* descriptor_pool_create_classrefs ********************************************
+   Create a table containing all the classrefs which were added to the pool
+
+   IN:
+       pool.............the descriptor_pool
+
+   OUT:
+       *count...........if count is non-NULL, this is set to the number
+                           of classrefs in the table
+
+   RETURN VALUE:
+       a pointer to the constant_classref table
+
+*******************************************************************************/
+
+constant_classref * 
+descriptor_pool_create_classrefs(descriptor_pool *pool, s4 *count)
+{
+       u4 nclasses;
+       u4 slot;
+       classref_hash_entry *c;
+       constant_classref *ref;
+       
+       assert(pool);
+
+       nclasses = pool->classrefhash.entries;
+       pool->classrefs = MNEW(constant_classref,nclasses);
+
+       /* fill the constant_classref structs */
+
+       for (slot = 0; slot < pool->classrefhash.size; ++slot) {
+               c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+               while (c) {
+                       ref = pool->classrefs + c->index;
+                       CLASSREF_INIT(*ref, pool->referer, c->name);
+                       c = c->hashlink;
+               }
+       }
+
+       if (count)
+               *count = nclasses;
+
+       return pool->classrefs;
+}
+
+
+/* descriptor_pool_lookup_classref *********************************************
+   Return the constant_classref for the given class name
+
+   IN:
+       pool.............the descriptor_pool
+          classname........name of the class to look up
+
+   RETURN VALUE:
+       a pointer to the constant_classref, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+constant_classref * 
+descriptor_pool_lookup_classref(descriptor_pool *pool, utf *classname)
+{
+       u4 key,slot;
+       classref_hash_entry *c;
+
+       assert(pool);
+       assert(pool->classrefs);
+       assert(classname);
+
+       key = utf_hashkey(classname->text, classname->blength);
+       slot = key & (pool->classrefhash.size - 1);
+       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+
+       while (c) {
+               if (c->name == classname)
+                       return pool->classrefs + c->index;
+               c = c->hashlink;
+       }
+
+       exceptions_throw_internalerror("Class reference not found in descriptor pool");
+       return NULL;
+}
+
+
+/* descriptor_pool_alloc_parsed_descriptors ************************************
+   Allocate space for the parsed descriptors
+
+   IN:
+       pool.............the descriptor_pool
+
+   NOTE:
+       This function must be called after all descriptors have been added
+          with descriptor_pool_add.
+
+*******************************************************************************/
+
+void 
+descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool)
+{
+       u4 size;
+       
+       assert(pool);
+
+       /* TWISTI: paramcount + 1: we don't know if the method is static or   */
+       /* not, i have no better solution yet.                                */
+
+       size =
+               pool->fieldcount * sizeof(typedesc) +
+               pool->methodcount * (sizeof(methoddesc) - sizeof(typedesc)) +
+               pool->paramcount * sizeof(typedesc) +
+               pool->methodcount * sizeof(typedesc);      /* possible `this' pointer */
+
+       pool->descriptorsize = size;
+       if (size) {
+               pool->descriptors = MNEW(u1, size);
+               pool->descriptors_next = pool->descriptors;
+       }
+
+       size = pool->fieldcount + pool->methodcount;
+       if (size) {
+               pool->descriptor_kind = DMNEW(u1, size);
+               pool->descriptor_kind_next = pool->descriptor_kind;
+       }
+}
+
+
+/* descriptor_pool_parse_field_descriptor **************************************
+   Parse the given field descriptor
+
+   IN:
+       pool.............the descriptor_pool
+          desc.............the field descriptor
+
+   RETURN VALUE:
+       a pointer to the parsed field descriptor, or
+          NULL if an exception has been thrown
+
+   NOTE:
+       descriptor_pool_alloc_parsed_descriptors must be called (once)
+       before this function is used.
+
+*******************************************************************************/
+
+typedesc * 
+descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc)
+{
+       u4 key,slot;
+       descriptor_hash_entry *d;
+       typedesc *td;
+
+       assert(pool);
+       assert(pool->descriptors);
+       assert(pool->descriptors_next);
+
+       /* lookup the descriptor in the hashtable */
+
+       key = utf_hashkey(desc->text, desc->blength);
+       slot = key & (pool->descriptorhash.size - 1);
+       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+
+       while (d) {
+               if (d->desc == desc) {
+                       /* found */
+                       if (d->parseddesc.fd)
+                               return d->parseddesc.fd;
+                       break;
+               }
+               d = d->hashlink;
+       }
+
+       assert(d);
+       
+       if (desc->text[0] == '(') {
+               exceptions_throw_classformaterror(pool->referer,
+                                                                                 "Method descriptor used in field reference");
+               return NULL;
+       }
+
+       td = (typedesc *) pool->descriptors_next;
+       pool->descriptors_next += sizeof(typedesc);
+       
+       if (!descriptor_to_typedesc(pool, desc->text, UTF_END(desc), NULL, td))
+               return NULL;
+
+       *(pool->descriptor_kind_next++) = 'f';
+
+       d->parseddesc.fd = td;
+
+       return td;
+}
+
+
+/* descriptor_pool_parse_method_descriptor *************************************
+   Parse the given method descriptor
+
+   IN:
+       pool.............the descriptor_pool
+       desc.............the method descriptor
+       mflags...........the method flags
+          thisclass........classref to the class containing the method.
+                                               This is ignored if mflags contains ACC_STATIC.
+                                               The classref is stored for inserting the 'this' argument.
+
+   RETURN VALUE:
+       a pointer to the parsed method descriptor, or
+          NULL if an exception has been thrown
+
+   NOTE: 
+       descriptor_pool_alloc_parsed_descriptors must be called
+       (once) before this function is used.
+
+*******************************************************************************/
+
+methoddesc * 
+descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
+                                                                               s4 mflags,constant_classref *thisclass)
+{
+       u4 key, slot;
+       descriptor_hash_entry *d;
+       methoddesc            *md;
+       typedesc              *td;
+       char *utf_ptr;
+       char *end_pos;
+       s2 paramcount = 0;
+       s2 paramslots = 0;
+
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_parse_method_descriptor(%p,%d,%p,",
+                       (void*)pool,(int)mflags,(void*)thisclass);
+       utf_fprint_printable_ascii(stderr,desc); fprintf(stderr,")\n");
+#endif
+
+       assert(pool);
+       assert(pool->descriptors);
+       assert(pool->descriptors_next);
+
+       /* check that it is a method descriptor */
+       
+       if (desc->text[0] != '(') {
+               exceptions_throw_classformaterror(pool->referer,
+                                                                                 "Field descriptor used in method reference");
+               return NULL;
+       }
+
+       /* lookup the descriptor in the hashtable */
+
+       key = utf_hashkey(desc->text, desc->blength);
+       slot = key & (pool->descriptorhash.size - 1);
+       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+
+       /* find an un-parsed descriptor */
+
+       while (d) {
+               if (d->desc == desc)
+                       if (!d->parseddesc.md)
+                               break;
+               d = d->hashlink;
+       }
+
+       assert(d);
+
+       md = (methoddesc *) pool->descriptors_next;
+       pool->descriptors_next += sizeof(methoddesc) - sizeof(typedesc);
+
+       utf_ptr = desc->text + 1; /* skip '(' */
+       end_pos = UTF_END(desc);
+
+       td = md->paramtypes;
+
+       /* count the `this' pointer */
+
+       if ((mflags != ACC_UNDEF) && !(mflags & ACC_STATIC)) {
+               td->type = TYPE_ADR;
+               td->decltype = TYPE_ADR;
+               td->arraydim = 0;
+               td->classref = thisclass;
+
+               td++;
+               pool->descriptors_next += sizeof(typedesc);
+               paramcount++;
+               paramslots++;
+       }
+
+       while (*utf_ptr != ')') {
+               /* parse a parameter type */
+
+               if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, &utf_ptr, td))
+                       return NULL;
+
+               if (IS_2_WORD_TYPE(td->type))
+                       paramslots++;
+               
+               td++;
+               pool->descriptors_next += sizeof(typedesc);
+               paramcount++;
+               paramslots++;
+       }
+       utf_ptr++; /* skip ')' */
+
+       /* Skip possible `this' pointer in paramtypes array to allow a possible   */
+       /* memory move later in parse.                                            */
+       /* We store the thisclass reference, so we can later correctly fill in    */
+       /* the parameter slot of the 'this' argument.                             */
+
+       if (mflags == ACC_UNDEF) {
+               td->classref = thisclass;
+               td++;
+               pool->descriptors_next += sizeof(typedesc);
+       }
+
+       /* parse return type */
+
+       if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, NULL,
+                                                               &(md->returntype)))
+               return NULL;
+
+       md->paramcount = paramcount;
+       md->paramslots = paramslots;
+
+       /* If m != ACC_UNDEF we parse a real loaded method, so do param prealloc. */
+       /* Otherwise we do this in stack analysis.                                */
+
+       if (mflags != ACC_UNDEF) {
+               if (md->paramcount > 0) {
+                       /* allocate memory for params */
+
+                       md->params = MNEW(paramdesc, md->paramcount);
+               }
+               else {
+                       md->params = METHODDESC_NOPARAMS;
+               }
+
+               /* fill the paramdesc */
+               /* md_param_alloc has to be called if md->paramcount == 0,
+                  too, so it can make the reservation for the Linkage Area,
+                  Return Register... */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (!opt_intrp)
+# endif
+                       md_param_alloc(md);
+#endif
+
+       } else {
+               /* params will be allocated later by
+                  descriptor_params_from_paramtypes if necessary */
+
+               md->params = NULL;
+       }
+
+       *(pool->descriptor_kind_next++) = 'm';
+
+       d->parseddesc.md = md;
+
+       return md;
+}
+
+/* descriptor_params_from_paramtypes *******************************************
+   Create the paramdescs for a method descriptor. This function is called
+   when we know whether the method is static or not. This function may only
+   be called once for each methoddesc, and only if md->params == NULL.
+
+   IN:
+       md...............the parsed method descriptor
+                           md->params MUST be NULL.
+          mflags...........the ACC_* access flags of the method. Only the
+                           ACC_STATIC bit is checked.
+                                               The value ACC_UNDEF is NOT allowed.
+
+   RETURN VALUE:
+       true.............the paramdescs were created successfully
+          false............an exception has been thrown
+
+   POSTCONDITION:
+       md->parms != NULL
+
+*******************************************************************************/
+
+bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
+{
+       typedesc *td;
+
+       assert(md);
+       assert(md->params == NULL);
+       assert(mflags != ACC_UNDEF);
+
+       td = md->paramtypes;
+
+       /* check for `this' pointer */
+
+       if (!(mflags & ACC_STATIC)) {
+               constant_classref *thisclass;
+
+               /* fetch class reference from reserved param slot */
+               thisclass = td[md->paramcount].classref;
+               assert(thisclass);
+
+               if (md->paramcount > 0) {
+                       /* shift param types by 1 argument */
+                       MMOVE(td + 1, td, typedesc, md->paramcount);
+               }
+
+               /* fill in first argument `this' */
+
+               td->type = TYPE_ADR;
+               td->decltype = TYPE_ADR;
+               td->arraydim = 0;
+               td->classref = thisclass;
+
+               md->paramcount++;
+               md->paramslots++;
+       }
+
+       /* if the method has params, process them */
+
+       if (md->paramcount > 0) {
+               /* allocate memory for params */
+
+               md->params = MNEW(paramdesc, md->paramcount);
+
+       } else {
+               md->params = METHODDESC_NOPARAMS;
+       }
+
+       /* fill the paramdesc */
+       /* md_param_alloc has to be called if md->paramcount == 0, too, so
+          it can make the reservation for the Linkage Area, Return
+          Register.. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (!opt_intrp)
+# endif
+               md_param_alloc(md);
+#endif
+
+       return true;
+}
+
+
+/* descriptor_pool_get_parsed_descriptors **************************************
+   Return a pointer to the block of parsed descriptors
+
+   IN:
+       pool.............the descriptor_pool
+
+   OUT:
+          *size............if size is non-NULL, this is set to the size of the
+                           parsed descriptor block (in u1)
+
+   RETURN VALUE:
+       a pointer to the block of parsed descriptors
+
+   NOTE:
+       descriptor_pool_alloc_parsed_descriptors must be called (once)
+       before this function is used.
+
+*******************************************************************************/
+
+void * 
+descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size)
+{
+       assert(pool);
+       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
+       
+       if (size)
+               *size = pool->descriptorsize;
+
+       return pool->descriptors;
+}
+
+
+/* descriptor_pool_get_sizes ***************************************************
+   Get the sizes of the class reference table and the parsed descriptors
+
+   IN:
+       pool.............the descriptor_pool
+
+   OUT:
+       *classrefsize....set to size of the class reference table
+          *descsize........set to size of the parsed descriptors
+
+   NOTE:
+       This function may only be called after both
+              descriptor_pool_create_classrefs, and
+                  descriptor_pool_alloc_parsed_descriptors
+          have been called.
+
+*******************************************************************************/
+
+void 
+descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize, u4 *descsize)
+{
+       assert(pool);
+       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
+       assert(pool->classrefs);
+       assert(classrefsize);
+       assert(descsize);
+
+       *classrefsize = pool->classrefhash.entries * sizeof(constant_classref);
+       *descsize = pool->descriptorsize;
+}
+
+
+/****************************************************************************/
+/* DEBUG HELPERS                                                            */
+/****************************************************************************/
+
+#ifndef NDEBUG
+/* descriptor_debug_print_typedesc *********************************************
+   Print the given typedesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parsed descriptor
+
+*******************************************************************************/
+
+void 
+descriptor_debug_print_typedesc(FILE *file,typedesc *d)
+{
+       int ch;
+
+       if (!d) {
+               fprintf(file,"(typedesc *)NULL");
+               return;
+       }
+       
+       if (d->type == TYPE_ADR) {
+               if (d->classref)
+                       utf_fprint_printable_ascii(file,d->classref->name);
+               else
+                       fprintf(file,"<class=NULL>");
+       }
+       else {
+               switch (d->decltype) {
+                       case PRIMITIVETYPE_INT    : ch='I'; break;
+                       case PRIMITIVETYPE_CHAR   : ch='C'; break;
+                       case PRIMITIVETYPE_BYTE   : ch='B'; break;
+                       case PRIMITIVETYPE_SHORT  : ch='S'; break;
+                       case PRIMITIVETYPE_BOOLEAN: ch='Z'; break;
+                       case PRIMITIVETYPE_LONG   : ch='J'; break;
+                       case PRIMITIVETYPE_FLOAT  : ch='F'; break;
+                       case PRIMITIVETYPE_DOUBLE : ch='D'; break;
+                       case PRIMITIVETYPE_VOID   : ch='V'; break;
+                       default                   : ch='!';
+               }
+               fputc(ch,file);
+       }
+       if (d->arraydim)
+               fprintf(file,"[%d]",d->arraydim);
+}
+
+/* descriptor_debug_print_paramdesc ********************************************
+   Print the given paramdesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parameter descriptor
+
+*******************************************************************************/
+
+void
+descriptor_debug_print_paramdesc(FILE *file,paramdesc *d)
+{
+       if (!d) {
+               fprintf(file,"(paramdesc *)NULL");
+               return;
+       }
+       
+       if (d->inmemory) {
+               fprintf(file,"<m%d>",d->regoff);
+       }
+       else {
+               fprintf(file,"<r%d>",d->regoff);
+       }
+}
+
+/* descriptor_debug_print_methoddesc *******************************************
+   Print the given methoddesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parsed descriptor
+
+*******************************************************************************/
+
+void 
+descriptor_debug_print_methoddesc(FILE *file,methoddesc *d)
+{
+       int i;
+       
+       if (!d) {
+               fprintf(file,"(methoddesc *)NULL");
+               return;
+       }
+       
+       fputc('(',file);
+       for (i=0; i<d->paramcount; ++i) {
+               if (i)
+                       fputc(',',file);
+               descriptor_debug_print_typedesc(file,d->paramtypes + i);
+               if (d->params) {
+                       descriptor_debug_print_paramdesc(file,d->params + i);
+               }
+       }
+       if (d->params == METHODDESC_NOPARAMS)
+               fputs("<NOPARAMS>",file);
+       fputc(')',file);
+       descriptor_debug_print_typedesc(file,&(d->returntype));
+}
+
+/* descriptor_pool_debug_dump **************************************************
+   Print the state of the descriptor_pool to the given stream
+
+   IN:
+       pool.............the descriptor_pool
+          file.............stream to print to
+
+*******************************************************************************/
+
+void 
+descriptor_pool_debug_dump(descriptor_pool *pool,FILE *file)
+{
+       u4 slot;
+       u1 *pos;
+       u1 *kind;
+       u4 size;
+       
+       fprintf(file,"======[descriptor_pool for ");
+       utf_fprint_printable_ascii(file,pool->referer->name);
+       fprintf(file,"]======\n");
+
+       fprintf(file,"fieldcount:     %d\n",pool->fieldcount);
+       fprintf(file,"methodcount:    %d\n",pool->methodcount);
+       fprintf(file,"paramcount:     %d\n",pool->paramcount);
+       fprintf(file,"classrefcount:  %d\n",pool->classrefhash.entries);
+       fprintf(file,"descriptorsize: %d bytes\n",pool->descriptorsize);
+       fprintf(file,"classrefsize:   %d bytes\n",
+                       (int)(pool->classrefhash.entries * sizeof(constant_classref)));
+
+       fprintf(file,"class references:\n");
+       for (slot=0; slot<pool->classrefhash.size; ++slot) {
+               classref_hash_entry *c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+               while (c) {
+                       fprintf(file,"    %4d: ",c->index);
+                       utf_fprint_printable_ascii(file,c->name);
+                       fprintf(file,"\n");
+                       c = c->hashlink;
+               }
+       }
+
+       fprintf(file,"hashed descriptors:\n");
+       for (slot=0; slot<pool->descriptorhash.size; ++slot) {
+               descriptor_hash_entry *c = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+               while (c) {
+                       fprintf(file,"    %p: ",c->parseddesc.any);
+                       utf_fprint_printable_ascii(file,c->desc);
+                       fprintf(file,"\n");
+                       c = c->hashlink;
+               }
+       }
+
+       fprintf(file,"descriptors:\n");
+       if (pool->descriptors) {
+               pos = pool->descriptors;
+               size = pool->descriptors_next - pool->descriptors;
+               fprintf(file,"    size: %d bytes\n",size);
+               
+               if (pool->descriptor_kind) {
+                       kind = pool->descriptor_kind;
+
+                       while (pos < (pool->descriptors + size)) {
+                               fprintf(file,"    %p: ",pos);
+                               switch (*kind++) {
+                                       case 'f':
+                                               descriptor_debug_print_typedesc(file,(typedesc*)pos);
+                                               pos += sizeof(typedesc);
+                                               break;
+                                       case 'm':
+                                               descriptor_debug_print_methoddesc(file,(methoddesc*)pos);
+                                               pos += ((methoddesc*)pos)->paramcount * sizeof(typedesc);
+                                               pos += sizeof(methoddesc) - sizeof(typedesc);
+                                               break;
+                                       default:
+                                               fprintf(file,"INVALID KIND");
+                               }
+                               fputc('\n',file);
+                       }
+               }
+               else {
+                       while (size >= sizeof(voidptr)) {
+                               fprintf(file,"    %p\n",*((voidptr*)pos));
+                               pos += sizeof(voidptr);
+                               size -= sizeof(voidptr);
+                       }
+               }
+       }
+
+       fprintf(file,"==========================================================\n");
+}
+#endif /* !defined(NDEBUG) */
+
+/*
+ * 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:
+ */
+
diff --git a/src/vmcore/descriptor.h b/src/vmcore/descriptor.h
new file mode 100644 (file)
index 0000000..5ea3e2e
--- /dev/null
@@ -0,0 +1,199 @@
+/* src/vmcore/descriptor.h - checking and parsing of field / method descriptors
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: descriptor.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _DESCRIPTOR_H
+#define _DESCRIPTOR_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct descriptor_pool descriptor_pool;
+typedef struct typedesc        typedesc;
+typedef struct paramdesc       paramdesc;
+typedef struct methoddesc      methoddesc;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+#include "vmcore/utf8.h"
+
+
+/* data structures ************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* Descriptor Pools                                                           */
+/*                                                                            */
+/* A descriptor_pool is a temporary data structure used during loading of     */
+/* a class. The descriptor_pool is used to allocate the table of              */
+/* constant_classrefs the class uses, and for parsing the field and method    */
+/* descriptors which occurr within the class. The inner workings of           */
+/* descriptor_pool are not important for outside code.                        */
+/*                                                                            */
+/* You use a descriptor_pool as follows:                                      */
+/*                                                                            */
+/* 1. create one with descriptor_pool_new                                     */
+/* 2. add all explicit class references with descriptor_pool_add_class        */
+/* 3. add all field/method descriptors with descriptor_pool_add               */
+/* 4. call descriptor_pool_create_classrefs                                   */
+/*    You can now lookup classrefs with descriptor_pool_lookup_classref       */
+/* 5. call descriptor_pool_alloc_parsed_descriptors                           */
+/* 6. for each field descriptor call descriptor_pool_parse_field_descriptor   */
+/*    for each method descriptor call descriptor_pool_parse_method_descriptor */
+/* 7. call descriptor_pool_get_parsed_descriptors                             */
+/*                                                                            */
+/* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
+/*            memory which can be thrown away when the steps above have been  */
+/*            done.                                                           */
+/*----------------------------------------------------------------------------*/
+
+struct descriptor_pool {
+       classinfo         *referer;
+       u4                 fieldcount;
+       u4                 methodcount;
+       u4                 paramcount;
+       u4                 descriptorsize;
+       u1                *descriptors;
+       u1                *descriptors_next;
+       hashtable          descriptorhash;
+       constant_classref *classrefs;
+       hashtable          classrefhash;
+       u1                *descriptor_kind;       /* useful for debugging */
+       u1                *descriptor_kind_next;  /* useful for debugging */
+};
+
+
+/* data structures for parsed field/method descriptors ************************/
+
+struct typedesc {
+       constant_classref *classref;   /* class reference for TYPE_ADR types      */
+       u1                 type;       /* TYPE_??? constant [1]                   */
+       u1                 decltype;   /* (PRIMITIVE)TYPE_??? constant [2]        */
+       u1                 arraydim;   /* array dimension (0 if no array)         */
+};
+
+/* [1]...the type field contains the basic type used within the VM. So ints,  */
+/*       shorts, chars, bytes, booleans all have TYPE_INT.                    */
+/* [2]...the decltype field contains the declared type.                       */
+/*       So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR.         */
+/*       For non-primitive types decltype is TYPE_ADR.                        */
+
+struct paramdesc {
+#if defined(__MIPS__)
+       u1   type;                  /* TYPE_??? of the register allocated         */
+#endif
+       bool inmemory;              /* argument in register or on stack           */
+       s4   regoff;                /* register index or stack offset             */
+};
+
+struct methoddesc {
+       s2         paramcount;      /* number of parameters                       */
+       s2         paramslots;      /* like above but LONG,DOUBLE count twice     */
+       s4         argintreguse;    /* number of used integer argument registers  */
+       s4         argfltreguse;    /* number of used float argument registers    */
+       s4         memuse;          /* number of stack slots used                 */
+       paramdesc *params;          /* allocated parameter descriptions [3]       */
+       typedesc   returntype;      /* parsed descriptor of the return type       */
+       typedesc   paramtypes[1];   /* parameter types, variable length!          */
+};
+
+/* [3]...If params is NULL, the parameter descriptions have not yet been      */
+/*       allocated. In this case ___the possible 'this' pointer of the method */
+/*       is NOT counted in paramcount/paramslots and it is NOT included in    */
+/*       the paramtypes array___.                                             */
+/*       If params != NULL, the parameter descriptions have been              */
+/*       allocated, and the 'this' pointer of the method, if any, IS included.*/
+/*       In case the method has no parameters at all, the special value       */
+/*       METHODDESC_NO_PARAMS is used (see below).                            */
+
+/* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field    */
+/* indicating that the method is a static method without any parameters.      */
+/* This special value must be != NULL and it may only be set if               */
+/* md->paramcount == 0.                                                       */
+
+#define METHODDESC_NOPARAMS  ((paramdesc*)1)
+
+/* function prototypes ********************************************************/
+
+descriptor_pool * descriptor_pool_new(classinfo *referer);
+
+bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
+bool descriptor_pool_add(descriptor_pool *pool,utf *desc,int *paramslots);
+
+u2 descriptor_to_basic_type(utf *desc);
+u2 descriptor_typesize(typedesc *td);
+
+constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
+                                                                                                        s4 *count);
+constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
+
+void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
+
+typedesc *descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc);
+methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags,
+                                                                                                       constant_classref *thisclass);
+
+bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags);
+
+void *descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size);
+void descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize,
+                                                          u4 *descsize);
+
+#ifndef NDEBUG
+void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
+void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
+void descriptor_debug_print_paramdesc(FILE *file,paramdesc *d);
+void descriptor_pool_debug_dump(descriptor_pool *pool, FILE *file);
+#endif /* !defined(NDEBUG) */
+
+/* machine dependent descriptor function */
+void md_param_alloc(methoddesc *md);
+
+#endif /* _DESCRIPTOR_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/field.c b/src/vmcore/field.c
new file mode 100644 (file)
index 0000000..01b5f72
--- /dev/null
@@ -0,0 +1,175 @@
+/* src/vmcore/field.c - field functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: field.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "vmcore/field.h"
+#include "vmcore/references.h"
+#include "vmcore/utf8.h"
+
+
+/* field_free ******************************************************************
+
+   Frees a fields' resources.
+
+*******************************************************************************/
+
+void field_free(fieldinfo *f)
+{
+       /* empty */
+}
+
+
+/* field_printflags ************************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_printflags(fieldinfo *f)
+{
+       if (f == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (f->flags & ACC_PUBLIC)       printf(" PUBLIC");
+       if (f->flags & ACC_PRIVATE)      printf(" PRIVATE");
+       if (f->flags & ACC_PROTECTED)    printf(" PROTECTED");
+       if (f->flags & ACC_STATIC)       printf(" STATIC");
+       if (f->flags & ACC_FINAL)        printf(" FINAL");
+       if (f->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+       if (f->flags & ACC_VOLATILE)     printf(" VOLATILE");
+       if (f->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
+       if (f->flags & ACC_NATIVE)       printf(" NATIVE");
+       if (f->flags & ACC_INTERFACE)    printf(" INTERFACE");
+       if (f->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
+}
+#endif
+
+
+/* field_print *****************************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_print(fieldinfo *f)
+{
+       if (f == NULL) {
+               printf("(fieldinfo*)NULL");
+               return;
+       }
+
+       utf_display_printable_ascii_classname(f->class->name);
+       printf(".");
+       utf_display_printable_ascii(f->name);
+       printf(" ");
+       utf_display_printable_ascii(f->descriptor);     
+
+       field_printflags(f);
+}
+#endif
+
+
+/* field_println ***************************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_println(fieldinfo *f)
+{
+       field_print(f);
+       printf("\n");
+}
+#endif
+
+/* field_fieldref_print ********************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_fieldref_print(constant_FMIref *fr)
+{
+       if (fr == NULL) {
+               printf("(constant_FMIref *)NULL");
+               return;
+       }
+
+       if (IS_FMIREF_RESOLVED(fr)) {
+               printf("<field> ");
+               field_print(fr->p.field);
+       }
+       else {
+               printf("<fieldref> ");
+               utf_display_printable_ascii_classname(fr->p.classref->name);
+               printf(".");
+               utf_display_printable_ascii(fr->name);
+               printf(" ");
+               utf_display_printable_ascii(fr->descriptor);
+       }
+}
+#endif
+
+/* field_fieldref_println ******************************************************
+
+   (debugging only)
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void field_fieldref_println(constant_FMIref *fr)
+{
+       field_fieldref_print(fr);
+       printf("\n");
+}
+#endif
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/field.h b/src/vmcore/field.h
new file mode 100644 (file)
index 0000000..dcbd1ee
--- /dev/null
@@ -0,0 +1,99 @@
+/* src/vmcore/field.h - field functions header
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: field.h 7246 2007-01-29 18:49:05Z twisti $
+*/
+
+
+#ifndef _FIELD_H
+#define _FIELD_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct fieldinfo fieldinfo; 
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/class.h"
+#include "vmcore/references.h"
+#include "vmcore/utf8.h"
+
+
+/* fieldinfo ******************************************************************/
+
+struct fieldinfo {           /* field of a class                                 */
+
+       /* CAUTION: The first field must be a pointer that is never the same      */
+       /*          value as CLASSREF_PSEUDO_VFTBL! This is used to check whether */
+       /*          a constant_FMIref has been resolved.                          */
+
+       classinfo *class;     /* needed by typechecker. Could be optimized        */
+                             /* away by using constant_FMIref instead of         */
+                             /* fieldinfo throughout the compiler.               */
+
+       s4         flags;     /* ACC flags                                        */
+       s4         type;      /* basic data type                                  */
+       utf       *name;      /* name of field                                    */
+       utf       *descriptor;/* JavaVM descriptor string of field                */
+       utf       *signature; /* Signature attribute string                       */
+       typedesc  *parseddesc;/* parsed descriptor                                */
+
+       s4         offset;    /* offset from start of object (instance variables) */
+
+       imm_union  value;     /* storage for static values (class variables)      */
+};
+
+
+/* function prototypes ********************************************************/
+
+void field_free(fieldinfo *f);
+
+#if !defined(NDEBUG)
+void field_printflags(fieldinfo *f);
+void field_print(fieldinfo *f);
+void field_println(fieldinfo *f);
+void field_fieldref_print(constant_FMIref *fr);
+void field_fieldref_println(constant_FMIref *fr);
+#endif
+
+#endif /* _FIELD_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:
+ */
diff --git a/src/vmcore/linker.c b/src/vmcore/linker.c
new file mode 100644 (file)
index 0000000..91ea0d7
--- /dev/null
@@ -0,0 +1,1399 @@
+/* src/vmcore/linker.c - class linker functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: linker.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+#include "native/native.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#else
+# include "threads/none/lock.h"
+#endif
+
+#include "toolbox/logging.h"
+
+#include "vm/access.h"
+#include "vm/exceptions.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+
+#include "vmcore/class.h"
+#include "vmcore/classcache.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+#include "vmcore/rt-timing.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+extern bool inline_debug_log;
+#define INLINELOG(code)  do { if (inline_debug_log) { code } } while (0)
+#else
+#define INLINELOG(code)
+#endif
+
+
+/* global variables ***********************************************************/
+
+static s4 interfaceindex;       /* sequential numbering of interfaces         */
+static s4 classvalue;
+
+
+/* primitivetype_table *********************************************************
+
+   Structure for primitive classes: contains the class for wrapping
+   the primitive type, the primitive class, the name of the class for
+   wrapping, the one character type signature and the name of the
+   primitive class.
+   CAUTION: Don't change the order of the types. This table is indexed
+   by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
+
+*******************************************************************************/
+
+primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
+       { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
+       { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
+       { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
+       { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
+       { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
+       { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
+       { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
+       { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
+       { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
+       { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
+#if defined(ENABLE_JAVASE)
+       { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }
+#else
+       { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
+#endif
+};
+
+
+/* private functions **********************************************************/
+
+static bool link_primitivetype_table(void);
+static classinfo *link_class_intern(classinfo *c);
+static arraydescriptor *link_array(classinfo *c);
+static void linker_compute_class_values(classinfo *c);
+static void linker_compute_subclasses(classinfo *c);
+static bool linker_addinterface(classinfo *c, classinfo *ic);
+static s4 class_highestinterface(classinfo *c);
+
+
+/* linker_init *****************************************************************
+
+   Initializes the linker subsystem.
+
+*******************************************************************************/
+
+bool linker_init(void)
+{
+       /* reset interface index */
+
+       interfaceindex = 0;
+
+       /* link java.lang.Class as first class of the system, because we
+       need it's vftbl for all other classes so we can use a class as
+       object */
+
+       if (!link_class(class_java_lang_Class))
+               return false;
+
+       /* now set the header.vftbl of all classes which were created
+       before java.lang.Class was linked */
+
+       class_postset_header_vftbl();
+
+
+       /* link important system classes */
+
+       if (!link_class(class_java_lang_Object))
+               return false;
+
+       if (!link_class(class_java_lang_String))
+               return false;
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_Cloneable))
+               return false;
+
+       if (!link_class(class_java_io_Serializable))
+               return false;
+#endif
+
+
+       /* link classes for wrapping primitive types */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_Void))
+               return false;
+#endif
+
+       if (!link_class(class_java_lang_Boolean))
+               return false;
+
+       if (!link_class(class_java_lang_Byte))
+               return false;
+
+       if (!link_class(class_java_lang_Character))
+               return false;
+
+       if (!link_class(class_java_lang_Short))
+               return false;
+
+       if (!link_class(class_java_lang_Integer))
+               return false;
+
+       if (!link_class(class_java_lang_Long))
+               return false;
+
+       if (!link_class(class_java_lang_Float))
+               return false;
+
+       if (!link_class(class_java_lang_Double))
+               return false;
+
+
+       /* load some other important classes */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_ClassLoader))
+               return false;
+
+       if (!link_class(class_java_lang_SecurityManager))
+               return false;
+#endif
+
+       if (!link_class(class_java_lang_System))
+               return false;
+
+       if (!link_class(class_java_lang_Thread))
+               return false;
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_ThreadGroup))
+               return false;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+       if (!link_class(class_java_lang_VMSystem))
+               return false;
+
+       if (!link_class(class_java_lang_VMThread))
+               return false;
+#endif
+
+
+       /* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_StackTraceElement))
+               return false;
+
+       if (!link_class(class_java_lang_reflect_Constructor))
+               return false;
+
+       if (!link_class(class_java_lang_reflect_Field))
+               return false;
+
+       if (!link_class(class_java_lang_reflect_Method))
+               return false;
+
+       if (!link_class(class_java_security_PrivilegedAction))
+               return false;
+
+       if (!link_class(class_java_util_Vector))
+               return false;
+
+       if (!link_class(arrayclass_java_lang_Object))
+               return false;
+#endif
+
+
+       /* create pseudo classes used by the typechecker */
+
+    /* pseudo class for Arraystubs (extends java.lang.Object) */
+
+       pseudo_class_Arraystub =
+               class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
+       pseudo_class_Arraystub->state            |= CLASS_LOADED;
+       pseudo_class_Arraystub->super.cls         = class_java_lang_Object;
+
+#if defined(ENABLE_JAVASE)
+       pseudo_class_Arraystub->interfacescount   = 2;
+       pseudo_class_Arraystub->interfaces        = MNEW(classref_or_classinfo, 2);
+       pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
+       pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+       pseudo_class_Arraystub->interfacescount   = 0;
+       pseudo_class_Arraystub->interfaces        = NULL;
+#endif
+
+       if (!classcache_store_unique(pseudo_class_Arraystub)) {
+               log_text("could not cache pseudo_class_Arraystub");
+               assert(0);
+       }
+
+       if (!link_class(pseudo_class_Arraystub))
+               return false;
+
+       /* pseudo class representing the null type */
+
+       pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
+       pseudo_class_Null->state |= CLASS_LOADED;
+       pseudo_class_Null->super.cls = class_java_lang_Object;
+
+       if (!classcache_store_unique(pseudo_class_Null))
+               vm_abort("linker_init: could not cache pseudo_class_Null");
+
+       if (!link_class(pseudo_class_Null))
+               return false;
+
+       /* pseudo class representing new uninitialized objects */
+    
+       pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
+       pseudo_class_New->state |= CLASS_LOADED;
+       pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
+       pseudo_class_New->super.cls = class_java_lang_Object;
+
+       if (!classcache_store_unique(pseudo_class_New))
+               vm_abort("linker_init: could not cache pseudo_class_New");
+
+       /* create classes representing primitive types */
+
+       if (!link_primitivetype_table())
+               return false;
+
+
+       /* Correct vftbl-entries (retarded loading and linking of class
+          java/lang/String). */
+
+       stringtable_update();
+
+       return true;
+}
+
+
+/* link_primitivetype_table ****************************************************
+
+   Create classes representing primitive types.
+
+*******************************************************************************/
+
+static bool link_primitivetype_table(void)
+{  
+       classinfo *c;
+       utf       *u;
+       s4         i;
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
+               /* skip dummies */
+
+               if (!primitivetype_table[i].name)
+                       continue;
+               
+               /* create primitive class */
+
+               c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
+
+               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
+               
+               /* prevent loader from loading primitive class */
+
+               c->state |= CLASS_LOADED;
+
+               /* INFO: don't put primitive classes into the classcache */
+
+               if (!link_class(c))
+                       return false;
+
+               primitivetype_table[i].class_primitive = c;
+
+               /* create class for wrapping the primitive type */
+
+               u = utf_new_char(primitivetype_table[i].wrapname);
+
+               if (!(c = load_class_bootstrap(u)))
+                       return false;
+
+               primitivetype_table[i].class_wrap = c;
+
+               /* create the primitive array class */
+
+               if (primitivetype_table[i].arrayname) {
+                       u = utf_new_char(primitivetype_table[i].arrayname);
+                       c = class_create_classinfo(u);
+                       c = load_newly_created_array(c, NULL);
+                       if (c == NULL)
+                               return false;
+
+                       primitivetype_table[i].arrayclass = c;
+
+                       assert(c->state & CLASS_LOADED);
+
+                       if (!(c->state & CLASS_LINKED))
+                               if (!link_class(c))
+                                       return false;
+
+                       primitivetype_table[i].arrayvftbl = c->vftbl;
+               }
+       }
+
+       return true;
+}
+
+
+/* link_class ******************************************************************
+
+   Wrapper function for link_class_intern to ease monitor enter/exit
+   and exception handling.
+
+*******************************************************************************/
+
+classinfo *link_class(classinfo *c)
+{
+       classinfo *r;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       if (c == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       LOCK_MONITOR_ENTER(c);
+
+       /* maybe the class is already linked */
+
+       if (c->state & CLASS_LINKED) {
+               LOCK_MONITOR_EXIT(c);
+
+               return c;
+       }
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getcompilingtime)
+               compilingtime_stop();
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* call the internal function */
+
+       r = link_class_intern(c);
+
+       /* if return value is NULL, we had a problem and the class is not linked */
+
+       if (!r)
+               c->state &= ~CLASS_LINKING;
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+
+       if (opt_getcompilingtime)
+               compilingtime_start();
+#endif
+
+       LOCK_MONITOR_EXIT(c);
+
+       RT_TIMING_GET_TIME(time_end);
+
+       RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
+
+       return r;
+}
+
+
+/* linker_overwrite_method *****************************************************
+
+   Overwrite a method with another one, update method flags and check
+   assumptions.
+
+   IN:
+      mg................the general method being overwritten
+         ms................the overwriting (more specialized) method
+         wl................worklist where to add invalidated methods
+
+   RETURN VALUE:
+      true..............everything ok
+         false.............an exception has been thrown
+
+*******************************************************************************/
+
+static bool linker_overwrite_method(methodinfo *mg,
+                                                                       methodinfo *ms,
+                                                                       method_worklist **wl)
+{
+       classinfo *cg;
+       classinfo *cs;
+
+       cg = mg->class;
+       cs = ms->class;
+
+       /* overriding a final method is illegal */
+
+       if (mg->flags & ACC_FINAL) {
+               exceptions_throw_verifyerror(mg, "Overriding final method");
+               return false;
+       }
+
+       /* method ms overwrites method mg */
+
+#if defined(ENABLE_VERIFIER)
+       /* Add loading constraints (for the more general types of method mg). */
+       /* Not for <init>, as it is not invoked virtually.                    */
+
+       if ((ms->name != utf_init)
+                       && !classcache_add_constraints_for_params(
+                               cs->classloader, cg->classloader, mg))
+       {
+               return false;
+       }
+#endif
+
+       /* inherit the vftbl index, and record the overwriting */
+
+       ms->vftblindex = mg->vftblindex;
+       ms->overwrites = mg;
+
+       /* update flags and check assumptions */
+       /* <init> methods are a special case, as they are never dispatched dynamically */
+
+       if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
+               do {
+                       if (mg->flags & ACC_METHOD_IMPLEMENTED) {
+                               /* this adds another implementation */
+
+                               mg->flags &= ~ACC_METHOD_MONOMORPHIC;
+
+                               INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
+
+                               method_break_assumption_monomorphic(mg, wl);
+                       }
+                       else {
+                               /* this is the first implementation */
+
+                               mg->flags |= ACC_METHOD_IMPLEMENTED;
+
+                               INLINELOG( printf("becomes implemented: "); method_println(mg); );
+                       }
+
+                       ms = mg;
+                       mg = mg->overwrites;
+               } while (mg != NULL);
+       }
+
+       return true;
+}
+
+
+/* link_class_intern ***********************************************************
+
+   Tries to link a class. The function calculates the length in bytes
+   that an instance of this class requires as well as the VTBL for
+   methods and interface methods.
+       
+*******************************************************************************/
+
+static classinfo *link_class_intern(classinfo *c)
+{
+       classinfo *super;             /* super class                              */
+       classinfo *tc;                /* temporary class variable                 */
+       s4 supervftbllength;          /* vftbllegnth of super class               */
+       s4 vftbllength;               /* vftbllength of current class             */
+       s4 interfacetablelength;      /* interface table length                   */
+       vftbl_t *v;                   /* vftbl of current class                   */
+       s4 i;                         /* interface/method/field counter           */
+       arraydescriptor *arraydesc;   /* descriptor for array classes             */
+       method_worklist *worklist;    /* worklist for recompilation               */
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_resolving, time_compute_vftbl,
+                                       time_abstract, time_compute_iftbl, time_fill_vftbl,
+                                       time_offsets, time_fill_iftbl, time_finalizer,
+                                       time_subclasses;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       /* the class is already linked */
+
+       if (c->state & CLASS_LINKED)
+               return c;
+
+#if !defined(NDEBUG)
+       if (linkverbose)
+               log_message_class("Linking class: ", c);
+#endif
+
+       /* the class must be loaded */
+
+       /* XXX should this be a specific exception? */
+       assert(c->state & CLASS_LOADED);
+
+       /* cache the self-reference of this class                          */
+       /* we do this for cases where the defining loader of the class     */
+       /* has not yet been recorded as an initiating loader for the class */
+       /* this is needed so subsequent code can assume that self-refs     */
+       /* will always resolve lazily                                      */
+       /* No need to do it for the bootloader - it is always registered   */
+       /* as initiating loader for the classes it loads.                  */
+       if (c->classloader)
+               classcache_store(c->classloader,c,false);
+
+       /* this class is currently linking */
+
+       c->state |= CLASS_LINKING;
+
+       arraydesc = NULL;
+       worklist = NULL;
+
+       /* check interfaces */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               /* resolve this super interface */
+
+               if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
+                                                                                  true, false, &tc))
+                       return NULL;
+
+               c->interfaces[i].cls = tc;
+               
+               /* detect circularity */
+
+               if (tc == c) {
+                       exceptions_throw_classcircularityerror(c);
+                       return NULL;
+               }
+
+               assert(tc->state & CLASS_LOADED);
+
+               if (!(tc->flags & ACC_INTERFACE)) {
+                       exceptions_throw_incompatibleclasschangeerror(tc,
+                                                                                                                 "Implementing class");
+                       return NULL;
+               }
+
+               if (!(tc->state & CLASS_LINKED))
+                       if (!link_class(tc))
+                               return NULL;
+       }
+       
+       /* check super class */
+
+       super = NULL;
+
+       if (c->super.any == NULL) {                     /* class java.lang.Object */
+               c->index = 0;
+               c->instancesize = sizeof(java_objectheader);
+               
+               vftbllength = supervftbllength = 0;
+
+               c->finalizer = NULL;
+
+       } else {
+               /* resolve super class */
+
+               if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
+                                                                                  &super))
+                       return NULL;
+               c->super.cls = super;
+               
+               /* detect circularity */
+
+               if (super == c) {
+                       exceptions_throw_classcircularityerror(c);
+                       return NULL;
+               }
+
+               assert(super->state & CLASS_LOADED);
+
+               if (super->flags & ACC_INTERFACE) {
+                       /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
+                       log_text("Interface specified as super class");
+                       assert(0);
+               }
+
+               /* Don't allow extending final classes */
+
+               if (super->flags & ACC_FINAL) {
+                       exceptions_throw_verifyerror(NULL,
+                                                                                "Cannot inherit from final class");
+                       return NULL;
+               }
+
+               /* link the superclass if necessary */
+               
+               if (!(super->state & CLASS_LINKED))
+                       if (!link_class(super))
+                               return NULL;
+
+               /* OR the ACC_CLASS_HAS_POINTERS flag */
+
+               c->flags |= (super->flags & ACC_CLASS_HAS_POINTERS);
+
+               /* handle array classes */
+
+               if (c->name->text[0] == '[')
+                       if (!(arraydesc = link_array(c)))
+                               return NULL;
+
+               if (c->flags & ACC_INTERFACE)
+                       c->index = interfaceindex++;
+               else
+                       c->index = super->index + 1;
+               
+               c->instancesize = super->instancesize;
+
+               vftbllength = supervftbllength = super->vftbl->vftbllength;
+               
+               c->finalizer = super->finalizer;
+       }
+       RT_TIMING_GET_TIME(time_resolving);
+
+
+       /* compute vftbl length */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               if (!(m->flags & ACC_STATIC)) { /* is instance method */
+                       tc = super;
+
+                       while (tc) {
+                               s4 j;
+
+                               for (j = 0; j < tc->methodscount; j++) {
+                                       if (method_canoverwrite(m, &(tc->methods[j]))) {
+                                               if (tc->methods[j].flags & ACC_PRIVATE)
+                                                       goto notfoundvftblindex;
+
+                                               /* package-private methods in other packages */
+                                               /* must not be overridden                    */
+                                               /* (see Java Language Specification 8.4.8.1) */
+                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
+                                                        && !SAME_PACKAGE(c,tc) ) 
+                                               {
+                                                   goto notfoundvftblindex;
+                                               }
+
+                                               if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
+                                                       return NULL;
+
+                                               goto foundvftblindex;
+                                       }
+                               }
+
+                               tc = tc->super.cls;
+                       }
+
+               notfoundvftblindex:
+                       m->vftblindex = (vftbllength++);
+               foundvftblindex:
+                       ;
+               }
+       }
+       RT_TIMING_GET_TIME(time_compute_vftbl);
+
+
+       /* Check all interfaces of an abstract class (maybe be an
+          interface too) for unimplemented methods.  Such methods are
+          called miranda-methods and are marked with the ACC_MIRANDA
+          flag.  VMClass.getDeclaredMethods does not return such
+          methods. */
+
+       if (c->flags & ACC_ABSTRACT) {
+               classinfo  *ic;
+               methodinfo *im;
+               s4 abstractmethodscount;
+               s4 j;
+               s4 k;
+
+               abstractmethodscount = 0;
+
+               /* check all interfaces of the abstract class */
+
+               for (i = 0; i < c->interfacescount; i++) {
+                       ic = c->interfaces[i].cls;
+
+                       for (j = 0; j < ic->methodscount; j++) {
+                               im = &(ic->methods[j]);
+
+                               /* skip `<clinit>' and `<init>' */
+
+                               if ((im->name == utf_clinit) || (im->name == utf_init))
+                                       continue;
+
+                               for (tc = c; tc != NULL; tc = tc->super.cls) {
+                                       for (k = 0; k < tc->methodscount; k++) {
+                                               if (method_canoverwrite(im, &(tc->methods[k])))
+                                                       goto noabstractmethod;
+                                       }
+                               }
+
+                               abstractmethodscount++;
+
+                       noabstractmethod:
+                               ;
+                       }
+               }
+
+               if (abstractmethodscount > 0) {
+                       methodinfo *am;
+
+                       /* reallocate methods memory */
+
+                       c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
+                                                                 c->methodscount + abstractmethodscount);
+
+                       for (i = 0; i < c->interfacescount; i++) {
+                               ic = c->interfaces[i].cls;
+
+                               for (j = 0; j < ic->methodscount; j++) {
+                                       im = &(ic->methods[j]);
+
+                                       /* skip `<clinit>' and `<init>' */
+
+                                       if ((im->name == utf_clinit) || (im->name == utf_init))
+                                               continue;
+
+                                       for (tc = c; tc != NULL; tc = tc->super.cls) {
+                                               for (k = 0; k < tc->methodscount; k++) {
+                                                       if (method_canoverwrite(im, &(tc->methods[k])))
+                                                               goto noabstractmethod2;
+                                               }
+                                       }
+
+                                       /* Copy the method found into the new c->methods
+                                          array and tag it as miranda-method. */
+
+                                       am = &(c->methods[c->methodscount]);
+                                       c->methodscount++;
+
+                                       MCOPY(am, im, methodinfo, 1);
+
+                                       am->vftblindex  = (vftbllength++);
+                                       am->class       = c;
+                                       am->flags      |= ACC_MIRANDA;
+
+                               noabstractmethod2:
+                                       ;
+                               }
+                       }
+               }
+       }
+       RT_TIMING_GET_TIME(time_abstract);
+
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_vftbl_len +=
+                       sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
+#endif
+
+       /* compute interfacetable length */
+
+       interfacetablelength = 0;
+
+       for (tc = c; tc != NULL; tc = tc->super.cls) {
+               for (i = 0; i < tc->interfacescount; i++) {
+                       s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
+
+                       if (h > interfacetablelength)
+                               interfacetablelength = h;
+               }
+       }
+       RT_TIMING_GET_TIME(time_compute_iftbl);
+
+       /* allocate virtual function table */
+
+       v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
+                                                         sizeof(methodptr) * (vftbllength - 1) +
+                                                         sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
+       v = (vftbl_t *) (((methodptr *) v) +
+                                        (interfacetablelength - 1) * (interfacetablelength > 1));
+
+       c->vftbl                = v;
+       v->class                = c;
+       v->vftbllength          = vftbllength;
+       v->interfacetablelength = interfacetablelength;
+       v->arraydesc            = arraydesc;
+
+       /* store interface index in vftbl */
+
+       if (c->flags & ACC_INTERFACE)
+               v->baseval = -(c->index);
+
+       /* copy virtual function table of super class */
+
+       for (i = 0; i < supervftbllength; i++) 
+               v->table[i] = super->vftbl->table[i];
+
+       /* Fill the remaining vftbl slots with the AbstractMethodError
+          stub (all after the super class slots, because they are already
+          initialized). */
+
+       for (; i < vftbllength; i++) {
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+               else
+# endif
+                       v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+               v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+       }
+
+       /* add method stubs into virtual function table */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               assert(m->stubroutine == NULL);
+
+               /* Don't create a compiler stub for abstract methods as they
+                  throw an AbstractMethodError with the default stub in the
+                  vftbl.  This entry is simply copied by sub-classes. */
+
+               if (m->flags & ACC_ABSTRACT)
+                       continue;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       m->stubroutine = intrp_createcompilerstub(m);
+               else
+#endif
+                       m->stubroutine = createcompilerstub(m);
+#else
+               m->stubroutine = intrp_createcompilerstub(m);
+#endif
+
+               /* static methods are not in the vftbl */
+
+               if (m->flags & ACC_STATIC)
+                       continue;
+
+               /* insert the stubroutine into the vftbl */
+
+               v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
+       }
+       RT_TIMING_GET_TIME(time_fill_vftbl);
+
+       /* compute instance size and offset of each field */
+       
+       for (i = 0; i < c->fieldscount; i++) {
+               s4 dsize;
+               fieldinfo *f = &(c->fields[i]);
+               
+               if (!(f->flags & ACC_STATIC)) {
+                       dsize = descriptor_typesize(f->parseddesc);
+
+                       /* On i386 we only align to 4 bytes even for double and s8.    */
+                       /* This matches what gcc does for struct members. We must      */
+                       /* do the same as gcc here because the offsets in native       */
+                       /* header structs like java_lang_Double must match the offsets */
+                       /* of the Java fields (eg. java.lang.Double.value).            */
+#if defined(__I386__)
+                       c->instancesize = MEMORY_ALIGN(c->instancesize, 4);
+#else
+                       c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
+#endif
+
+                       f->offset = c->instancesize;
+                       c->instancesize += dsize;
+               }
+       }
+       RT_TIMING_GET_TIME(time_offsets);
+
+       /* initialize interfacetable and interfacevftbllength */
+
+       v->interfacevftbllength = MNEW(s4, interfacetablelength);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
+#endif
+
+       for (i = 0; i < interfacetablelength; i++) {
+               v->interfacevftbllength[i] = 0;
+               v->interfacetable[-i] = NULL;
+       }
+
+       /* add interfaces */
+
+       for (tc = c; tc != NULL; tc = tc->super.cls)
+               for (i = 0; i < tc->interfacescount; i++)
+                       if (!linker_addinterface(c, tc->interfaces[i].cls))
+                               return NULL;
+
+       RT_TIMING_GET_TIME(time_fill_iftbl);
+
+       /* add finalizer method (not for java.lang.Object) */
+
+       if (super) {
+               methodinfo *fi;
+
+               fi = class_findmethod(c, utf_finalize, utf_void__void);
+
+               if (fi)
+                       if (!(fi->flags & ACC_STATIC))
+                               c->finalizer = fi;
+       }
+       RT_TIMING_GET_TIME(time_finalizer);
+
+       /* final tasks */
+
+       linker_compute_subclasses(c);
+
+       RT_TIMING_GET_TIME(time_subclasses);
+
+       /* revert the linking state and class is linked */
+
+       c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
+
+       /* check worklist */
+
+       /* XXX must this also be done in case of exception? */
+
+       while (worklist != NULL) {
+               method_worklist *wi = worklist;
+
+               worklist = worklist->next;
+
+               INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
+               jit_invalidate_code(wi->m);
+
+               /* XXX put worklist into dump memory? */
+               FREE(wi, method_worklist);
+       }
+
+#if !defined(NDEBUG)
+       if (linkverbose)
+               log_message_class("Linking done class: ", c);
+#endif
+
+       RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
+       RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
+       RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
+       RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
+       RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
+       RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
+       RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
+       RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
+       RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
+
+       /* just return c to show that we didn't had a problem */
+
+       return c;
+}
+
+
+/* link_array ******************************************************************
+
+   This function is called by link_class to create the arraydescriptor
+   for an array class.
+
+   This function returns NULL if the array cannot be linked because
+   the component type has not been linked yet.
+
+*******************************************************************************/
+
+static arraydescriptor *link_array(classinfo *c)
+{
+       classinfo       *comp;
+       s4               namelen;
+       arraydescriptor *desc;
+       vftbl_t         *compvftbl;
+       utf             *u;
+
+       comp = NULL;
+       namelen = c->name->blength;
+
+       /* Check the component type */
+
+       switch (c->name->text[1]) {
+       case '[':
+               /* c is an array of arrays. */
+               u = utf_new(c->name->text + 1, namelen - 1);
+               if (!(comp = load_class_from_classloader(u, c->classloader)))
+                       return NULL;
+               break;
+
+       case 'L':
+               /* c is an array of objects. */
+               u = utf_new(c->name->text + 2, namelen - 3);
+               if (!(comp = load_class_from_classloader(u, c->classloader)))
+                       return NULL;
+               break;
+       }
+
+       /* If the component type has not been linked, link it now */
+
+       assert(!comp || (comp->state & CLASS_LOADED));
+
+       if (comp && !(comp->state & CLASS_LINKED))
+               if (!link_class(comp))
+                       return NULL;
+
+       /* Allocate the arraydescriptor */
+
+       desc = NEW(arraydescriptor);
+
+       if (comp) {
+               /* c is an array of references */
+               desc->arraytype = ARRAYTYPE_OBJECT;
+               desc->componentsize = sizeof(void*);
+               desc->dataoffset = OFFSET(java_objectarray, data);
+               
+               compvftbl = comp->vftbl;
+
+               if (!compvftbl) {
+                       log_text("Component class has no vftbl");
+                       assert(0);
+               }
+
+               desc->componentvftbl = compvftbl;
+               
+               if (compvftbl->arraydesc) {
+                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+
+                       if (compvftbl->arraydesc->dimension >= 255) {
+                               log_text("Creating array of dimension >255");
+                               assert(0);
+                       }
+
+                       desc->dimension = compvftbl->arraydesc->dimension + 1;
+                       desc->elementtype = compvftbl->arraydesc->elementtype;
+
+               } else {
+                       desc->elementvftbl = compvftbl;
+                       desc->dimension = 1;
+                       desc->elementtype = ARRAYTYPE_OBJECT;
+               }
+
+       } else {
+               /* c is an array of a primitive type */
+               switch (c->name->text[1]) {
+               case 'Z':
+                       desc->arraytype = ARRAYTYPE_BOOLEAN;
+                       desc->dataoffset = OFFSET(java_booleanarray,data);
+                       desc->componentsize = sizeof(u1);
+                       break;
+
+               case 'B':
+                       desc->arraytype = ARRAYTYPE_BYTE;
+                       desc->dataoffset = OFFSET(java_bytearray,data);
+                       desc->componentsize = sizeof(u1);
+                       break;
+
+               case 'C':
+                       desc->arraytype = ARRAYTYPE_CHAR;
+                       desc->dataoffset = OFFSET(java_chararray,data);
+                       desc->componentsize = sizeof(u2);
+                       break;
+
+               case 'D':
+                       desc->arraytype = ARRAYTYPE_DOUBLE;
+                       desc->dataoffset = OFFSET(java_doublearray,data);
+                       desc->componentsize = sizeof(double);
+                       break;
+
+               case 'F':
+                       desc->arraytype = ARRAYTYPE_FLOAT;
+                       desc->dataoffset = OFFSET(java_floatarray,data);
+                       desc->componentsize = sizeof(float);
+                       break;
+
+               case 'I':
+                       desc->arraytype = ARRAYTYPE_INT;
+                       desc->dataoffset = OFFSET(java_intarray,data);
+                       desc->componentsize = sizeof(s4);
+                       break;
+
+               case 'J':
+                       desc->arraytype = ARRAYTYPE_LONG;
+                       desc->dataoffset = OFFSET(java_longarray,data);
+                       desc->componentsize = sizeof(s8);
+                       break;
+
+               case 'S':
+                       desc->arraytype = ARRAYTYPE_SHORT;
+                       desc->dataoffset = OFFSET(java_shortarray,data);
+                       desc->componentsize = sizeof(s2);
+                       break;
+
+               default:
+                       exceptions_throw_noclassdeffounderror(c->name);
+                       return NULL;
+               }
+               
+               desc->componentvftbl = NULL;
+               desc->elementvftbl = NULL;
+               desc->dimension = 1;
+               desc->elementtype = desc->arraytype;
+       }
+
+       return desc;
+}
+
+
+/* linker_compute_subclasses ***************************************************
+
+   XXX
+
+*******************************************************************************/
+
+static void linker_compute_subclasses(classinfo *c)
+{
+#if defined(ENABLE_THREADS)
+       compiler_lock();
+#endif
+
+       if (!(c->flags & ACC_INTERFACE)) {
+               c->nextsub = 0;
+               c->sub = 0;
+       }
+
+       if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
+               c->nextsub = c->super.cls->sub;
+               c->super.cls->sub = c;
+       }
+
+       classvalue = 0;
+
+       /* compute class values */
+
+       linker_compute_class_values(class_java_lang_Object);
+
+#if defined(ENABLE_THREADS)
+       compiler_unlock();
+#endif
+}
+
+
+/* linker_compute_class_values *************************************************
+
+   XXX
+
+*******************************************************************************/
+
+static void linker_compute_class_values(classinfo *c)
+{
+       classinfo *subs;
+
+       c->vftbl->baseval = ++classvalue;
+
+       subs = c->sub;
+
+       while (subs) {
+               linker_compute_class_values(subs);
+
+               subs = subs->nextsub;
+       }
+
+       c->vftbl->diffval = classvalue - c->vftbl->baseval;
+}
+
+
+/* linker_addinterface *********************************************************
+
+   Is needed by link_class for adding a VTBL to a class. All
+   interfaces implemented by ic are added as well.
+
+   RETURN VALUE:
+      true.........everything ok
+         false........an exception has been thrown
+
+*******************************************************************************/
+
+static bool linker_addinterface(classinfo *c, classinfo *ic)
+{
+       s4          j, k;
+       vftbl_t    *v;
+       s4          i;
+       classinfo  *sc;
+       methodinfo *m;
+
+       v = c->vftbl;
+       i = ic->index;
+
+       if (i >= v->interfacetablelength)
+               vm_abort("Internal error: interfacetable overflow");
+
+       /* if this interface has already been added, return immediately */
+
+       if (v->interfacetable[-i] != NULL)
+               return true;
+
+       if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
+               v->interfacevftbllength[i] = 1;
+               v->interfacetable[-i]      = MNEW(methodptr, 1);
+               v->interfacetable[-i][0]   = NULL;
+       }
+       else {
+               v->interfacevftbllength[i] = ic->methodscount;
+               v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_vftbl_len += sizeof(methodptr) *
+                               (ic->methodscount + (ic->methodscount == 0));
+#endif
+
+               for (j = 0; j < ic->methodscount; j++) {
+                       for (sc = c; sc != NULL; sc = sc->super.cls) {
+                               for (k = 0; k < sc->methodscount; k++) {
+                                       m = &(sc->methods[k]);
+
+                                       if (method_canoverwrite(m, &(ic->methods[j]))) {
+                                               /* method m overwrites the (abstract) method */
+#if defined(ENABLE_VERIFIER)
+                                               /* Add loading constraints (for the more
+                                                  general types of the method
+                                                  ic->methods[j]).  */
+                                               if (!classcache_add_constraints_for_params(
+                                                                       c->classloader, ic->classloader,
+                                                                       &(ic->methods[j])))
+                                               {
+                                                       return false;
+                                               }
+#endif
+
+                                               /* XXX taken from gcj */
+                                               /* check for ACC_STATIC: IncompatibleClassChangeError */
+
+                                               /* check for !ACC_PUBLIC: IllegalAccessError */
+
+                                               /* check for ACC_ABSTRACT: AbstracMethodError,
+                                                  not sure about that one */
+
+                                               v->interfacetable[-i][j] = v->table[m->vftblindex];
+                                               goto foundmethod;
+                                       }
+                               }
+                       }
+
+                       /* If no method was found, insert the AbstractMethodError
+                          stub. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+                       if (opt_intrp)
+                               v->interfacetable[-i][j] =
+                                       (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+                       else
+# endif
+                               v->interfacetable[-i][j] =
+                                       (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+                       v->interfacetable[-i][j] =
+                               (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+
+               foundmethod:
+                       ;
+               }
+       }
+
+       /* add superinterfaces of this interface */
+
+       for (j = 0; j < ic->interfacescount; j++)
+               if (!linker_addinterface(c, ic->interfaces[j].cls))
+                       return false;
+
+       /* everything ok */
+
+       return true;
+}
+
+
+/* class_highestinterface ******************************************************
+
+   Used by the function link_class to determine the amount of memory
+   needed for the interface table.
+
+*******************************************************************************/
+
+static s4 class_highestinterface(classinfo *c)
+{
+       s4 h;
+       s4 h2;
+       s4 i;
+       
+    /* check for ACC_INTERFACE bit already done in link_class_intern */
+
+    h = c->index;
+
+       for (i = 0; i < c->interfacescount; i++) {
+               h2 = class_highestinterface(c->interfaces[i].cls);
+
+               if (h2 > h)
+                       h = h2;
+       }
+
+       return 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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/linker.h b/src/vmcore/linker.h
new file mode 100644 (file)
index 0000000..efd6b2e
--- /dev/null
@@ -0,0 +1,181 @@
+/* src/vmcore/linker.h - class linker header
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: linker.h 7246 2007-01-29 18:49:05Z twisti $
+*/
+
+
+#ifndef _LINKER_H
+#define _LINKER_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct _vftbl vftbl_t;
+typedef struct arraydescriptor arraydescriptor;
+typedef struct primitivetypeinfo primitivetypeinfo;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vmcore/class.h"
+#include "vmcore/references.h"
+
+
+/* virtual function table ******************************************************
+
+   The vtbl has a bidirectional layout with open ends at both sides.
+   interfacetablelength gives the number of entries of the interface
+   table at the start of the vftbl. The vftbl pointer points to
+   &interfacetable[0].  vftbllength gives the number of entries of
+   table at the end of the vftbl.
+
+   runtime type check (checkcast):
+
+   Different methods are used for runtime type check depending on the
+   argument of checkcast/instanceof.
+       
+   A check against a class is implemented via relative numbering on
+   the class hierachy tree. The tree is numbered in a depth first
+   traversal setting the base field and the diff field. The diff field
+   gets the result of (high - base) so that a range check can be
+   implemented by an unsigned compare. A sub type test is done by
+   checking the inclusion of base of the sub class in the range of the
+   superclass.
+
+   A check against an interface is implemented via the
+   interfacevftbl. If the interfacevftbl contains a nonnull value a
+   class is a subclass of this interface.
+
+   interfacetable:
+
+   Like standard virtual methods interface methods are called using
+   virtual function tables. All interfaces are numbered sequentially
+   (starting with zero). For each class there exist an interface table
+   of virtual function tables for each implemented interface. The
+   length of the interface table is determined by the highest number
+   of an implemented interface.
+
+   The following example assumes a class which implements interface 0 and 3:
+
+   interfacetablelength = 4
+
+                  | ...       |            +----------+
+                     +-----------+            | method 2 |---> method z
+                     | class     |            | method 1 |---> method y
+                     +-----------+            | method 0 |---> method x
+                     | ivftbl  0 |----------> +----------+
+       vftblptr ---> +-----------+
+                  | ivftbl -1 |--> NULL    +----------+
+                  | ivftbl -2 |--> NULL    | method 1 |---> method x
+                  | ivftbl -3 |-----+      | method 0 |---> method a
+                  +-----------+     +----> +----------+
+     
+                              +---------------+
+                                 | length 3 = 2  |
+                                 | length 2 = 0  |
+                                 | length 1 = 0  |
+                                 | length 0 = 3  |
+       interfacevftbllength ---> +---------------+
+
+*******************************************************************************/
+
+struct _vftbl {
+       methodptr   *interfacetable[1];    /* interface table (access via macro)  */
+       classinfo   *class;                /* class, the vtbl belongs to          */
+       arraydescriptor *arraydesc;        /* for array classes, otherwise NULL   */
+       s4           vftbllength;          /* virtual function table length       */
+       s4           interfacetablelength; /* interface table length              */
+       s4           baseval;              /* base for runtime type check         */
+                                          /* (-index for interfaces)             */
+       s4           diffval;              /* high - base for runtime type check  */
+       s4          *interfacevftbllength; /* length of interface vftbls          */
+       methodptr    table[1];             /* class vftbl                         */
+};
+
+
+/* arraydescriptor *************************************************************
+
+   For every array class an arraydescriptor is allocated which
+   describes the array class. The arraydescriptor is referenced from
+   the vftbl of the array class.
+
+*******************************************************************************/
+
+struct arraydescriptor {
+       vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
+       vftbl_t *elementvftbl;   /* vftbl of the element type, NULL for primitive */
+       s2       arraytype;      /* ARRAYTYPE_* constant                          */
+       s2       dimension;      /* dimension of the array (always >= 1)          */
+       s4       dataoffset;     /* offset of the array data from object pointer  */
+       s4       componentsize;  /* size of a component in bytes                  */
+       s2       elementtype;    /* ARRAYTYPE_* constant                          */
+};
+
+
+/* primitivetypeinfo **********************************************************/
+
+struct primitivetypeinfo {
+       classinfo *class_wrap;               /* class for wrapping primitive type */
+       classinfo *class_primitive;          /* primitive class                   */
+       char      *wrapname;                 /* name of class for wrapping        */
+       char       typesig;                  /* one character type signature      */
+       char      *name;                     /* name of primitive class           */
+       char      *arrayname;                /* name of primitive array class     */
+       classinfo *arrayclass;               /* primitive array class             */
+       vftbl_t   *arrayvftbl;               /* vftbl of primitive array class    */
+};
+
+
+/* global variables ***********************************************************/
+
+/* This array can be indexed by the PRIMITIVETYPE_ and ARRAYTYPE_ constants   */
+/* (except ARRAYTYPE_OBJECT).                                                 */
+
+extern primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT];
+
+
+/* function prototypes ********************************************************/
+
+/* initialize the linker subsystem */
+bool linker_init(void);
+
+/* link a class */
+classinfo *link_class(classinfo *c);
+
+#endif /* _LINKER_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:
+ */
diff --git a/src/vmcore/loader.c b/src/vmcore/loader.c
new file mode 100644 (file)
index 0000000..c1bf1f7
--- /dev/null
@@ -0,0 +1,2614 @@
+/* src/vmcore/loader.c - class loader functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: loader.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#endif
+
+#include "toolbox/logging.h"
+
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/codegen-common.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vmcore/annotation.h"
+# include "vmcore/stackmap.h"
+#endif
+
+#include "vmcore/classcache.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/rt-timing.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/suck.h"
+
+#if defined(ENABLE_ZLIB)
+# include "vmcore/zip.h"
+#endif
+
+#if defined(ENABLE_JVMTI)
+# include "native/jvmti/cacaodbg.h"
+#endif
+
+
+/* loader_init *****************************************************************
+
+   Initializes all lists and loads all classes required for the system
+   or the compiler.
+
+*******************************************************************************/
+bool loader_init(void)
+{
+#if defined(ENABLE_THREADS)
+       list_classpath_entry *lce;
+
+       /* Initialize the monitor pointer for zip/jar file locking. */
+
+       for (lce = list_first(list_classpath_entries); lce != NULL;
+                lce = list_next(list_classpath_entries, lce))
+               if (lce->type == CLASSPATH_ARCHIVE)
+                       lock_init_object_lock((java_objectheader *) lce);
+#endif
+
+       /* load some important classes */
+
+       if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
+               return false;
+
+       if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
+               return false;
+
+#if defined(ENABLE_JAVASE)
+       if (!(class_java_lang_Cloneable =
+                 load_class_bootstrap(utf_java_lang_Cloneable)))
+               return false;
+
+       if (!(class_java_io_Serializable =
+                 load_class_bootstrap(utf_java_io_Serializable)))
+               return false;
+#endif
+
+       /* load classes for wrapping primitive types */
+
+#if defined(ENABLE_JAVASE)
+       if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
+               return false;
+#endif
+
+       if (!(class_java_lang_Boolean =
+                 load_class_bootstrap(utf_java_lang_Boolean)))
+               return false;
+
+       if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
+               return false;
+
+       if (!(class_java_lang_Character =
+                 load_class_bootstrap(utf_java_lang_Character)))
+               return false;
+
+       if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
+               return false;
+
+       if (!(class_java_lang_Integer =
+                 load_class_bootstrap(utf_java_lang_Integer)))
+               return false;
+
+       if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
+               return false;
+
+       if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
+               return false;
+
+       if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
+               return false;
+
+
+       /* load some other important classes */
+
+       if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
+               return false;
+
+#if defined(ENABLE_JAVASE)
+       if (!(class_java_lang_ClassLoader =
+                 load_class_bootstrap(utf_java_lang_ClassLoader)))
+               return false;
+
+       if (!(class_java_lang_SecurityManager =
+                 load_class_bootstrap(utf_java_lang_SecurityManager)))
+               return false;
+#endif
+
+       if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
+               return false;
+
+       if (!(class_java_lang_Thread =
+                 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
+               return false;
+
+#if defined(ENABLE_JAVASE)
+       if (!(class_java_lang_ThreadGroup =
+                 load_class_bootstrap(utf_java_lang_ThreadGroup)))
+               return false;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+       if (!(class_java_lang_VMSystem =
+                 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
+
+               return false;
+
+       if (!(class_java_lang_VMThread =
+                 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
+               return false;
+#endif
+
+
+       /* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+       if (!(class_java_lang_StackTraceElement =
+                 load_class_bootstrap(utf_java_lang_StackTraceElement)))
+               return false;
+
+       if (!(class_java_lang_reflect_Constructor =
+                 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
+               return false;
+
+       if (!(class_java_lang_reflect_Field =
+                 load_class_bootstrap(utf_java_lang_reflect_Field)))
+               return false;
+
+       if (!(class_java_lang_reflect_Method =
+                 load_class_bootstrap(utf_java_lang_reflect_Method)))
+               return false;
+
+       if (!(class_java_security_PrivilegedAction =
+                 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
+               return false;
+
+       if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
+               return false;
+
+       if (!(arrayclass_java_lang_Object =
+                 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
+               return false;
+#endif
+
+       return true;
+}
+
+
+/* loader_load_all_classes *****************************************************
+
+   Loads all classes specified in the BOOTCLASSPATH.
+
+*******************************************************************************/
+
+void loader_load_all_classes(void)
+{
+       list_classpath_entry    *lce;
+#if defined(ENABLE_ZLIB)
+       hashtable               *ht;
+       s4                       slot;
+       hashtable_zipfile_entry *htzfe;
+       utf                     *u;
+#endif
+
+       for (lce = list_first(list_classpath_entries); lce != NULL;
+                lce = list_next(list_classpath_entries, lce)) {
+#if defined(ENABLE_ZLIB)
+               if (lce->type == CLASSPATH_ARCHIVE) {
+                       /* get the classes hashtable */
+
+                       ht = lce->htclasses;
+
+                       for (slot = 0; slot < ht->size; slot++) {
+                               htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
+
+                               for (; htzfe; htzfe = htzfe->hashlink) {
+                                       u = htzfe->filename;
+
+                                       /* skip all entries in META-INF and .properties,
+                       .png files */
+
+                                       if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
+                                               strstr(u->text, ".properties") ||
+                                               strstr(u->text, ".png"))
+                                               continue;
+
+                                       /* load class from bootstrap classloader */
+
+                                       if (!load_class_bootstrap(u)) {
+                                               fprintf(stderr, "Error loading: ");
+                                               utf_fprint_printable_ascii_classname(stderr, u);
+                                               fprintf(stderr, "\n");
+
+#if !defined(NDEBUG)
+                                               /* print out exception and cause */
+
+                                               exceptions_print_current_exception();
+#endif
+                                       }
+                               }
+                       }
+
+               } else {
+#endif
+#if defined(ENABLE_ZLIB)
+               }
+#endif
+       }
+}
+
+
+/* loader_skip_attribute_body **************************************************
+
+   Skips an attribute the attribute_name_index has already been read.
+       
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
+*******************************************************************************/
+
+bool loader_skip_attribute_body(classbuffer *cb)
+{
+       u4 attribute_length;
+
+       if (!suck_check_classbuffer_size(cb, 4))
+               return false;
+
+       attribute_length = suck_u4(cb);
+
+       if (!suck_check_classbuffer_size(cb, attribute_length))
+               return false;
+
+       suck_skip_nbytes(cb, attribute_length);
+
+       return true;
+}
+
+
+/* load_constantpool ***********************************************************
+
+   Loads the constantpool of a class, the entries are transformed into
+   a simpler format by resolving references (a detailed overview of
+   the compact structures can be found in global.h).
+
+*******************************************************************************/
+
+static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
+{
+
+       /* The following structures are used to save information which cannot be 
+          processed during the first pass. After the complete constantpool has 
+          been traversed the references can be resolved. 
+          (only in specific order)                                                */
+       
+       /* CONSTANT_Class entries */
+       typedef struct forward_class {
+               struct forward_class *next;
+               u2 thisindex;
+               u2 name_index;
+       } forward_class;
+
+       /* CONSTANT_String */
+       typedef struct forward_string {
+               struct forward_string *next;
+               u2 thisindex;
+               u2 string_index;
+       } forward_string;
+
+       /* CONSTANT_NameAndType */
+       typedef struct forward_nameandtype {
+               struct forward_nameandtype *next;
+               u2 thisindex;
+               u2 name_index;
+               u2 sig_index;
+       } forward_nameandtype;
+
+       /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
+       typedef struct forward_fieldmethint {
+               struct forward_fieldmethint *next;
+               u2 thisindex;
+               u1 tag;
+               u2 class_index;
+               u2 nameandtype_index;
+       } forward_fieldmethint;
+
+
+       classinfo *c;
+       u4 idx;
+
+       forward_class *forward_classes = NULL;
+       forward_string *forward_strings = NULL;
+       forward_nameandtype *forward_nameandtypes = NULL;
+       forward_fieldmethint *forward_fieldmethints = NULL;
+
+       forward_class *nfc;
+       forward_string *nfs;
+       forward_nameandtype *nfn;
+       forward_fieldmethint *nff;
+
+       u4 cpcount;
+       u1 *cptags;
+       voidptr *cpinfos;
+
+       c = cb->class;
+
+       /* number of entries in the constant_pool table plus one */
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       cpcount = c->cpcount = suck_u2(cb);
+
+       /* allocate memory */
+       cptags  = c->cptags  = MNEW(u1, cpcount);
+       cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
+
+       if (cpcount < 1) {
+               exceptions_throw_classformaterror(c, "Illegal constant pool size");
+               return false;
+       }
+       
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
+#endif
+       
+       /* initialize constantpool */
+       for (idx = 0; idx < cpcount; idx++) {
+               cptags[idx] = CONSTANT_UNUSED;
+               cpinfos[idx] = NULL;
+       }
+
+                       
+       /******* first pass *******/
+       /* entries which cannot be resolved now are written into 
+          temporary structures and traversed again later        */
+                  
+       idx = 1;
+       while (idx < cpcount) {
+               u4 t;
+
+               /* get constant type */
+               if (!suck_check_classbuffer_size(cb, 1))
+                       return false;
+
+               t = suck_u1(cb);
+
+               switch (t) {
+               case CONSTANT_Class:
+                       nfc = DNEW(forward_class);
+
+                       nfc->next = forward_classes;
+                       forward_classes = nfc;
+
+                       nfc->thisindex = idx;
+                       /* reference to CONSTANT_NameAndType */
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       nfc->name_index = suck_u2(cb);
+
+                       idx++;
+                       break;
+                       
+               case CONSTANT_String:
+                       nfs = DNEW(forward_string);
+                               
+                       nfs->next = forward_strings;
+                       forward_strings = nfs;
+                               
+                       nfs->thisindex = idx;
+
+                       /* reference to CONSTANT_Utf8_info with string characters */
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       nfs->string_index = suck_u2(cb);
+                               
+                       idx++;
+                       break;
+
+               case CONSTANT_NameAndType:
+                       nfn = DNEW(forward_nameandtype);
+                               
+                       nfn->next = forward_nameandtypes;
+                       forward_nameandtypes = nfn;
+                               
+                       nfn->thisindex = idx;
+
+                       if (!suck_check_classbuffer_size(cb, 2 + 2))
+                               return false;
+
+                       /* reference to CONSTANT_Utf8_info containing simple name */
+                       nfn->name_index = suck_u2(cb);
+
+                       /* reference to CONSTANT_Utf8_info containing field or method
+                          descriptor */
+                       nfn->sig_index = suck_u2(cb);
+                               
+                       idx++;
+                       break;
+
+               case CONSTANT_Fieldref:
+               case CONSTANT_Methodref:
+               case CONSTANT_InterfaceMethodref:
+                       nff = DNEW(forward_fieldmethint);
+                       
+                       nff->next = forward_fieldmethints;
+                       forward_fieldmethints = nff;
+
+                       nff->thisindex = idx;
+                       /* constant type */
+                       nff->tag = t;
+
+                       if (!suck_check_classbuffer_size(cb, 2 + 2))
+                               return false;
+
+                       /* class or interface type that contains the declaration of the
+                          field or method */
+                       nff->class_index = suck_u2(cb);
+
+                       /* name and descriptor of the field or method */
+                       nff->nameandtype_index = suck_u2(cb);
+
+                       idx++;
+                       break;
+                               
+               case CONSTANT_Integer: {
+                       constant_integer *ci = NEW(constant_integer);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_integer);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 4))
+                               return false;
+
+                       ci->value = suck_s4(cb);
+                       cptags[idx] = CONSTANT_Integer;
+                       cpinfos[idx] = ci;
+
+                       idx++;
+                       break;
+               }
+                               
+               case CONSTANT_Float: {
+                       constant_float *cf = NEW(constant_float);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_float);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 4))
+                               return false;
+
+                       cf->value = suck_float(cb);
+                       cptags[idx] = CONSTANT_Float;
+                       cpinfos[idx] = cf;
+
+                       idx++;
+                       break;
+               }
+                               
+               case CONSTANT_Long: {
+                       constant_long *cl = NEW(constant_long);
+                                       
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_long);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 8))
+                               return false;
+
+                       cl->value = suck_s8(cb);
+                       cptags[idx] = CONSTANT_Long;
+                       cpinfos[idx] = cl;
+                       idx += 2;
+                       if (idx > cpcount) {
+                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
+                               return false;
+                       }
+                       break;
+               }
+                       
+               case CONSTANT_Double: {
+                       constant_double *cd = NEW(constant_double);
+                               
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_const_pool_len += sizeof(constant_double);
+#endif
+
+                       if (!suck_check_classbuffer_size(cb, 8))
+                               return false;
+
+                       cd->value = suck_double(cb);
+                       cptags[idx] = CONSTANT_Double;
+                       cpinfos[idx] = cd;
+                       idx += 2;
+                       if (idx > cpcount) {
+                               exceptions_throw_classformaterror(c, "Invalid constant pool entry");
+                               return false;
+                       }
+                       break;
+               }
+                               
+               case CONSTANT_Utf8: { 
+                       u4 length;
+
+                       /* number of bytes in the bytes array (not string-length) */
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       length = suck_u2(cb);
+                       cptags[idx] = CONSTANT_Utf8;
+
+                       /* validate the string */
+                       if (!suck_check_classbuffer_size(cb, length))
+                               return false;
+
+#ifdef ENABLE_VERIFIER
+                       if (opt_verify &&
+                               !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
+                       {
+                               exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
+                               return false;
+                       }
+#endif /* ENABLE_VERIFIER */
+                       /* insert utf-string into the utf-symboltable */
+                       cpinfos[idx] = utf_new((char *) cb->pos, length);
+
+                       /* skip bytes of the string (buffer size check above) */
+                       suck_skip_nbytes(cb, length);
+                       idx++;
+                       break;
+               }
+                                                                               
+               default:
+                       exceptions_throw_classformaterror(c, "Illegal constant pool type");
+                       return false;
+               }  /* end switch */
+       } /* end while */
+
+
+       /* resolve entries in temporary structures */
+
+       while (forward_classes) {
+               utf *name =
+                       class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
+               if (!name)
+                       return false;
+
+#ifdef ENABLE_VERIFIER
+               if (opt_verify && !is_valid_name_utf(name)) {
+                       exceptions_throw_classformaterror(c, "Class reference with invalid name");
+                       return false;
+               }
+#endif /* ENABLE_VERIFIER */
+
+               /* add all class references to the descriptor_pool */
+
+               if (!descriptor_pool_add_class(descpool, name))
+                       return false;
+
+               cptags[forward_classes->thisindex] = CONSTANT_Class;
+
+               if (opt_eager) {
+                       classinfo *tc;
+
+                       if (!(tc = load_class_bootstrap(name)))
+                               return false;
+
+                       /* link the class later, because we cannot link the class currently
+                          loading */
+                       list_add_first(&unlinkedclasses, tc);
+               }
+
+               /* the classref is created later */
+               cpinfos[forward_classes->thisindex] = name;
+
+               nfc = forward_classes;
+               forward_classes = forward_classes->next;
+       }
+
+       while (forward_strings) {
+               utf *text =
+                       class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
+               if (!text)
+                       return false;
+
+               /* resolve utf-string */
+               cptags[forward_strings->thisindex] = CONSTANT_String;
+               cpinfos[forward_strings->thisindex] = text;
+               
+               nfs = forward_strings;
+               forward_strings = forward_strings->next;
+       }
+
+       while (forward_nameandtypes) {
+               constant_nameandtype *cn = NEW(constant_nameandtype);   
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_const_pool_len += sizeof(constant_nameandtype);
+#endif
+
+               /* resolve simple name and descriptor */
+               cn->name = class_getconstant(c,
+                                                                        forward_nameandtypes->name_index,
+                                                                        CONSTANT_Utf8);
+               if (!cn->name)
+                       return false;
+
+               cn->descriptor = class_getconstant(c,
+                                                                                  forward_nameandtypes->sig_index,
+                                                                                  CONSTANT_Utf8);
+               if (!cn->descriptor)
+                       return false;
+
+#ifdef ENABLE_VERIFIER
+               if (opt_verify) {
+                       /* check name */
+                       if (!is_valid_name_utf(cn->name)) {
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal Field name \"%s\"",
+                                                                                                 cn->name->text);
+
+                               return false;
+                       }
+
+                       /* disallow referencing <clinit> among others */
+                       if (cn->name->text[0] == '<' && cn->name != utf_init) {
+                               exceptions_throw_classformaterror(c, "Illegal reference to special method");
+                               return false;
+                       }
+               }
+#endif /* ENABLE_VERIFIER */
+
+               cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
+               cpinfos[forward_nameandtypes->thisindex] = cn;
+
+               nfn = forward_nameandtypes;
+               forward_nameandtypes = forward_nameandtypes->next;
+       }
+
+       while (forward_fieldmethints) {
+               constant_nameandtype *nat;
+               constant_FMIref *fmi = NEW(constant_FMIref);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_const_pool_len += sizeof(constant_FMIref);
+#endif
+               /* resolve simple name and descriptor */
+
+               nat = class_getconstant(c,
+                                                               forward_fieldmethints->nameandtype_index,
+                                                               CONSTANT_NameAndType);
+               if (!nat)
+                       return false;
+
+               /* add all descriptors in {Field,Method}ref to the descriptor_pool */
+
+               if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
+                       return false;
+
+               /* the classref is created later */
+
+               fmi->p.index = forward_fieldmethints->class_index;
+               fmi->name = nat->name;
+               fmi->descriptor = nat->descriptor;
+
+               cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
+               cpinfos[forward_fieldmethints->thisindex] = fmi;
+       
+               nff = forward_fieldmethints;
+               forward_fieldmethints = forward_fieldmethints->next;
+       }
+
+       /* everything was ok */
+
+       return true;
+}
+
+
+/* loader_load_attribute_signature *********************************************
+
+   Signature_attribute {
+       u2 attribute_name_index;
+          u4 atrribute_length;
+          u2 signature_index;
+   }
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
+{
+       classinfo *c;
+       u4         attribute_length;
+       u2         signature_index;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* check remaining bytecode */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* check attribute length */
+
+       attribute_length = suck_u4(cb);
+
+       if (attribute_length != 2) {
+               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+               return false;
+       }
+
+       if (*signature != NULL) {
+               exceptions_throw_classformaterror(c, "Multiple Signature attributes");
+               return false;
+       }
+
+       /* get signature */
+
+       signature_index = suck_u2(cb);
+
+       if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
+               return false;
+
+       return true;
+}
+#endif /* defined(ENABLE_JAVASE) */
+
+
+/* load_field ******************************************************************
+
+   Load everything about a class field from the class file and fill a
+   'fieldinfo' structure. For static fields, space in the data segment
+   is allocated.
+
+*******************************************************************************/
+
+#define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
+
+static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
+{
+       classinfo *c;
+       u4 attrnum, i;
+       u4 jtype;
+       u4 pindex = field_load_NOVALUE;     /* constantvalue_index */
+       utf *u;
+
+       c = cb->class;
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
+               return false;
+
+       f->flags = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+               return false;
+
+       f->name = u;
+
+       if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+               return false;
+
+       f->descriptor = u;
+       f->parseddesc = NULL;
+
+       if (!descriptor_pool_add(descpool, u, NULL))
+               return false;
+
+       /* descriptor_pool_add accepts method descriptors, so we have to check  */
+       /* against them here before the call of descriptor_to_basic_type below. */
+       if (u->text[0] == '(') {
+               exceptions_throw_classformaterror(c, "Method descriptor used for field");
+               return false;
+       }
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+               /* check name */
+               if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal Field name \"%s\"",
+                                                                                         f->name->text);
+                       return false;
+               }
+
+               /* check flag consistency */
+               i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
+
+               if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
+                       ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal field modifiers: 0x%X",
+                                                                                         f->flags);
+                       return false;
+               }
+
+               if (c->flags & ACC_INTERFACE) {
+                       if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
+                               != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
+                               f->flags & ACC_TRANSIENT) {
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal field modifiers: 0x%X",
+                                                                                                 f->flags);
+                               return false;
+                       }
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+
+       f->type   = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
+       f->offset = 0;                             /* offset from start of object */
+       f->class  = c;
+
+       switch (f->type) {
+       case TYPE_INT:
+               f->value.i = 0;
+               break;
+
+       case TYPE_FLT:
+               f->value.f = 0.0;
+               break;
+
+       case TYPE_DBL:
+               f->value.d = 0.0;
+               break;
+
+       case TYPE_ADR:
+               f->value.a = NULL;
+               if (!(f->flags & ACC_STATIC))
+                       c->flags |= ACC_CLASS_HAS_POINTERS;
+               break;
+
+       case TYPE_LNG:
+#if U8_AVAILABLE
+               f->value.l = 0;
+#else
+               f->value.l.low  = 0;
+               f->value.l.high = 0;
+#endif
+               break;
+       }
+
+       /* read attributes */
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       attrnum = suck_u2(cb);
+       for (i = 0; i < attrnum; i++) {
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
+                       return false;
+
+               if (u == utf_ConstantValue) {
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* check attribute length */
+
+                       if (suck_u4(cb) != 2) {
+                               exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
+                               return false;
+                       }
+                       
+                       /* constant value attribute */
+
+                       if (pindex != field_load_NOVALUE) {
+                               exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
+                               return false;
+                       }
+                       
+                       /* index of value in constantpool */
+
+                       pindex = suck_u2(cb);
+               
+                       /* initialize field with value from constantpool */             
+                       switch (jtype) {
+                       case TYPE_INT: {
+                               constant_integer *ci; 
+
+                               if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
+                                       return false;
+
+                               f->value.i = ci->value;
+                       }
+                       break;
+                                       
+                       case TYPE_LNG: {
+                               constant_long *cl; 
+
+                               if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
+                                       return false;
+
+                               f->value.l = cl->value;
+                       }
+                       break;
+
+                       case TYPE_FLT: {
+                               constant_float *cf;
+
+                               if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
+                                       return false;
+
+                               f->value.f = cf->value;
+                       }
+                       break;
+                                                                                       
+                       case TYPE_DBL: {
+                               constant_double *cd;
+
+                               if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
+                                       return false;
+
+                               f->value.d = cd->value;
+                       }
+                       break;
+                                               
+                       case TYPE_ADR:
+                               if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
+                                       return false;
+
+                               /* create javastring from compressed utf8-string */
+                               f->value.a = literalstring_new(u);
+                               break;
+       
+                       default: 
+                               log_text("Invalid Constant - Type");
+                       }
+               }
+#if defined(ENABLE_JAVASE)
+               else if (u == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(f->signature)))
+                               return false;
+               }
+#endif
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       /* everything was ok */
+
+       return true;
+}
+
+
+/* loader_load_method **********************************************************
+
+   Loads a method from the class file and fills an existing
+   'methodinfo' structure. For native methods, the function pointer
+   field is set to the real function pointer, for JavaVM methods a
+   pointer to the compiler is used preliminarily.
+
+   method_info {
+       u2 access_flags;
+          u2 name_index;
+          u2 descriptor_index;
+          u2 attributes_count;
+          attribute_info attributes[attribute_count];
+   }
+
+   attribute_info {
+       u2 attribute_name_index;
+          u4 attribute_length;
+          u1 info[attribute_length];
+   }
+
+   LineNumberTable_attribute {
+       u2 attribute_name_index;
+          u4 attribute_length;
+          u2 line_number_table_length;
+          {
+              u2 start_pc;
+                  u2 line_number;
+          } line_number_table[line_number_table_length];
+   }
+
+*******************************************************************************/
+
+static bool loader_load_method(classbuffer *cb, methodinfo *m,
+                                                          descriptor_pool *descpool)
+{
+       classinfo *c;
+       int argcount;
+       s4         i, j, k, l;
+       utf       *u;
+       u2         name_index;
+       u2         descriptor_index;
+       u2         attributes_count;
+       u2         attribute_name_index;
+       utf       *attribute_name;
+       u2         code_attributes_count;
+       u2         code_attribute_name_index;
+       utf       *code_attribute_name;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&m->header);
+#endif
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_all_methods++;
+#endif
+
+       /* all fields of m have been zeroed in load_class_from_classbuffer */
+
+       m->class = c;
+       
+       if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
+               return false;
+
+       /* access flags */
+
+       m->flags = suck_u2(cb);
+
+       /* name */
+
+       name_index = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
+               return false;
+
+       m->name = u;
+
+       /* descriptor */
+
+       descriptor_index = suck_u2(cb);
+
+       if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
+               return false;
+
+       m->descriptor = u;
+
+       if (!descriptor_pool_add(descpool, u, &argcount))
+               return false;
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+               if (!is_valid_name_utf(m->name)) {
+                       exceptions_throw_classformaterror(c, "Method with invalid name");
+                       return false;
+               }
+
+               if (m->name->text[0] == '<' &&
+                       m->name != utf_init && m->name != utf_clinit) {
+                       exceptions_throw_classformaterror(c, "Method with invalid special name");
+                       return false;
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+       
+       if (!(m->flags & ACC_STATIC))
+               argcount++; /* count the 'this' argument */
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+               if (argcount > 255) {
+                       exceptions_throw_classformaterror(c, "Too many arguments in signature");
+                       return false;
+               }
+
+               /* check flag consistency */
+               if (m->name != utf_clinit) {
+                       i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
+
+                       if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
+                               exceptions_throw_classformaterror(c,
+                                                                                                 "Illegal method modifiers: 0x%X",
+                                                                                                 m->flags);
+                               return false;
+                       }
+
+                       if (m->flags & ACC_ABSTRACT) {
+                               if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
+                                                                ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
+                                       exceptions_throw_classformaterror(c,
+                                                                                                         "Illegal method modifiers: 0x%X",
+                                                                                                         m->flags);
+                                       return false;
+                               }
+                       }
+
+                       if (c->flags & ACC_INTERFACE) {
+                               if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
+                                       exceptions_throw_classformaterror(c,
+                                                                                                         "Illegal method modifiers: 0x%X",
+                                                                                                         m->flags);
+                                       return false;
+                               }
+                       }
+
+                       if (m->name == utf_init) {
+                               if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
+                                                               ACC_NATIVE | ACC_ABSTRACT)) {
+                                       exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
+                                       return false;
+                               }
+                       }
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+
+       /* mark the method as monomorphic until further notice */
+
+       m->flags |= ACC_METHOD_MONOMORPHIC;
+
+       /* non-abstract methods have an implementation in this class */
+
+       if (!(m->flags & ACC_ABSTRACT))
+               m->flags |= ACC_METHOD_IMPLEMENTED;
+               
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* attributes count */
+
+       attributes_count = suck_u2(cb);
+
+       for (i = 0; i < attributes_count; i++) {
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               /* attribute name index */
+
+               attribute_name_index = suck_u2(cb);
+
+               if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
+                       return false;
+
+               if (attribute_name == utf_Code) {
+                       /* Code */
+                       if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
+                               exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
+                               return false;
+                       }
+                       
+                       if (m->jcode) {
+                               exceptions_throw_classformaterror(c, "Multiple Code attributes");
+                               return false;
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+                               return false;
+
+                       suck_u4(cb);
+                       m->maxstack = suck_u2(cb);
+                       m->maxlocals = suck_u2(cb);
+
+                       if (m->maxlocals < argcount) {
+                               exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
+                               return false;
+                       }
+                       
+                       if (!suck_check_classbuffer_size(cb, 4))
+                               return false;
+
+                       m->jcodelength = suck_u4(cb);
+
+                       if (m->jcodelength == 0) {
+                               exceptions_throw_classformaterror(c, "Code of a method has length 0");
+                               return false;
+                       }
+                       
+                       if (m->jcodelength > 65535) {
+                               exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
+                               return false;
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, m->jcodelength))
+                               return false;
+
+                       m->jcode = MNEW(u1, m->jcodelength);
+                       suck_nbytes(m->jcode, cb, m->jcodelength);
+
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       m->rawexceptiontablelength = suck_u2(cb);
+                       if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
+                               return false;
+
+                       m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
+
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat) {
+                               count_vmcode_len += m->jcodelength + 18;
+                               count_extable_len +=
+                                       m->rawexceptiontablelength * sizeof(raw_exception_entry);
+                       }
+#endif
+
+                       for (j = 0; j < m->rawexceptiontablelength; j++) {
+                               u4 idx;
+                               m->rawexceptiontable[j].startpc = suck_u2(cb);
+                               m->rawexceptiontable[j].endpc = suck_u2(cb);
+                               m->rawexceptiontable[j].handlerpc = suck_u2(cb);
+
+                               idx = suck_u2(cb);
+                               if (!idx) {
+                                       m->rawexceptiontable[j].catchtype.any = NULL;
+
+                               } else {
+                                       /* the classref is created later */
+                                       if (!(m->rawexceptiontable[j].catchtype.any =
+                                                 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
+                                               return false;
+                               }
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, 2))
+                               return false;
+
+                       /* code attributes count */
+
+                       code_attributes_count = suck_u2(cb);
+
+                       for (k = 0; k < code_attributes_count; k++) {
+                               if (!suck_check_classbuffer_size(cb, 2))
+                                       return false;
+
+                               /* code attribute name index */
+
+                               code_attribute_name_index = suck_u2(cb);
+
+                               if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
+                                       return false;
+
+                               /* check which code attribute */
+
+                               if (code_attribute_name == utf_LineNumberTable) {
+                                       /* LineNumberTable */
+                                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                                               return false;
+
+                                       /* attribute length */
+
+                                       (void) suck_u4(cb);
+
+                                       /* line number table length */
+
+                                       m->linenumbercount = suck_u2(cb);
+
+                                       if (!suck_check_classbuffer_size(cb,
+                                                                                               (2 + 2) * m->linenumbercount))
+                                               return false;
+
+                                       m->linenumbers = MNEW(lineinfo, m->linenumbercount);
+
+#if defined(ENABLE_STATISTICS)
+                                       if (opt_stat)
+                                               size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
+#endif
+                                       
+                                       for (l = 0; l < m->linenumbercount; l++) {
+                                               m->linenumbers[l].start_pc    = suck_u2(cb);
+                                               m->linenumbers[l].line_number = suck_u2(cb);
+                                       }
+                               }
+#if defined(ENABLE_JAVASE)
+                               else if (code_attribute_name == utf_StackMapTable) {
+                                       /* StackTableMap */
+
+                                       if (!stackmap_load_attribute_stackmaptable(cb, m))
+                                               return false;
+                               }
+#endif
+                               else {
+                                       /* unknown code attribute */
+
+                                       if (!loader_skip_attribute_body(cb))
+                                               return false;
+                               }
+                       }
+               }
+               else if (attribute_name == utf_Exceptions) {
+                       /* Exceptions */
+
+                       if (m->thrownexceptions != NULL) {
+                               exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
+                               return false;
+                       }
+
+                       if (!suck_check_classbuffer_size(cb, 4 + 2))
+                               return false;
+
+                       /* attribute length */
+
+                       (void) suck_u4(cb);
+
+                       m->thrownexceptionscount = suck_u2(cb);
+
+                       if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
+                               return false;
+
+                       m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
+
+                       for (j = 0; j < m->thrownexceptionscount; j++) {
+                               /* the classref is created later */
+                               if (!((m->thrownexceptions)[j].any =
+                                         (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
+                                       return false;
+                       }
+               }
+#if defined(ENABLE_JAVASE)
+               else if (attribute_name == utf_Signature) {
+                       /* Signature */
+
+                       if (!loader_load_attribute_signature(cb, &(m->signature)))
+                               return false;
+               }
+#endif
+               else {
+                       /* unknown attribute */
+
+                       if (!loader_skip_attribute_body(cb))
+                               return false;
+               }
+       }
+
+       if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
+               exceptions_throw_classformaterror(c, "Missing Code attribute");
+               return false;
+       }
+
+       /* everything was ok */
+
+       return true;
+}
+
+
+/* load_class_from_sysloader ***************************************************
+
+   Load the class with the given name using the system class loader
+
+   IN:
+       name.............the classname
+
+   RETURN VALUE:
+       the loaded class, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+classinfo *load_class_from_sysloader(utf *name)
+{
+       methodinfo        *m;
+       java_objectheader *cl;
+       classinfo         *c;
+
+       assert(class_java_lang_Object);
+       assert(class_java_lang_ClassLoader);
+       assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
+       
+       m = class_resolveclassmethod(class_java_lang_ClassLoader,
+                                                                utf_getSystemClassLoader,
+                                                                utf_void__java_lang_ClassLoader,
+                                                                class_java_lang_Object,
+                                                                false);
+
+       if (!m)
+               return false;
+
+       cl = vm_call_method(m, NULL);
+
+       if (!cl)
+               return false;
+
+       c = load_class_from_classloader(name, cl);
+
+       return c;
+}
+
+
+/* load_class_from_classloader *************************************************
+
+   Load the class with the given name using the given user-defined class loader.
+
+   IN:
+       name.............the classname
+          cl...............user-defined class loader
+          
+   RETURN VALUE:
+       the loaded class, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
+{
+       java_objectheader *o;
+       classinfo         *c;
+       classinfo         *tmpc;
+       java_objectheader *string;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_lookup, time_prepare, time_java, 
+                                       time_cache;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       assert(name);
+
+       /* lookup if this class has already been loaded */
+
+       c = classcache_lookup(cl, name);
+
+       RT_TIMING_GET_TIME(time_lookup);
+       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
+
+       if (c != NULL)
+               return c;
+
+       /* if other class loader than bootstrap, call it */
+
+       if (cl != NULL) {
+               methodinfo *lc;
+               char       *text;
+               s4          namelen;
+
+               text = name->text;
+               namelen = name->blength;
+
+               /* handle array classes */
+               if (text[0] == '[') {
+                       classinfo *comp;
+                       utf       *u;
+
+                       switch (text[1]) {
+                       case 'L':
+                               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
+                               if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
+                                       exceptions_throw_noclassdeffounderror(name);
+                                       return false;
+                               }
+
+                               u = utf_new(text + 2, namelen - 3);
+
+                               if (!(comp = load_class_from_classloader(u, cl)))
+                                       return false;
+
+                               /* create the array class */
+
+                               c = class_array_of(comp, false);
+
+                               tmpc = classcache_store(cl, c, true);
+
+                               if (tmpc == NULL) {
+                                       /* exception, free the loaded class */
+                                       c->state &= ~CLASS_LOADING;
+                                       class_free(c);
+                               }
+
+                               return tmpc;
+
+                       case '[':
+                               /* load the component class */
+
+                               u = utf_new(text + 1, namelen - 1);
+
+                               if (!(comp = load_class_from_classloader(u, cl)))
+                                       return false;
+
+                               /* create the array class */
+
+                               c = class_array_of(comp, false);
+
+                               tmpc = classcache_store(cl, c, true);
+
+                               if (tmpc == NULL) {
+                                       /* exception, free the loaded class */
+                                       c->state &= ~CLASS_LOADING;
+                                       class_free(c);
+                               }
+
+                               return tmpc;
+
+                       default:
+                               /* primitive array classes are loaded by the bootstrap loader */
+
+                               c = load_class_bootstrap(name);
+
+                               return c;
+                       }
+               }
+               
+               assert(class_java_lang_Object);
+
+               lc = class_resolveclassmethod(cl->vftbl->class,
+                                                                         utf_loadClass,
+                                                                         utf_java_lang_String__java_lang_Class,
+                                                                         class_java_lang_Object,
+                                                                         true);
+
+               if (!lc)
+                       return false; /* exception */
+
+               /* move return value into `o' and cast it afterwards to a classinfo* */
+
+               string = javastring_new_slash_to_dot(name);
+
+               RT_TIMING_GET_TIME(time_prepare);
+
+               o = vm_call_method(lc, cl, string);
+
+               RT_TIMING_GET_TIME(time_java);
+
+               c = (classinfo *) o;
+
+               if (c != NULL) {
+                       /* Store this class in the loaded class cache. If another
+                          class with the same (initloader,name) pair has been
+                          stored earlier it will be returned by classcache_store
+                          In this case classcache_store may not free the class
+                          because it has already been exposed to Java code which
+                          may have kept references to that class. */
+
+                   tmpc = classcache_store(cl, c, false);
+
+                       if (tmpc == NULL) {
+                               /* exception, free the loaded class */
+                               c->state &= ~CLASS_LOADING;
+                               class_free(c);
+                       }
+
+                       c = tmpc;
+
+               } else {
+                       /* loadClass has thrown an exception.  We must convert
+                          ClassNotFoundException into
+                          NoClassDefFoundException. */
+
+                       /* XXX Maybe we should have a flag that avoids this
+                          conversion for calling load_class_from_classloader from
+                          Class.forName.  Currently we do a double conversion in
+                          these cases.  */
+
+                       classnotfoundexception_to_noclassdeffounderror();
+               }
+
+               RT_TIMING_GET_TIME(time_cache);
+
+               RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
+               RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
+               RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
+
+               /* SUN compatible -verbose:class output */
+
+               if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
+                       printf("[Loaded ");
+                       utf_display_printable_ascii_classname(name);
+                       printf("]\n");
+               }
+
+#if defined(ENABLE_JVMTI)
+               /* fire Class Load JVMTI event */
+               if (jvmti) jvmti_ClassLoadPrepare(false, c);
+#endif
+
+
+               return c;
+       } 
+
+       c = load_class_bootstrap(name);
+
+       return c;
+}
+
+
+/* load_class_bootstrap ********************************************************
+       
+   Load the class with the given name using the bootstrap class loader.
+
+   IN:
+       name.............the classname
+
+   RETURN VALUE:
+       loaded classinfo, or
+          NULL if an exception has been thrown
+
+   SYNCHRONIZATION:
+       load_class_bootstrap is synchronized. It can be treated as an
+          atomic operation.
+
+*******************************************************************************/
+
+classinfo *load_class_bootstrap(utf *name)
+{
+       classbuffer *cb;
+       classinfo   *c;
+       classinfo   *r;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_lookup, time_array, time_suck, 
+                                       time_load, time_cache;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       /* for debugging */
+
+       assert(name);
+
+       /* lookup if this class has already been loaded */
+
+       if ((r = classcache_lookup(NULL, name))) {
+
+               RT_TIMING_GET_TIME(time_lookup);
+               RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
+               
+               return r;
+       }
+
+       RT_TIMING_GET_TIME(time_lookup);
+       RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
+               
+       /* create the classinfo */
+
+       c = class_create_classinfo(name);
+
+       /* handle array classes */
+
+       if (name->text[0] == '[') {
+               c = load_newly_created_array(c, NULL);
+               if (c == NULL)
+                       return NULL;
+               assert(c->state & CLASS_LOADED);
+
+               RT_TIMING_GET_TIME(time_array);
+               RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
+               
+               return c;
+       }
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getcompilingtime)
+               compilingtime_stop();
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* load classdata, throw exception on error */
+
+       cb = suck_start(c);
+
+       if (cb == NULL) {
+               /* this normally means, the classpath was not set properly */
+
+               if (name == utf_java_lang_Object)
+                       vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
+
+               exceptions_throw_noclassdeffounderror(name);
+
+               return NULL;
+       }
+
+       RT_TIMING_GET_TIME(time_suck);
+       
+       /* load the class from the buffer */
+
+       r = load_class_from_classbuffer(cb);
+
+       RT_TIMING_GET_TIME(time_load);
+       
+       if (!r) {
+               /* the class could not be loaded, free the classinfo struct */
+
+               class_free(c);
+
+       } else {
+               /* Store this class in the loaded class cache this step also
+               checks the loading constraints. If the class has been loaded
+               before, the earlier loaded class is returned. */
+
+               classinfo *res = classcache_store(NULL, c, true);
+
+               if (!res) {
+                       /* exception */
+                       class_free(c);
+               }
+
+               r = res;
+       }
+
+       RT_TIMING_GET_TIME(time_cache);
+       
+       /* SUN compatible -verbose:class output */
+
+       if (opt_verboseclass && r) {
+               printf("[Loaded ");
+               utf_display_printable_ascii_classname(name);
+               printf(" from %s]\n", cb->path);
+       }
+
+       /* free memory */
+
+       suck_stop(cb);
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+
+       if (opt_getcompilingtime)
+               compilingtime_start();
+#endif
+
+       RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
+       RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
+       RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
+       RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
+
+       return r;
+}
+
+
+/* load_class_from_classbuffer *************************************************
+       
+   Loads everything interesting about a class from the class file. The
+   'classinfo' structure must have been allocated previously.
+
+   The super class and the interfaces implemented by this class need
+   not be loaded. The link is set later by the function 'class_link'.
+
+   The loaded class is removed from the list 'unloadedclasses' and
+   added to the list 'unlinkedclasses'.
+       
+   SYNCHRONIZATION:
+       This function is NOT synchronized!
+   
+*******************************************************************************/
+
+classinfo *load_class_from_classbuffer(classbuffer *cb)
+{
+       classinfo *c;
+       utf *name;
+       utf *supername;
+       u4 i,j;
+       u4 ma, mi;
+       s4 dumpsize;
+       descriptor_pool *descpool;
+#if defined(ENABLE_STATISTICS)
+       u4 classrefsize;
+       u4 descsize;
+#endif
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_checks, time_ndpool, time_cpool,
+                                       time_setup, time_fields, time_methods, time_classrefs,
+                                       time_descs,     time_setrefs, time_parsefds, time_parsemds,
+                                       time_parsecpool, time_verify, time_attrs;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       /* get the classbuffer's class */
+
+       c = cb->class;
+
+       /* the class is already loaded */
+
+       if (c->state & CLASS_LOADED)
+               return c;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_class_loads++;
+#endif
+
+#if !defined(NDEBUG)
+       /* output for debugging purposes */
+
+       if (loadverbose)
+               log_message_class("Loading class: ", c);
+#endif
+
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* class is currently loading */
+
+       c->state |= CLASS_LOADING;
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
+               goto return_exception;
+
+       /* check signature */
+
+       if (suck_u4(cb) != MAGIC) {
+               exceptions_throw_classformaterror(c, "Bad magic number");
+
+               goto return_exception;
+       }
+
+       /* check version */
+
+       mi = suck_u2(cb);
+       ma = suck_u2(cb);
+
+       if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
+               exceptions_throw_unsupportedclassversionerror(c, ma, mi);
+               goto return_exception;
+       }
+
+       RT_TIMING_GET_TIME(time_checks);
+
+       /* create a new descriptor pool */
+
+       descpool = descriptor_pool_new(c);
+
+       RT_TIMING_GET_TIME(time_ndpool);
+
+       /* load the constant pool */
+
+       if (!load_constantpool(cb, descpool))
+               goto return_exception;
+
+       RT_TIMING_GET_TIME(time_cpool);
+
+       /* ACC flags */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               goto return_exception;
+
+       c->flags = suck_u2(cb);
+
+       /* check ACC flags consistency */
+
+       if (c->flags & ACC_INTERFACE) {
+               if (!(c->flags & ACC_ABSTRACT)) {
+                       /* We work around this because interfaces in JDK 1.1 are
+                        * not declared abstract. */
+
+                       c->flags |= ACC_ABSTRACT;
+               }
+
+               if (c->flags & ACC_FINAL) {
+                       exceptions_throw_classformaterror(c,
+                                                                                         "Illegal class modifiers: 0x%X",
+                                                                                         c->flags);
+                       goto return_exception;
+               }
+
+               if (c->flags & ACC_SUPER) {
+                       c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
+               }
+       }
+
+       if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
+               exceptions_throw_classformaterror(c,
+                                                                                 "Illegal class modifiers: 0x%X",
+                                                                                 c->flags);
+               goto return_exception;
+       }
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2))
+               goto return_exception;
+
+       /* this class */
+
+       i = suck_u2(cb);
+       if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
+               goto return_exception;
+
+       if (c->name == utf_not_named_yet) {
+               /* we finally have a name for this class */
+               c->name = name;
+               class_set_packagename(c);
+
+       } else if (name != c->name) {
+               /* TODO: i want to be an exceptions-function! */
+               char *msg;
+               s4    msglen;
+
+               msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
+                       utf_bytes(name) + strlen(")") + strlen("0");
+
+               msg = MNEW(char, msglen);
+
+               utf_copy_classname(msg, c->name);
+               strcat(msg, " (wrong name: ");
+               utf_cat_classname(msg, name);
+               strcat(msg, ")");
+
+#warning FIX ME!
+/*             *exceptionptr = */
+/*                     new_exception_message("java/lang/NoClassDefFoundError", msg); */
+               exceptions_throw_noclassdeffounderror(c->name);
+
+               MFREE(msg, char, msglen);
+
+               goto return_exception;
+       }
+
+       /* retrieve superclass */
+
+       c->super.any = NULL;
+       if ((i = suck_u2(cb))) {
+               if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
+                       goto return_exception;
+
+               /* java.lang.Object may not have a super class. */
+
+               if (c->name == utf_java_lang_Object) {
+                       exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
+                       goto return_exception;
+               }
+
+               /* Interfaces must have java.lang.Object as super class. */
+
+               if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
+                       exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
+                       goto return_exception;
+               }
+
+       } else {
+               supername = NULL;
+
+               /* This is only allowed for java.lang.Object. */
+
+               if (c->name != utf_java_lang_Object) {
+                       exceptions_throw_classformaterror(c, "Bad superclass index");
+                       goto return_exception;
+               }
+       }
+
+       /* retrieve interfaces */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               goto return_exception;
+
+       c->interfacescount = suck_u2(cb);
+
+       if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
+               goto return_exception;
+
+       c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
+       for (i = 0; i < c->interfacescount; i++) {
+               /* the classrefs are created later */
+               if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
+                       goto return_exception;
+       }
+
+       RT_TIMING_GET_TIME(time_setup);
+
+       /* load fields */
+       if (!suck_check_classbuffer_size(cb, 2))
+               goto return_exception;
+
+       c->fieldscount = suck_u2(cb);
+#if defined(ENABLE_GC_CACAO)
+       c->fields = MNEW(fieldinfo, c->fieldscount);
+       MZERO(c->fields, fieldinfo, c->fieldscount);
+#else
+       c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
+#endif
+
+       for (i = 0; i < c->fieldscount; i++) {
+               if (!load_field(cb, &(c->fields[i]),descpool))
+                       goto return_exception;
+       }
+
+       RT_TIMING_GET_TIME(time_fields);
+
+       /* load methods */
+       if (!suck_check_classbuffer_size(cb, 2))
+               goto return_exception;
+
+       c->methodscount = suck_u2(cb);
+       c->methods = MNEW(methodinfo, c->methodscount);
+
+       MZERO(c->methods, methodinfo, c->methodscount);
+       
+       for (i = 0; i < c->methodscount; i++) {
+               if (!loader_load_method(cb, &(c->methods[i]), descpool))
+                       goto return_exception;
+       }
+
+       RT_TIMING_GET_TIME(time_methods);
+
+       /* create the class reference table */
+
+       c->classrefs =
+               descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
+
+       RT_TIMING_GET_TIME(time_classrefs);
+
+       /* allocate space for the parsed descriptors */
+
+       descriptor_pool_alloc_parsed_descriptors(descpool);
+       c->parseddescs =
+               descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat) {
+               descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
+               count_classref_len += classrefsize;
+               count_parsed_desc_len += descsize;
+       }
+#endif
+
+       RT_TIMING_GET_TIME(time_descs);
+
+       /* put the classrefs in the constant pool */
+       for (i = 0; i < c->cpcount; i++) {
+               if (c->cptags[i] == CONSTANT_Class) {
+                       utf *name = (utf *) c->cpinfos[i];
+                       c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
+               }
+       }
+
+       /* set the super class reference */
+
+       if (supername) {
+               c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
+               if (!c->super.ref)
+                       goto return_exception;
+       }
+
+       /* set the super interfaces references */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               c->interfaces[i].ref =
+                       descriptor_pool_lookup_classref(descpool,
+                                                                                       (utf *) c->interfaces[i].any);
+               if (!c->interfaces[i].ref)
+                       goto return_exception;
+       }
+
+       RT_TIMING_GET_TIME(time_setrefs);
+
+       /* parse field descriptors */
+
+       for (i = 0; i < c->fieldscount; i++) {
+               c->fields[i].parseddesc =
+                       descriptor_pool_parse_field_descriptor(descpool,
+                                                                                                  c->fields[i].descriptor);
+               if (!c->fields[i].parseddesc)
+                       goto return_exception;
+       }
+
+       RT_TIMING_GET_TIME(time_parsefds);
+
+       /* parse method descriptors */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &c->methods[i];
+               m->parseddesc =
+                       descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
+                                                                                                       m->flags, class_get_self_classref(m->class));
+               if (!m->parseddesc)
+                       goto return_exception;
+
+               for (j = 0; j < m->rawexceptiontablelength; j++) {
+                       if (!m->rawexceptiontable[j].catchtype.any)
+                               continue;
+                       if ((m->rawexceptiontable[j].catchtype.ref =
+                                descriptor_pool_lookup_classref(descpool,
+                                               (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
+                               goto return_exception;
+               }
+
+               for (j = 0; j < m->thrownexceptionscount; j++) {
+                       if (!m->thrownexceptions[j].any)
+                               continue;
+                       if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
+                                               (utf *) m->thrownexceptions[j].any)) == NULL)
+                               goto return_exception;
+               }
+       }
+
+       RT_TIMING_GET_TIME(time_parsemds);
+
+       /* parse the loaded descriptors */
+
+       for (i = 0; i < c->cpcount; i++) {
+               constant_FMIref *fmi;
+               s4               index;
+
+               switch (c->cptags[i]) {
+               case CONSTANT_Fieldref:
+                       fmi = (constant_FMIref *) c->cpinfos[i];
+                       fmi->parseddesc.fd =
+                               descriptor_pool_parse_field_descriptor(descpool,
+                                                                                                          fmi->descriptor);
+                       if (!fmi->parseddesc.fd)
+                               goto return_exception;
+                       index = fmi->p.index;
+                       fmi->p.classref =
+                               (constant_classref *) class_getconstant(c, index,
+                                                                                                               CONSTANT_Class);
+                       if (!fmi->p.classref)
+                               goto return_exception;
+                       break;
+               case CONSTANT_Methodref:
+               case CONSTANT_InterfaceMethodref:
+                       fmi = (constant_FMIref *) c->cpinfos[i];
+                       index = fmi->p.index;
+                       fmi->p.classref =
+                               (constant_classref *) class_getconstant(c, index,
+                                                                                                               CONSTANT_Class);
+                       if (!fmi->p.classref)
+                               goto return_exception;
+                       fmi->parseddesc.md =
+                               descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                               fmi->descriptor,
+                                                                                                               ACC_UNDEF,
+                                                                                                               fmi->p.classref);
+                       if (!fmi->parseddesc.md)
+                               goto return_exception;
+                       break;
+               }
+       }
+
+       RT_TIMING_GET_TIME(time_parsecpool);
+
+#ifdef ENABLE_VERIFIER
+       /* Check if all fields and methods can be uniquely
+        * identified by (name,descriptor). */
+
+       if (opt_verify) {
+               /* We use a hash table here to avoid making the
+                * average case quadratic in # of methods, fields.
+                */
+               static int shift = 0;
+               u2 *hashtab;
+               u2 *next; /* for chaining colliding hash entries */
+               size_t len;
+               size_t hashlen;
+               u2 index;
+               u2 old;
+
+               /* Allocate hashtable */
+               len = c->methodscount;
+               if (len < c->fieldscount) len = c->fieldscount;
+               hashlen = 5 * len;
+               hashtab = MNEW(u2,(hashlen + len));
+               next = hashtab + hashlen;
+
+               /* Determine bitshift (to get good hash values) */
+               if (!shift) {
+                       len = sizeof(utf);
+                       while (len) {
+                               len >>= 1;
+                               shift++;
+                       }
+               }
+
+               /* Check fields */
+               memset(hashtab, 0, sizeof(u2) * (hashlen + len));
+
+               for (i = 0; i < c->fieldscount; ++i) {
+                       fieldinfo *fi = c->fields + i;
+
+                       /* It's ok if we lose bits here */
+                       index = ((((size_t) fi->name) +
+                                         ((size_t) fi->descriptor)) >> shift) % hashlen;
+
+                       if ((old = hashtab[index])) {
+                               old--;
+                               next[i] = old;
+                               do {
+                                       if (c->fields[old].name == fi->name &&
+                                               c->fields[old].descriptor == fi->descriptor) {
+                                               exceptions_throw_classformaterror(c, "Repetitive field name/signature");
+                                               goto return_exception;
+                                       }
+                               } while ((old = next[old]));
+                       }
+                       hashtab[index] = i + 1;
+               }
+
+               /* Check methods */
+               memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
+
+               for (i = 0; i < c->methodscount; ++i) {
+                       methodinfo *mi = c->methods + i;
+
+                       /* It's ok if we lose bits here */
+                       index = ((((size_t) mi->name) +
+                                         ((size_t) mi->descriptor)) >> shift) % hashlen;
+
+                       /*{ JOWENN
+                               int dbg;
+                               for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
+                                       printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
+                               }
+                       }*/
+
+                       if ((old = hashtab[index])) {
+                               old--;
+                               next[i] = old;
+                               do {
+                                       if (c->methods[old].name == mi->name &&
+                                               c->methods[old].descriptor == mi->descriptor) {
+                                               exceptions_throw_classformaterror(c, "Repetitive method name/signature");
+                                               goto return_exception;
+                                       }
+                               } while ((old = next[old]));
+                       }
+                       hashtab[index] = i + 1;
+               }
+
+               MFREE(hashtab, u2, (hashlen + len));
+       }
+#endif /* ENABLE_VERIFIER */
+
+       RT_TIMING_GET_TIME(time_verify);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat) {
+               size_classinfo  += sizeof(classinfo*) * c->interfacescount;
+               size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
+               size_methodinfo += sizeof(methodinfo) * c->methodscount;
+       }
+#endif
+
+       /* load attribute structures */
+
+       if (!class_load_attributes(cb))
+               goto return_exception;
+
+       /* Pre Java 1.5 version don't check this. This implementation is like
+          Java 1.5 do it: for class file version 45.3 we don't check it, older
+          versions are checked.
+        */
+
+       if (((ma == 45) && (mi > 3)) || (ma > 45)) {
+               /* check if all data has been read */
+               s4 classdata_left = ((cb->data + cb->size) - cb->pos);
+
+               if (classdata_left > 0) {
+                       exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
+                       goto return_exception;
+               }
+       }
+
+       RT_TIMING_GET_TIME(time_attrs);
+
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       /* revert loading state and class is loaded */
+
+       c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
+
+#if defined(ENABLE_JVMTI)
+       /* fire Class Prepare JVMTI event */
+
+       if (jvmti)
+               jvmti_ClassLoadPrepare(true, c);
+#endif
+
+#if !defined(NDEBUG)
+       if (loadverbose)
+               log_message_class("Loading done class: ", c);
+#endif
+
+       RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
+       RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
+       RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
+       RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
+       RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
+       RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
+       RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
+       RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
+       RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
+       RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
+       RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
+       RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
+       RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
+       RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
+       RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
+
+       return c;
+
+return_exception:
+       /* release dump area */
+
+       dump_release(dumpsize);
+
+       /* an exception has been thrown */
+
+       return NULL;
+}
+
+
+/* load_newly_created_array ****************************************************
+
+   Load a newly created array class.
+
+       RETURN VALUE:
+           c....................the array class C has been loaded
+               other classinfo......the array class was found in the class cache, 
+                                    C has been freed
+           NULL.................an exception has been thrown
+
+       Note:
+               This is an internal function. Do not use it unless you know exactly
+               what you are doing!
+
+               Use one of the load_class_... functions for general array class loading.
+
+*******************************************************************************/
+
+classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
+{
+       classinfo         *comp = NULL;
+       methodinfo        *clone;
+       methoddesc        *clonedesc;
+       constant_classref *classrefs;
+       char              *text;
+       s4                 namelen;
+       utf               *u;
+
+       text = c->name->text;
+       namelen = c->name->blength;
+
+       /* Check array class name */
+
+       if ((namelen < 2) || (text[0] != '[')) {
+               exceptions_throw_noclassdeffounderror(c->name);
+               return NULL;
+       }
+
+       /* Check the element type */
+
+       switch (text[1]) {
+       case '[':
+               /* c is an array of arrays. We have to create the component class. */
+
+               u = utf_new(text + 1, namelen - 1);
+               if (!(comp = load_class_from_classloader(u, loader)))
+                       return NULL;
+
+               assert(comp->state & CLASS_LOADED);
+
+               if (opt_eager)
+                       if (!link_class(c))
+                               return NULL;
+
+               /* the array's flags are that of the component class */
+               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
+               c->classloader = comp->classloader;
+               break;
+
+       case 'L':
+               /* c is an array of objects. */
+
+               /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
+               if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
+                       exceptions_throw_noclassdeffounderror(c->name);
+                       return NULL;
+               }
+
+               u = utf_new(text + 2, namelen - 3);
+
+               if (!(comp = load_class_from_classloader(u, loader)))
+                       return NULL;
+
+               assert(comp->state & CLASS_LOADED);
+
+               if (opt_eager)
+                       if (!link_class(c))
+                               return NULL;
+
+               /* the array's flags are that of the component class */
+               c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
+               c->classloader = comp->classloader;
+               break;
+
+       default:
+               /* c is an array of a primitive type */
+
+               /* check for cases like `[II' */
+               if (namelen > 2) {
+                       exceptions_throw_noclassdeffounderror(c->name);
+                       return NULL;
+               }
+
+               /* the accessibility of the array class is public (VM Spec 5.3.3) */
+               c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
+               c->classloader = NULL;
+       }
+
+       assert(class_java_lang_Object);
+#if defined(ENABLE_JAVASE)
+       assert(class_java_lang_Cloneable);
+       assert(class_java_io_Serializable);
+#endif
+
+       /* setup the array class */
+
+       c->super.cls = class_java_lang_Object;
+
+    c->interfacescount = 0;
+       c->interfaces = NULL;
+
+#if defined(ENABLE_JAVASE)
+    c->interfaces = MNEW(classref_or_classinfo, 2);
+
+       if (opt_eager) {
+               classinfo *tc;
+
+               tc = class_java_lang_Cloneable;
+               assert(tc->state & CLASS_LOADED);
+               list_add_first(&unlinkedclasses, tc);
+               c->interfaces[0].cls = tc;
+
+               tc = class_java_io_Serializable;
+               assert(tc->state & CLASS_LOADED);
+               list_add_first(&unlinkedclasses, tc);
+               c->interfaces[1].cls = tc;
+       }
+       else {
+               c->interfaces[0].cls = class_java_lang_Cloneable;
+               c->interfaces[1].cls = class_java_io_Serializable;
+       }
+#endif
+
+       c->methodscount = 1;
+       c->methods = MNEW(methodinfo, c->methodscount);
+       MZERO(c->methods, methodinfo, c->methodscount);
+
+       classrefs = MNEW(constant_classref, 2);
+       CLASSREF_INIT(classrefs[0], c, c->name);
+       CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
+
+       /* create descriptor for clone method */
+       /* we need one paramslot which is reserved for the 'this' parameter */
+       clonedesc = NEW(methoddesc);
+       clonedesc->returntype.type = TYPE_ADR;
+       clonedesc->returntype.classref = classrefs + 1;
+       clonedesc->returntype.arraydim = 0;
+       /* initialize params to "empty", add real params below in
+          descriptor_params_from_paramtypes */
+       clonedesc->paramcount = 0;
+       clonedesc->paramslots = 0;
+       clonedesc->paramtypes[0].classref = classrefs + 0;
+       clonedesc->params = NULL;
+
+       /* create methodinfo */
+
+       clone = c->methods;
+       MSET(clone, 0, methodinfo, 1);
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&clone->header);
+#endif
+
+       /* ATTENTION: if you delete the ACC_NATIVE below, set
+          clone->maxlocals=1 (interpreter related) */
+
+       clone->flags      = ACC_PUBLIC | ACC_NATIVE;
+       clone->name       = utf_clone;
+       clone->descriptor = utf_void__java_lang_Object;
+       clone->parseddesc = clonedesc;
+       clone->class      = c;
+
+       /* parse the descriptor to get the register allocation */
+
+       if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
+               return false;
+
+       clone->code = codegen_createnativestub(BUILTIN_clone, clone);
+
+       /* XXX: field: length? */
+
+       /* array classes are not loaded from class files */
+
+       c->state          |= CLASS_LOADED;
+       c->parseddescs    = (u1 *) clonedesc;
+       c->parseddescsize = sizeof(methodinfo);
+       c->classrefs      = classrefs;
+       c->classrefcount  = 1;
+
+       /* insert class into the loaded class cache */
+       /* XXX free classinfo if NULL returned? */
+
+       return classcache_store(loader, c, true);
+}
+
+
+/* loader_close ****************************************************************
+
+   Frees all resources.
+       
+*******************************************************************************/
+
+void loader_close(void)
+{
+       /* empty */
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/loader.h b/src/vmcore/loader.h
new file mode 100644 (file)
index 0000000..779018b
--- /dev/null
@@ -0,0 +1,151 @@
+/* src/vmcore/loader.h - class loader header
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: loader.h 7246 2007-01-29 18:49:05Z twisti $
+*/
+
+
+#ifndef _LOADER_H
+#define _LOADER_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct classbuffer classbuffer;
+
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+#include "vmcore/utf8.h"
+
+
+/* constant pool entries *******************************************************
+
+       All constant pool entries need a data structure which contain the entrys
+       value. In some cases this structure exist already, in the remaining cases
+       this structure must be generated:
+
+               kind                      structure                     generated?
+       ----------------------------------------------------------------------
+    CONSTANT_Class               constant_classref                  yes
+    CONSTANT_Fieldref            constant_FMIref                    yes
+    CONSTANT_Methodref           constant_FMIref                    yes
+    CONSTANT_InterfaceMethodref  constant_FMIref                    yes
+    CONSTANT_String              unicode                             no
+    CONSTANT_Integer             constant_integer                   yes
+    CONSTANT_Float               constant_float                     yes
+    CONSTANT_Long                constant_long                      yes
+    CONSTANT_Double              constant_double                    yes
+    CONSTANT_NameAndType         constant_nameandtype               yes
+    CONSTANT_Utf8                unicode                             no
+    CONSTANT_UNUSED              -
+
+*******************************************************************************/
+
+typedef struct {            /* Integer                                        */
+       s4 value;
+} constant_integer;
+
+       
+typedef struct {            /* Float                                          */
+       float value;
+} constant_float;
+
+
+typedef struct {            /* Long                                           */
+       s8 value;
+} constant_long;
+       
+
+typedef struct {            /* Double                                         */
+       double value;
+} constant_double;
+
+
+typedef struct {            /* NameAndType (Field or Method)                  */
+       utf *name;              /* field/method name                              */
+       utf *descriptor;        /* field/method type descriptor string            */
+} constant_nameandtype;
+
+
+/* classbuffer ****************************************************************/
+
+struct classbuffer {
+       classinfo *class;                   /* pointer to classinfo structure     */
+       u1        *data;                    /* pointer to byte code               */
+       s4         size;                    /* size of the byte code              */
+       u1        *pos;                     /* current read position              */
+       char      *path;                    /* path to file (for debugging)       */
+};
+
+
+/* function prototypes ********************************************************/
+
+/* initialize loader, load important systemclasses */
+bool loader_init(void);
+
+void loader_load_all_classes(void);
+
+bool loader_skip_attribute_body(classbuffer *cb);
+
+#if defined(ENABLE_JAVASE)
+bool loader_load_attribute_signature(classbuffer *cb, utf **signature);
+#endif
+
+/* free resources */
+void loader_close(void);
+
+/* class loading functions */
+classinfo *load_class_from_sysloader(utf *name);
+classinfo *load_class_from_classloader(utf *name, java_objectheader *cl);
+classinfo *load_class_bootstrap(utf *name);
+
+/* (don't use the following directly) */
+classinfo *load_class_from_classbuffer(classbuffer *cb);
+classinfo *load_newly_created_array(classinfo *c,java_objectheader *loader);
+
+#endif /* _LOADER_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/method.c b/src/vmcore/method.c
new file mode 100644 (file)
index 0000000..662ae1b
--- /dev/null
@@ -0,0 +1,418 @@
+/* src/vmcore/method.c - method functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: method.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"
+
+#include "vm/jit/methodheader.h"
+
+#include "vmcore/class.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
+
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+extern bool inline_debug_log;
+#define INLINELOG(code)  do { if (inline_debug_log) { code } } while (0)
+#else
+#define INLINELOG(code)
+#endif
+
+
+/* method_free *****************************************************************
+
+   Frees all memory that was allocated for this method.
+
+*******************************************************************************/
+
+void method_free(methodinfo *m)
+{
+       if (m->jcode)
+               MFREE(m->jcode, u1, m->jcodelength);
+
+       if (m->rawexceptiontable)
+               MFREE(m->rawexceptiontable, raw_exception_entry, m->rawexceptiontablelength);
+
+       code_free_code_of_method(m);
+
+       if (m->stubroutine) {
+               if (m->flags & ACC_NATIVE) {
+                       removenativestub(m->stubroutine);
+
+               } else {
+                       removecompilerstub(m->stubroutine);
+               }
+       }
+}
+
+
+/* method_canoverwrite *********************************************************
+
+   Check if m and old are identical with respect to type and
+   name. This means that old can be overwritten with m.
+       
+*******************************************************************************/
+
+bool method_canoverwrite(methodinfo *m, methodinfo *old)
+{
+       if (m->name != old->name)
+               return false;
+
+       if (m->descriptor != old->descriptor)
+               return false;
+
+       if (m->flags & ACC_STATIC)
+               return false;
+
+       return true;
+}
+
+
+/* method_vftbl_lookup *********************************************************
+
+   Does a method lookup in the passed virtual function table.  This
+   function does exactly the same thing as JIT, but additionally
+   relies on the fact, that the methodinfo pointer is at the first
+   data segment slot (even for compiler stubs).
+
+*******************************************************************************/
+
+methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m)
+{
+       methodptr   mptr;
+       methodptr  *pmptr;
+       methodinfo *resm;                   /* pointer to new resolved method     */
+       codeinfo   *code;
+
+       /* If the method is not an instance method, just return it. */
+
+       if (m->flags & ACC_STATIC)
+               return m;
+
+       assert(vftbl);
+
+       /* Get the method from the virtual function table.  Is this an
+          interface method? */
+
+       if (m->class->flags & ACC_INTERFACE) {
+               pmptr = vftbl->interfacetable[-(m->class->index)];
+               mptr  = pmptr[(m - m->class->methods)];
+       }
+       else {
+               mptr = vftbl->table[m->vftblindex];
+       }
+
+       /* and now get the codeinfo pointer from the first data segment slot */
+
+       code = *((codeinfo **) (mptr + CodeinfoPointer));
+
+       resm = code->m;
+
+       return resm;
+}
+
+
+/* method_count_implementations ************************************************
+
+   Count the implementations of a method in a class cone (a class and all its
+   subclasses.)
+
+   IN:
+       m................the method to count
+          c................class at which to start the counting (this class and
+                           all its subclasses will be searched)
+
+   OUT:
+       *found...........if found != NULL, *found receives the method
+                           implementation that was found. This value is only
+                                               meaningful if the return value is 1.
+
+   RETURN VALUE:
+       the number of implementations found
+
+*******************************************************************************/
+
+s4 method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found)
+{
+       s4          count;
+       methodinfo *mp;
+       methodinfo *mend;
+       classinfo  *child;
+
+       count = 0;
+
+       mp = c->methods;
+       mend = mp + c->methodscount;
+
+       for (; mp < mend; ++mp) {
+               if (method_canoverwrite(mp, m)) {
+                       if (found)
+                               *found = mp;
+                       count++;
+                       break;
+               }
+       }
+
+       for (child = c->sub; child != NULL; child = child->nextsub) {
+               count += method_count_implementations(m, child, found);
+       }
+
+       return count;
+}
+
+
+/* method_add_to_worklist ******************************************************
+
+   Add the method to the given worklist. If the method already occurs in
+   the worklist, the worklist remains unchanged.
+
+*******************************************************************************/
+
+static void method_add_to_worklist(methodinfo *m, method_worklist **wl)
+{
+       method_worklist *wi;
+
+       for (wi = *wl; wi != NULL; wi = wi->next)
+               if (wi->m == m)
+                       return;
+
+       wi = NEW(method_worklist);
+       wi->next = *wl;
+       wi->m = m;
+
+       *wl = wi;
+}
+
+
+/* method_add_assumption_monomorphic *******************************************
+
+   Record the assumption that the method is monomorphic.
+
+   IN:
+      m.................the method
+         caller............the caller making the assumption
+
+*******************************************************************************/
+
+void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller)
+{
+       method_assumption *as;
+
+       /* XXX LOCKING FOR THIS FUNCTION? */
+
+       /* check if we already have registered this assumption */
+
+       for (as = m->assumptions; as != NULL; as = as->next) {
+               if (as->context == caller)
+                       return;
+       }
+
+       /* register the assumption */
+
+       as = NEW(method_assumption);
+       as->next = m->assumptions;
+       as->context = caller;
+
+       m->assumptions = as;
+}
+
+
+/* method_break_assumption_monomorphic *****************************************
+
+   Break the assumption that this method is monomorphic. All callers that
+   have registered this assumption are added to the worklist.
+
+   IN:
+      m.................the method
+         wl................worklist where to add invalidated callers
+
+*******************************************************************************/
+
+void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl)
+{
+       method_assumption *as;
+
+       /* XXX LOCKING FOR THIS FUNCTION? */
+
+       for (as = m->assumptions; as != NULL; as = as->next) {
+               INLINELOG(
+                       printf("ASSUMPTION BROKEN (monomorphism): ");
+                       method_print(m);
+                       printf(" in ");
+                       method_println(as->context);
+               );
+
+               method_add_to_worklist(as->context, wl);
+       }
+}
+
+
+/* method_printflags ***********************************************************
+
+   Prints the flags of a method to stdout like.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_printflags(methodinfo *m)
+{
+       if (m == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       if (m->flags & ACC_PUBLIC)       printf(" PUBLIC");
+       if (m->flags & ACC_PRIVATE)      printf(" PRIVATE");
+       if (m->flags & ACC_PROTECTED)    printf(" PROTECTED");
+       if (m->flags & ACC_STATIC)       printf(" STATIC");
+       if (m->flags & ACC_FINAL)        printf(" FINAL");
+       if (m->flags & ACC_SYNCHRONIZED) printf(" SYNCHRONIZED");
+       if (m->flags & ACC_VOLATILE)     printf(" VOLATILE");
+       if (m->flags & ACC_TRANSIENT)    printf(" TRANSIENT");
+       if (m->flags & ACC_NATIVE)       printf(" NATIVE");
+       if (m->flags & ACC_INTERFACE)    printf(" INTERFACE");
+       if (m->flags & ACC_ABSTRACT)     printf(" ABSTRACT");
+       if (m->flags & ACC_METHOD_MONOMORPHIC) printf(" (mono)");
+       if (m->flags & ACC_METHOD_IMPLEMENTED) printf(" (impl)");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_print ****************************************************************
+
+   Prints a method to stdout like:
+
+   java.lang.Object.<init>()V
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_print(methodinfo *m)
+{
+       if (m == NULL) {
+               printf("NULL");
+               return;
+       }
+
+       utf_display_printable_ascii_classname(m->class->name);
+       printf(".");
+       utf_display_printable_ascii(m->name);
+       utf_display_printable_ascii(m->descriptor);
+
+       method_printflags(m);
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_println **************************************************************
+
+   Prints a method plus new line to stdout like:
+
+   java.lang.Object.<init>()V
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_println(methodinfo *m)
+{
+       if (opt_debugcolor) printf("\033[31m"); /* red */
+       method_print(m);
+       if (opt_debugcolor) printf("\033[m");   
+       printf("\n");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_methodref_print ******************************************************
+
+   Prints a method reference to stdout.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_methodref_print(constant_FMIref *mr)
+{
+       if (!mr) {
+               printf("(constant_FMIref *)NULL");
+               return;
+       }
+
+       if (IS_FMIREF_RESOLVED(mr)) {
+               printf("<method> ");
+               method_print(mr->p.method);
+       }
+       else {
+               printf("<methodref> ");
+               utf_display_printable_ascii_classname(mr->p.classref->name);
+               printf(".");
+               utf_display_printable_ascii(mr->name);
+               utf_display_printable_ascii(mr->descriptor);
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* method_methodref_println ****************************************************
+
+   Prints a method reference to stdout, followed by a newline.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void method_methodref_println(constant_FMIref *mr)
+{
+       method_methodref_print(mr);
+       printf("\n");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/method.h b/src/vmcore/method.h
new file mode 100644 (file)
index 0000000..b90a346
--- /dev/null
@@ -0,0 +1,181 @@
+/* src/vmcore/method.h - method functions header
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: method.h 7246 2007-01-29 18:49:05Z twisti $
+*/
+
+
+#ifndef _METHOD_H
+#define _METHOD_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct methodinfo          methodinfo; 
+typedef struct raw_exception_entry raw_exception_entry;
+typedef struct lineinfo            lineinfo; 
+typedef struct method_assumption   method_assumption;
+typedef struct method_worklist     method_worklist;
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vm/jit/code.h"
+#include "vm/jit/codegen-common.h"
+
+#include "vmcore/descriptor.h"
+#include "vmcore/references.h"
+#include "vmcore/linker.h"
+
+#if defined(ENABLE_JAVASE)
+# include "vmcore/stackmap.h"
+#endif
+
+#include "vmcore/utf8.h"
+
+
+/* methodinfo *****************************************************************/
+
+struct methodinfo {                 /* method structure                       */
+       java_objectheader header;       /* we need this in jit's monitorenter     */
+       s4            flags;            /* ACC flags                              */
+       utf          *name;             /* name of method                         */
+       utf          *descriptor;       /* JavaVM descriptor string of method     */
+#if defined(ENABLE_JAVASE)
+       utf          *signature;        /* Signature attribute                    */
+       stack_map_t  *stack_map;        /* StackMapTable attribute                */
+#endif
+
+       methoddesc   *parseddesc;       /* parsed descriptor                      */
+                            
+       classinfo    *class;            /* class, the method belongs to           */
+       s4            vftblindex;       /* index of method in virtual function    */
+                                       /* table (if it is a virtual method)      */
+       s4            maxstack;         /* maximum stack depth of method          */
+       s4            maxlocals;        /* maximum number of local variables      */
+       s4            jcodelength;      /* length of JavaVM code                  */
+       u1           *jcode;            /* pointer to JavaVM code                 */
+
+       s4            rawexceptiontablelength;  /* exceptiontable length          */
+       raw_exception_entry *rawexceptiontable; /* the exceptiontable             */
+
+       u2            thrownexceptionscount; /* number of exceptions attribute    */
+       classref_or_classinfo *thrownexceptions; /* except. a method may throw    */
+
+       u2            linenumbercount;  /* number of linenumber attributes        */
+       lineinfo     *linenumbers;      /* array of lineinfo items                */
+
+       u1           *stubroutine;      /* stub for compiling or calling natives  */
+       codeinfo     *code;             /* current code of this method            */
+
+#if defined(ENABLE_LSRA)
+       s4            maxlifetimes;     /* helper for lsra                        */
+#endif
+
+       methodinfo   *overwrites;       /* method that is directly overwritten    */
+       method_assumption *assumptions; /* list of assumptions about this method  */
+};
+
+
+/* method_assumption ***********************************************************
+
+   This struct is used for registering assumptions about methods.
+
+*******************************************************************************/
+
+struct method_assumption {
+       method_assumption *next;
+       methodinfo        *context;
+};
+
+
+/* method_worklist *************************************************************
+
+   List node used for method worklists.
+
+*******************************************************************************/
+
+struct method_worklist {
+       method_worklist *next;
+       methodinfo      *m;
+};
+
+
+/* raw_exception_entry ********************************************************/
+
+/* exception table entry read by the loader */
+
+struct raw_exception_entry {    /* exceptiontable entry in a method           */
+       classref_or_classinfo catchtype; /* catchtype of exc. (0 == catchall)     */
+       u2              startpc;    /* start pc of guarded area (inclusive)       */
+       u2              endpc;      /* end pc of guarded area (exklusive)         */
+       u2              handlerpc;  /* pc of exception handler                    */
+};
+
+
+/* lineinfo *******************************************************************/
+
+struct lineinfo {
+       u2 start_pc;
+       u2 line_number;
+};
+
+
+/* function prototypes ********************************************************/
+
+void method_free(methodinfo *m);
+bool method_canoverwrite(methodinfo *m, methodinfo *old);
+
+methodinfo *method_vftbl_lookup(vftbl_t *vftbl, methodinfo* m);
+
+void method_add_assumption_monomorphic(methodinfo *m, methodinfo *caller);
+void method_break_assumption_monomorphic(methodinfo *m, method_worklist **wl);
+
+s4   method_count_implementations(methodinfo *m, classinfo *c, methodinfo **found);
+
+#if !defined(NDEBUG)
+void method_printflags(methodinfo *m);
+void method_print(methodinfo *m);
+void method_println(methodinfo *m);
+void method_methodref_print(constant_FMIref *mr);
+void method_methodref_println(constant_FMIref *mr);
+#endif
+
+#endif /* _METHOD_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/options.c b/src/vmcore/options.c
new file mode 100644 (file)
index 0000000..3429c82
--- /dev/null
@@ -0,0 +1,236 @@
+/* src/vmcore/options.c - contains global options
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Christian Thalinger
+
+   $Id: options.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "vmcore/options.h"
+
+
+/* command line option ********************************************************/
+
+s4    opt_index = 0;            /* index of processed arguments               */
+char *opt_arg;                  /* this one exports the option argument       */
+
+bool opt_foo = false;           /* option for development                     */
+
+bool opt_jar = false;
+
+#if defined(ENABLE_JIT)
+bool opt_jit = true;            /* JIT mode execution (default)               */
+bool opt_intrp = false;         /* interpreter mode execution                 */
+#else
+bool opt_jit = false;           /* JIT mode execution                         */
+bool opt_intrp = true;          /* interpreter mode execution (default)       */
+#endif
+
+bool opt_run = true;
+
+s4   opt_heapmaxsize   = 0;     /* maximum heap size                          */
+s4   opt_heapstartsize = 0;     /* initial heap size                          */
+s4   opt_stacksize     = 0;     /* thread stack size                          */
+
+bool opt_verbose = false;
+bool opt_debugcolor = false;   /* use ANSI terminal sequences                */
+bool compileall = false;
+
+bool loadverbose = false;
+bool linkverbose = false;
+bool initverbose = false;
+
+bool opt_verboseclass     = false;
+bool opt_verbosegc        = false;
+bool opt_verbosejni       = false;
+bool opt_verbosecall      = false;      /* trace all method invocation        */
+bool opt_verboseexception = false;
+
+bool showmethods = false;
+bool showconstantpool = false;
+bool showutf = false;
+
+char *opt_method = NULL;
+char *opt_signature = NULL;
+
+bool compileverbose =  false;           /* trace compiler actions             */
+bool showstack = false;
+
+bool opt_showdisassemble    = false;    /* generate disassembler listing      */
+bool opt_shownops           = false;
+bool opt_showddatasegment   = false;    /* generate data segment listing      */
+bool opt_showintermediate   = false;    /* generate intermediate code listing */
+bool opt_showexceptionstubs = false;
+bool opt_shownativestub     = false;
+
+bool useinlining = false;      /* use method inlining                        */
+bool inlinevirtuals = false;   /* inline unique virtual methods              */
+bool inlineexceptions = false; /* inline methods, that contain excptions     */
+bool inlineparamopt = false;   /* optimize parameter passing to inlined methods */
+bool inlineoutsiders = false;  /* inline methods, that are not member of the invoker's class */
+
+bool checkbounds = true;       /* check array bounds                         */
+bool checknull = true;         /* check null pointers                        */
+bool opt_noieee = false;       /* don't implement ieee compliant floats      */
+bool checksync = true;         /* do synchronization                         */
+#if defined(ENABLE_LOOP)
+bool opt_loops = false;        /* optimize array accesses in loops           */
+#endif
+
+bool makeinitializations = true;
+
+#if defined(ENABLE_STATISTICS)
+bool opt_stat    = false;
+bool opt_getloadingtime = false;   /* to measure the runtime                 */
+bool opt_getcompilingtime = false; /* compute compile time                   */
+#endif
+#if defined(ENABLE_VERIFIER)
+bool opt_verify  = true;       /* true if classfiles should be verified      */
+#endif
+bool opt_eager   = false;
+
+#if defined(ENABLE_PROFILING)
+bool opt_prof    = false;
+bool opt_prof_bb = false;
+#endif
+
+
+/* optimization options *******************************************************/
+
+#if defined(ENABLE_IFCONV)
+bool opt_ifconv = false;
+#endif
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+bool opt_lsra = false;
+#endif
+
+
+/* interpreter options ********************************************************/
+
+#if defined(ENABLE_INTRP)
+bool opt_no_dynamic = false;            /* suppress dynamic superinstructions */
+bool opt_no_replication = false;        /* don't use replication in intrp     */
+bool opt_no_quicksuper = false;         /* instructions for quickening cannot be
+                                                                                  part of dynamic superinstructions */
+
+s4   opt_static_supers = 0x7fffffff;
+bool vm_debug = false;          /* XXX this should be called `opt_trace'      */
+#endif
+
+
+/* options_get *****************************************************************
+
+   DOCUMENT ME!!!
+
+*******************************************************************************/
+
+s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args)
+{
+       char *option;
+       s4    i;
+
+       if (opt_index >= vm_args->nOptions)
+               return OPT_DONE;
+
+       /* get the current option */
+
+       option = vm_args->options[opt_index].optionString;
+
+       if ((option == NULL) || (option[0] != '-'))
+               return OPT_DONE;
+
+       for (i = 0; opts[i].name; i++) {
+               if (!opts[i].arg) {
+                       /* boolean option found */
+
+                       if (strcmp(option + 1, opts[i].name) == 0) {
+                               opt_index++;
+                               return opts[i].value;
+                       }
+
+               } else {
+                       /* parameter option found */
+
+                       /* with a space between */
+
+                       if (strcmp(option + 1, opts[i].name) == 0) {
+                               opt_index++;
+
+                               if (opt_index < vm_args->nOptions) {
+                                       opt_arg = strdup(vm_args->options[opt_index].optionString);
+                                       opt_index++;
+                                       return opts[i].value;
+                               }
+
+                               return OPT_ERROR;
+
+                       } else {
+                               /* parameter and option have no space between */
+
+                               /* FIXME: this assumption is plain wrong, hits you if there is a
+                                * parameter with no argument starting with same letter as param with argument
+                                * but named after that one, ouch! */
+
+                               size_t l = strlen(opts[i].name);
+
+                               if (strlen(option + 1) > l) {
+                                       if (memcmp(option + 1, opts[i].name, l) == 0) {
+                                               opt_index++;
+                                               opt_arg = strdup(option + 1 + l);
+                                               return opts[i].value;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return OPT_ERROR;
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/options.h b/src/vmcore/options.h
new file mode 100644 (file)
index 0000000..fef61b2
--- /dev/null
@@ -0,0 +1,186 @@
+/* src/vm/options.h - define global options extern
+
+   Copyright (C) 1996-2005, 2006 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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Christian Thalinger
+
+   Changes:
+
+   $Id: options.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "native/jni.h"
+#include "vm/global.h"
+
+
+/* reserved option numbers ****************************************************/
+
+/* define these negative since the other options are an enum */
+
+#define OPT_DONE       -1
+#define OPT_ERROR      -2
+#define OPT_IGNORE     -3
+
+
+typedef struct opt_struct opt_struct;
+
+struct opt_struct {
+       char *name;
+       bool  arg;
+       int   value;
+};
+
+
+/* global variables ***********************************************************/
+
+extern s4    opt_index;
+extern char *opt_arg;
+
+extern bool opt_foo;
+
+extern bool opt_jit;
+extern bool opt_intrp;
+
+extern bool opt_jar;
+extern bool opt_run;
+
+extern s4   opt_heapmaxsize;
+extern s4   opt_heapstartsize;
+extern s4   opt_stacksize;
+
+extern bool opt_verbose;
+extern bool opt_debugcolor;
+extern bool compileall;
+
+extern bool loadverbose;         /* Print debug messages during loading */
+extern bool linkverbose;
+extern bool initverbose;         /* Log class initialization */ 
+
+extern bool opt_verboseclass;
+extern bool opt_verbosegc;
+extern bool opt_verbosejni;
+extern bool opt_verbosecall;
+extern bool opt_verboseexception;
+
+extern bool showmethods;
+extern bool showconstantpool;
+extern bool showutf;
+
+extern char *opt_method;
+extern char *opt_signature;
+
+extern bool compileverbose;
+extern bool showstack;
+
+extern bool opt_showdisassemble;
+extern bool opt_shownops;
+extern bool opt_showddatasegment;
+extern bool opt_showintermediate;
+extern bool opt_showexceptionstubs;
+extern bool opt_shownativestub;
+
+extern bool useinlining;
+extern bool inlinevirtuals;
+extern bool inlineexceptions;
+extern bool inlineparamopt;
+extern bool inlineoutsiders;
+
+extern bool checkbounds;
+extern bool checknull;
+extern bool opt_noieee;
+extern bool checksync;
+#if defined(ENABLE_LOOP)
+extern bool opt_loops;
+#endif
+
+extern bool makeinitializations;
+
+#if defined(ENABLE_STATISTICS)
+extern bool opt_stat;
+extern bool opt_getloadingtime;
+extern bool opt_getcompilingtime;
+#endif
+#if defined(ENABLE_VERIFIER)
+extern bool opt_verify;
+#endif
+extern bool opt_eager;
+
+#if defined(ENABLE_PROFILING)
+extern bool opt_prof;
+extern bool opt_prof_bb;
+#endif
+
+
+/* optimization options *******************************************************/
+
+#if defined(ENABLE_IFCONV)
+extern bool opt_ifconv;
+#endif
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+extern bool opt_lsra;
+#endif
+
+
+/* interpreter options ********************************************************/
+
+#if defined(ENABLE_INTRP)
+extern bool opt_no_dynamic;
+extern bool opt_no_replication;
+extern bool opt_no_quicksuper;
+
+extern s4   opt_static_supers;
+extern bool vm_debug;
+#endif
+
+
+/* function prototypes ********************************************************/
+
+s4 options_get(opt_struct *opts, JavaVMInitArgs *vm_args);
+
+#endif /* _OPTIONS_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:
+ */
diff --git a/src/vmcore/references.h b/src/vmcore/references.h
new file mode 100644 (file)
index 0000000..04344fb
--- /dev/null
@@ -0,0 +1,172 @@
+/* src/vmcore/references.h - references to classes/fields/methods
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: references.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+#ifndef _REFERENCES_H_
+#define _REFERENCES_H_
+
+/* forward typedefs ***********************************************************/
+
+typedef struct constant_classref constant_classref;
+typedef struct constant_FMIref   constant_FMIref;
+
+
+/* constant_classref **********************************************************/
+
+struct constant_classref {
+       void             *pseudo_vftbl; /* for distinguishing it from classinfo   */
+       struct classinfo *referer;    /* class containing the reference           */
+       struct utf       *name;       /* name of the class refered to             */
+};
+
+
+/* classref_or_classinfo ******************************************************/
+
+typedef union classref_or_classinfo {
+       constant_classref *ref;       /* a symbolic class reference               */
+       struct classinfo  *cls;       /* an already loaded class                  */
+       void              *any;       /* used for general access (x != NULL,...)  */
+} classref_or_classinfo;
+
+
+/* parseddesc *****************************************************************/
+
+typedef union parseddesc {
+       struct typedesc   *fd;        /* parsed field descriptor                  */
+       struct methoddesc *md;        /* parsed method descriptor                 */
+       void              *any;       /* used for simple test against NULL        */
+} parseddesc;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+#include "vmcore/descriptor.h"
+#include "vmcore/field.h"
+#include "vmcore/method.h"
+#include "vmcore/utf8.h"
+
+
+/*----------------------------------------------------------------------------*/
+/* References                                                                 */
+/*                                                                            */
+/* This header files defines the following types used for references to       */
+/* classes/methods/fields and descriptors:                                    */
+/*                                                                            */
+/*     classinfo *                a loaded class                              */
+/*     constant_classref          a symbolic reference                        */
+/*     classref_or_classinfo      a loaded class or a symbolic reference      */
+/*                                                                            */
+/*     constant_FMIref            a symb. ref. to a field/method/intf.method  */
+/*                                                                            */
+/*     typedesc *                 describes a field type                      */
+/*     methoddesc *               descrives a method type                     */
+/*     parseddesc                 describes a field type or a method type     */
+/*----------------------------------------------------------------------------*/
+
+/* structs ********************************************************************/
+
+/* constant_FMIref ************************************************************/
+
+struct constant_FMIref{     /* Fieldref, Methodref and InterfaceMethodref     */
+       union {
+               s4                 index;     /* used only within the loader          */
+               constant_classref *classref;  /* class having this field/meth./intfm. */
+               fieldinfo         *field;     /* resolved field                       */
+               methodinfo        *method;    /* resolved method                      */
+       } p;
+       utf       *name;        /* field/method/interfacemethod name              */
+       utf       *descriptor;  /* field/method/intfmeth. type descriptor string  */
+       parseddesc parseddesc;  /* parsed descriptor                              */
+};
+
+
+/* macros *********************************************************************/
+
+/* a value that never occurrs in classinfo.header.vftbl                       */
+#define CLASSREF_PSEUDO_VFTBL ((void *) 1)
+
+/* macro for testing if a classref_or_classinfo is a classref                 */
+/* `reforinfo` is only evaluated once                                         */
+#define IS_CLASSREF(reforinfo)  \
+       ((reforinfo).ref->pseudo_vftbl == CLASSREF_PSEUDO_VFTBL)
+
+/* macro for testing if a constant_FMIref has been resolved                   */
+/* `fmiref` is only evaluated once                                            */
+#define IS_FMIREF_RESOLVED(fmiref)  \
+       ((fmiref)->p.classref->pseudo_vftbl != CLASSREF_PSEUDO_VFTBL)
+
+/* the same as IS_CLASSREF, but also check against NULL */
+#define IS_XCLASSREF(reforinfo)  \
+       ((reforinfo).any && IS_CLASSREF(reforinfo))
+
+/* macro for casting a classref/classinfo * to a classref_or_classinfo        */
+#define CLASSREF_OR_CLASSINFO(value) \
+       (*((classref_or_classinfo *)(&(value))))
+
+/* macro for accessing the name of a classref/classinfo                       */
+#define CLASSREF_OR_CLASSINFO_NAME(value) \
+       (IS_CLASSREF(value) ? (value).ref->name : (value).cls->name)
+
+/* macro for accessing the class name of a method reference                   */
+#define METHODREF_CLASSNAME(fmiref) \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.method->class->name \
+                                                               : (fmiref)->p.classref->name)
+
+/* macro for accessing the class name of a method reference                   */
+#define FIELDREF_CLASSNAME(fmiref) \
+       (IS_FMIREF_RESOLVED(fmiref) ? (fmiref)->p.field->class->name \
+                                                               : (fmiref)->p.classref->name)
+
+/* initialize a constant_classref with referer `ref` and name `classname`     */
+
+#define CLASSREF_INIT(c,ref,classname) \
+    do { \
+        (c).pseudo_vftbl = CLASSREF_PSEUDO_VFTBL; \
+        (c).referer = (ref); \
+        (c).name = (classname); \
+    } while (0)
+
+#endif /* _REFERENCES_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+
diff --git a/src/vmcore/resolve.c b/src/vmcore/resolve.c
new file mode 100644 (file)
index 0000000..ec4caac
--- /dev/null
@@ -0,0 +1,3025 @@
+/* src/vmcore/resolve.c - resolving classes/interfaces/fields/methods
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: resolve.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/access.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+
+#include "vm/jit/jit.h"
+#include "vm/jit/verify/typeinfo.h"
+
+#include "vmcore/classcache.h"
+#include "vmcore/descriptor.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/resolve.h"
+
+
+/******************************************************************************/
+/* DEBUG HELPERS                                                              */
+/******************************************************************************/
+
+/*#define RESOLVE_VERBOSE*/
+
+/******************************************************************************/
+/* CLASS RESOLUTION                                                           */
+/******************************************************************************/
+
+/* resolve_class_from_name *****************************************************
+   Resolve a symbolic class reference
+  
+   IN:
+       referer..........the class containing the reference
+       refmethod........the method from which resolution was triggered
+                        (may be NULL if not applicable)
+       classname........class name to resolve
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+          checkaccess......if true, access rights to the class are checked
+          link.............if true, guarantee that the returned class, if any,
+                           has been linked
+  
+   OUT:
+       *result..........set to result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+                        (*result may still be NULL for resolveLazy)
+       false............an exception has been thrown
+
+   NOTE:
+       The returned class is *not* guaranteed to be linked!
+          (It is guaranteed to be loaded, though.)
+   
+*******************************************************************************/
+
+bool resolve_class_from_name(classinfo *referer,
+                                                        methodinfo *refmethod,
+                                                        utf *classname,
+                                                        resolve_mode_t mode,
+                                                        bool checkaccess,
+                                                        bool link,
+                                                        classinfo **result)
+{
+       classinfo *cls = NULL;
+       char *utf_ptr;
+       int len;
+       
+       assert(result);
+       assert(referer);
+       assert(classname);
+       assert(mode == resolveLazy || mode == resolveEager);
+       
+       *result = NULL;
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_class_from_name(");
+       utf_fprint_printable_ascii(stdout,referer->name);
+       printf(",%p,",(void*)referer->classloader);
+       utf_fprint_printable_ascii(stdout,classname);
+       printf(",%d,%d)\n",(int)checkaccess,(int)link);
+#endif
+
+       /* lookup if this class has already been loaded */
+
+       cls = classcache_lookup(referer->classloader, classname);
+
+#ifdef RESOLVE_VERBOSE
+       printf("    lookup result: %p\n",(void*)cls);
+#endif
+
+       if (!cls) {
+               /* resolve array types */
+
+               if (classname->text[0] == '[') {
+                       utf_ptr = classname->text + 1;
+                       len = classname->blength - 1;
+
+                       /* classname is an array type name */
+
+                       switch (*utf_ptr) {
+                               case 'L':
+                                       utf_ptr++;
+                                       len -= 2;
+                                       /* FALLTHROUGH */
+                               case '[':
+                                       /* the component type is a reference type */
+                                       /* resolve the component type */
+                                       if (!resolve_class_from_name(referer,refmethod,
+                                                                          utf_new(utf_ptr,len),
+                                                                          mode,checkaccess,link,&cls))
+                                               return false; /* exception */
+                                       if (!cls) {
+                                               assert(mode == resolveLazy);
+                                               return true; /* be lazy */
+                                       }
+                                       /* create the array class */
+                                       cls = class_array_of(cls,false);
+                                       if (!cls)
+                                               return false; /* exception */
+                       }
+               }
+               else {
+                       /* the class has not been loaded, yet */
+                       if (mode == resolveLazy)
+                               return true; /* be lazy */
+               }
+
+#ifdef RESOLVE_VERBOSE
+               printf("    loading...\n");
+#endif
+
+               /* load the class */
+               if (!cls) {
+                       if (!(cls = load_class_from_classloader(classname,
+                                                                                                       referer->classloader)))
+                               return false; /* exception */
+               }
+       }
+
+       /* the class is now loaded */
+       assert(cls);
+       assert(cls->state & CLASS_LOADED);
+
+#ifdef RESOLVE_VERBOSE
+       printf("    checking access rights...\n");
+#endif
+       
+       /* check access rights of referer to refered class */
+       if (checkaccess && !access_is_accessible_class(referer,cls)) {
+               int msglen;
+               char *message;
+
+               msglen = utf_bytes(cls->name) + utf_bytes(referer->name) + 100;
+               message = MNEW(char, msglen);
+               strcpy(message, "class is not accessible (");
+               utf_cat_classname(message, cls->name);
+               strcat(message, " from ");
+               utf_cat_classname(message, referer->name);
+               strcat(message, ")");
+
+               exceptions_throw_illegalaccessexception(message);
+
+               MFREE(message, char, msglen);
+
+               return false; /* exception */
+       }
+
+       /* link the class if necessary */
+       if (link) {
+               if (!(cls->state & CLASS_LINKED))
+                       if (!link_class(cls))
+                               return false; /* exception */
+
+               assert(cls->state & CLASS_LINKED);
+       }
+
+       /* resolution succeeds */
+#ifdef RESOLVE_VERBOSE
+       printf("    success.\n");
+#endif
+       *result = cls;
+       return true;
+}
+
+/* resolve_classref ************************************************************
+   Resolve a symbolic class reference
+  
+   IN:
+       refmethod........the method from which resolution was triggered
+                        (may be NULL if not applicable)
+       ref..............class reference
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+          checkaccess......if true, access rights to the class are checked
+          link.............if true, guarantee that the returned class, if any,
+                           has been linked
+  
+   OUT:
+       *result..........set to result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+                        (*result may still be NULL for resolveLazy)
+       false............an exception has been thrown
+   
+*******************************************************************************/
+
+bool resolve_classref(methodinfo *refmethod,
+                                         constant_classref *ref,
+                                         resolve_mode_t mode,
+                                         bool checkaccess,
+                                         bool link,
+                                         classinfo **result)
+{
+       return resolve_classref_or_classinfo(refmethod,CLASSREF_OR_CLASSINFO(ref),mode,checkaccess,link,result);
+}
+
+/* resolve_classref_or_classinfo ***********************************************
+   Resolve a symbolic class reference if necessary
+  
+   IN:
+       refmethod........the method from which resolution was triggered
+                        (may be NULL if not applicable)
+       cls..............class reference or classinfo
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+          checkaccess......if true, access rights to the class are checked
+          link.............if true, guarantee that the returned class, if any,
+                           has been linked
+  
+   OUT:
+       *result..........set to result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+                        (*result may still be NULL for resolveLazy)
+       false............an exception has been thrown
+   
+*******************************************************************************/
+
+bool resolve_classref_or_classinfo(methodinfo *refmethod,
+                                                                  classref_or_classinfo cls,
+                                                                  resolve_mode_t mode,
+                                                                  bool checkaccess,
+                                                                  bool link,
+                                                                  classinfo **result)
+{
+       classinfo         *c;
+       
+       assert(cls.any);
+       assert(mode == resolveEager || mode == resolveLazy);
+       assert(result);
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_classref_or_classinfo(");
+       utf_fprint_printable_ascii(stdout,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
+       printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
+#endif
+
+       *result = NULL;
+
+       if (IS_CLASSREF(cls)) {
+               /* we must resolve this reference */
+
+               if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
+                                                                        mode, checkaccess, link, &c))
+                       goto return_exception;
+
+       } else {
+               /* cls has already been resolved */
+               c = cls.cls;
+               assert(c->state & CLASS_LOADED);
+       }
+       assert(c || (mode == resolveLazy));
+
+       if (!c)
+               return true; /* be lazy */
+       
+       assert(c);
+       assert(c->state & CLASS_LOADED);
+
+       if (link) {
+               if (!(c->state & CLASS_LINKED))
+                       if (!link_class(c))
+                               goto return_exception;
+
+               assert(c->state & CLASS_LINKED);
+       }
+
+       /* succeeded */
+       *result = c;
+       return true;
+
+ return_exception:
+       *result = NULL;
+       return false;
+}
+
+
+/* resolve_class_from_typedesc *************************************************
+   Return a classinfo * for the given type descriptor
+  
+   IN:
+       d................type descriptor
+          checkaccess......if true, access rights to the class are checked
+          link.............if true, guarantee that the returned class, if any,
+                           has been linked
+   OUT:
+       *result..........set to result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+       false............an exception has been thrown
+
+   NOTE:
+       This function always resolves eagerly.
+   
+*******************************************************************************/
+
+bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
+{
+       classinfo *cls;
+       
+       assert(d);
+       assert(result);
+
+       *result = NULL;
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_class_from_typedesc(");
+       descriptor_debug_print_typedesc(stdout,d);
+       printf(",%i,%i)\n",(int)checkaccess,(int)link);
+#endif
+
+       if (d->type == TYPE_ADR) {
+               /* a reference type */
+               assert(d->classref);
+               if (!resolve_classref_or_classinfo(NULL,CLASSREF_OR_CLASSINFO(d->classref),
+                                                                                  resolveEager,checkaccess,link,&cls))
+                       return false; /* exception */
+       }
+       else {
+               /* a primitive type */
+               cls = primitivetype_table[d->decltype].class_primitive;
+               assert(cls->state & CLASS_LOADED);
+               if (!(cls->state & CLASS_LINKED))
+                       if (!link_class(cls))
+                               return false; /* exception */
+       }
+       assert(cls);
+       assert(cls->state & CLASS_LOADED);
+       assert(!link || (cls->state & CLASS_LINKED));
+
+#ifdef RESOLVE_VERBOSE
+       printf("    result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
+#endif
+
+       *result = cls;
+       return true;
+}
+
+/******************************************************************************/
+/* SUBTYPE SET CHECKS                                                         */
+/******************************************************************************/
+
+/* resolve_subtype_check *******************************************************
+   Resolve the given types lazily and perform a subtype check
+  
+   IN:
+       refmethod........the method triggering the resolution
+       subtype..........checked to be a subtype of supertype
+          supertype........the super type to check agaings
+          mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+       error............which type of exception to throw if
+                        the test fails. May be:
+                            resolveLinkageError, or
+                            resolveIllegalAccessError
+                                               IMPORTANT: If error==resolveIllegalAccessError,
+                                               then array types are not checked.
+
+   RETURN VALUE:
+       resolveSucceeded.....the check succeeded
+       resolveDeferred......the check could not be performed due to
+                               unresolved types. (This can only happen for
+                                                       mode == resolveLazy.)
+          resolveFailed........the check failed, an exception has been thrown.
+   
+   NOTE:
+          The types are resolved first, so any
+          exception which may occurr during resolution may
+          be thrown by this function.
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
+                                                                                     classref_or_classinfo subtype,
+                                                                                         classref_or_classinfo supertype,
+                                                                                         resolve_mode_t mode,
+                                                                                         resolve_err_t error)
+{
+       classinfo *subclass;
+       typeinfo subti;
+       typecheck_result r;
+
+       assert(refmethod);
+       assert(subtype.any);
+       assert(supertype.any);
+       assert(mode == resolveLazy || mode == resolveEager);
+       assert(error == resolveLinkageError || error == resolveIllegalAccessError);
+
+       /* resolve the subtype */
+
+       if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
+               /* the subclass could not be resolved. therefore we are sure that  */
+               /* no instances of this subclass will ever exist -> skip this test */
+               /* XXX this assumes that class loading has invariant results (as in JVM spec) */
+               exceptions_clear_exception();
+               return resolveSucceeded;
+       }
+       if (!subclass)
+               return resolveDeferred; /* be lazy */
+
+       assert(subclass->state & CLASS_LINKED);
+
+       /* do not check access to protected members of arrays */
+
+       if (error == resolveIllegalAccessError && subclass->name->text[0] == '[') {
+               return resolveSucceeded;
+       }
+
+       /* perform the subtype check */
+
+       typeinfo_init_classinfo(&subti,subclass);
+check_again:
+       r = typeinfo_is_assignable_to_class(&subti,supertype);
+       if (r == typecheck_FAIL)
+               return resolveFailed; /* failed, exception is already set */
+
+       if (r == typecheck_MAYBE) {
+               assert(IS_CLASSREF(supertype));
+               if (mode == resolveEager) {
+                       if (!resolve_classref_or_classinfo(refmethod,supertype,
+                                                                                          resolveEager,false,true,
+                                                                                          &supertype.cls))
+                       {
+                               return resolveFailed;
+                       }
+                       assert(supertype.cls);
+                       goto check_again;
+               }
+
+               return resolveDeferred; /* be lazy */
+       }
+
+       if (!r) {
+               /* sub class relationship is false */
+
+               char *message;
+               int msglen;
+
+#if defined(RESOLVE_VERBOSE)
+               printf("SUBTYPE CHECK FAILED!\n");
+#endif
+
+               msglen =
+                       utf_bytes(subclass->name) +
+                       utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
+                       + 200;
+
+               message = MNEW(char, msglen);
+
+               strcpy(message, (error == resolveIllegalAccessError) ?
+                               "illegal access to protected member ("
+                               : "subtype constraint violated (");
+
+               utf_cat_classname(message, subclass->name);
+               strcat(message, " is not a subclass of ");
+               utf_cat_classname(message, CLASSREF_OR_CLASSINFO_NAME(supertype));
+               strcat(message, ")");
+
+               if (error == resolveIllegalAccessError)
+                       exceptions_throw_illegalaccessexception(message);
+               else
+                       exceptions_throw_linkageerror(message, NULL);
+
+               MFREE(message, char, msglen);
+
+               return resolveFailed; /* exception */
+       }
+
+       /* everything ok */
+
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+/* resolve_lazy_subtype_checks *************************************************
+   Resolve the types to check lazily and perform subtype checks
+  
+   IN:
+       refmethod........the method triggering the resolution
+       subtinfo.........the typeinfo containing the subtypes
+       supertype........the supertype to test againgst
+          mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+       error............which type of exception to throw if
+                        the test fails. May be:
+                            resolveLinkageError, or
+                            resolveIllegalAccessError
+                                               IMPORTANT: If error==resolveIllegalAccessError,
+                                               then array types in the set are skipped.
+
+   RETURN VALUE:
+       resolveSucceeded.....the check succeeded
+       resolveDeferred......the check could not be performed due to
+                               unresolved types
+          resolveFailed........the check failed, an exception has been thrown.
+   
+   NOTE:
+       The references in the set are resolved first, so any
+       exception which may occurr during resolution may
+       be thrown by this function.
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
+                                                                                                       typeinfo *subtinfo,
+                                                                                                       classref_or_classinfo supertype,
+                                                                                                       resolve_err_t error)
+{
+       int count;
+       int i;
+       resolve_result_t result;
+
+       assert(refmethod);
+       assert(subtinfo);
+       assert(supertype.any);
+       assert(error == resolveLinkageError || error == resolveIllegalAccessError);
+
+       /* returnAddresses are illegal here */
+
+       if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
+               exceptions_throw_verifyerror(refmethod,
+                               "Invalid use of returnAddress");
+               return resolveFailed;
+       }
+
+       /* uninitialized objects are illegal here */
+
+       if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
+               exceptions_throw_verifyerror(refmethod,
+                               "Invalid use of uninitialized object");
+               return resolveFailed;
+       }
+
+       /* the nulltype is always assignable */
+
+       if (TYPEINFO_IS_NULLTYPE(*subtinfo))
+               return resolveSucceeded;
+
+       /* every type is assignable to (BOOTSTRAP)java.lang.Object */
+
+       if (supertype.cls == class_java_lang_Object
+               || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
+                       && refmethod->class->classloader == NULL))
+       {
+               return resolveSucceeded;
+       }
+
+       if (subtinfo->merged) {
+
+               /* for a merged type we have to do a series of checks */
+
+               count = subtinfo->merged->count;
+               for (i=0; i<count; ++i) {
+                       classref_or_classinfo c = subtinfo->merged->list[i];
+                       if (subtinfo->dimension > 0) {
+                               /* a merge of array types */
+                               /* the merged list contains the possible _element_ types, */
+                               /* so we have to create array types with these elements.  */
+                               if (IS_CLASSREF(c)) {
+                                       c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
+                               }
+                               else {
+                                       c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
+                               }
+                       }
+
+                       /* do the subtype check against the type c */
+
+                       result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
+                       if (result != resolveSucceeded)
+                               return result;
+               }
+       }
+       else {
+
+               /* a single type, this is the common case, hopefully */
+
+               if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
+                       == CLASSREF_OR_CLASSINFO_NAME(supertype))
+               {
+                       /* the class names are the same */
+                   /* equality is guaranteed by the loading constraints */
+                       return resolveSucceeded;
+               }
+               else {
+
+                       /* some other type name, try to perform the check lazily */
+
+                       return resolve_subtype_check(refmethod,
+                                                                                subtinfo->typeclass,supertype,
+                                                                                resolveLazy,
+                                                                                error);
+               }
+       }
+
+       /* everything ok */
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+/* resolve_and_check_subtype_set ***********************************************
+   Resolve the references in the given set and test subtype relationships
+  
+   IN:
+       refmethod........the method triggering the resolution
+       ref..............a set of class/interface references
+                        (may be empty)
+       typeref..........the type to test against the set
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+       error............which type of exception to throw if
+                        the test fails. May be:
+                            resolveLinkageError, or
+                            resolveIllegalAccessError
+                                               IMPORTANT: If error==resolveIllegalAccessError,
+                                               then array types in the set are skipped.
+
+   RETURN VALUE:
+       resolveSucceeded.....the check succeeded
+       resolveDeferred......the check could not be performed due to
+                               unresolved types. (This can only happen if
+                                                       mode == resolveLazy.)
+          resolveFailed........the check failed, an exception has been thrown.
+   
+   NOTE:
+       The references in the set are resolved first, so any
+       exception which may occurr during resolution may
+       be thrown by this function.
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
+                                                                         unresolved_subtype_set *ref,
+                                                                         classref_or_classinfo typeref,
+                                                                         resolve_mode_t mode,
+                                                                         resolve_err_t error)
+{
+       classref_or_classinfo *setp;
+       typecheck_result checkresult;
+
+       assert(refmethod);
+       assert(ref);
+       assert(typeref.any);
+       assert(mode == resolveLazy || mode == resolveEager);
+       assert(error == resolveLinkageError || error == resolveIllegalAccessError);
+
+#if defined(RESOLVE_VERBOSE)
+       printf("resolve_and_check_subtype_set:\n");
+       unresolved_subtype_set_debug_dump(ref, stdout);
+       if (IS_CLASSREF(typeref))
+               class_classref_println(typeref.ref);
+       else
+               class_println(typeref.cls);
+#endif
+
+       setp = ref->subtyperefs;
+
+       /* an empty set of tests always succeeds */
+       if (!setp || !setp->any) {
+               return resolveSucceeded;
+       }
+
+       /* first resolve the type if necessary */
+       if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
+               return resolveFailed; /* exception */
+       if (!typeref.cls)
+               return resolveDeferred; /* be lazy */
+
+       assert(typeref.cls->state & CLASS_LINKED);
+
+       /* iterate over the set members */
+
+       for (; setp->any; ++setp) {
+               checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
+#if defined(RESOLVE_VERBOSE)
+               if (checkresult != resolveSucceeded)
+                       printf("SUBTYPE CHECK FAILED!\n");
+#endif
+               if (checkresult != resolveSucceeded)
+                       return checkresult;
+       }
+
+       /* check succeeds */
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+/******************************************************************************/
+/* CLASS RESOLUTION                                                           */
+/******************************************************************************/
+
+/* resolve_class ***************************************************************
+   Resolve an unresolved class reference. The class is also linked.
+  
+   IN:
+       ref..............struct containing the reference
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+          checkaccess......if true, access rights to the class are checked
+   
+   OUT:
+       *result..........set to the result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+                        (*result may still be NULL for resolveLazy)
+       false............an exception has been thrown
+   
+*******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+bool resolve_class(unresolved_class *ref,
+                                  resolve_mode_t mode,
+                                  bool checkaccess,
+                                  classinfo **result)
+{
+       classinfo *cls;
+       resolve_result_t checkresult;
+       
+       assert(ref);
+       assert(result);
+       assert(mode == resolveLazy || mode == resolveEager);
+
+       *result = NULL;
+
+#ifdef RESOLVE_VERBOSE
+       unresolved_class_debug_dump(ref,stdout);
+#endif
+
+       /* first we must resolve the class */
+       if (!resolve_classref(ref->referermethod,
+                                             ref->classref,mode,checkaccess,true,&cls))
+       {
+               /* the class reference could not be resolved */
+               return false; /* exception */
+       }
+       if (!cls)
+               return true; /* be lazy */
+
+       assert(cls);
+       assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
+
+       /* now we check the subtype constraints */
+       
+       checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                                                          &(ref->subtypeconstraints),
+                                                                          CLASSREF_OR_CLASSINFO(cls),
+                                                                          mode,
+                                                                          resolveLinkageError);
+       if (checkresult != resolveSucceeded)
+               return (bool) checkresult;
+
+       /* succeed */
+       *result = cls;
+       return true;
+}
+#endif /* ENABLE_VERIFIER */
+
+/* resolve_classref_eager ******************************************************
+   Resolve an unresolved class reference eagerly. The class is also linked and
+   access rights to the class are checked.
+  
+   IN:
+       ref..............constant_classref to the class
+   
+   RETURN VALUE:
+       classinfo * to the class, or
+          NULL if an exception has been thrown
+   
+*******************************************************************************/
+
+classinfo * resolve_classref_eager(constant_classref *ref)
+{
+       classinfo *c;
+
+       if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
+               return NULL;
+
+       return c;
+}
+
+/* resolve_classref_eager_nonabstract ******************************************
+   Resolve an unresolved class reference eagerly. The class is also linked and
+   access rights to the class are checked. A check is performed that the class
+   is not abstract.
+  
+   IN:
+       ref..............constant_classref to the class
+   
+   RETURN VALUE:
+       classinfo * to the class, or
+          NULL if an exception has been thrown
+   
+*******************************************************************************/
+
+classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
+{
+       classinfo *c;
+
+       if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
+               return NULL;
+
+       /* ensure that the class is not abstract */
+
+       if (c->flags & ACC_ABSTRACT) {
+               exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
+               return NULL;
+       }
+
+       return c;
+}
+
+/* resolve_class_eager *********************************************************
+   Resolve an unresolved class reference eagerly. The class is also linked and
+   access rights to the class are checked.
+  
+   IN:
+       ref..............struct containing the reference
+   
+   RETURN VALUE:
+       classinfo * to the class, or
+          NULL if an exception has been thrown
+   
+*******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+classinfo * resolve_class_eager(unresolved_class *ref)
+{
+       classinfo *c;
+
+       if (!resolve_class(ref,resolveEager,true,&c))
+               return NULL;
+
+       return c;
+}
+#endif /* ENABLE_VERIFIER */
+
+/******************************************************************************/
+/* FIELD RESOLUTION                                                           */
+/******************************************************************************/
+
+/* resolve_field_verifier_checks *******************************************
+   Do the verifier checks necessary after field has been resolved.
+  
+   IN:
+       refmethod........the method containing the reference
+          fieldref.........the field reference
+          container........the class where the field was found
+          fi...............the fieldinfo of the resolved field
+          instanceti.......instance typeinfo, if available
+          valueti..........value typeinfo, if available
+          isstatic.........true if this is a *STATIC* instruction
+          isput............true if this is a PUT* instruction
+  
+   RETURN VALUE:
+       resolveSucceeded....everything ok
+          resolveDeferred.....tests could not be done, have been deferred
+       resolveFailed.......exception has been thrown
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
+                                                                                          constant_FMIref *fieldref,
+                                                                                          classinfo *container,
+                                                                                          fieldinfo *fi,
+                                                                                          typeinfo *instanceti,
+                                                                                          typeinfo *valueti,
+                                                                                          bool isstatic,
+                                                                                          bool isput)
+{
+       classinfo *declarer;
+       classinfo *referer;
+       resolve_result_t result;
+       constant_classref *fieldtyperef;
+
+       assert(refmethod);
+       assert(fieldref);
+       assert(container);
+       assert(fi);
+
+       /* get the classinfos and the field type */
+
+       referer = refmethod->class;
+       assert(referer);
+
+       declarer = fi->class;
+       assert(declarer);
+       assert(referer->state & CLASS_LINKED);
+
+       fieldtyperef = fieldref->parseddesc.fd->classref;
+
+       /* check static */
+
+#if true != 1
+#error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
+#endif
+
+       if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
+               /* a static field is accessed via an instance, or vice versa */
+               exceptions_throw_incompatibleclasschangeerror(declarer,
+                                                                                                         (fi->flags & ACC_STATIC)
+                                                                                                         ? "static field accessed via instance"
+                                                                                                         : "instance field  accessed without instance");
+
+               return resolveFailed;
+       }
+
+       /* check access rights */
+
+       if (!access_is_accessible_member(referer,declarer,fi->flags)) {
+               int msglen;
+               char *message;
+
+               msglen =
+                       utf_bytes(declarer->name) +
+                       utf_bytes(fi->name) +
+                       utf_bytes(referer->name) +
+                       100;
+
+               message = MNEW(char, msglen);
+
+               strcpy(message, "field is not accessible (");
+               utf_cat_classname(message, declarer->name);
+               strcat(message, ".");
+               utf_cat(message, fi->name);
+               strcat(message, " from ");
+               utf_cat_classname(message, referer->name);
+               strcat(message, ")");
+
+               exceptions_throw_illegalaccessexception(message);
+
+               MFREE(message, char, msglen);
+
+               return resolveFailed; /* exception */
+       }
+
+       /* for non-static methods we have to check the constraints on the         */
+       /* instance type                                                          */
+
+       if (instanceti) {
+               typeinfo *insttip;
+               typeinfo tinfo;
+
+               /* The instanceslot must contain a reference to a non-array type */
+
+               if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
+                       return resolveFailed;
+               }
+               if (TYPEINFO_IS_ARRAY(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
+                       return resolveFailed;
+               }
+
+               if (isput && TYPEINFO_IS_NEWOBJECT(*instanceti))
+               {
+                       /* The instruction writes a field in an uninitialized object. */
+                       /* This is only allowed when a field of an uninitialized 'this' object is */
+                       /* written inside an initialization method                                */
+
+                       classinfo *initclass;
+                       instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
+
+                       if (ins != NULL) {
+                               exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
+                               return resolveFailed;
+                       }
+
+                       /* XXX check that class of field == refmethod->class */
+                       initclass = referer; /* XXX classrefs */
+                       assert(initclass->state & CLASS_LINKED);
+
+                       typeinfo_init_classinfo(&tinfo, initclass);
+                       insttip = &tinfo;
+               }
+               else {
+                       insttip = instanceti;
+               }
+
+               result = resolve_lazy_subtype_checks(refmethod,
+                               insttip,
+                               CLASSREF_OR_CLASSINFO(container),
+                               resolveLinkageError);
+               if (result != resolveSucceeded)
+                       return result;
+
+               /* check protected access */
+
+               if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
+               {
+                       result = resolve_lazy_subtype_checks(refmethod,
+                                       instanceti,
+                                       CLASSREF_OR_CLASSINFO(referer),
+                                       resolveIllegalAccessError);
+                       if (result != resolveSucceeded)
+                               return result;
+               }
+
+       }
+
+       /* for PUT* instructions we have to check the constraints on the value type */
+
+       if (valueti) {
+               assert(fieldtyperef);
+
+               /* check subtype constraints */
+               result = resolve_lazy_subtype_checks(refmethod,
+                               valueti,
+                               CLASSREF_OR_CLASSINFO(fieldtyperef),
+                               resolveLinkageError);
+
+               if (result != resolveSucceeded)
+                       return result;
+       }
+
+       /* impose loading constraint on field type */
+
+       if (fi->type == TYPE_ADR) {
+               assert(fieldtyperef);
+               if (!classcache_add_constraint(declarer->classloader,
+                                                                          referer->classloader,
+                                                                          fieldtyperef->name))
+                       return resolveFailed;
+       }
+
+       /* XXX impose loading constraint on instance? */
+
+       /* everything ok */
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+/* resolve_field_lazy **********************************************************
+   Resolve an unresolved field reference lazily
+
+   NOTE: This function does NOT do any verification checks. In case of a
+         successful resolution, you must call resolve_field_verifier_checks
+                in order to perform the necessary checks!
+  
+   IN:
+          refmethod........the referer method
+          fieldref.........the field reference
+  
+   RETURN VALUE:
+       resolveSucceeded.....the reference has been resolved
+       resolveDeferred......the resolving could not be performed lazily
+          resolveFailed........resolving failed, an exception has been thrown.
+   
+*******************************************************************************/
+
+resolve_result_t resolve_field_lazy(methodinfo *refmethod,
+                                                                       constant_FMIref *fieldref)
+{
+       classinfo *referer;
+       classinfo *container;
+       fieldinfo *fi;
+
+       assert(refmethod);
+
+       /* the class containing the reference */
+
+       referer = refmethod->class;
+       assert(referer);
+
+       /* check if the field itself is already resolved */
+
+       if (IS_FMIREF_RESOLVED(fieldref))
+               return resolveSucceeded;
+
+       /* first we must resolve the class containg the field */
+
+       /* XXX can/may lazyResolving trigger linking? */
+
+       if (!resolve_class_from_name(referer, refmethod,
+                  fieldref->p.classref->name, resolveLazy, true, true, &container))
+       {
+               /* the class reference could not be resolved */
+               return resolveFailed; /* exception */
+       }
+       if (!container)
+               return resolveDeferred; /* be lazy */
+
+       assert(container->state & CLASS_LINKED);
+
+       /* now we must find the declaration of the field in `container`
+        * or one of its superclasses */
+
+       fi = class_resolvefield(container,
+                                                       fieldref->name, fieldref->descriptor,
+                                                       referer, true);
+       if (!fi) {
+               /* The field does not exist. But since we were called lazily, */
+               /* this error must not be reported now. (It will be reported   */
+               /* if eager resolving of this field is ever tried.)           */
+
+               exceptions_clear_exception();
+               return resolveDeferred; /* be lazy */
+       }
+
+       /* cache the result of the resolution */
+
+       fieldref->p.field = fi;
+
+       /* everything ok */
+       return resolveSucceeded;
+}
+
+/* resolve_field ***************************************************************
+   Resolve an unresolved field reference
+  
+   IN:
+       ref..............struct containing the reference
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+  
+   OUT:
+       *result..........set to the result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+                        (*result may still be NULL for resolveLazy)
+       false............an exception has been thrown
+   
+*******************************************************************************/
+
+bool resolve_field(unresolved_field *ref,
+                                  resolve_mode_t mode,
+                                  fieldinfo **result)
+{
+       classinfo *referer;
+       classinfo *container;
+       classinfo *declarer;
+       constant_classref *fieldtyperef;
+       fieldinfo *fi;
+       resolve_result_t checkresult;
+
+       assert(ref);
+       assert(result);
+       assert(mode == resolveLazy || mode == resolveEager);
+
+       *result = NULL;
+
+#ifdef RESOLVE_VERBOSE
+       unresolved_field_debug_dump(ref,stdout);
+#endif
+
+       /* the class containing the reference */
+
+       referer = ref->referermethod->class;
+       assert(referer);
+
+       /* check if the field itself is already resolved */
+       if (IS_FMIREF_RESOLVED(ref->fieldref)) {
+               fi = ref->fieldref->p.field;
+               container = fi->class;
+               goto resolved_the_field;
+       }
+
+       /* first we must resolve the class containg the field */
+       if (!resolve_class_from_name(referer,ref->referermethod,
+                                          ref->fieldref->p.classref->name,mode,true,true,&container))
+       {
+               /* the class reference could not be resolved */
+               return false; /* exception */
+       }
+       if (!container)
+               return true; /* be lazy */
+
+       assert(container);
+       assert(container->state & CLASS_LOADED);
+       assert(container->state & CLASS_LINKED);
+
+       /* now we must find the declaration of the field in `container`
+        * or one of its superclasses */
+
+#ifdef RESOLVE_VERBOSE
+               printf("    resolving field in class...\n");
+#endif
+
+       fi = class_resolvefield(container,
+                                                       ref->fieldref->name,ref->fieldref->descriptor,
+                                                       referer,true);
+       if (!fi) {
+               if (mode == resolveLazy) {
+                       /* The field does not exist. But since we were called lazily, */
+                       /* this error must not be reported now. (It will be reported   */
+                       /* if eager resolving of this field is ever tried.)           */
+
+                       exceptions_clear_exception();
+                       return true; /* be lazy */
+               }
+
+               return false; /* exception */
+       }
+
+       /* cache the result of the resolution */
+       ref->fieldref->p.field = fi;
+
+resolved_the_field:
+
+#ifdef ENABLE_VERIFIER
+       /* Checking opt_verify is ok here, because the NULL iptr guarantees */
+       /* that no missing parts of an instruction will be accessed.        */
+       if (opt_verify) {
+               checkresult = resolve_field_verifier_checks(
+                               ref->referermethod,
+                               ref->fieldref,
+                               container,
+                               fi,
+                               NULL, /* instanceti, handled by constraints below */
+                               NULL, /* valueti, handled by constraints below  */
+                               (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
+                               (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
+
+               if (checkresult != resolveSucceeded)
+                       return (bool) checkresult;
+
+               declarer = fi->class;
+               assert(declarer);
+               assert(declarer->state & CLASS_LOADED);
+               assert(declarer->state & CLASS_LINKED);
+
+               /* for non-static accesses we have to check the constraints on the */
+               /* instance type */
+
+               if (!(ref->flags & RESOLVE_STATIC)) {
+                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                       &(ref->instancetypes),
+                                       CLASSREF_OR_CLASSINFO(container),
+                                       mode, resolveLinkageError);
+                       if (checkresult != resolveSucceeded)
+                               return (bool) checkresult;
+               }
+
+               fieldtyperef = ref->fieldref->parseddesc.fd->classref;
+
+               /* for PUT* instructions we have to check the constraints on the value type */
+               if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
+                       assert(fieldtyperef);
+                       if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
+                               /* check subtype constraints */
+                               checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                               &(ref->valueconstraints),
+                                               CLASSREF_OR_CLASSINFO(fieldtyperef),
+                                               mode, resolveLinkageError);
+                               if (checkresult != resolveSucceeded)
+                                       return (bool) checkresult;
+                       }
+               }
+
+               /* check protected access */
+               if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
+                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                       &(ref->instancetypes),
+                                       CLASSREF_OR_CLASSINFO(referer),
+                                       mode,
+                                       resolveIllegalAccessError);
+                       if (checkresult != resolveSucceeded)
+                               return (bool) checkresult;
+               }
+
+       }
+#endif /* ENABLE_VERIFIER */
+
+       /* succeed */
+       *result = fi;
+
+       return true;
+}
+
+/* resolve_field_eager *********************************************************
+   Resolve an unresolved field reference eagerly.
+  
+   IN:
+       ref..............struct containing the reference
+   
+   RETURN VALUE:
+       fieldinfo * to the field, or
+          NULL if an exception has been thrown
+   
+*******************************************************************************/
+
+fieldinfo * resolve_field_eager(unresolved_field *ref)
+{
+       fieldinfo *fi;
+
+       if (!resolve_field(ref,resolveEager,&fi))
+               return NULL;
+
+       return fi;
+}
+
+/******************************************************************************/
+/* METHOD RESOLUTION                                                          */
+/******************************************************************************/
+
+/* resolve_method_invokespecial_lookup *****************************************
+   Do the special lookup for methods invoked by INVOKESPECIAL
+  
+   IN:
+       refmethod........the method containing the reference
+          mi...............the methodinfo of the resolved method
+  
+   RETURN VALUE:
+       a methodinfo *...the result of the lookup,
+          NULL.............an exception has been thrown
+   
+*******************************************************************************/
+
+methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
+                                                                                                methodinfo *mi)
+{
+       classinfo *declarer;
+       classinfo *referer;
+
+       assert(refmethod);
+       assert(mi);
+
+       /* get referer and declarer classes */
+
+       referer = refmethod->class;
+       assert(referer);
+
+       declarer = mi->class;
+       assert(declarer);
+       assert(referer->state & CLASS_LINKED);
+
+       /* checks for INVOKESPECIAL:                                       */
+       /* for <init> and methods of the current class we don't need any   */
+       /* special checks. Otherwise we must verify that the called method */
+       /* belongs to a super class of the current class                   */
+
+       if ((referer != declarer) && (mi->name != utf_init)) {
+               /* check that declarer is a super class of the current class   */
+
+               if (!class_issubclass(referer,declarer)) {
+                       exceptions_throw_verifyerror(refmethod,
+                                       "INVOKESPECIAL calling non-super class method");
+                       return NULL;
+               }
+
+               /* if the referer has ACC_SUPER set, we must do the special    */
+               /* lookup starting with the direct super class of referer      */
+
+               if ((referer->flags & ACC_SUPER) != 0) {
+                       mi = class_resolvemethod(referer->super.cls,
+                                                                        mi->name,
+                                                                        mi->descriptor);
+
+                       if (mi == NULL) {
+#if defined(ENABLE_JAVASE)
+                               /* the spec calls for an AbstractMethodError in this case */
+                               exceptions_throw_abstractmethoderror();
+#else
+                               exceptions_throw_virtualmachineerror();
+#endif
+                               return NULL;
+                       }
+               }
+       }
+
+       /* everything ok */
+       return mi;
+}
+
+/* resolve_method_verifier_checks ******************************************
+   Do the verifier checks necessary after a method has been resolved.
+  
+   IN:
+       refmethod........the method containing the reference
+          methodref........the method reference
+          mi...............the methodinfo of the resolved method
+          invokestatic.....true if the method is invoked by INVOKESTATIC
+  
+   RETURN VALUE:
+       resolveSucceeded....everything ok
+          resolveDeferred.....tests could not be done, have been deferred
+       resolveFailed.......exception has been thrown
+   
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
+                                                                                               constant_FMIref *methodref,
+                                                                                               methodinfo *mi,
+                                                                                               bool invokestatic)
+{
+       classinfo *declarer;
+       classinfo *referer;
+
+       assert(refmethod);
+       assert(methodref);
+       assert(mi);
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_method_verifier_checks\n");
+       printf("    flags: %02x\n",mi->flags);
+#endif
+
+       /* get the classinfos and the method descriptor */
+
+       referer = refmethod->class;
+       assert(referer);
+
+       declarer = mi->class;
+       assert(declarer);
+
+       /* check static */
+
+       if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
+               /* a static method is accessed via an instance, or vice versa */
+               exceptions_throw_incompatibleclasschangeerror(declarer,
+                                                                                                         (mi->flags & ACC_STATIC)
+                                                                                                         ? "static method called via instance"
+                                                                                                         : "instance method called without instance");
+
+               return resolveFailed;
+       }
+
+       /* check access rights */
+
+       if (!access_is_accessible_member(referer,declarer,mi->flags)) {
+               int msglen;
+               char *message;
+
+               /* XXX clean this up. this should be in exceptions.c */
+               msglen =
+                       utf_bytes(declarer->name) +
+                       utf_bytes(mi->name) +
+                       utf_bytes(mi->descriptor) +
+                       utf_bytes(referer->name) +
+                       100;
+
+               message = MNEW(char, msglen);
+
+               strcpy(message, "method is not accessible (");
+               utf_cat_classname(message, declarer->name);
+               strcat(message, ".");
+               utf_cat(message, mi->name);
+               utf_cat(message, mi->descriptor);
+               strcat(message, " from ");
+               utf_cat_classname(message, referer->name);
+               strcat(message, ")");
+
+               exceptions_throw_illegalaccessexception(message);
+
+               MFREE(message, char, msglen);
+
+               return resolveFailed; /* exception */
+       }
+
+       /* everything ok */
+
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* resolve_method_instance_type_checks *****************************************
+
+   Check the instance type of a method invocation.
+
+   IN:
+       refmethod........the method containing the reference
+          mi...............the methodinfo of the resolved method
+          instanceti.......typeinfo of the instance slot
+          invokespecial....true if the method is invoked by INVOKESPECIAL
+
+   RETURN VALUE:
+       resolveSucceeded....everything ok
+          resolveDeferred.....tests could not be done, have been deferred
+       resolveFailed.......exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
+                                                                                                        methodinfo *mi,
+                                                                                                        typeinfo *instanceti,
+                                                                                                        bool invokespecial)
+{
+       typeinfo         tinfo;
+       typeinfo        *tip;
+       resolve_result_t result;
+
+       if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
+       {   /* XXX clean up */
+               instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
+               classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
+                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
+               tip = &tinfo;
+               if (!typeinfo_init_class(tip, initclass))
+                       return false;
+       }
+       else {
+               tip = instanceti;
+       }
+
+       result = resolve_lazy_subtype_checks(refmethod,
+                                                                                tip,
+                                                                                CLASSREF_OR_CLASSINFO(mi->class),
+                                                                                resolveLinkageError);
+       if (result != resolveSucceeded)
+               return result;
+
+       /* check protected access */
+
+       /* XXX use other `declarer` than mi->class? */
+       if (((mi->flags & ACC_PROTECTED) != 0)
+                       && !SAME_PACKAGE(mi->class, refmethod->class))
+       {
+               result = resolve_lazy_subtype_checks(refmethod,
+                               tip,
+                               CLASSREF_OR_CLASSINFO(refmethod->class),
+                               resolveIllegalAccessError);
+               if (result != resolveSucceeded)
+                       return result;
+       }
+
+       /* everything ok */
+
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* resolve_method_param_type_checks ********************************************
+
+   Check non-instance parameter types of a method invocation.
+
+   IN:
+          jd...............jitdata of the method doing the call
+       refmethod........the method containing the reference
+          iptr.............the invoke instruction
+          mi...............the methodinfo of the resolved method
+          invokestatic.....true if the method is invoked by INVOKESTATIC
+
+   RETURN VALUE:
+       resolveSucceeded....everything ok
+          resolveDeferred.....tests could not be done, have been deferred
+       resolveFailed.......exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+resolve_result_t resolve_method_param_type_checks(jitdata *jd, 
+                                                                                                 methodinfo *refmethod,
+                                                                                                 instruction *iptr, 
+                                                                                                 methodinfo *mi,
+                                                                                                 bool invokestatic)
+{
+       varinfo         *param;
+       resolve_result_t result;
+       methoddesc      *md;
+       typedesc        *paramtypes;
+       s4               type;
+       s4               instancecount;
+       s4               i;
+
+       assert(jd);
+
+       instancecount = (invokestatic) ? 0 : 1;
+
+       /* check subtype constraints for TYPE_ADR parameters */
+
+       md = mi->parseddesc;
+       paramtypes = md->paramtypes;
+
+       for (i = md->paramcount-1-instancecount; i>=0; --i) {
+               param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
+               type = md->paramtypes[i+instancecount].type;
+
+               assert(param);
+               assert(type == param->type);
+
+               if (type == TYPE_ADR) {
+                       result = resolve_lazy_subtype_checks(refmethod,
+                                       &(param->typeinfo),
+                                       CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
+                                       resolveLinkageError);
+                       if (result != resolveSucceeded)
+                               return result;
+               }
+       }
+
+       /* everything ok */
+
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* resolve_method_param_type_checks_stackbased *********************************
+
+   Check non-instance parameter types of a method invocation.
+
+   IN:
+       refmethod........the method containing the reference
+          mi...............the methodinfo of the resolved method
+          invokestatic.....true if the method is invoked by INVOKESTATIC
+          stack............TOS before the INVOKE instruction
+
+   RETURN VALUE:
+       resolveSucceeded....everything ok
+          resolveDeferred.....tests could not be done, have been deferred
+       resolveFailed.......exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+resolve_result_t resolve_method_param_type_checks_stackbased(
+               methodinfo *refmethod, 
+               methodinfo *mi,
+               bool invokestatic, 
+               typedescriptor *stack)
+{
+       typedescriptor  *param;
+       resolve_result_t result;
+       methoddesc      *md;
+       typedesc        *paramtypes;
+       s4               type;
+       s4               instancecount;
+       s4               i;
+
+       instancecount = (invokestatic) ? 0 : 1;
+
+       /* check subtype constraints for TYPE_ADR parameters */
+
+       md = mi->parseddesc;
+       paramtypes = md->paramtypes;
+
+       param = stack - (md->paramslots - 1 - instancecount);
+
+       for (i = instancecount; i < md->paramcount; ++i) {
+               type = md->paramtypes[i].type;
+
+               assert(type == param->type);
+
+               if (type == TYPE_ADR) {
+                       result = resolve_lazy_subtype_checks(refmethod,
+                                       &(param->typeinfo),
+                                       CLASSREF_OR_CLASSINFO(paramtypes[i].classref),
+                                       resolveLinkageError);
+                       if (result != resolveSucceeded)
+                               return result;
+               }
+
+               param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
+       }
+
+       /* everything ok */
+
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* resolve_method_loading_constraints ******************************************
+
+   Impose loading constraints on the parameters and return type of the
+   given method.
+
+   IN:
+       referer..........the class refering to the method
+          mi...............the method
+
+   RETURN VALUE:
+       true................everything ok
+          false...............an exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool resolve_method_loading_constraints(classinfo *referer,
+                                                                               methodinfo *mi)
+{
+       methoddesc *md;
+       typedesc   *paramtypes;
+       utf        *name;
+       s4          i;
+       s4          instancecount;
+
+       /* impose loading constraints on parameters (including instance) */
+
+       md = mi->parseddesc;
+       paramtypes = md->paramtypes;
+       instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
+
+       for (i = 0; i < md->paramcount; i++) {
+               if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
+                       if (i < instancecount) {
+                               /* The type of the 'this' pointer is the class containing */
+                               /* the method definition. Since container is the same as, */
+                               /* or a subclass of declarer, we also constrain declarer  */
+                               /* by transitivity of loading constraints.                */
+                               name = mi->class->name;
+                       }
+                       else {
+                               name = paramtypes[i].classref->name;
+                       }
+
+                       /* The caller (referer) and the callee (container) must agree */
+                       /* on the types of the parameters.                            */
+                       if (!classcache_add_constraint(referer->classloader,
+                                                                                  mi->class->classloader, name))
+                               return false; /* exception */
+               }
+       }
+
+       /* impose loading constraint onto return type */
+
+       if (md->returntype.type == TYPE_ADR) {
+               /* The caller (referer) and the callee (container) must agree */
+               /* on the return type.                                        */
+               if (!classcache_add_constraint(referer->classloader,
+                                       mi->class->classloader,
+                                       md->returntype.classref->name))
+                       return false; /* exception */
+       }
+
+       /* everything ok */
+
+       return true;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* resolve_method_lazy *********************************************************
+   Resolve an unresolved method reference lazily
+  
+   NOTE: This function does NOT do any verification checks. In case of a
+         successful resolution, you must call resolve_method_verifier_checks
+                in order to perform the necessary checks!
+  
+   IN:
+          refmethod........the referer method
+          methodref........the method reference
+          invokespecial....true if this is an INVOKESPECIAL instruction
+  
+   RETURN VALUE:
+       resolveSucceeded.....the reference has been resolved
+       resolveDeferred......the resolving could not be performed lazily
+          resolveFailed........resolving failed, an exception has been thrown.
+   
+*******************************************************************************/
+
+resolve_result_t resolve_method_lazy(methodinfo *refmethod,
+                                                                        constant_FMIref *methodref,
+                                                                        bool invokespecial)
+{
+       classinfo *referer;
+       classinfo *container;
+       methodinfo *mi;
+
+       assert(refmethod);
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_method_lazy\n");
+#endif
+
+       /* the class containing the reference */
+
+       referer = refmethod->class;
+       assert(referer);
+
+       /* check if the method itself is already resolved */
+
+       if (IS_FMIREF_RESOLVED(methodref))
+               return resolveSucceeded;
+
+       /* first we must resolve the class containg the method */
+
+       if (!resolve_class_from_name(referer, refmethod,
+                  methodref->p.classref->name, resolveLazy, true, true, &container))
+       {
+               /* the class reference could not be resolved */
+               return resolveFailed; /* exception */
+       }
+       if (!container)
+               return resolveDeferred; /* be lazy */
+
+       assert(container->state & CLASS_LINKED);
+
+       /* now we must find the declaration of the method in `container`
+        * or one of its superclasses */
+
+       if (container->flags & ACC_INTERFACE) {
+               mi = class_resolveinterfacemethod(container,
+                                                                             methodref->name,
+                                                                                 methodref->descriptor,
+                                                                             referer, true);
+
+       } else {
+               mi = class_resolveclassmethod(container,
+                                                                         methodref->name,
+                                                                         methodref->descriptor,
+                                                                         referer, true);
+       }
+
+       if (!mi) {
+               /* The method does not exist. But since we were called lazily, */
+               /* this error must not be reported now. (It will be reported   */
+               /* if eager resolving of this method is ever tried.)           */
+
+               exceptions_clear_exception();
+               return resolveDeferred; /* be lazy */
+       }
+
+       if (invokespecial) {
+               mi = resolve_method_invokespecial_lookup(refmethod, mi);
+               if (!mi)
+                       return resolveFailed; /* exception */
+       }
+
+       /* have the method params already been parsed? no, do it. */
+
+       if (!mi->parseddesc->params)
+               if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
+                       return resolveFailed;
+
+       /* cache the result of the resolution */
+
+       methodref->p.method = mi;
+
+       /* succeed */
+
+       return resolveSucceeded;
+}
+
+/* resolve_method **************************************************************
+   Resolve an unresolved method reference
+  
+   IN:
+       ref..............struct containing the reference
+       mode.............mode of resolution:
+                            resolveLazy...only resolve if it does not
+                                          require loading classes
+                            resolveEager..load classes if necessary
+  
+   OUT:
+       *result..........set to the result of resolution, or to NULL if
+                        the reference has not been resolved
+                        In the case of an exception, *result is
+                        guaranteed to be set to NULL.
+  
+   RETURN VALUE:
+       true.............everything ok 
+                        (*result may still be NULL for resolveLazy)
+       false............an exception has been thrown
+   
+*******************************************************************************/
+
+bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
+{
+       classinfo *referer;
+       classinfo *container;
+       classinfo *declarer;
+       methodinfo *mi;
+       typedesc *paramtypes;
+       int instancecount;
+       int i;
+       resolve_result_t checkresult;
+
+       assert(ref);
+       assert(result);
+       assert(mode == resolveLazy || mode == resolveEager);
+
+#ifdef RESOLVE_VERBOSE
+       unresolved_method_debug_dump(ref,stdout);
+#endif
+
+       *result = NULL;
+
+       /* the class containing the reference */
+
+       referer = ref->referermethod->class;
+       assert(referer);
+
+       /* check if the method itself is already resolved */
+
+       if (IS_FMIREF_RESOLVED(ref->methodref)) {
+               mi = ref->methodref->p.method;
+               container = mi->class;
+               goto resolved_the_method;
+       }
+
+       /* first we must resolve the class containing the method */
+
+       if (!resolve_class_from_name(referer,ref->referermethod,
+                                          ref->methodref->p.classref->name,mode,true,true,&container))
+       {
+               /* the class reference could not be resolved */
+               return false; /* exception */
+       }
+       if (!container)
+               return true; /* be lazy */
+
+       assert(container);
+       assert(container->state & CLASS_LINKED);
+
+       /* now we must find the declaration of the method in `container`
+        * or one of its superclasses */
+
+       if (container->flags & ACC_INTERFACE) {
+               mi = class_resolveinterfacemethod(container,
+                                                                             ref->methodref->name,
+                                                                                 ref->methodref->descriptor,
+                                                                             referer, true);
+
+       } else {
+               mi = class_resolveclassmethod(container,
+                                                                         ref->methodref->name,
+                                                                         ref->methodref->descriptor,
+                                                                         referer, true);
+       }
+
+       if (!mi) {
+               if (mode == resolveLazy) {
+                       /* The method does not exist. But since we were called lazily, */
+                       /* this error must not be reported now. (It will be reported   */
+                       /* if eager resolving of this method is ever tried.)           */
+
+                       exceptions_clear_exception();
+                       return true; /* be lazy */
+               }
+
+               return false; /* exception */ /* XXX set exceptionptr? */
+       }
+
+       /* { the method reference has been resolved } */
+
+       if (ref->flags & RESOLVE_SPECIAL) {
+               mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
+               if (!mi)
+                       return false; /* exception */
+       }
+
+       /* have the method params already been parsed? no, do it. */
+
+       if (!mi->parseddesc->params)
+               if (!descriptor_params_from_paramtypes(mi->parseddesc, mi->flags))
+                       return false;
+
+       /* cache the resolution */
+
+       ref->methodref->p.method = mi;
+
+resolved_the_method:
+
+#ifdef ENABLE_VERIFIER
+       if (opt_verify) {
+
+               checkresult = resolve_method_verifier_checks(
+                               ref->referermethod,
+                               ref->methodref,
+                               mi,
+                               (ref->flags & RESOLVE_STATIC));
+
+               if (checkresult != resolveSucceeded)
+                       return (bool) checkresult;
+
+               /* impose loading constraints on params and return type */
+
+               if (!resolve_method_loading_constraints(referer, mi))
+                       return false;
+
+               declarer = mi->class;
+               assert(declarer);
+               assert(referer->state & CLASS_LINKED);
+
+               /* for non-static methods we have to check the constraints on the         */
+               /* instance type                                                          */
+
+               if (!(ref->flags & RESOLVE_STATIC)) {
+                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                       &(ref->instancetypes),
+                                       CLASSREF_OR_CLASSINFO(container),
+                                       mode,
+                                       resolveLinkageError);
+                       if (checkresult != resolveSucceeded)
+                               return (bool) checkresult;
+                       instancecount = 1;
+               }
+               else {
+                       instancecount = 0;
+               }
+
+               /* check subtype constraints for TYPE_ADR parameters */
+
+               assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
+               paramtypes = mi->parseddesc->paramtypes;
+
+               for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
+                       if (paramtypes[i+instancecount].type == TYPE_ADR) {
+                               if (ref->paramconstraints) {
+                                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                                       ref->paramconstraints + i,
+                                                       CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
+                                                       mode,
+                                                       resolveLinkageError);
+                                       if (checkresult != resolveSucceeded)
+                                               return (bool) checkresult;
+                               }
+                       }
+               }
+
+               /* check protected access */
+
+               if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
+               {
+                       checkresult = resolve_and_check_subtype_set(ref->referermethod,
+                                       &(ref->instancetypes),
+                                       CLASSREF_OR_CLASSINFO(referer),
+                                       mode,
+                                       resolveIllegalAccessError);
+                       if (checkresult != resolveSucceeded)
+                               return (bool) checkresult;
+               }
+       }
+#endif /* ENABLE_VERIFIER */
+
+       /* succeed */
+       *result = mi;
+       return true;
+}
+
+/* resolve_method_eager ********************************************************
+   Resolve an unresolved method reference eagerly.
+  
+   IN:
+       ref..............struct containing the reference
+   
+   RETURN VALUE:
+       methodinfo * to the method, or
+          NULL if an exception has been thrown
+   
+*******************************************************************************/
+
+methodinfo * resolve_method_eager(unresolved_method *ref)
+{
+       methodinfo *mi;
+
+       if (!resolve_method(ref,resolveEager,&mi))
+               return NULL;
+
+       return mi;
+}
+
+/******************************************************************************/
+/* CREATING THE DATA STRUCTURES                                               */
+/******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
+                                                                                                methodinfo *refmethod,
+                                                                                                unresolved_subtype_set *stset,
+                                                                                                typeinfo *tinfo,
+                                                                                                utf *declaredclassname)
+{
+       int count;
+       int i;
+
+       assert(stset);
+       assert(tinfo);
+
+#ifdef RESOLVE_VERBOSE
+       printf("unresolved_subtype_set_from_typeinfo\n");
+#ifdef TYPEINFO_DEBUG
+       typeinfo_print(stdout,tinfo,4);
+#endif
+       printf("    declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
+       printf("\n");
+#endif
+
+       if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
+               exceptions_throw_verifyerror(refmethod,
+                               "Invalid use of returnAddress");
+               return false;
+       }
+
+       if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
+               exceptions_throw_verifyerror(refmethod,
+                               "Invalid use of uninitialized object");
+               return false;
+       }
+
+       /* the nulltype is always assignable */
+       if (TYPEINFO_IS_NULLTYPE(*tinfo))
+               goto empty_set;
+
+       /* every type is assignable to (BOOTSTRAP)java.lang.Object */
+       if (declaredclassname == utf_java_lang_Object
+                       && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
+       {
+               goto empty_set;
+       }
+
+       if (tinfo->merged) {
+               count = tinfo->merged->count;
+               stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
+               for (i=0; i<count; ++i) {
+                       classref_or_classinfo c = tinfo->merged->list[i];
+                       if (tinfo->dimension > 0) {
+                               /* a merge of array types */
+                               /* the merged list contains the possible _element_ types, */
+                               /* so we have to create array types with these elements.  */
+                               if (IS_CLASSREF(c)) {
+                                       c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
+                               }
+                               else {
+                                       c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
+                               }
+                       }
+                       stset->subtyperefs[i] = c;
+               }
+               stset->subtyperefs[count].any = NULL; /* terminate */
+       }
+       else {
+               if ((IS_CLASSREF(tinfo->typeclass)
+                                       ? tinfo->typeclass.ref->name
+                                       : tinfo->typeclass.cls->name) == declaredclassname)
+               {
+                       /* the class names are the same */
+                   /* equality is guaranteed by the loading constraints */
+                       goto empty_set;
+               }
+               else {
+                       stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
+                       stset->subtyperefs[0] = tinfo->typeclass;
+                       stset->subtyperefs[1].any = NULL; /* terminate */
+               }
+       }
+
+       return true;
+
+empty_set:
+       UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
+       return true;
+}
+#endif /* ENABLE_VERIFIER */
+
+/* create_unresolved_class *****************************************************
+   Create an unresolved_class struct for the given class reference
+  
+   IN:
+          refmethod........the method triggering the resolution (if any)
+          classref.........the class reference
+          valuetype........value type to check against the resolved class
+                                               may be NULL, if no typeinfo is available
+
+   RETURN VALUE:
+       a pointer to a new unresolved_class struct, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+unresolved_class * create_unresolved_class(methodinfo *refmethod,
+                                                                                  constant_classref *classref,
+                                                                                  typeinfo *valuetype)
+{
+       unresolved_class *ref;
+
+#ifdef RESOLVE_VERBOSE
+       printf("create_unresolved_class\n");
+       printf("    referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
+       if (refmethod) {
+               printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
+               printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
+       }
+       printf("    name   : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
+#endif
+
+       ref = NEW(unresolved_class);
+       ref->classref = classref;
+       ref->referermethod = refmethod;
+
+       if (valuetype) {
+               if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
+                                       &(ref->subtypeconstraints),valuetype,classref->name))
+                       return NULL;
+       }
+       else {
+               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
+       }
+
+       return ref;
+}
+#endif /* ENABLE_VERIFIER */
+
+/* resolve_create_unresolved_field *********************************************
+   Create an unresolved_field struct for the given field access instruction
+  
+   IN:
+       referer..........the class containing the reference
+          refmethod........the method triggering the resolution (if any)
+          iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
+
+   RETURN VALUE:
+       a pointer to a new unresolved_field struct, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+unresolved_field * resolve_create_unresolved_field(classinfo *referer,
+                                                                                                  methodinfo *refmethod,
+                                                                                                  instruction *iptr)
+{
+       unresolved_field *ref;
+       constant_FMIref *fieldref = NULL;
+
+#ifdef RESOLVE_VERBOSE
+       printf("create_unresolved_field\n");
+       printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
+       printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
+       printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
+#endif
+
+       ref = NEW(unresolved_field);
+       ref->flags = 0;
+       ref->referermethod = refmethod;
+       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
+
+       switch (iptr->opc) {
+               case ICMD_PUTFIELD:
+                       ref->flags |= RESOLVE_PUTFIELD;
+                       break;
+
+               case ICMD_PUTFIELDCONST:
+                       ref->flags |= RESOLVE_PUTFIELD;
+                       break;
+
+               case ICMD_PUTSTATIC:
+                       ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
+                       break;
+
+               case ICMD_PUTSTATICCONST:
+                       ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
+                       break;
+
+               case ICMD_GETFIELD:
+                       break;
+
+               case ICMD_GETSTATIC:
+                       ref->flags |= RESOLVE_STATIC;
+                       break;
+
+#if !defined(NDEBUG)
+               default:
+                       assert(false);
+#endif
+       }
+
+       fieldref = iptr->sx.s23.s3.fmiref;
+
+       assert(fieldref);
+
+#ifdef RESOLVE_VERBOSE
+/*     printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
+       printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
+       printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
+       printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
+       fputc('\n',stdout);
+#endif
+
+       ref->fieldref = fieldref;
+
+       return ref;
+}
+
+/* resolve_constrain_unresolved_field ******************************************
+   Record subtype constraints for a field access.
+  
+   IN:
+       ref..............the unresolved_field structure of the access
+       referer..........the class containing the reference
+          refmethod........the method triggering the resolution (if any)
+          instanceti.......instance typeinfo, if available
+          valueti..........value typeinfo, if available
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool resolve_constrain_unresolved_field(unresolved_field *ref,
+                                                                               classinfo *referer, 
+                                                                               methodinfo *refmethod,
+                                                                           typeinfo *instanceti,
+                                                                           typeinfo *valueti)
+{
+       constant_FMIref *fieldref;
+       int type;
+       typeinfo tinfo;
+       typedesc *fd;
+
+       assert(ref);
+
+       fieldref = ref->fieldref;
+       assert(fieldref);
+
+#ifdef RESOLVE_VERBOSE
+       printf("constrain_unresolved_field\n");
+       printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
+       printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
+       printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
+/*     printf("    class  : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
+       printf("    name   : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
+       printf("    desc   : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
+       printf("    type   : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
+       fputc('\n',stdout);
+#endif
+
+       assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
+       fd = fieldref->parseddesc.fd;
+       assert(fd);
+
+       /* record subtype constraints for the instance type, if any */
+       if (instanceti) {
+               typeinfo *insttip;
+
+               /* The instanceslot must contain a reference to a non-array type */
+               if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, 
+                                       "illegal instruction: field access on non-reference");
+                       return false;
+               }
+               if (TYPEINFO_IS_ARRAY(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, 
+                                       "illegal instruction: field access on array");
+                       return false;
+               }
+
+               if (((ref->flags & RESOLVE_PUTFIELD) != 0) &&
+                               TYPEINFO_IS_NEWOBJECT(*instanceti))
+               {
+                       /* The instruction writes a field in an uninitialized object. */
+                       /* This is only allowed when a field of an uninitialized 'this' object is */
+                       /* written inside an initialization method                                */
+
+                       classinfo *initclass;
+                       instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
+
+                       if (ins != NULL) {
+                               exceptions_throw_verifyerror(refmethod, 
+                                               "accessing field of uninitialized object");
+                               return false;
+                       }
+                       /* XXX check that class of field == refmethod->class */
+                       initclass = refmethod->class; /* XXX classrefs */
+                       assert(initclass->state & CLASS_LOADED);
+                       assert(initclass->state & CLASS_LINKED);
+
+                       typeinfo_init_classinfo(&tinfo, initclass);
+                       insttip = &tinfo;
+               }
+               else {
+                       insttip = instanceti;
+               }
+               if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
+                                       &(ref->instancetypes), insttip, 
+                                       FIELDREF_CLASSNAME(fieldref)))
+                       return false;
+       }
+       else {
+               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
+       }
+
+       /* record subtype constraints for the value type, if any */
+       type = fd->type;
+       if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
+               assert(valueti);
+               if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
+                                       &(ref->valueconstraints), valueti, 
+                                       fieldref->parseddesc.fd->classref->name))
+                       return false;
+       }
+       else {
+               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
+       }
+
+       return true;
+}
+#endif /* ENABLE_VERIFIER */
+
+/* resolve_create_unresolved_method ********************************************
+   Create an unresolved_method struct for the given method invocation
+  
+   IN:
+       referer..........the class containing the reference
+          refmethod........the method triggering the resolution (if any)
+          iptr.............the INVOKE* instruction
+
+   RETURN VALUE:
+       a pointer to a new unresolved_method struct, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+unresolved_method * resolve_create_unresolved_method(classinfo *referer,
+                                                                                                        methodinfo *refmethod,
+                                                                                                        constant_FMIref *methodref,
+                                                                                                        bool invokestatic,
+                                                                                                        bool invokespecial)
+{
+       unresolved_method *ref;
+
+       assert(methodref);
+
+#ifdef RESOLVE_VERBOSE
+       printf("create_unresolved_method\n");
+       printf("    referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
+       printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
+       printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
+       printf("    name   : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
+       printf("    desc   : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
+#endif
+
+       /* allocate params if necessary */
+       if (!methodref->parseddesc.md->params)
+               if (!descriptor_params_from_paramtypes(methodref->parseddesc.md,
+                                       (invokestatic) ? ACC_STATIC : ACC_NONE))
+                       return NULL;
+
+       /* create the data structure */
+       ref = NEW(unresolved_method);
+       ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
+                          | ((invokespecial) ? RESOLVE_SPECIAL : 0);
+       ref->referermethod = refmethod;
+       ref->methodref = methodref;
+       ref->paramconstraints = NULL;
+       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
+
+       return ref;
+}
+
+
+/* resolve_constrain_unresolved_method_instance ********************************
+   Record subtype constraints for the instance argument of a method call.
+  
+   IN:
+       ref..............the unresolved_method structure of the call
+       referer..........the class containing the reference
+          refmethod........the method triggering the resolution (if any)
+          iptr.............the INVOKE* instruction
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
+                                                                                                 methodinfo *refmethod,
+                                                                                                 typeinfo *instanceti,
+                                                                                                 bool invokespecial)
+{
+       constant_FMIref   *methodref;
+       constant_classref *instanceref;
+       typeinfo           tinfo;
+       typeinfo          *tip;
+
+       assert(ref);
+       methodref = ref->methodref;
+       assert(methodref);
+
+       /* XXX clean this up */
+       instanceref = IS_FMIREF_RESOLVED(methodref)
+               ? class_get_self_classref(methodref->p.method->class)
+               : methodref->p.classref;
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_constrain_unresolved_method_instance\n");
+       printf("    rmethod: "); method_println(refmethod);
+       printf("    mref   : "); method_methodref_println(methodref);
+#endif
+
+       /* record subtype constraints for the instance type, if any */
+
+       if (invokespecial && TYPEINFO_IS_NEWOBJECT(*instanceti))
+       {   /* XXX clean up */
+               instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
+               classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c
+                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
+               tip = &tinfo;
+               if (!typeinfo_init_class(tip, initclass))
+                       return false;
+       }
+       else {
+               tip = instanceti;
+       }
+
+       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
+                               &(ref->instancetypes),tip,instanceref->name))
+               return false;
+
+       return true;
+}
+#endif /* defined(ENABLE_VERIFIER) */
+
+
+/* resolve_constrain_unresolved_method_params  *********************************
+   Record subtype constraints for the non-instance arguments of a method call.
+  
+   IN:
+       jd...............current jitdata (for looking up variables)
+       ref..............the unresolved_method structure of the call
+          refmethod........the method triggering the resolution (if any)
+          iptr.............the INVOKE* instruction
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool resolve_constrain_unresolved_method_params(jitdata *jd,
+                                                                                               unresolved_method *ref,
+                                                                                               methodinfo *refmethod,
+                                                                                               instruction *iptr)
+{
+       constant_FMIref *methodref;
+       varinfo *param;
+       methoddesc *md;
+       int i,j;
+       int type;
+       int instancecount;
+
+       assert(ref);
+       methodref = ref->methodref;
+       assert(methodref);
+       md = methodref->parseddesc.md;
+       assert(md);
+       assert(md->params != NULL);
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_constrain_unresolved_method_params\n");
+       printf("    rmethod: "); method_println(refmethod);
+       printf("    mref   : "); method_methodref_println(methodref);
+#endif
+
+       instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
+
+       /* record subtype constraints for the parameter types, if any */
+
+       for (i=md->paramcount-1-instancecount; i>=0; --i) {
+               param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
+               type = md->paramtypes[i+instancecount].type;
+
+               assert(param);
+               assert(type == param->type);
+
+               if (type == TYPE_ADR) {
+                       if (!ref->paramconstraints) {
+                               ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
+                               for (j=md->paramcount-1-instancecount; j>i; --j)
+                                       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
+                       }
+                       assert(ref->paramconstraints);
+                       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
+                                               ref->paramconstraints + i,&(param->typeinfo),
+                                               md->paramtypes[i+instancecount].classref->name))
+                               return false;
+               }
+               else {
+                       if (ref->paramconstraints)
+                               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
+               }
+       }
+
+       return true;
+}
+#endif /* ENABLE_VERIFIER */
+
+
+/* resolve_constrain_unresolved_method_params_stackbased ***********************
+   Record subtype constraints for the non-instance arguments of a method call.
+  
+   IN:
+       ref..............the unresolved_method structure of the call
+          refmethod........the method triggering the resolution (if any)
+          stack............TOS before the INVOKE instruction
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool resolve_constrain_unresolved_method_params_stackbased(
+               unresolved_method *ref,
+               methodinfo *refmethod,
+               typedescriptor *stack)
+{
+       constant_FMIref *methodref;
+       typedescriptor *param;
+       methoddesc *md;
+       int i,j;
+       int type;
+       int instancecount;
+
+       assert(ref);
+       methodref = ref->methodref;
+       assert(methodref);
+       md = methodref->parseddesc.md;
+       assert(md);
+       assert(md->params != NULL);
+
+#ifdef RESOLVE_VERBOSE
+       printf("resolve_constrain_unresolved_method_params_stackbased\n");
+       printf("    rmethod: "); method_println(refmethod);
+       printf("    mref   : "); method_methodref_println(methodref);
+#endif
+
+       instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
+
+       /* record subtype constraints for the parameter types, if any */
+
+       param = stack - (md->paramslots - 1 - instancecount);
+
+       for (i = instancecount; i < md->paramcount; ++i) {
+               type = md->paramtypes[i].type;
+
+               assert(type == param->type);
+
+               if (type == TYPE_ADR) {
+                       if (!ref->paramconstraints) {
+                               ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
+                               for (j = 0; j < i - instancecount; ++j)
+                                       UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
+                       }
+                       assert(ref->paramconstraints);
+                       if (!unresolved_subtype_set_from_typeinfo(refmethod->class, refmethod,
+                                               ref->paramconstraints + i - instancecount,&(param->typeinfo),
+                                               md->paramtypes[i].classref->name))
+                               return false;
+               }
+               else {
+                       if (ref->paramconstraints)
+                               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
+               }
+
+               param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
+       }
+
+       return true;
+}
+#endif /* ENABLE_VERIFIER */
+
+
+/******************************************************************************/
+/* FREEING MEMORY                                                             */
+/******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
+{
+       if (list) {
+               classref_or_classinfo *p = list;
+
+               /* this is silly. we *only* need to count the elements for MFREE */
+               while ((p++)->any)
+                       ;
+               MFREE(list,classref_or_classinfo,(p - list));
+       }
+}
+#endif /* ENABLE_VERIFIER */
+
+/* unresolved_class_free *******************************************************
+   Free the memory used by an unresolved_class
+  
+   IN:
+       ref..............the unresolved_class
+
+*******************************************************************************/
+
+void unresolved_class_free(unresolved_class *ref)
+{
+       assert(ref);
+
+#ifdef ENABLE_VERIFIER
+       unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
+#endif
+       FREE(ref,unresolved_class);
+}
+
+/* unresolved_field_free *******************************************************
+   Free the memory used by an unresolved_field
+  
+   IN:
+       ref..............the unresolved_field
+
+*******************************************************************************/
+
+void unresolved_field_free(unresolved_field *ref)
+{
+       assert(ref);
+
+#ifdef ENABLE_VERIFIER
+       unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
+       unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
+#endif
+       FREE(ref,unresolved_field);
+}
+
+/* unresolved_method_free ******************************************************
+   Free the memory used by an unresolved_method
+  
+   IN:
+       ref..............the unresolved_method
+
+*******************************************************************************/
+
+void unresolved_method_free(unresolved_method *ref)
+{
+       assert(ref);
+
+#ifdef ENABLE_VERIFIER
+       unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
+       if (ref->paramconstraints) {
+               int i;
+               int count = ref->methodref->parseddesc.md->paramcount;
+
+               for (i=0; i<count; ++i)
+                       unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
+               MFREE(ref->paramconstraints,unresolved_subtype_set,count);
+       }
+#endif
+       FREE(ref,unresolved_method);
+}
+
+/******************************************************************************/
+/* DEBUG DUMPS                                                                */
+/******************************************************************************/
+
+#if !defined(NDEBUG)
+
+/* unresolved_subtype_set_debug_dump *******************************************
+   Print debug info for unresolved_subtype_set to stream
+  
+   IN:
+       stset............the unresolved_subtype_set
+          file.............the stream
+
+*******************************************************************************/
+
+void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
+{
+       classref_or_classinfo *p;
+
+       if (SUBTYPESET_IS_EMPTY(*stset)) {
+               fprintf(file,"        (empty)\n");
+       }
+       else {
+               p = stset->subtyperefs;
+               for (;p->any; ++p) {
+                       if (IS_CLASSREF(*p)) {
+                               fprintf(file,"        ref: ");
+                               utf_fprint_printable_ascii(file,p->ref->name);
+                       }
+                       else {
+                               fprintf(file,"        cls: ");
+                               utf_fprint_printable_ascii(file,p->cls->name);
+                       }
+                       fputc('\n',file);
+               }
+       }
+}
+
+/* unresolved_class_debug_dump *************************************************
+   Print debug info for unresolved_class to stream
+  
+   IN:
+       ref..............the unresolved_class
+          file.............the stream
+
+*******************************************************************************/
+
+void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
+{
+       fprintf(file,"unresolved_class(%p):\n",(void *)ref);
+       if (ref) {
+               fprintf(file,"    referer   : ");
+               utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
+               fprintf(file,"    refmethod : ");
+               utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
+               fprintf(file,"    refmethodd: ");
+               utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
+               fprintf(file,"    classname : ");
+               utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
+               fprintf(file,"    subtypeconstraints:\n");
+               unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
+       }
+}
+
+/* unresolved_field_debug_dump *************************************************
+   Print debug info for unresolved_field to stream
+  
+   IN:
+       ref..............the unresolved_field
+          file.............the stream
+
+*******************************************************************************/
+
+void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
+{
+       fprintf(file,"unresolved_field(%p):\n",(void *)ref);
+       if (ref) {
+               fprintf(file,"    referer   : ");
+               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
+               fprintf(file,"    refmethod : ");
+               utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
+               fprintf(file,"    refmethodd: ");
+               utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
+               fprintf(file,"    classname : ");
+               utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
+               fprintf(file,"    name      : ");
+               utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
+               fprintf(file,"    descriptor: ");
+               utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
+               fprintf(file,"    parseddesc: ");
+               descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
+               fprintf(file,"    flags     : %04x\n",ref->flags);
+               fprintf(file,"    instancetypes:\n");
+               unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
+               fprintf(file,"    valueconstraints:\n");
+               unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
+       }
+}
+
+/* unresolved_method_debug_dump ************************************************
+   Print debug info for unresolved_method to stream
+  
+   IN:
+       ref..............the unresolved_method
+          file.............the stream
+
+*******************************************************************************/
+
+void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
+{
+       int i;
+
+       fprintf(file,"unresolved_method(%p):\n",(void *)ref);
+       if (ref) {
+               fprintf(file,"    referer   : ");
+               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
+               fprintf(file,"    refmethod : ");
+               utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
+               fprintf(file,"    refmethodd: ");
+               utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
+               fprintf(file,"    classname : ");
+               utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
+               fprintf(file,"    name      : ");
+               utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
+               fprintf(file,"    descriptor: ");
+               utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
+               fprintf(file,"    parseddesc: ");
+               descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
+               fprintf(file,"    flags     : %04x\n",ref->flags);
+               fprintf(file,"    instancetypes:\n");
+               unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
+               fprintf(file,"    paramconstraints:\n");
+               if (ref->paramconstraints) {
+                       for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
+                               fprintf(file,"      param %d:\n",i);
+                               unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
+                       }
+               }
+               else {
+                       fprintf(file,"      (empty)\n");
+               }
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/resolve.h b/src/vmcore/resolve.h
new file mode 100644 (file)
index 0000000..2f49a2e
--- /dev/null
@@ -0,0 +1,273 @@
+/* src/vmcore/resolve.h - resolving classes/interfaces/fields/methods
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: resolve.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _RESOLVE_H
+#define _RESOLVE_H
+
+/* forward declarations *******************************************************/
+
+typedef struct unresolved_class unresolved_class;
+typedef struct unresolved_field unresolved_field;
+typedef struct unresolved_method unresolved_method;
+typedef struct unresolved_subtype_set unresolved_subtype_set;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vm/jit/jit.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/verify/typeinfo.h"
+
+#include "vmcore/class.h"
+#include "vmcore/field.h"
+#include "vmcore/method.h"
+#include "vmcore/references.h"
+
+
+/* constants ******************************************************************/
+
+#define RESOLVE_STATIC    0x0001  /* ref to static fields/methods             */
+#define RESOLVE_PUTFIELD  0x0002  /* field ref inside a PUT{FIELD,STATIC}...  */
+#define RESOLVE_SPECIAL   0x0004  /* method ref inside INVOKESPECIAL          */
+
+
+/* enums **********************************************************************/
+
+typedef enum {
+       resolveLazy,
+       resolveEager
+} resolve_mode_t;
+
+typedef enum {
+       resolveLinkageError,
+       resolveIllegalAccessError
+} resolve_err_t;
+
+typedef enum {
+       resolveFailed = false,  /* this must be a false value */
+       resolveDeferred = true, /* this must be a true value  */
+       resolveSucceeded
+} resolve_result_t;
+
+/* structs ********************************************************************/
+
+struct unresolved_subtype_set {
+       classref_or_classinfo *subtyperefs;     /* NULL terminated list */
+};
+
+struct unresolved_class {
+       constant_classref      *classref;
+       methodinfo                     *referermethod;
+       unresolved_subtype_set  subtypeconstraints;
+};
+
+/* XXX unify heads of unresolved_field and unresolved_method? */
+
+struct unresolved_field {
+       constant_FMIref *fieldref;
+       methodinfo      *referermethod;
+       s4               flags;
+       
+       unresolved_subtype_set  instancetypes;
+       unresolved_subtype_set  valueconstraints;
+};
+
+struct unresolved_method {
+       constant_FMIref *methodref;
+       methodinfo      *referermethod;
+       s4               flags;
+       
+       unresolved_subtype_set  instancetypes;
+       unresolved_subtype_set *paramconstraints;
+};
+
+#define SUBTYPESET_IS_EMPTY(stset) \
+       ((stset).subtyperefs == NULL)
+
+#define UNRESOLVED_SUBTYPE_SET_EMTPY(stset) \
+       do { (stset).subtyperefs = NULL; } while(0)
+
+/* function prototypes ********************************************************/
+
+bool resolve_class_from_name(classinfo* referer,methodinfo *refmethod,
+                                               utf *classname,
+                                               resolve_mode_t mode,
+                                               bool checkaccess,
+                                               bool link,
+                                               classinfo **result);
+
+bool resolve_classref(methodinfo *refmethod,
+                                constant_classref *ref,
+                                resolve_mode_t mode,
+                                bool checkaccess,
+                            bool link,
+                                classinfo **result);
+
+bool resolve_classref_or_classinfo(methodinfo *refmethod,
+                                                         classref_or_classinfo cls,
+                                                         resolve_mode_t mode,
+                                                         bool checkaccess,
+                                                         bool link,
+                                                         classinfo **result);
+
+bool resolve_class_from_typedesc(typedesc *d,bool checkaccess,bool link,classinfo **result);
+
+#ifdef ENABLE_VERIFIER
+bool resolve_class(unresolved_class *ref,
+                         resolve_mode_t mode,
+                         bool checkaccess,
+                         classinfo **result);
+
+classinfo * resolve_class_eager(unresolved_class *ref);
+#endif /* ENABLE_VERIFIER */
+
+bool resolve_field(unresolved_field *ref,
+                         resolve_mode_t mode,
+                         fieldinfo **result);
+
+bool resolve_method(unresolved_method *ref,
+                         resolve_mode_t mode,
+                          methodinfo **result);
+
+classinfo * resolve_classref_eager(constant_classref *ref);
+classinfo * resolve_classref_eager_nonabstract(constant_classref *ref);
+fieldinfo * resolve_field_eager(unresolved_field *ref);
+methodinfo * resolve_method_eager(unresolved_method *ref);
+
+#ifdef ENABLE_VERIFIER
+unresolved_class * create_unresolved_class(methodinfo *refmethod,
+                                               constant_classref *classref,
+                                               typeinfo *valuetype);
+#endif
+
+unresolved_field *resolve_create_unresolved_field(classinfo *referer,
+                                                                                         methodinfo *refmethod,
+                                                                                         instruction *iptr);
+
+unresolved_method * resolve_create_unresolved_method(classinfo *referer,
+                                                                                                        methodinfo *refmethod,
+                                                                                                        constant_FMIref *methodref,
+                                                                                                        bool invokestatic,
+                                                                                                        bool invokespecial);
+
+void unresolved_class_free(unresolved_class *ref);
+void unresolved_field_free(unresolved_field *ref);
+void unresolved_method_free(unresolved_method *ref);
+
+resolve_result_t resolve_method_lazy(methodinfo *refmethod,
+                                                                        constant_FMIref *methodref,
+                                                                        bool invokespecial);
+
+resolve_result_t resolve_field_lazy(methodinfo *refmethod,
+                                                                       constant_FMIref *fieldref);
+
+#if defined(ENABLE_VERIFIER)
+resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
+                                                                                          constant_FMIref *fieldref,
+                                                                                          classinfo *container,
+                                                                                          fieldinfo *fi,
+                                                                                          typeinfo *instanceti,
+                                                                                          typeinfo *valueti,
+                                                                                          bool isstatic,
+                                                                                          bool isput);
+
+bool resolve_constrain_unresolved_field(unresolved_field *ref,
+                                                                               classinfo *referer, 
+                                                                               methodinfo *refmethod,
+                                                                           typeinfo *instanceti,
+                                                                           typeinfo *valueti);
+
+resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
+                                                                                               constant_FMIref *methodref,
+                                                                                               methodinfo *mi,
+                                                                                               bool invokestatic);
+
+resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
+                                                                                                        methodinfo *mi,
+                                                                                                        typeinfo *instanceti,
+                                                                                                        bool invokespecial);
+
+resolve_result_t resolve_method_param_type_checks(jitdata *jd, 
+                                                                                                 methodinfo *refmethod,
+                                                                                                 instruction *iptr, 
+                                                                                                 methodinfo *mi,
+                                                                                                 bool invokestatic);
+
+resolve_result_t resolve_method_param_type_checks_stackbased(
+               methodinfo *refmethod, 
+               methodinfo *mi,
+               bool invokestatic, 
+               typedescriptor *stack);
+
+bool resolve_method_loading_constraints(classinfo *referer,
+                                                                               methodinfo *mi);
+
+bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
+                                                                                                 methodinfo *refmethod,
+                                                                                                 typeinfo *instanceti,
+                                                                                                 bool invokespecial);
+
+bool resolve_constrain_unresolved_method_params(jitdata *jd,
+                                                                                               unresolved_method *ref,
+                                                                                               methodinfo *refmethod,
+                                                                                               instruction *iptr);
+
+bool resolve_constrain_unresolved_method_params_stackbased(
+               unresolved_method *ref,
+               methodinfo *refmethod,
+               typedescriptor *stack);
+
+#endif /* defined(ENABLE_VERIFIER) */
+
+#ifndef NDEBUG
+void unresolved_class_debug_dump(unresolved_class *ref,FILE *file);
+void unresolved_field_debug_dump(unresolved_field *ref,FILE *file);
+void unresolved_method_debug_dump(unresolved_method *ref,FILE *file);
+void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file);
+#endif
+       
+#endif /* _RESOLVE_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+
diff --git a/src/vmcore/rt-timing.c b/src/vmcore/rt-timing.c
new file mode 100644 (file)
index 0000000..1cb99a1
--- /dev/null
@@ -0,0 +1,186 @@
+/* src/vmcore/rt-timing.c - POSIX real-time timing utilities
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id$
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"
+
+#include "vmcore/rt-timing.h"
+
+
+struct rt_timing_stat {
+       int index;
+       int totalindex;
+       const char *name;
+};
+
+static struct rt_timing_stat rt_timing_stat_defs[] = {
+    { RT_TIMING_JIT_CHECKS      ,RT_TIMING_JIT_TOTAL , "checks at beginning" },
+    { RT_TIMING_JIT_PARSE       ,RT_TIMING_JIT_TOTAL , "parse" },
+    { RT_TIMING_JIT_STACK       ,RT_TIMING_JIT_TOTAL , "analyse_stack" },
+    { RT_TIMING_JIT_TYPECHECK   ,RT_TIMING_JIT_TOTAL , "typecheck" },
+    { RT_TIMING_JIT_LOOP        ,RT_TIMING_JIT_TOTAL , "loop" },
+    { RT_TIMING_JIT_IFCONV      ,RT_TIMING_JIT_TOTAL , "if conversion" },
+    { RT_TIMING_JIT_ALLOC       ,RT_TIMING_JIT_TOTAL , "register allocation" },
+    { RT_TIMING_JIT_RPLPOINTS   ,RT_TIMING_JIT_TOTAL , "replacement point generation" },
+    { RT_TIMING_JIT_CODEGEN     ,RT_TIMING_JIT_TOTAL , "codegen" },
+    { RT_TIMING_JIT_TOTAL       ,-1                  , "total compile time" },
+    { -1                        ,-1                  , "" },
+
+    { RT_TIMING_LINK_RESOLVE    ,RT_TIMING_LINK_TOTAL, "link: resolve superclass/superinterfaces"},
+    { RT_TIMING_LINK_C_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute vftbl length"},
+    { RT_TIMING_LINK_ABSTRACT   ,RT_TIMING_LINK_TOTAL, "link: handle abstract methods"},
+    { RT_TIMING_LINK_C_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: compute interface table"},
+    { RT_TIMING_LINK_F_VFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill vftbl"},
+    { RT_TIMING_LINK_OFFSETS    ,RT_TIMING_LINK_TOTAL, "link: set offsets"},
+    { RT_TIMING_LINK_F_IFTBL    ,RT_TIMING_LINK_TOTAL, "link: fill interface table"},
+    { RT_TIMING_LINK_FINALIZER  ,RT_TIMING_LINK_TOTAL, "link: set finalizer"},
+    { RT_TIMING_LINK_EXCEPTS    ,RT_TIMING_LINK_TOTAL, "link: resolve exception classes"},
+    { RT_TIMING_LINK_SUBCLASS   ,RT_TIMING_LINK_TOTAL, "link: re-calculate subclass indices"},
+    { RT_TIMING_LINK_TOTAL      ,-1                  , "total link time" },
+    { -1                        ,-1                  , "" },
+       
+       { RT_TIMING_LOAD_CHECKS     ,RT_TIMING_LOAD_TOTAL, "load: initial checks"},
+       { RT_TIMING_LOAD_NDPOOL     ,RT_TIMING_LOAD_TOTAL, "load: new descriptor pool"},
+       { RT_TIMING_LOAD_CPOOL      ,RT_TIMING_LOAD_TOTAL, "load: load constant pool"},
+       { RT_TIMING_LOAD_SETUP      ,RT_TIMING_LOAD_TOTAL, "load: class setup"},
+       { RT_TIMING_LOAD_FIELDS     ,RT_TIMING_LOAD_TOTAL, "load: load fields"},
+       { RT_TIMING_LOAD_METHODS    ,RT_TIMING_LOAD_TOTAL, "load: load methods"},
+       { RT_TIMING_LOAD_CLASSREFS  ,RT_TIMING_LOAD_TOTAL, "load: create classrefs"},
+       { RT_TIMING_LOAD_DESCS      ,RT_TIMING_LOAD_TOTAL, "load: allocate descriptors"},
+       { RT_TIMING_LOAD_SETREFS    ,RT_TIMING_LOAD_TOTAL, "load: set classrefs"},
+       { RT_TIMING_LOAD_PARSEFDS   ,RT_TIMING_LOAD_TOTAL, "load: parse field descriptors"},
+       { RT_TIMING_LOAD_PARSEMDS   ,RT_TIMING_LOAD_TOTAL, "load: parse method descriptors"},
+       { RT_TIMING_LOAD_PARSECP    ,RT_TIMING_LOAD_TOTAL, "load: parse descriptors in constant pool"},
+       { RT_TIMING_LOAD_VERIFY     ,RT_TIMING_LOAD_TOTAL, "load: verifier checks"},
+       { RT_TIMING_LOAD_ATTRS      ,RT_TIMING_LOAD_TOTAL, "load: load attributes"},
+       { RT_TIMING_LOAD_TOTAL      ,-1                  , "total load time (from classbuffer)"},
+    { -1                        ,-1                  , "" },
+
+       { RT_TIMING_LOAD_BOOT_LOOKUP,-1                       , "boot: lookup in classcache"},
+       { RT_TIMING_LOAD_BOOT_ARRAY ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load array classes"},
+       { RT_TIMING_LOAD_BOOT_SUCK  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: suck class files"},
+       { RT_TIMING_LOAD_BOOT_LOAD  ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: load from class buffer"},
+       { RT_TIMING_LOAD_BOOT_CACHE ,RT_TIMING_LOAD_BOOT_TOTAL, "boot: store in classcache"},
+       { RT_TIMING_LOAD_BOOT_TOTAL ,-1                       , "total bootstrap loader time"},
+    { -1                        ,-1                       , "" },
+
+       { RT_TIMING_LOAD_CL_LOOKUP  ,-1                       , "classloader: lookup in classcache" },
+       { RT_TIMING_LOAD_CL_PREPARE ,-1                       , "classloader: prepare loader call" },
+       { RT_TIMING_LOAD_CL_JAVA    ,-1                       , "classloader: loader Java code" },
+       { RT_TIMING_LOAD_CL_CACHE   ,-1                       , "classloader: store in classcache" },
+    { -1                        ,-1                       , "" },
+
+       { RT_TIMING_NEW_OBJECT      ,-1                       , "builtin_new time" },
+       { RT_TIMING_NEW_ARRAY       ,-1                       , "builtin_newarray time" },
+    { -1                        ,-1                       , "" },
+
+    { 0                         ,-1                       , NULL }
+};
+
+static long long rt_timing_sum[RT_TIMING_N] = { 0 };
+
+void rt_timing_gettime(struct timespec *ts)
+{
+       if (clock_gettime(CLOCK_THREAD_CPUTIME_ID,ts) != 0) {
+               fprintf(stderr,"could not get time by clock_gettime: %s\n",strerror(errno));
+               abort();
+       }
+}
+
+long rt_timing_diff_usec(struct timespec *a,struct timespec *b)
+{
+       long diff;
+       time_t atime;
+
+       diff = (b->tv_nsec - a->tv_nsec) / 1000;
+       atime = a->tv_sec;
+       while (atime < b->tv_sec) {
+               atime++;
+               diff += 1000000;
+       }
+       return diff;
+}
+
+void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index)
+{
+       long diff;
+
+       diff = rt_timing_diff_usec(a,b);
+       rt_timing_sum[index] += diff;
+}
+
+void rt_timing_print_time_stats(FILE *file)
+{
+       struct rt_timing_stat *stats;
+       double total;
+
+       for (stats = rt_timing_stat_defs; stats->name; ++stats) {
+               if (stats->index < 0) {
+                       fprintf(file,"%s\n",stats->name);
+                       continue;
+               }
+               
+               if (stats->totalindex >= 0) {
+                       total = rt_timing_sum[stats->totalindex];
+                       fprintf(file,"%12lld usec %3.0f%% %s\n",
+                                       rt_timing_sum[stats->index],
+                                       (total != 0.0) ? rt_timing_sum[stats->index] / total * 100.0 : 0.0,
+                                       stats->name);
+               }
+               else {
+                       fprintf(file,"%12lld usec      %s\n",
+                                       rt_timing_sum[stats->index],
+                                       stats->name);
+               }
+       }
+}
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/rt-timing.h b/src/vmcore/rt-timing.h
new file mode 100644 (file)
index 0000000..2585315
--- /dev/null
@@ -0,0 +1,137 @@
+/* src/vmcore/rt-timing.h - POSIX real-time timing utilities
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id$
+
+*/
+
+
+#ifndef _RT_TIMING_H
+#define _RT_TIMING_H
+
+#include "config.h"
+
+#if defined(ENABLE_RT_TIMING)
+
+#include <time.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/global.h"
+
+
+#define RT_TIMING_GET_TIME(ts) \
+       rt_timing_gettime(&(ts));
+
+#define RT_TIMING_TIME_DIFF(a,b,index) \
+       rt_timing_time_diff(&(a),&(b),(index));
+
+#define RT_TIMING_JIT_CHECKS       0
+#define RT_TIMING_JIT_PARSE        1
+#define RT_TIMING_JIT_STACK        2
+#define RT_TIMING_JIT_TYPECHECK    3
+#define RT_TIMING_JIT_LOOP         4
+#define RT_TIMING_JIT_IFCONV       5
+#define RT_TIMING_JIT_ALLOC        6
+#define RT_TIMING_JIT_RPLPOINTS    7
+#define RT_TIMING_JIT_CODEGEN      8
+#define RT_TIMING_JIT_TOTAL        9
+
+#define RT_TIMING_LINK_RESOLVE     10
+#define RT_TIMING_LINK_C_VFTBL     11
+#define RT_TIMING_LINK_ABSTRACT    12
+#define RT_TIMING_LINK_C_IFTBL     13
+#define RT_TIMING_LINK_F_VFTBL     14
+#define RT_TIMING_LINK_OFFSETS     15
+#define RT_TIMING_LINK_F_IFTBL     16
+#define RT_TIMING_LINK_FINALIZER   17
+#define RT_TIMING_LINK_EXCEPTS     18
+#define RT_TIMING_LINK_SUBCLASS    19
+#define RT_TIMING_LINK_TOTAL       20
+
+#define RT_TIMING_LOAD_CHECKS      21
+#define RT_TIMING_LOAD_NDPOOL      22
+#define RT_TIMING_LOAD_CPOOL       23
+#define RT_TIMING_LOAD_SETUP       24
+#define RT_TIMING_LOAD_FIELDS      25
+#define RT_TIMING_LOAD_METHODS     26
+#define RT_TIMING_LOAD_CLASSREFS   27
+#define RT_TIMING_LOAD_DESCS       28
+#define RT_TIMING_LOAD_SETREFS     29
+#define RT_TIMING_LOAD_PARSEFDS    30
+#define RT_TIMING_LOAD_PARSEMDS    31
+#define RT_TIMING_LOAD_PARSECP     32
+#define RT_TIMING_LOAD_VERIFY      33
+#define RT_TIMING_LOAD_ATTRS       34
+#define RT_TIMING_LOAD_TOTAL       35
+
+#define RT_TIMING_LOAD_BOOT_LOOKUP 36
+#define RT_TIMING_LOAD_BOOT_ARRAY  37
+#define RT_TIMING_LOAD_BOOT_SUCK   38
+#define RT_TIMING_LOAD_BOOT_LOAD   39
+#define RT_TIMING_LOAD_BOOT_CACHE  40
+#define RT_TIMING_LOAD_BOOT_TOTAL  41
+
+#define RT_TIMING_LOAD_CL_LOOKUP   42
+#define RT_TIMING_LOAD_CL_PREPARE  43
+#define RT_TIMING_LOAD_CL_JAVA     44
+#define RT_TIMING_LOAD_CL_CACHE    45
+
+#define RT_TIMING_NEW_OBJECT       46
+#define RT_TIMING_NEW_ARRAY        47
+
+#define RT_TIMING_N                48
+
+void rt_timing_gettime(struct timespec *ts);
+
+void rt_timing_time_diff(struct timespec *a,struct timespec *b,int index);
+
+long rt_timing_diff_usec(struct timespec *a,struct timespec *b);
+
+void rt_timing_print_time_stats(FILE *file);
+
+#else /* !defined(ENABLE_RT_TIMING) */
+
+#define RT_TIMING_GET_TIME(ts)
+#define RT_TIMING_TIME_DIFF(a,b,index)
+
+#endif /* defined(ENABLE_RT_TIMING) */
+
+#endif /* _RT_TIMING_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/stackmap.c b/src/vmcore/stackmap.c
new file mode 100644 (file)
index 0000000..d642c34
--- /dev/null
@@ -0,0 +1,528 @@
+/* src/vmcore/stackmap.c - class attribute StackMapTable
+
+   Copyright (C) 2006, 2007 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.
+
+   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.
+
+   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+
+*/
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/exceptions.h"
+
+#include "vmcore/class.h"
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+#include "vmcore/stackmap.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/suck.h"
+
+
+/* stackmap_get_verification_type_info *****************************************
+
+   union verification_type_info {
+       Top_variable_info;
+          Integer_variable_info;
+          Float_variable_info;
+          Long_variable_info;
+          Double_variable_info;
+          Null_variable_info;
+          UninitializedThis_variable_info;
+          Object_variable_info;
+          Uninitialized_variable_info;
+   }
+
+   Top_variable_info {
+       u1 tag = ITEM_Top;  // 0
+   }
+
+   Integer_variable_info {
+       u1 tag = ITEM_Integer;  // 1
+   }
+
+   Float_variable_info {
+       u1 tag = ITEM_Float;  // 2
+   }
+
+   Long_variable_info {
+       u1 tag = ITEM_Long;  // 4
+   }
+
+   Double_variable_info {
+       u1 tag = ITEM_Double;  // 3
+   }
+
+   Null_variable_info {
+       u1 tag = ITEM_Null;  // 5
+   }
+
+   UninitializedThis_variable_info {
+       u1 tag = ITEM_UninitializedThis;  // 6
+   }
+
+   Object_variable_info {
+       u1 tag = ITEM_Object;  // 7
+          u2 cpool_index;
+   }
+
+   Uninitialized_variable_info {
+       u1 tag = ITEM_Uninitialized;  // 8
+          u2 offset;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_verification_type_info(classbuffer *cb, verification_type_info_t *verification_type_info)
+{
+       /* get verification type */
+
+       if (!suck_check_classbuffer_size(cb, 1))
+               return false;
+
+       verification_type_info->tag = suck_u1(cb);
+
+       /* process the tag */
+
+       switch (verification_type_info->tag) {
+       case ITEM_Top:
+       case ITEM_Integer:
+       case ITEM_Float:
+       case ITEM_Long:
+       case ITEM_Double:
+       case ITEM_Null:
+       case ITEM_UninitializedThis:
+               break;
+
+       case ITEM_Object:
+               /* get constant pool index */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               verification_type_info->Object_variable_info.cpool_index = suck_u2(cb);
+               break;
+
+       case ITEM_Uninitialized:
+               /* get offset */
+
+               if (!suck_check_classbuffer_size(cb, 2))
+                       return false;
+
+               verification_type_info->Uninitialized_variable_info.offset = suck_u2(cb);
+               break;
+       }
+
+       return true;
+}
+
+
+/* stackmap_get_same_locals_1_stack_item_frame *********************************
+
+   same_locals_1_stack_item_frame {
+       u1 frame_type = SAME_LOCALS_1_STACK_ITEM;  // 64-127
+          verification_type_info stack[1];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_locals_1_stack_item_frame(classbuffer *cb, stack_map_frame_t *stack_map_frame)
+{
+       same_locals_1_stack_item_frame_t *same_locals_1_stack_item_frame;
+
+       /* for convenience */
+
+       same_locals_1_stack_item_frame =
+               &(stack_map_frame->same_locals_1_stack_item_frame);
+
+       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame->stack[0])))
+               return false;
+
+       return true;
+}
+
+
+/* stackmap_get_same_locals_1_stack_item_frame_extended ************************
+
+   same_locals_1_stack_item_frame_extended {
+       u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED;  // 247
+          u2 offset_delta;
+          verification_type_info stack[1];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_locals_1_stack_item_frame_extended(classbuffer *cb, stack_map_frame_t *stack_map_frame)
+{
+       same_locals_1_stack_item_frame_extended_t *same_locals_1_stack_item_frame_extended;
+
+       /* for convenience */
+
+       same_locals_1_stack_item_frame_extended =
+               &(stack_map_frame->same_locals_1_stack_item_frame_extended);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       same_locals_1_stack_item_frame_extended->offset_delta = suck_u2(cb);
+
+       /* process stack */
+
+       if (!stackmap_get_verification_type_info(cb, &(same_locals_1_stack_item_frame_extended->stack[0])))
+               return false;
+
+       return true;
+}
+
+
+/* stackmap_get_chop_frame *****************************************************
+
+   chop_frame {
+       u1 frame_type = CHOP_FRAME;  // 248-250
+          u2 offset_delta;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_chop_frame(classbuffer *cb,
+                                                                       stack_map_frame_t *stack_map_frame)
+{
+       chop_frame_t *chop_frame;
+
+       /* for convenience */
+
+       chop_frame = &(stack_map_frame->chop_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       chop_frame->offset_delta = suck_u2(cb);
+
+       return true;
+}
+
+
+/* stackmap_get_same_frame_extended ********************************************
+
+   same_frame_extended {
+       u1 frame_type = SAME_FRAME_EXTENDED;  // 251
+          u2 offset_delta;
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_same_frame_extended(classbuffer *cb,
+                                                                                        stack_map_frame_t *stack_map_frame)
+{
+       same_frame_extended_t *same_frame_extended;
+
+       /* for convenience */
+
+       same_frame_extended = &(stack_map_frame->same_frame_extended);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       same_frame_extended->offset_delta = suck_u2(cb);
+
+       return true;
+}
+
+
+/* stackmap_get_append_frame ***************************************************
+
+   append_frame {
+       u1 frame_type = APPEND_FRAME;  // 252-254
+          u2 offset_delta;
+          verification_type_info locals[frame_Type - 251];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_append_frame(classbuffer *cb,
+                                                                         stack_map_frame_t *stack_map_frame)
+{
+       append_frame_t *append_frame;
+       s4              number_of_locals;
+       s4              i;
+
+       /* for convenience */
+
+       append_frame = &(stack_map_frame->append_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       /* get offset delta */
+
+       append_frame->offset_delta = suck_u2(cb);
+
+       /* allocate locals array */
+
+       number_of_locals = append_frame->frame_type - 251;
+
+       append_frame->locals = DMNEW(verification_type_info_t, number_of_locals);
+
+       /* process all locals */
+
+       for (i = 0; i < number_of_locals; i++)
+               if (!stackmap_get_verification_type_info(cb, &(append_frame->locals[i])))
+                       return false;
+
+       return true;
+}
+
+
+/* stackmap_get_full_frame *****************************************************
+
+   full_frame {
+       u1 frame_type = FULL_FRAME;
+          u2 offset_delta;
+          u2 number_of_locals;
+          verification_type_info locals[number_of_locals];
+          u2 number_of_stack_items;
+          verification_type_info stack[number_of_stack_items];
+   }
+
+*******************************************************************************/
+
+static bool stackmap_get_full_frame(classbuffer *cb,
+                                                                       stack_map_frame_t *stack_map_frame)
+{
+       full_frame_t *full_frame;
+       s4 i;
+
+       /* for convenience */
+
+       full_frame = &(stack_map_frame->full_frame);
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 2 + 2))
+               return false;
+
+       /*  get offset delta */
+
+       stack_map_frame->full_frame.offset_delta = suck_u2(cb);
+
+       /* get number of locals */
+
+       full_frame->number_of_locals = suck_u2(cb);
+
+       /* allocate locals array */
+
+       full_frame->locals =
+               DMNEW(verification_type_info_t, full_frame->number_of_locals);
+
+       /* process all locals */
+
+       for (i = 0; i < full_frame->number_of_locals; i++)
+               if (!stackmap_get_verification_type_info(cb, &(full_frame->locals[i])))
+                       return false;
+
+       /* get number of stack items */
+
+       if (!suck_check_classbuffer_size(cb, 2))
+               return false;
+
+       full_frame->number_of_stack_items = suck_u2(cb);
+
+       /* allocate stack array */
+
+       full_frame->stack =
+               DMNEW(verification_type_info_t, full_frame->number_of_stack_items);
+
+       /* process all stack items */
+
+       for (i = 0; i < full_frame->number_of_stack_items; i++)
+               if (!stackmap_get_verification_type_info(cb, &(full_frame->stack[i])))
+                       return false;
+
+       return true;
+}
+
+
+/* stackmap_load_attribute_stackmaptable ***************************************
+
+   stack_map {
+          u2 attribute_name_index;
+          u4 attribute_length;
+          u2 number_of_entries;
+          stack_map_frame entries[number_of_entries];
+   }
+
+   union stack_map_frame {
+       same_frame;
+          same_locals_1_stack_item_frame;
+          same_locals_1_stack_item_frame_extended;
+          chop_frame;
+          same_frame_extended;
+          append_frame;
+          full_frame;
+   }
+
+   same_frame {
+       u1 frame_type = SAME;  // 0-63
+   }
+
+*******************************************************************************/
+
+bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m)
+{
+       classinfo       *c;
+       stack_map_t     *stack_map;
+       s4               i;
+       u1               frame_type;
+
+       /* get classinfo */
+
+       c = cb->class;
+
+       /* allocate stack map structure */
+
+       stack_map = DNEW(stack_map_t);
+
+       STATISTICS(size_stack_map += sizeof(stack_map_t));
+
+       /* check buffer size */
+
+       if (!suck_check_classbuffer_size(cb, 4 + 2))
+               return false;
+
+       /* attribute_length */
+
+       stack_map->attribute_length = suck_u4(cb);
+
+       if (!suck_check_classbuffer_size(cb, stack_map->attribute_length))
+               return false;
+
+       /* get number of entries */
+
+       stack_map->number_of_entries = suck_u2(cb);
+
+       /* process all entries */
+
+       stack_map->entries = DMNEW(stack_map_frame_t, stack_map->number_of_entries);
+
+       for (i = 0; i < stack_map->number_of_entries; i++) {
+               /* get the frame type */
+
+               frame_type = suck_u1(cb);
+
+               stack_map->entries[i].frame_type = frame_type;
+
+               /* process frame */
+
+               if (frame_type <= FRAME_TYPE_SAME) {
+                       /* same_frame */
+               }
+               else if (frame_type <= FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM) {
+                       /* same_locals_1_stack_item_frame */
+
+                       if (!stackmap_get_same_locals_1_stack_item_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_RESERVED) {
+                       /* reserved */
+
+                       exceptions_throw_classformaterror(c, "reserved frame type");
+                       return false;
+               }
+               else if (frame_type == FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
+                       /* same_locals_1_stack_item_frame_extended */
+
+                       if (!stackmap_get_same_locals_1_stack_item_frame_extended(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_CHOP) {
+                       /* chop_frame */
+
+                       if (!stackmap_get_chop_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type == FRAME_TYPE_SAME_FRAME_EXTENDED) {
+                       /* same_frame_extended */
+
+                       if (!stackmap_get_same_frame_extended(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type <= FRAME_TYPE_APPEND) {
+                       /* append_frame */
+
+                       if (!stackmap_get_append_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+               else if (frame_type == FRAME_TYPE_FULL_FRAME) {
+                       /* full_frame */
+
+                       if (!stackmap_get_full_frame(cb, &(stack_map->entries[i])))
+                               return false;
+               }
+       }
+
+       /* store stack map in method structure */
+
+#if 0
+       /* currently not used */
+
+       m->stack_map = stack_map;
+#endif
+
+       return true;
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/stackmap.h b/src/vmcore/stackmap.h
new file mode 100644 (file)
index 0000000..e8e519a
--- /dev/null
@@ -0,0 +1,234 @@
+/* src/vmcore/stackmap.h - class attribute StackMapTable
+
+   Copyright (C) 2006, 2007 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.
+
+   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.
+
+   $Id: utf8.h 5920 2006-11-05 21:23:09Z twisti $
+
+*/
+
+
+#ifndef _STACKMAP_H
+#define _STACKMAP_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct stack_map_t                       stack_map_t;
+typedef union  stack_map_frame_t                 stack_map_frame_t;
+typedef struct same_locals_1_stack_item_frame_t  same_locals_1_stack_item_frame_t;
+typedef struct same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended_t;
+typedef struct chop_frame_t                      chop_frame_t;
+typedef struct same_frame_extended_t             same_frame_extended_t;
+typedef struct append_frame_t                    append_frame_t;
+typedef struct full_frame_t                      full_frame_t;
+
+typedef union  verification_type_info_t          verification_type_info_t;
+typedef struct Top_variable_info_t                  Top_variable_info_t;
+typedef struct Integer_variable_info_t           Integer_variable_info_t;
+typedef struct Float_variable_info_t             Float_variable_info_t;
+typedef struct Long_variable_info_t              Long_variable_info_t;
+typedef struct Double_variable_info_t            Double_variable_info_t;
+typedef struct Null_variable_info_t              Null_variable_info_t;
+typedef struct UninitializedThis_variable_info_t UninitializedThis_variable_info_t;
+typedef struct Object_variable_info_t            Object_variable_info_t;
+typedef struct Uninitialized_variable_info_t     Uninitialized_variable_info_t;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/method.h"
+
+
+/* verification_type_info *****************************************************/
+
+#define ITEM_Top                  0
+#define ITEM_Integer              1
+#define ITEM_Float                2
+#define ITEM_Double               3
+#define ITEM_Long                 4
+#define ITEM_Null                 5
+#define ITEM_UninitializedThis    6
+#define ITEM_Object               7
+#define ITEM_Uninitialized        8
+
+struct Top_variable_info_t {
+       u1 tag;
+};
+
+struct Integer_variable_info_t {
+       u1 tag;
+};
+
+struct Float_variable_info_t {
+       u1 tag;
+};
+
+struct Long_variable_info_t {
+       u1 tag;
+};
+
+struct Double_variable_info_t {
+       u1 tag;
+};
+
+struct Null_variable_info_t {
+       u1 tag;
+};
+
+struct UninitializedThis_variable_info_t {
+       u1 tag;
+};
+
+struct Object_variable_info_t {
+       u1 tag;
+       u2 cpool_index;
+};
+
+struct Uninitialized_variable_info_t {
+       u1 tag;
+       u2 offset;
+};
+
+union verification_type_info_t {
+       u1 tag;
+       Top_variable_info_t                   Top_variable_info;
+       Integer_variable_info_t           Integer_variable_info;
+       Float_variable_info_t             Float_variable_info;
+       Long_variable_info_t              Long_variable_info;
+       Double_variable_info_t            Double_variable_info;
+       Null_variable_info_t              Null_variable_info;
+       UninitializedThis_variable_info_t UninitializedThis_variable_info;
+       Object_variable_info_t            Object_variable_info;
+       Uninitialized_variable_info_t     Uninitialized_variable_info;
+};
+
+
+/* stack_map_t ****************************************************************/
+
+struct stack_map_t {
+       u2                 attribute_name_index;
+       u4                 attribute_length;
+       u2                 number_of_entries;
+       stack_map_frame_t *entries;
+};
+
+
+/* same_locals_1_stack_item_frame_t *******************************************/
+
+struct same_locals_1_stack_item_frame_t {
+       u1                       frame_type;
+       verification_type_info_t stack[1];
+};
+
+
+/* same_locals_1_stack_item_frame_extended_t **********************************/
+
+struct same_locals_1_stack_item_frame_extended_t {
+       u1                       frame_type;
+       u2                       offset_delta;
+       verification_type_info_t stack[1];
+};
+
+
+/* chop_frame_t ***************************************************************/
+
+struct chop_frame_t {
+       u1 frame_type;
+       u2 offset_delta;
+};
+
+
+/* same_frame_extended_t ******************************************************/
+
+struct same_frame_extended_t {
+       u1 frame_type;
+       u2 offset_delta;
+};
+
+
+/* append_frame_t *************************************************************/
+
+struct append_frame_t {
+       u1                        frame_type;
+       u2                        offset_delta;
+       verification_type_info_t *locals;
+};
+
+
+/* full_frame_t ***************************************************************/
+
+struct full_frame_t {
+       u1                        frame_type;
+       u2                        offset_delta;
+       u2                        number_of_locals;
+       verification_type_info_t *locals;
+       u2                        number_of_stack_items;
+       verification_type_info_t *stack;
+};
+
+
+/* stack_map_frame_t **********************************************************/
+
+#define FRAME_TYPE_SAME                                 63   /* 0-63          */
+#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM             127  /* 0-127         */
+#define FRAME_TYPE_RESERVED                             246  /* 128-246       */
+#define FRAME_TYPE_SAME_LOCALS_1_STACK_ITEM_EXTENDED    247  /* 247           */
+#define FRAME_TYPE_CHOP                                 250  /* 248-250       */
+#define FRAME_TYPE_SAME_FRAME_EXTENDED                  251  /* 251           */
+#define FRAME_TYPE_APPEND                               254  /* 252-254       */
+#define FRAME_TYPE_FULL_FRAME                           255  /* 255           */
+
+union stack_map_frame_t {
+       u1                                        frame_type;
+       same_locals_1_stack_item_frame_t          same_locals_1_stack_item_frame;
+       same_locals_1_stack_item_frame_extended_t same_locals_1_stack_item_frame_extended;
+       chop_frame_t                              chop_frame;
+       same_frame_extended_t                     same_frame_extended;
+       append_frame_t                            append_frame;
+       full_frame_t                              full_frame;
+};
+
+
+/* function prototypes ********************************************************/
+
+bool stackmap_load_attribute_stackmaptable(classbuffer *cb, methodinfo *m);
+
+#endif /* _STACKMAP_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/statistics.c b/src/vmcore/statistics.c
new file mode 100644 (file)
index 0000000..5135be2
--- /dev/null
@@ -0,0 +1,665 @@
+/* src/vmcore/statistics.c - global varables for statistics
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: statistics.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <string.h> 
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "vm/types.h"
+
+#include "toolbox/logging.h"
+#include "vm/global.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+
+
+/* global variables ***********************************************************/
+
+static s8 loadingtime = 0;              /* accumulated loading time           */
+static s8 loadingstarttime = 0;
+static s8 loadingstoptime = 0;
+static s4 loadingtime_recursion = 0;
+
+static s8 compilingtime = 0;            /* accumulated compile time           */
+static s8 compilingstarttime = 0;
+static s8 compilingstoptime = 0;
+static s4 compilingtime_recursion = 0;
+
+s4 codememusage = 0;
+s4 maxcodememusage = 0;
+
+s4 memoryusage = 0;
+s4 maxmemusage = 0;
+
+s4 maxdumpsize = 0;
+
+s4 globalallocateddumpsize = 0;
+s4 globaluseddumpsize = 0;
+
+
+/* variables for measurements *************************************************/
+
+s4 size_classinfo  = 0;
+s4 size_fieldinfo  = 0;
+s4 size_methodinfo = 0;
+s4 size_lineinfo   = 0;
+s4 size_codeinfo   = 0;
+
+s4 size_stack_map  = 0;
+
+int count_const_pool_len = 0;
+int count_classref_len = 0;
+int count_parsed_desc_len = 0;
+int count_vftbl_len = 0;
+int count_all_methods = 0;
+int count_methods_marked_used = 0;  /* RTA */
+
+int count_vmcode_len = 0;
+int count_extable_len = 0;
+int count_class_loads = 0;
+int count_class_inits = 0;
+
+int count_utf_len = 0;                  /* size of utf hash                   */
+int count_utf_new = 0;                  /* calls of utf_new                   */
+int count_utf_new_found  = 0;           /* calls of utf_new with fast return  */
+
+int count_locals_conflicts = 0;         /* register allocator statistics */
+int count_locals_spilled = 0;
+int count_locals_register = 0;
+int count_ss_spilled = 0;
+int count_ss_register = 0;
+int count_methods_allocated_by_lsra = 0;
+int count_mem_move_bb = 0;
+int count_interface_size = 0;
+int count_argument_mem_ss = 0;
+int count_argument_reg_ss = 0;
+int count_method_in_register = 0;
+int count_mov_reg_reg = 0;
+int count_mov_mem_reg = 0;
+int count_mov_reg_mem = 0;
+int count_mov_mem_mem = 0;
+
+int count_jit_calls = 0;
+int count_methods = 0;
+int count_spills = 0;
+int count_spills_read = 0;
+int count_pcmd_activ = 0;
+int count_pcmd_drop = 0;
+int count_pcmd_zero = 0;
+int count_pcmd_const_store = 0;
+int count_pcmd_const_alu = 0;
+int count_pcmd_const_bra = 0;
+int count_pcmd_load = 0;
+int count_pcmd_move = 0;
+int count_load_instruction = 0;
+int count_pcmd_store = 0;
+int count_pcmd_store_comb = 0;
+int count_dup_instruction = 0;
+int count_pcmd_op = 0;
+int count_pcmd_mem = 0;
+int count_pcmd_met = 0;
+int count_pcmd_bra = 0;
+int count_pcmd_table = 0;
+int count_pcmd_return = 0;
+int count_pcmd_returnx = 0;
+int count_check_null = 0;
+int count_check_bound = 0;
+int count_max_basic_blocks = 0;
+int count_basic_blocks = 0;
+int count_javainstr = 0;
+int count_max_javainstr = 0;
+int count_javacodesize = 0;
+int count_javaexcsize = 0;
+int count_calls = 0;
+int count_tryblocks = 0;
+int count_code_len = 0;
+int count_data_len = 0;
+int count_cstub_len = 0;
+int count_nstub_len = 0;
+int count_max_new_stack = 0;
+int count_upper_bound_new_stack = 0;
+
+s4 count_branches_resolved   = 0;
+s4 count_branches_unresolved = 0;
+
+u8 count_native_function_calls=0;
+u8 count_jni_callXmethod_calls=0;
+u8 count_jni_calls=0;
+
+
+static int count_block_stack_init[11] = {
+       0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 
+       0
+};
+int *count_block_stack = count_block_stack_init;
+static int count_analyse_iterations_init[5] = {
+       0, 0, 0, 0, 0
+};
+int *count_analyse_iterations = count_analyse_iterations_init;
+static int count_method_bb_distribution_init[9] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0
+};
+int *count_method_bb_distribution = count_method_bb_distribution_init;
+static int count_block_size_distribution_init[18] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0
+};
+int *count_block_size_distribution = count_block_size_distribution_init;
+static int count_store_length_init[21] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0
+};
+int *count_store_length = count_store_length_init;
+static int count_store_depth_init[11] = {
+       0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0,
+       0
+};
+int *count_store_depth = count_store_depth_init;
+
+
+/* instruction scheduler statistics *******************************************/
+
+s4 count_schedule_basic_blocks = 0;
+s4 count_schedule_nodes = 0;
+s4 count_schedule_leaders = 0;
+s4 count_schedule_max_leaders = 0;
+s4 count_schedule_critical_path = 0;
+
+
+/* nativeinvokation ***********************************************************
+
+   increments the native invokation count by one
+       
+*******************************************************************************/
+
+void nativeinvokation(void)
+{
+       /* XXX do locking here */
+       count_native_function_calls++;
+}
+
+
+/* jnicallXmethodinvokation ***************************************************
+
+   increments the jni CallXMethod invokation count by one
+       
+*******************************************************************************/
+
+void jnicallXmethodnvokation(void)
+{
+       /* XXX do locking here */
+       count_jni_callXmethod_calls++;
+}
+
+
+/* jniinvokation *************************************************************
+
+   increments the jni overall  invokation count by one
+       
+*******************************************************************************/
+
+void jniinvokation(void)
+{
+       /* XXX do locking here */
+       count_jni_calls++;
+}
+
+
+/* getcputime *********************************** ******************************
+
+   Returns the used CPU time in microseconds
+       
+*******************************************************************************/
+
+s8 getcputime(void)
+{
+       struct rusage ru;
+       int sec, usec;
+
+       getrusage(RUSAGE_SELF, &ru);
+       sec = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
+       usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
+
+       return sec * 1000000 + usec;
+}
+
+
+/* loadingtime_stop ************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void loadingtime_start(void)
+{
+       loadingtime_recursion++;
+
+       if (loadingtime_recursion == 1)
+               loadingstarttime = getcputime();
+}
+
+
+/* loadingtime_stop ************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void loadingtime_stop(void)
+{
+       if (loadingtime_recursion == 1) {
+               loadingstoptime = getcputime();
+               loadingtime += (loadingstoptime - loadingstarttime);
+       }
+
+       loadingtime_recursion--;
+}
+
+
+/* compilingtime_stop **********************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void compilingtime_start(void)
+{
+       compilingtime_recursion++;
+
+       if (compilingtime_recursion == 1)
+               compilingstarttime = getcputime();
+}
+
+
+/* compilingtime_stop **********************************************************
+
+   XXX
+
+*******************************************************************************/
+
+void compilingtime_stop(void)
+{
+       if (compilingtime_recursion == 1) {
+               compilingstoptime = getcputime();
+               compilingtime += (compilingstoptime - compilingstarttime);
+       }
+
+       compilingtime_recursion--;
+}
+
+
+/* print_times *****************************************************************
+
+   Prints a summary of CPU time usage.
+
+*******************************************************************************/
+
+void print_times(void)
+{
+       s8 totaltime;
+       s8 runtime;
+
+       totaltime = getcputime();
+       runtime = totaltime - loadingtime - compilingtime;
+
+#if SIZEOF_VOID_P == 8
+       dolog("Time for loading classes: %6ld ms", loadingtime / 1000);
+       dolog("Time for compiling code:  %6ld ms", compilingtime / 1000);
+       dolog("Time for running program: %6ld ms", runtime / 1000);
+       dolog("Total time:               %6ld ms", totaltime / 1000);
+#else
+       dolog("Time for loading classes: %6lld ms", loadingtime / 1000);
+       dolog("Time for compiling code:  %6lld ms", compilingtime / 1000);
+       dolog("Time for running program: %6lld ms", runtime / 1000);
+       dolog("Total time:               %6lld ms", totaltime / 1000);
+#endif
+}
+
+
+/* print_stats *****************************************************************
+
+   outputs detailed compiler statistics
+
+*******************************************************************************/
+
+void print_stats(void)
+{
+       s4    i;
+       float f;
+       s4    sum;
+
+
+       dolog("Number of JIT compiler calls: %6d", count_jit_calls);
+       dolog("Number of compiled methods:   %6d", count_methods);
+
+       dolog("Number of compiled basic blocks:               %6d",
+                 count_basic_blocks);
+       dolog("Number of max. basic blocks per method:        %6d",
+                 count_max_basic_blocks);
+
+       dolog("Number of compiled JavaVM instructions:        %6d",
+                 count_javainstr);
+       dolog("Number of max. JavaVM instructions per method: %6d",
+                 count_max_javainstr);
+       dolog("Size of compiled JavaVM instructions:          %6d(%d)",
+                 count_javacodesize, count_javacodesize - count_methods * 18);
+
+       dolog("Size of compiled Exception Tables:      %d", count_javaexcsize);
+       dolog("Number of Machine-Instructions: %d", count_code_len >> 2);
+       dolog("Number of Spills (write to memory): %d", count_spills);
+       dolog("Number of Spills (read from memory): %d", count_spills_read);
+       dolog("Number of Activ    Pseudocommands: %6d", count_pcmd_activ);
+       dolog("Number of Drop     Pseudocommands: %6d", count_pcmd_drop);
+       dolog("Number of Const    Pseudocommands: %6d (zero:%5d)",
+                 count_pcmd_load, count_pcmd_zero);
+       dolog("Number of ConstAlu Pseudocommands: %6d (cmp: %5d, store:%5d)",
+                 count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
+       dolog("Number of Move     Pseudocommands: %6d", count_pcmd_move);
+       dolog("Number of Load     Pseudocommands: %6d", count_load_instruction);
+       dolog("Number of Store    Pseudocommands: %6d (combined: %5d)",
+                 count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
+       dolog("Number of OP       Pseudocommands: %6d", count_pcmd_op);
+       dolog("Number of DUP      Pseudocommands: %6d", count_dup_instruction);
+       dolog("Number of Mem      Pseudocommands: %6d", count_pcmd_mem);
+       dolog("Number of Method   Pseudocommands: %6d", count_pcmd_met);
+       dolog("Number of Branch   Pseudocommands: %6d (rets:%5d, Xrets: %5d)",
+                 count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
+       log_println("                resolved branches: %6d", count_branches_resolved);
+       log_println("              unresolved branches: %6d", count_branches_unresolved);
+       dolog("Number of Table    Pseudocommands: %6d", count_pcmd_table);
+       dolog("Number of Useful   Pseudocommands: %6d", count_pcmd_table +
+                 count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
+       dolog("Number of Null Pointer Checks:     %6d", count_check_null);
+       dolog("Number of Array Bound Checks:      %6d", count_check_bound);
+       dolog("Number of Try-Blocks: %d", count_tryblocks);
+       dolog("Maximal count of stack elements:   %d", count_max_new_stack);
+       dolog("Upper bound of max stack elements: %d", count_upper_bound_new_stack);
+       dolog("Distribution of stack sizes at block boundary");
+       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_block_stack[0], count_block_stack[1], count_block_stack[2],
+                 count_block_stack[3], count_block_stack[4], count_block_stack[5],
+                 count_block_stack[6], count_block_stack[7], count_block_stack[8],
+                 count_block_stack[9], count_block_stack[10]);
+       dolog("Distribution of store stack depth");
+       dolog("     0     1     2     3     4     5     6     7     8     9  >=10");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_depth[0], count_store_depth[1], count_store_depth[2],
+                 count_store_depth[3], count_store_depth[4], count_store_depth[5],
+                 count_store_depth[6], count_store_depth[7], count_store_depth[8],
+                 count_store_depth[9], count_store_depth[10]);
+       dolog("Distribution of store creator chains first part");
+       dolog("     0     1     2     3     4     5     6     7     8     9");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_length[0], count_store_length[1], count_store_length[2],
+                 count_store_length[3], count_store_length[4], count_store_length[5],
+                 count_store_length[6], count_store_length[7], count_store_length[8],
+                 count_store_length[9]);
+       dolog("Distribution of store creator chains second part");
+       dolog("    10    11    12    13    14    15    16    17    18    19  >=20");
+       dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
+                 count_store_length[10], count_store_length[11],
+                 count_store_length[12], count_store_length[13],
+                 count_store_length[14], count_store_length[15],
+                 count_store_length[16], count_store_length[17],
+                 count_store_length[18], count_store_length[19],
+                 count_store_length[20]);
+       dolog("Distribution of analysis iterations");
+       dolog("     1     2     3     4   >=5");
+       dolog("%6d%6d%6d%6d%6d",
+                 count_analyse_iterations[0], count_analyse_iterations[1],
+                 count_analyse_iterations[2], count_analyse_iterations[3],
+                 count_analyse_iterations[4]);
+
+
+       /* Distribution of basic blocks per method ********************************/
+
+       log_println("Distribution of basic blocks per method:");
+       log_println("   <=5  <=10  <=15  <=20  <=30  <=40  <=50  <=75   >75");
+
+       log_start();
+       for (i = 0; i <= 8; i++)
+               log_print("%6d", count_method_bb_distribution[i]);
+       log_finish();
+
+       /* print ratio */
+
+       f = (float) count_methods;
+
+       log_start();
+       for (i = 0; i <= 8; i++)
+               log_print("%6.2f", (float) count_method_bb_distribution[i] / f);
+       log_finish();
+
+       /* print cumulated ratio */
+
+       log_start();
+       for (i = 0, sum = 0; i <= 8; i++) {
+               sum += count_method_bb_distribution[i];
+               log_print("%6.2f", (float) sum / f);
+       }
+       log_finish();
+
+
+       /* Distribution of basic block sizes **************************************/
+
+       log_println("Distribution of basic block sizes:");
+       log_println("     0     1     2     3     4     5     6     7     8     9   <13   <15   <17   <19   <21   <26   <31   >30");
+
+       /* print block sizes */
+
+       log_start();
+       for (i = 0; i <= 17; i++)
+               log_print("%6d", count_block_size_distribution[i]);
+       log_finish();
+
+       /* print ratio */
+
+       f = (float) count_basic_blocks;
+
+       log_start();
+       for (i = 0; i <= 17; i++)
+               log_print("%6.2f", (float) count_block_size_distribution[i] / f);
+       log_finish();
+
+       /* print cumulated ratio */
+
+       log_start();
+       for (i = 0, sum = 0; i <= 17; i++) {
+               sum += count_block_size_distribution[i];
+               log_print("%6.2f", (float) sum / f);
+       }
+       log_finish();
+
+       statistics_print_memory_usage();
+
+       dolog("Number of class loads:    %6d", count_class_loads);
+       dolog("Number of class inits:    %6d", count_class_inits);
+       dolog("Number of loaded Methods: %6d\n", count_all_methods);
+
+       dolog("Calls of utf_new:                 %6d", count_utf_new);
+       dolog("Calls of utf_new (element found): %6d\n", count_utf_new_found);
+
+
+       /* LSRA statistics ********************************************************/
+
+       dolog("Moves reg -> reg:     %6d", count_mov_reg_reg);
+       dolog("Moves mem -> reg:     %6d", count_mov_mem_reg);
+       dolog("Moves reg -> mem:     %6d", count_mov_reg_mem);
+       dolog("Moves mem -> mem:     %6d", count_mov_mem_mem);
+
+       dolog("Methods allocated by LSRA:         %6d",
+                 count_methods_allocated_by_lsra);
+       dolog("Conflicts between local Variables: %6d", count_locals_conflicts);
+       dolog("Local Variables held in Memory:    %6d", count_locals_spilled);
+       dolog("Local Variables held in Registers: %6d", count_locals_register);
+       dolog("Stackslots held in Memory:         %6d", count_ss_spilled);
+       dolog("Stackslots held in Registers:      %6d", count_ss_register);
+       dolog("Memory moves at BB Boundaries:     %6d", count_mem_move_bb);
+       dolog("Number of interface slots:         %6d\n", count_interface_size);
+       dolog("Number of Argument stack slots in register:  %6d",
+                 count_argument_reg_ss);
+       dolog("Number of Argument stack slots in memory:    %6d\n",
+                 count_argument_mem_ss);
+       dolog("Number of Methods kept in registers:         %6d\n",
+                 count_method_in_register);
+
+
+       /* instruction scheduler statistics ***************************************/
+
+#if defined(USE_SCHEDULER)
+       dolog("Instruction scheduler statistics:");
+       dolog("Number of basic blocks:       %7d", count_schedule_basic_blocks);
+       dolog("Number of nodes:              %7d", count_schedule_nodes);
+       dolog("Number of leaders nodes:      %7d", count_schedule_leaders);
+       dolog("Number of max. leaders nodes: %7d", count_schedule_max_leaders);
+       dolog("Length of critical path:      %7d\n", count_schedule_critical_path);
+#endif
+
+
+       /* call statistics ********************************************************/
+
+       dolog("Function call statistics:");
+       dolog("Number of native function invokations:           %ld",
+                 count_native_function_calls);
+       dolog("Number of jni->CallXMethod function invokations: %ld",
+                 count_jni_callXmethod_calls);
+       dolog("Overall number of jni invokations:               %ld",
+                 count_jni_calls);
+
+
+       /* now print other statistics ********************************************/
+
+#if defined(ENABLE_INTRP)
+       print_dynamic_super_statistics();
+#endif
+}
+
+
+/* statistics_print_memory_usage ***********************************************
+
+   Print current memory usage.
+
+*******************************************************************************/
+
+void statistics_print_memory_usage(void)
+{
+       s4 sum;
+
+       printf("memory usage ----------------------\n\n");
+       printf("code:                   %10d\n", count_code_len);
+       printf("data:                   %10d\n", count_data_len);
+
+       printf("                         ----------\n");
+
+       sum =
+               count_code_len +
+               count_data_len;
+
+       printf("                        %10d\n", sum);
+       printf("\n");
+
+       printf("classinfo  (%3d B):     %10d\n", sizeof(classinfo), size_classinfo);
+       printf("fieldinfo  (%3d B):     %10d\n", sizeof(fieldinfo), size_fieldinfo);
+       printf("methodinfo (%3d B):     %10d\n", sizeof(methodinfo), size_methodinfo);
+       printf("lineinfo   (%3d B):     %10d\n", sizeof(lineinfo), size_lineinfo);
+       printf("codeinfo   (%3d B):     %10d\n", sizeof(codeinfo), size_codeinfo);
+       printf("                         ----------\n");
+
+       sum =
+               size_classinfo +
+               size_fieldinfo +
+               size_methodinfo +
+               size_lineinfo +
+               size_codeinfo;
+
+       printf("                        %10d\n", sum);
+       printf("\n");
+
+       printf("constant pool:          %10d\n", count_const_pool_len);
+       printf("classref:               %10d\n", count_classref_len);
+       printf("parsed descriptors:     %10d\n", count_parsed_desc_len);
+       printf("vftbl:                  %10d\n", count_vftbl_len);
+       printf("compiler stubs:         %10d\n", count_cstub_len);
+       printf("native stubs:           %10d\n", count_nstub_len);
+       printf("utf:                    %10d\n", count_utf_len);
+       printf("vmcode:                 %10d\n", count_vmcode_len);
+       printf("exception tables:       %10d\n", count_extable_len);
+    printf("stack map:              %10d\n", size_stack_map);
+       printf("                         ----------\n");
+
+       sum =
+               count_const_pool_len +
+               count_classref_len +
+               count_parsed_desc_len + 
+               count_vftbl_len +
+               count_cstub_len +
+               count_nstub_len +
+               count_utf_len +
+               count_vmcode_len +
+               count_extable_len +
+               size_stack_map;
+
+       printf("                        %10d\n", sum);
+       printf("\n");
+
+       printf("max. memory usage:      %10d\n", maxcodememusage);
+       printf("max. heap memory usage: %10d\n", maxmemusage);
+       printf("max. dump memory usage: %10d\n", maxdumpsize);
+       printf("\n");
+                  
+       printf("heap memory not freed:  %10d\n", (s4) memoryusage);
+       printf("dump memory not freed:  %10d\n", (s4) globalallocateddumpsize);
+       printf("\n");
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/statistics.h b/src/vmcore/statistics.h
new file mode 100644 (file)
index 0000000..fdf371a
--- /dev/null
@@ -0,0 +1,237 @@
+/* src/vmcore/statistics.h - exports global varables for statistics
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: statistics.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _STATISTICS_H
+#define _STATISTICS_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
+/* statistic macros ***********************************************************/
+
+#if defined(ENABLE_STATISTICS)
+#define STATISTICS(x) \
+    do { \
+        if (opt_stat) { \
+            x; \
+        } \
+    } while (0)
+#else
+#define STATISTICS(x)    /* nothing */
+#endif
+
+/* in_  inline statistics */
+
+#define IN_MAX                  9
+#define IN_UNIQUEVIRT           0x0000 
+#define IN_UNIQUE_INTERFACE     0x0001
+#define IN_OUTSIDERS            0x0004
+#define IN_MAXDEPTH             0x0008
+#define IN_MAXCODE              0x0010
+#define IN_JCODELENGTH          0x0020
+#define IN_EXCEPTION            0x0040
+#define IN_NOT_UNIQUE_VIRT      0x0080
+#define IN_NOT_UNIQUE_INTERFACE 0x0100
+
+#define N_UNIQUEVIRT            0
+#define N_UNIQUE_INTERFACE      1
+#define N_OUTSIDERS             2
+#define N_MAXDEPTH             3       
+#define N_MAXCODE               4 
+#define N_JCODELENGTH           5 
+#define N_EXCEPTION            6 
+#define N_NOT_UNIQUE_VIRT       7 
+#define N_NOT_UNIQUE_INTERFACE  8 
+
+
+/* global variables ***********************************************************/
+
+extern s4 codememusage;
+extern s4 maxcodememusage;
+
+extern s4 memoryusage;
+extern s4 maxmemusage;
+
+extern s4 maxdumpsize;
+
+extern s4 globalallocateddumpsize;
+extern s4 globaluseddumpsize;
+
+
+/* variables for measurements *************************************************/
+
+extern s4 size_classinfo;
+extern s4 size_fieldinfo;
+extern s4 size_methodinfo;
+extern s4 size_lineinfo;
+extern s4 size_codeinfo;
+
+extern s4 size_stack_map;
+
+extern int count_const_pool_len;
+extern int count_classref_len;
+extern int count_parsed_desc_len;
+extern int count_vftbl_len;
+extern int count_all_methods;
+extern int count_methods_marked_used;  /*RTA*/
+extern int count_vmcode_len;
+extern int count_extable_len;
+extern int count_class_loads;
+extern int count_class_inits;
+
+extern int count_utf_len;               /* size of utf hash                   */
+extern int count_utf_new;
+extern int count_utf_new_found;
+
+extern int count_locals_conflicts;
+extern int count_locals_spilled;
+extern int count_locals_register;
+extern int count_ss_spilled;
+extern int count_ss_register;
+extern int count_methods_allocated_by_lsra;
+extern int count_mem_move_bb;
+extern int count_interface_size;
+extern int count_argument_mem_ss;
+extern int count_argument_reg_ss;
+extern int count_method_in_register;
+extern int count_mov_reg_reg;
+extern int count_mov_mem_reg;
+extern int count_mov_reg_mem;
+extern int count_mov_mem_mem;
+
+extern int count_jit_calls;
+extern int count_methods;
+extern int count_spills;
+extern int count_spills_read;
+extern int count_pcmd_activ;
+extern int count_pcmd_drop;
+extern int count_pcmd_zero;
+extern int count_pcmd_const_store;
+extern int count_pcmd_const_alu;
+extern int count_pcmd_const_bra;
+extern int count_pcmd_load;
+extern int count_pcmd_move;
+extern int count_load_instruction;
+extern int count_pcmd_store;
+extern int count_pcmd_store_comb;
+extern int count_dup_instruction;
+extern int count_pcmd_op;
+extern int count_pcmd_mem;
+extern int count_pcmd_met;
+extern int count_pcmd_bra;
+extern int count_pcmd_table;
+extern int count_pcmd_return;
+extern int count_pcmd_returnx;
+extern int count_check_null;
+extern int count_check_bound;
+extern int count_max_basic_blocks;
+extern int count_basic_blocks;
+extern int count_max_javainstr;
+extern int count_javainstr;
+extern int count_javacodesize;
+extern int count_javaexcsize;
+extern int count_calls;
+extern int count_tryblocks;
+extern int count_code_len;
+extern int count_data_len;
+extern int count_cstub_len;
+extern int count_nstub_len;
+extern int count_max_new_stack;
+extern int count_upper_bound_new_stack;
+
+extern s4 count_branches_resolved;
+extern s4 count_branches_unresolved;
+
+extern int *count_block_stack;
+extern int *count_analyse_iterations;
+extern int *count_method_bb_distribution;
+extern int *count_block_size_distribution;
+extern int *count_store_length;
+extern int *count_store_depth;
+                                /* in_  inline statistics */
+extern int count_in;
+extern int count_in_uniqVirt;
+extern int count_in_uniqIntf;
+extern int count_in_rejected;
+extern int count_in_rejected_mult;
+extern int count_in_outsiders;
+extern int count_in_uniqueVirt_not_inlined;
+extern int count_in_uniqueInterface_not_inlined;
+extern int count_in_maxDepth;
+extern int count_in_maxMethods;
+
+extern u2 count_in_not   [512];
+
+/* instruction scheduler statistics *******************************************/
+
+extern s4 count_schedule_basic_blocks;
+extern s4 count_schedule_nodes;
+extern s4 count_schedule_leaders;
+extern s4 count_schedule_max_leaders;
+extern s4 count_schedule_critical_path;
+
+
+/* function prototypes ********************************************************/
+
+s8 getcputime(void);
+
+void loadingtime_start(void);
+void loadingtime_stop(void);
+void compilingtime_start(void);
+void compilingtime_stop(void);
+
+void print_times(void);
+void print_stats(void);
+
+void statistics_print_memory_usage(void);
+void mem_usagelog(bool givewarnings);
+
+void nativeinvokation(void);
+void compiledinvokation(void);
+void jnicallXmethodnvokation(void);
+void jniinvokation(void);
+
+#endif /* _STATISTICS_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:
+ */
diff --git a/src/vmcore/suck.c b/src/vmcore/suck.c
new file mode 100644 (file)
index 0000000..5aeed73
--- /dev/null
@@ -0,0 +1,647 @@
+/* src/vmcore/suck.c - functions to read LE ordered types from a buffer
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: suck.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#else
+# include "threads/none/lock.h"
+#endif
+
+#include "toolbox/list.h"
+#include "toolbox/logging.h"
+#include "toolbox/util.h"
+
+#include "vm/exceptions.h"
+#include "vm/properties.h"
+#include "vm/vm.h"
+
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/suck.h"
+#include "vmcore/zip.h"
+
+
+/* global variables ***********************************************************/
+
+list *list_classpath_entries;
+
+
+/* suck_init *******************************************************************
+
+   Initializes the suck subsystem like initializing the classpath
+   entries list.
+
+*******************************************************************************/
+
+bool suck_init(void)
+{
+       list_classpath_entries = list_create(OFFSET(list_classpath_entry, linkage));
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* scandir_filter **************************************************************
+
+   Filters for zip/jar files.
+
+*******************************************************************************/
+
+#if defined(__LINUX__)
+static int scandir_filter(const struct dirent *a)
+#else
+static int scandir_filter(struct dirent *a)
+#endif
+{
+       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(char *key)
+{
+       char           *value;
+       char           *start;
+       char           *end;
+       char           *path;
+       s4              pathlen;
+       struct dirent **namelist;
+       s4              n;
+       s4              i;
+       s4              namlen;
+       char           *tmpbootclasspath;
+
+       /* 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 = 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
+
+                                       /* reallocate memory for bootclasspath */
+
+                                       tmpbootclasspath = MNEW(char,
+                                                                                       pathlen + strlen("/") + namlen +
+                                                                                       strlen(":") +
+                                                                                       strlen(_Jv_bootclasspath) +
+                                                                                       strlen("0"));
+
+                                       /* prepend the file found to bootclasspath */
+
+                                       strcpy(tmpbootclasspath, path);
+                                       strcat(tmpbootclasspath, "/");
+                                       strcat(tmpbootclasspath, namelist[i]->d_name);
+                                       strcat(tmpbootclasspath, ":");
+
+                                       strcat(tmpbootclasspath, _Jv_bootclasspath);
+
+                                       /* free old bootclasspath memory */
+
+                                       MFREE(_Jv_bootclasspath, u1, strlen(_Jv_bootclasspath));
+
+                                       /* and set the new bootclasspath */
+
+                                       _Jv_bootclasspath = tmpbootclasspath;
+
+                                       /* 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)->class, "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
+
+       if (sizeof(float) != 4) {
+               exceptions_throw_internalerror("Incompatible float-format");
+
+               /* XXX should we exit in such a case? */
+               throw_exception_exit();
+       }
+       
+       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
+
+       if (sizeof(double) != 8) {
+               exceptions_throw_internalerror("Incompatible double-format");
+
+               /* XXX should we exit in such a case? */
+               throw_exception_exit();
+       }
+       
+       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 */
+
+                       LOCK_MONITOR_ENTER(lce);
+
+                       /* try to get the file in current archive */
+
+                       cb = zip_get(lce, c);
+
+                       /* leave the monitor */
+
+                       LOCK_MONITOR_EXIT(lce);
+
+               } else {
+#endif /* defined(ENABLE_ZLIB) */
+                       path = MNEW(char, lce->pathlen + filenamelen);
+                       strcpy(path, lce->path);
+                       strcat(path, filename);
+
+                       classfile = fopen(path, "r");
+
+                       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;
+                                       cb->path  = lce->path;
+
+                                       /* read class data */
+
+                                       len = fread(cb->data, 1, cb->size, classfile);
+
+                                       if (len != buffer.st_size) {
+                                               suck_stop(cb);
+/*                                             if (ferror(classfile)) { */
+/*                                             } */
+                                       }
+
+                                       /* close the class file */
+
+                                       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:
+ */
diff --git a/src/vmcore/suck.h b/src/vmcore/suck.h
new file mode 100644 (file)
index 0000000..8d24a09
--- /dev/null
@@ -0,0 +1,203 @@
+/* src/vmcore/suck.h - functions to read LE ordered types from a buffer
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: suck.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _SUCK_H
+#define _SUCK_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+#include "toolbox/list.h"
+
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+
+
+/* list_classpath_entry *******************************************************/
+
+enum {
+       CLASSPATH_PATH,
+       CLASSPATH_ARCHIVE
+};
+
+typedef struct list_classpath_entry list_classpath_entry;
+
+struct list_classpath_entry {
+#if defined(ENABLE_THREADS)
+       java_objectheader  header;              /* monitor locking on zip/jar files   */
+#endif
+       s4                 type;
+       char              *path;
+       s4                 pathlen;
+#if defined(ENABLE_ZLIB)
+       hashtable         *htclasses;
+#endif
+       listnode           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 *list_classpath_entries;
+
+
+/* function prototypes ********************************************************/
+
+bool suck_init(void);
+
+void suck_add(char *classpath);
+void suck_add_from_property(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);
+
+#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:
+ */
diff --git a/src/vmcore/utf8.c b/src/vmcore/utf8.c
new file mode 100644 (file)
index 0000000..46a0c7e
--- /dev/null
@@ -0,0 +1,1867 @@
+/* src/vmcore/utf8.c - utf8 string functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: utf8.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <string.h>
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#else
+# include "threads/none/lock.h"
+#endif
+
+#include "toolbox/hashtable.h"
+
+#include "vm/exceptions.h"
+
+#include "vmcore/options.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
+#include "vmcore/utf8.h"
+
+
+/* global variables ***********************************************************/
+
+/* hashsize must be power of 2 */
+
+#define HASHTABLE_UTF_SIZE    16384     /* initial size of utf-hash           */
+
+hashtable *hashtable_utf;               /* hashtable for utf8-symbols         */
+
+
+/* utf-symbols for pointer comparison of frequently used strings **************/
+
+utf *utf_java_lang_Object;
+
+utf *utf_java_lang_Class;
+utf *utf_java_lang_ClassLoader;
+utf *utf_java_lang_Cloneable;
+utf *utf_java_lang_SecurityManager;
+utf *utf_java_lang_String;
+utf *utf_java_lang_System;
+utf *utf_java_lang_ThreadGroup;
+utf *utf_java_io_Serializable;
+
+utf *utf_java_lang_Throwable;
+utf *utf_java_lang_Error;
+utf *utf_java_lang_ClassCircularityError;
+utf *utf_java_lang_ClassFormatError;
+utf *utf_java_lang_ExceptionInInitializerError;
+utf *utf_java_lang_IncompatibleClassChangeError;
+utf *utf_java_lang_InstantiationError;
+utf *utf_java_lang_InternalError;
+utf *utf_java_lang_LinkageError;
+utf *utf_java_lang_NoClassDefFoundError;
+utf *utf_java_lang_OutOfMemoryError;
+utf *utf_java_lang_UnsatisfiedLinkError;
+utf *utf_java_lang_UnsupportedClassVersionError;
+utf *utf_java_lang_VerifyError;
+utf *utf_java_lang_VirtualMachineError;
+
+#if defined(ENABLE_JAVASE)
+utf *utf_java_lang_AbstractMethodError;
+utf *utf_java_lang_NoSuchFieldError;
+utf *utf_java_lang_NoSuchMethodError;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+utf *utf_java_lang_VMThrowable;
+#endif
+
+utf *utf_java_lang_Exception;
+utf *utf_java_lang_ArithmeticException;
+utf *utf_java_lang_ArrayIndexOutOfBoundsException;
+utf *utf_java_lang_ArrayStoreException;
+utf *utf_java_lang_ClassCastException;
+utf *utf_java_lang_ClassNotFoundException;
+utf *utf_java_lang_CloneNotSupportedException;
+utf *utf_java_lang_IllegalAccessException;
+utf *utf_java_lang_IllegalArgumentException;
+utf *utf_java_lang_IllegalMonitorStateException;
+utf *utf_java_lang_InstantiationException;
+utf *utf_java_lang_InterruptedException;
+utf *utf_java_lang_InvocationTargetException;
+utf *utf_java_lang_NegativeArraySizeException;
+utf *utf_java_lang_NullPointerException;
+utf *utf_java_lang_StringIndexOutOfBoundsException;
+
+#if defined(ENABLE_JAVASE)
+utf* utf_java_lang_Void;
+#endif
+
+utf* utf_java_lang_Boolean;
+utf* utf_java_lang_Byte;
+utf* utf_java_lang_Character;
+utf* utf_java_lang_Short;
+utf* utf_java_lang_Integer;
+utf* utf_java_lang_Long;
+utf* utf_java_lang_Float;
+utf* utf_java_lang_Double;
+
+#if defined(ENABLE_JAVASE)
+utf *utf_java_lang_StackTraceElement;
+utf *utf_java_lang_reflect_Constructor;
+utf *utf_java_lang_reflect_Field;
+utf *utf_java_lang_reflect_Method;
+utf *utf_java_util_Vector;
+#endif
+
+utf *utf_InnerClasses;                  /* InnerClasses                       */
+utf *utf_ConstantValue;                 /* ConstantValue                      */
+utf *utf_Code;                          /* Code                               */
+utf *utf_Exceptions;                    /* Exceptions                         */
+utf *utf_LineNumberTable;               /* LineNumberTable                    */
+utf *utf_SourceFile;                    /* SourceFile                         */
+
+#if defined(ENABLE_JAVASE)
+utf *utf_EnclosingMethod;
+utf *utf_Signature;
+utf *utf_RuntimeVisibleAnnotations;
+utf *utf_StackMapTable;
+#endif
+
+utf *utf_init;                          /* <init>                             */
+utf *utf_clinit;                        /* <clinit>                           */
+utf *utf_clone;                         /* clone                              */
+utf *utf_finalize;                      /* finalize                           */
+utf *utf_run;                           /* run                                */
+
+utf *utf_add;
+utf *utf_remove;
+utf *utf_addThread;
+utf *utf_removeThread;
+utf *utf_put;
+utf *utf_get;
+utf *utf_value;
+
+utf *utf_fillInStackTrace;
+utf *utf_getSystemClassLoader;
+utf *utf_loadClass;
+utf *utf_printStackTrace;
+
+utf *utf_Z;                             /* Z                                  */
+utf *utf_B;                             /* B                                  */
+utf *utf_C;                             /* C                                  */
+utf *utf_S;                             /* S                                  */
+utf *utf_I;                             /* I                                  */
+utf *utf_J;                             /* J                                  */
+utf *utf_F;                             /* F                                  */
+utf *utf_D;                             /* D                                  */
+
+utf *utf_void__void;                    /* ()V                                */
+utf *utf_boolean__void;                 /* (Z)V                               */
+utf *utf_byte__void;                    /* (B)V                               */
+utf *utf_char__void;                    /* (C)V                               */
+utf *utf_short__void;                   /* (S)V                               */
+utf *utf_int__void;                     /* (I)V                               */
+utf *utf_long__void;                    /* (J)V                               */
+utf *utf_float__void;                   /* (F)V                               */
+utf *utf_double__void;                  /* (D)V                               */
+
+utf *utf_void__java_lang_ClassLoader;   /* ()Ljava/lang/ClassLoader;          */
+utf *utf_void__java_lang_Object;        /* ()Ljava/lang/Object;               */
+utf *utf_void__java_lang_Throwable;     /* ()Ljava/lang/Throwable;            */
+utf *utf_java_lang_Object__java_lang_Object;
+utf *utf_java_lang_String__void;        /* (Ljava/lang/String;)V              */
+utf *utf_java_lang_String__java_lang_Class;
+utf *utf_java_lang_Thread__V;           /* (Ljava/lang/Thread;)V              */
+utf *utf_java_lang_Throwable__void;     /* (Ljava/lang/Throwable;)V           */
+
+utf *utf_not_named_yet;                 /* special name for unnamed classes   */
+utf *utf_null;
+utf *array_packagename;
+
+
+/* utf_init ********************************************************************
+
+   Initializes the utf8 subsystem.
+
+*******************************************************************************/
+
+bool utf8_init(void)
+{
+       /* create utf8 hashtable */
+
+       hashtable_utf = NEW(hashtable);
+
+       hashtable_create(hashtable_utf, HASHTABLE_UTF_SIZE);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_utf_len += sizeof(utf*) * hashtable_utf->size;
+#endif
+
+       /* create utf-symbols for pointer comparison of frequently used strings */
+
+       utf_java_lang_Object           = utf_new_char("java/lang/Object");
+
+       utf_java_lang_Class            = utf_new_char("java/lang/Class");
+       utf_java_lang_ClassLoader      = utf_new_char("java/lang/ClassLoader");
+       utf_java_lang_Cloneable        = utf_new_char("java/lang/Cloneable");
+       utf_java_lang_SecurityManager  = utf_new_char("java/lang/SecurityManager");
+       utf_java_lang_String           = utf_new_char("java/lang/String");
+       utf_java_lang_System           = utf_new_char("java/lang/System");
+       utf_java_lang_ThreadGroup      = utf_new_char("java/lang/ThreadGroup");
+       utf_java_io_Serializable       = utf_new_char("java/io/Serializable");
+
+       utf_java_lang_Throwable        = utf_new_char("java/lang/Throwable");
+       utf_java_lang_Error            = utf_new_char("java/lang/Error");
+
+       utf_java_lang_ClassCircularityError =
+               utf_new_char("java/lang/ClassCircularityError");
+
+       utf_java_lang_ClassFormatError = utf_new_char("java/lang/ClassFormatError");
+
+       utf_java_lang_ExceptionInInitializerError =
+               utf_new_char("java/lang/ExceptionInInitializerError");
+
+       utf_java_lang_IncompatibleClassChangeError =
+               utf_new_char("java/lang/IncompatibleClassChangeError");
+
+       utf_java_lang_InstantiationError =
+               utf_new_char("java/lang/InstantiationError");
+
+       utf_java_lang_InternalError    = utf_new_char("java/lang/InternalError");
+       utf_java_lang_LinkageError     = utf_new_char("java/lang/LinkageError");
+
+       utf_java_lang_NoClassDefFoundError =
+               utf_new_char("java/lang/NoClassDefFoundError");
+
+       utf_java_lang_OutOfMemoryError = utf_new_char("java/lang/OutOfMemoryError");
+
+       utf_java_lang_UnsatisfiedLinkError =
+               utf_new_char("java/lang/UnsatisfiedLinkError");
+
+       utf_java_lang_UnsupportedClassVersionError =
+               utf_new_char("java/lang/UnsupportedClassVersionError");
+
+       utf_java_lang_VerifyError      = utf_new_char("java/lang/VerifyError");
+
+       utf_java_lang_VirtualMachineError =
+               utf_new_char("java/lang/VirtualMachineError");
+
+#if defined(ENABLE_JAVASE)
+       utf_java_lang_AbstractMethodError =
+               utf_new_char("java/lang/AbstractMethodError");
+
+       utf_java_lang_NoSuchFieldError =
+               utf_new_char("java/lang/NoSuchFieldError");
+
+       utf_java_lang_NoSuchMethodError =
+               utf_new_char("java/lang/NoSuchMethodError");
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+       utf_java_lang_VMThrowable      = utf_new_char("java/lang/VMThrowable");
+#endif
+
+       utf_java_lang_Exception        = utf_new_char("java/lang/Exception");
+
+       utf_java_lang_ArithmeticException =
+               utf_new_char("java/lang/ArithmeticException");
+
+       utf_java_lang_ArrayIndexOutOfBoundsException =
+               utf_new_char("java/lang/ArrayIndexOutOfBoundsException");
+
+       utf_java_lang_ArrayStoreException =
+               utf_new_char("java/lang/ArrayStoreException");
+
+       utf_java_lang_ClassCastException =
+               utf_new_char("java/lang/ClassCastException");
+
+       utf_java_lang_ClassNotFoundException =
+               utf_new_char("java/lang/ClassNotFoundException");
+
+       utf_java_lang_CloneNotSupportedException =
+               utf_new_char("java/lang/CloneNotSupportedException");
+
+       utf_java_lang_IllegalAccessException =
+               utf_new_char("java/lang/IllegalAccessException");
+
+       utf_java_lang_IllegalArgumentException =
+               utf_new_char("java/lang/IllegalArgumentException");
+
+       utf_java_lang_IllegalMonitorStateException =
+               utf_new_char("java/lang/IllegalMonitorStateException");
+
+       utf_java_lang_InstantiationException =
+               utf_new_char("java/lang/InstantiationException");
+
+       utf_java_lang_InterruptedException =
+               utf_new_char("java/lang/InterruptedException");
+
+       utf_java_lang_InvocationTargetException =
+               utf_new_char("java/lang/InvocationTargetException");
+       utf_java_lang_NegativeArraySizeException =
+               utf_new_char("java/lang/NegativeArraySizeException");
+
+       utf_java_lang_NullPointerException =
+               utf_new_char("java/lang/NullPointerException");
+
+       utf_java_lang_StringIndexOutOfBoundsException =
+               utf_new_char("java/lang/StringIndexOutOfBoundsException");
+
+#if defined(ENABLE_JAVASE)
+       utf_java_lang_Void             = utf_new_char("java/lang/Void");
+#endif
+
+       utf_java_lang_Boolean          = utf_new_char("java/lang/Boolean");
+       utf_java_lang_Byte             = utf_new_char("java/lang/Byte");
+       utf_java_lang_Character        = utf_new_char("java/lang/Character");
+       utf_java_lang_Short            = utf_new_char("java/lang/Short");
+       utf_java_lang_Integer          = utf_new_char("java/lang/Integer");
+       utf_java_lang_Long             = utf_new_char("java/lang/Long");
+       utf_java_lang_Float            = utf_new_char("java/lang/Float");
+       utf_java_lang_Double           = utf_new_char("java/lang/Double");
+
+#if defined(ENABLE_JAVASE)
+       utf_java_lang_StackTraceElement =
+               utf_new_char("java/lang/StackTraceElement");
+
+       utf_java_lang_reflect_Constructor =
+               utf_new_char("java/lang/reflect/Constructor");
+
+       utf_java_lang_reflect_Field    = utf_new_char("java/lang/reflect/Field");
+       utf_java_lang_reflect_Method   = utf_new_char("java/lang/reflect/Method");
+       utf_java_util_Vector           = utf_new_char("java/util/Vector");
+#endif
+
+       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");
+
+#if defined(ENABLE_JAVASE)
+       utf_EnclosingMethod            = utf_new_char("EnclosingMethod");
+       utf_Signature                  = utf_new_char("Signature");
+       utf_RuntimeVisibleAnnotations  = utf_new_char("RuntimeVisibleAnnotations");
+       utf_StackMapTable              = utf_new_char("StackMapTable");
+#endif
+
+       utf_init                           = utf_new_char("<init>");
+       utf_clinit                         = utf_new_char("<clinit>");
+       utf_clone                      = utf_new_char("clone");
+       utf_finalize                   = utf_new_char("finalize");
+       utf_run                        = utf_new_char("run");
+
+       utf_add                        = utf_new_char("add");
+       utf_remove                     = utf_new_char("remove");
+       utf_addThread                  = utf_new_char("addThread");
+       utf_removeThread               = utf_new_char("removeThread");
+       utf_put                        = utf_new_char("put");
+       utf_get                        = utf_new_char("get");
+       utf_value                      = utf_new_char("value");
+
+       utf_printStackTrace            = utf_new_char("printStackTrace");
+       utf_fillInStackTrace           = utf_new_char("fillInStackTrace");
+       utf_loadClass                  = utf_new_char("loadClass");
+       utf_getSystemClassLoader       = utf_new_char("getSystemClassLoader");
+
+       utf_Z                          = utf_new_char("Z");
+       utf_B                          = utf_new_char("B");
+       utf_C                          = utf_new_char("C");
+       utf_S                          = utf_new_char("S");
+       utf_I                          = utf_new_char("I");
+       utf_J                          = utf_new_char("J");
+       utf_F                          = utf_new_char("F");
+       utf_D                          = utf_new_char("D");
+
+       utf_void__void                 = utf_new_char("()V");
+       utf_boolean__void              = utf_new_char("(Z)V");
+       utf_byte__void                 = utf_new_char("(B)V");
+       utf_char__void                 = utf_new_char("(C)V");
+       utf_short__void                = utf_new_char("(S)V");
+       utf_int__void                  = utf_new_char("(I)V");
+       utf_long__void                 = utf_new_char("(J)V");
+       utf_float__void                = utf_new_char("(F)V");
+       utf_double__void               = utf_new_char("(D)V");
+       utf_void__java_lang_Object     = utf_new_char("()Ljava/lang/Object;");
+       utf_void__java_lang_Throwable  = utf_new_char("()Ljava/lang/Throwable;");
+
+       utf_void__java_lang_ClassLoader =
+               utf_new_char("()Ljava/lang/ClassLoader;");
+
+       utf_java_lang_Object__java_lang_Object =
+               utf_new_char("(Ljava/lang/Object;)Ljava/lang/Object;");
+
+       utf_java_lang_String__void     = utf_new_char("(Ljava/lang/String;)V");
+
+       utf_java_lang_String__java_lang_Class =
+               utf_new_char("(Ljava/lang/String;)Ljava/lang/Class;");
+
+       utf_java_lang_Thread__V        = utf_new_char("(Ljava/lang/Thread;)V");
+       utf_java_lang_Throwable__void  = utf_new_char("(Ljava/lang/Throwable;)V");
+
+       utf_null                       = utf_new_char("null");
+       utf_not_named_yet              = utf_new_char("\t<not_named_yet>");
+       array_packagename              = utf_new_char("\t<the array package>");
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* utf_hashkey *****************************************************************
+
+   The hashkey is computed from the utf-text by using up to 8
+   characters.  For utf-symbols longer than 15 characters 3 characters
+   are taken from the beginning and the end, 2 characters are taken
+   from the middle.
+
+*******************************************************************************/
+
+#define nbs(val) ((u4) *(++text) << val) /* get next byte, left shift by val  */
+#define fbs(val) ((u4) *(  text) << val) /* get first byte, left shift by val */
+
+u4 utf_hashkey(const char *text, u4 length)
+{
+       const char *start_pos = text;       /* pointer to utf text                */
+       u4 a;
+
+       switch (length) {
+       case 0: /* empty string */
+               return 0;
+
+       case 1: return fbs(0);
+       case 2: return fbs(0) ^ nbs(3);
+       case 3: return fbs(0) ^ nbs(3) ^ nbs(5);
+       case 4: return fbs(0) ^ nbs(2) ^ nbs(4) ^ nbs(6);
+       case 5: return fbs(0) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(6);
+       case 6: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(5) ^ nbs(6);
+       case 7: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6);
+       case 8: return fbs(0) ^ nbs(1) ^ nbs(2) ^ nbs(3) ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7);
+
+       case 9:
+               a = fbs(0);
+               a ^= nbs(1);
+               a ^= nbs(2);
+               text++;
+               return a ^ nbs(4) ^ nbs(5) ^ nbs(6) ^ nbs(7) ^ nbs(8);
+
+       case 10:
+               a = fbs(0);
+               text++;
+               a ^= nbs(2);
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text++;
+               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9);
+
+       case 11:
+               a = fbs(0);
+               text++;
+               a ^= nbs(2);
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text++;
+               return a ^ nbs(6) ^ nbs(7) ^ nbs(8) ^ nbs(9) ^ nbs(10);
+
+       case 12:
+               a = fbs(0);
+               text += 2;
+               a ^= nbs(2);
+               a ^= nbs(3);
+               text++;
+               a ^= nbs(5);
+               a ^= nbs(6);
+               a ^= nbs(7);
+               text++;
+               return a ^ nbs(9) ^ nbs(10);
+
+       case 13:
+               a = fbs(0);
+               a ^= nbs(1);
+               text++;
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text += 2;      
+               a ^= nbs(7);
+               a ^= nbs(8);
+               text += 2;
+               return a ^ nbs(9) ^ nbs(10);
+
+       case 14:
+               a = fbs(0);
+               text += 2;      
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text += 2;      
+               a ^= nbs(7);
+               a ^= nbs(8);
+               text += 2;
+               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
+
+       case 15:
+               a = fbs(0);
+               text += 2;      
+               a ^= nbs(3);
+               a ^= nbs(4);
+               text += 2;      
+               a ^= nbs(7);
+               a ^= nbs(8);
+               text += 2;
+               return a ^ nbs(9) ^ nbs(10) ^ nbs(11);
+
+       default:  /* 3 characters from beginning */
+               a = fbs(0);
+               text += 2;
+               a ^= nbs(3);
+               a ^= nbs(4);
+
+               /* 2 characters from middle */
+               text = start_pos + (length / 2);
+               a ^= fbs(5);
+               text += 2;
+               a ^= nbs(6);    
+
+               /* 3 characters from end */
+               text = start_pos + length - 4;
+
+               a ^= fbs(7);
+               text++;
+
+               return a ^ nbs(10) ^ nbs(11);
+    }
+}
+
+/* utf_full_hashkey ************************************************************
+
+   This function computes a hash value using all bytes in the string.
+
+   The algorithm is the "One-at-a-time" algorithm as published
+   by Bob Jenkins on http://burtleburtle.net/bob/hash/doobs.html.
+
+*******************************************************************************/
+
+u4 utf_full_hashkey(const char *text, u4 length)
+{
+       register const unsigned char *p = (const unsigned char *) text;
+       register u4 hash;
+       register u4 i;
+
+       hash = 0;
+       for (i=length; i--;)
+       {
+           hash += *p++;
+           hash += (hash << 10);
+           hash ^= (hash >> 6);
+       }
+       hash += (hash << 3);
+       hash ^= (hash >> 11);
+       hash += (hash << 15);
+
+       return hash;
+}
+
+/* unicode_hashkey *************************************************************
+
+   Compute the hashkey of a unicode string.
+
+*******************************************************************************/
+
+u4 unicode_hashkey(u2 *text, u2 len)
+{
+       return utf_hashkey((char *) text, len);
+}
+
+
+/* utf_new *********************************************************************
+
+   Creates a new utf-symbol, the text of the symbol is passed as a
+   u1-array. The function searches the utf-hashtable for a utf-symbol
+   with this text. On success the element returned, otherwise a new
+   hashtable element is created.
+
+   If the number of entries in the hashtable exceeds twice the size of
+   the hashtable slots a reorganization of the hashtable is done and
+   the utf symbols are copied to a new hashtable with doubled size.
+
+*******************************************************************************/
+
+utf *utf_new(const char *text, u2 length)
+{
+       u4 key;                             /* hashkey computed from utf-text     */
+       u4 slot;                            /* slot in hashtable                  */
+       utf *u;                             /* hashtable element                  */
+       u2 i;
+
+       LOCK_MONITOR_ENTER(hashtable_utf->header);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_utf_new++;
+#endif
+
+       key  = utf_hashkey(text, length);
+       slot = key & (hashtable_utf->size - 1);
+       u    = hashtable_utf->ptr[slot];
+
+       /* search external hash chain for utf-symbol */
+
+       while (u) {
+               if (u->blength == length) {
+                       /* compare text of hashtable elements */
+
+                       for (i = 0; i < length; i++)
+                               if (text[i] != u->text[i])
+                                       goto nomatch;
+                       
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_utf_new_found++;
+#endif
+
+                       /* symbol found in hashtable */
+
+                       LOCK_MONITOR_EXIT(hashtable_utf->header);
+
+                       return u;
+               }
+
+       nomatch:
+               u = u->hashlink; /* next element in external chain */
+       }
+
+       /* location in hashtable found, create new utf element */
+
+       u = NEW(utf);
+
+       u->blength  = length;               /* length in bytes of utfstring       */
+       u->hashlink = hashtable_utf->ptr[slot]; /* link in external hashchain     */
+       u->text     = mem_alloc(length + 1);/* allocate memory for utf-text       */
+
+       memcpy(u->text, text, length);      /* copy utf-text                      */
+       u->text[length] = '\0';
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_utf_len += sizeof(utf) + length + 1;
+#endif
+
+       hashtable_utf->ptr[slot] = u;       /* insert symbol into table           */
+       hashtable_utf->entries++;           /* update number of entries           */
+
+       if (hashtable_utf->entries > (hashtable_utf->size * 2)) {
+
+        /* reorganization of hashtable, average length of the external
+           chains is approx. 2 */
+
+               hashtable *newhash;                              /* the new hashtable */
+               u4         i;
+               utf       *u;
+               utf       *nextu;
+               u4         slot;
+
+               /* create new hashtable, double the size */
+
+               newhash = hashtable_resize(hashtable_utf, hashtable_utf->size * 2);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_utf_len += sizeof(utf*) * hashtable_utf->size;
+#endif
+
+               /* transfer elements to new hashtable */
+
+               for (i = 0; i < hashtable_utf->size; i++) {
+                       u = hashtable_utf->ptr[i];
+
+                       while (u) {
+                               nextu = u->hashlink;
+                               slot  = utf_hashkey(u->text, u->blength) & (newhash->size - 1);
+                                               
+                               u->hashlink = (utf *) newhash->ptr[slot];
+                               newhash->ptr[slot] = u;
+
+                               /* follow link in external hash chain */
+
+                               u = nextu;
+                       }
+               }
+       
+               /* dispose old table */
+
+               hashtable_free(hashtable_utf);
+
+               hashtable_utf = newhash;
+       }
+
+       LOCK_MONITOR_EXIT(hashtable_utf->header);
+
+       return u;
+}
+
+
+/* utf_new_u2 ******************************************************************
+
+   Make utf symbol from u2 array, if isclassname is true '.' is
+   replaced by '/'.
+
+*******************************************************************************/
+
+utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
+{
+       char *buffer;                   /* memory buffer for  unicode characters  */
+       char *pos;                      /* pointer to current position in buffer  */
+       u4 left;                        /* unicode characters left                */
+       u4 buflength;                   /* utf length in bytes of the u2 array    */
+       utf *result;                    /* resulting utf-string                   */
+       int i;          
+
+       /* determine utf length in bytes and allocate memory */
+
+       buflength = u2_utflength(unicode_pos, unicode_length); 
+       buffer    = MNEW(char, buflength);
+       left = buflength;
+       pos  = buffer;
+
+       for (i = 0; i++ < unicode_length; unicode_pos++) {
+               /* next unicode character */
+               u2 c = *unicode_pos;
+               
+               if ((c != 0) && (c < 0x80)) {
+                       /* 1 character */       
+                       left--;
+               if ((int) left < 0) break;
+                       /* convert classname */
+                       if (isclassname && c == '.')
+                               *pos++ = '/';
+                       else
+                               *pos++ = (char) c;
+
+               } else if (c < 0x800) {             
+                       /* 2 characters */                              
+               unsigned char high = c >> 6;
+               unsigned char low  = c & 0x3F;
+                       left = left - 2;
+               if ((int) left < 0) break;
+               *pos++ = high | 0xC0; 
+               *pos++ = low  | 0x80;     
+
+               } else {         
+               /* 3 characters */                              
+               char low  = c & 0x3f;
+               char mid  = (c >> 6) & 0x3F;
+               char high = c >> 12;
+                       left = left - 3;
+               if ((int) left < 0) break;
+               *pos++ = high | 0xE0; 
+               *pos++ = mid  | 0x80;  
+               *pos++ = low  | 0x80;   
+               }
+       }
+       
+       /* insert utf-string into symbol-table */
+       result = utf_new(buffer,buflength);
+
+       MFREE(buffer, char, buflength);
+
+       return result;
+}
+
+
+/* utf_new_char ****************************************************************
+
+   Creates a new utf symbol, the text for this symbol is passed as a
+   c-string ( = char* ).
+
+*******************************************************************************/
+
+utf *utf_new_char(const char *text)
+{
+       return utf_new(text, strlen(text));
+}
+
+
+/* utf_new_char_classname ******************************************************
+
+   Creates a new utf symbol, the text for this symbol is passed as a
+   c-string ( = char* ) "." characters are going to be replaced by
+   "/". Since the above function is used often, this is a separte
+   function, instead of an if.
+
+*******************************************************************************/
+
+utf *utf_new_char_classname(const char *text)
+{
+       if (strchr(text, '.')) {
+               char *txt = strdup(text);
+               char *end = txt + strlen(txt);
+               char *c;
+               utf *tmpRes;
+
+               for (c = txt; c < end; c++)
+                       if (*c == '.') *c = '/';
+
+               tmpRes = utf_new(txt, strlen(txt));
+               FREE(txt, 0);
+
+               return tmpRes;
+
+       } else
+               return utf_new(text, strlen(text));
+}
+
+
+/* utf_nextu2 ******************************************************************
+
+   Read the next unicode character from the utf string and increment
+   the utf-string pointer accordingly.
+
+   CAUTION: This function is unsafe for input that was not checked 
+            by is_valid_utf!
+
+*******************************************************************************/
+
+u2 utf_nextu2(char **utf_ptr)
+{
+    /* uncompressed unicode character */
+    u2 unicode_char = 0;
+    /* current position in utf text */ 
+    unsigned char *utf = (unsigned char *) (*utf_ptr);
+    /* bytes representing the unicode character */
+    unsigned char ch1, ch2, ch3;
+    /* number of bytes used to represent the unicode character */
+    int len = 0;
+       
+    switch ((ch1 = utf[0]) >> 4) {
+       default: /* 1 byte */
+               (*utf_ptr)++;
+               return (u2) ch1;
+       case 0xC: 
+       case 0xD: /* 2 bytes */
+               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
+                       unsigned char high = ch1 & 0x1F;
+                       unsigned char low  = ch2 & 0x3F;
+                       unicode_char = (high << 6) + low;
+                       len = 2;
+               }
+               break;
+
+       case 0xE: /* 2 or 3 bytes */
+               if (((ch2 = utf[1]) & 0xC0) == 0x80) {
+                       if (((ch3 = utf[2]) & 0xC0) == 0x80) {
+                               unsigned char low  = ch3 & 0x3f;
+                               unsigned char mid  = ch2 & 0x3f;
+                               unsigned char high = ch1 & 0x0f;
+                               unicode_char = (((high << 6) + mid) << 6) + low;
+                               len = 3;
+                       } else
+                               len = 2;                                           
+               }
+               break;
+    }
+
+    /* update position in utf-text */
+    *utf_ptr = (char *) (utf + len);
+
+    return unicode_char;
+}
+
+
+/* utf_bytes *******************************************************************
+
+   Determine number of bytes (aka. octets) in the utf string.
+
+   IN:
+      u............utf string
+
+   OUT:
+      The number of octets of this utf string.
+         There is _no_ terminating zero included in this count.
+
+*******************************************************************************/
+
+u4 utf_bytes(utf *u)
+{
+       return u->blength;
+}
+
+
+/* utf_get_number_of_u2s_for_buffer ********************************************
+
+   Determine number of UTF-16 u2s in the given UTF-8 buffer
+
+   CAUTION: This function is unsafe for input that was not checked 
+            by is_valid_utf!
+
+   CAUTION: Use this function *only* when you want to convert an UTF-8 buffer
+   to an array of u2s (UTF-16) and want to know how many of them you will get.
+   All other uses of this function are probably wrong.
+
+   IN:
+      buffer........points to first char in buffer
+         blength.......number of _bytes_ in the buffer
+
+   OUT:
+      the number of u2s needed to hold this string in UTF-16 encoding.
+         There is _no_ terminating zero included in this count.
+
+   NOTE: Unlike utf_get_number_of_u2s, this function never throws an
+   exception.
+
+*******************************************************************************/
+
+u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength)
+{
+       const char *endpos;                 /* points behind utf string           */
+       const char *utf_ptr;                /* current position in utf text       */
+       u4 len = 0;                         /* number of unicode characters       */
+
+       utf_ptr = buffer;
+       endpos = utf_ptr + blength;
+
+       while (utf_ptr < endpos) {
+               len++;
+               /* next unicode character */
+               utf_nextu2((char **)&utf_ptr);
+       }
+
+       assert(utf_ptr == endpos);
+
+       return len;
+}
+
+
+/* utf_get_number_of_u2s *******************************************************
+
+   Determine number of UTF-16 u2s in the utf string.
+
+   CAUTION: This function is unsafe for input that was not checked 
+            by is_valid_utf!
+
+   CAUTION: Use this function *only* when you want to convert a utf string
+   to an array of u2s and want to know how many of them you will get.
+   All other uses of this function are probably wrong.
+
+   IN:
+      u............utf string
+
+   OUT:
+      the number of u2s needed to hold this string in UTF-16 encoding.
+         There is _no_ terminating zero included in this count.
+         XXX 0 if a NullPointerException has been thrown (see below)
+
+*******************************************************************************/
+
+u4 utf_get_number_of_u2s(utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+       u4 len = 0;                         /* number of unicode characters       */
+
+       /* XXX this is probably not checked by most callers! Review this after */
+       /* the invalid uses of this function have been eliminated */
+       if (u == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               len++;
+               /* next unicode character */
+               utf_nextu2(&utf_ptr);
+       }
+
+       if (utf_ptr != endpos) {
+               /* string ended abruptly */
+               exceptions_throw_internalerror("Illegal utf8 string");
+               return NULL;
+       }
+
+       return len;
+}
+
+
+/* utf8_safe_number_of_u2s *****************************************************
+
+   Determine number of UTF-16 u2s needed for decoding the given UTF-8 string.
+   (For invalid UTF-8 the U+fffd replacement character will be counted.)
+
+   This function is safe even for invalid UTF-8 strings.
+
+   IN:
+      text..........zero-terminated(!) UTF-8 string (may be invalid)
+                       must NOT be NULL
+         nbytes........strlen(text). (This is needed to completely emulate
+                       the RI).
+
+   OUT:
+      the number of u2s needed to hold this string in UTF-16 encoding.
+         There is _no_ terminating zero included in this count.
+
+*******************************************************************************/
+
+s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes) {
+       register const unsigned char *t;
+       register s4 byte;
+       register s4 len;
+       register const unsigned char *tlimit;
+       s4 byte1;
+       s4 byte2;
+       s4 byte3;
+       s4 value;
+       s4 skip;
+
+       assert(text);
+       assert(nbytes >= 0);
+
+       len = 0;
+       t = (const unsigned char *) text;
+       tlimit = t + nbytes;
+
+       /* CAUTION: Keep this code in sync with utf8_safe_convert_to_u2s! */
+
+       while (1) {
+               byte = *t++;
+
+               if (byte & 0x80) {
+                       /* highest bit set, non-ASCII character */
+
+                       if ((byte & 0xe0) == 0xc0) {
+                               /* 2-byte: should be 110..... 10...... ? */
+
+                               if ((*t++ & 0xc0) == 0x80)
+                                       ; /* valid 2-byte */
+                               else
+                                       t--; /* invalid */
+                       }
+                       else if ((byte & 0xf0) == 0xe0) {
+                               /* 3-byte: should be 1110.... 10...... 10...... */
+                               /*                            ^t                */
+
+                               if (t + 2 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               if ((*t++ & 0xc0) == 0x80) {
+                                       if ((*t++ & 0xc0) == 0x80)
+                                               ; /* valid 3-byte */
+                                       else
+                                               t--; /* invalid */
+                               }
+                               else
+                                       t--; /* invalid */
+                       }
+                       else if ((byte & 0xf8) == 0xf0) {
+                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
+                               /*                            ^t                         */
+
+                               if (t + 3 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
+                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
+                                                       /* valid 4-byte UTF-8? */
+                                                       value = ((byte  & 0x07) << 18)
+                                                                 | ((byte1 & 0x3f) << 12)
+                                                                 | ((byte2 & 0x3f) <<  6)
+                                                                 | ((byte3 & 0x3f)      );
+
+                                                       if (value > 0x10FFFF)
+                                                               ; /* invalid */
+                                                       else if (value > 0xFFFF)
+                                                               len += 1; /* we need surrogates */
+                                                       else
+                                                               ; /* 16bit suffice */
+                                               }
+                                               else
+                                                       t--; /* invalid */
+                                       }
+                                       else
+                                               t--; /* invalid */
+                               }
+                               else
+                                       t--; /* invalid */
+                       }
+                       else if ((byte & 0xfc) == 0xf8) {
+                               /* invalid 5-byte */
+                               if (t + 4 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               skip = 4;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                       }
+                       else if ((byte & 0xfe) == 0xfc) {
+                               /* invalid 6-byte */
+                               if (t + 5 > tlimit)
+                                       return len + 1; /* invalid, stop here */
+
+                               skip = 5;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                       }
+                       else
+                               ; /* invalid */
+               }
+               else {
+                       /* NUL */
+
+                       if (byte == 0)
+                               break;
+
+                       /* ASCII character, common case */
+               }
+
+               len++;
+       }
+
+       return len;
+}
+
+
+/* utf8_safe_convert_to_u2s ****************************************************
+
+   Convert the given UTF-8 string to UTF-16 into a pre-allocated buffer.
+   (Invalid UTF-8 will be replaced with the U+fffd replacement character.)
+   Use utf8_safe_number_of_u2s to determine the number of u2s to allocate.
+
+   This function is safe even for invalid UTF-8 strings.
+
+   IN:
+      text..........zero-terminated(!) UTF-8 string (may be invalid)
+                       must NOT be NULL
+         nbytes........strlen(text). (This is needed to completely emulate
+                                       the RI).
+         buffer........a preallocated array of u2s to receive the decoded
+                       string. Use utf8_safe_number_of_u2s to get the
+                                       required number of u2s for allocating this.
+
+*******************************************************************************/
+
+#define UNICODE_REPLACEMENT  0xfffd
+
+void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer) {
+       register const unsigned char *t;
+       register s4 byte;
+       register const unsigned char *tlimit;
+       s4 byte1;
+       s4 byte2;
+       s4 byte3;
+       s4 value;
+       s4 skip;
+
+       assert(text);
+       assert(nbytes >= 0);
+
+       t = (const unsigned char *) text;
+       tlimit = t + nbytes;
+
+       /* CAUTION: Keep this code in sync with utf8_safe_number_of_u2s! */
+
+       while (1) {
+               byte = *t++;
+
+               if (byte & 0x80) {
+                       /* highest bit set, non-ASCII character */
+
+                       if ((byte & 0xe0) == 0xc0) {
+                               /* 2-byte: should be 110..... 10...... */
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       /* valid 2-byte UTF-8 */
+                                       *buffer++ = ((byte  & 0x1f) << 6)
+                                                         | ((byte1 & 0x3f)     );
+                               }
+                               else {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       t--;
+                               }
+                       }
+                       else if ((byte & 0xf0) == 0xe0) {
+                               /* 3-byte: should be 1110.... 10...... 10...... */
+
+                               if (t + 2 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
+                                               /* valid 3-byte UTF-8 */
+                                               *buffer++ = ((byte  & 0x0f) << 12)
+                                                                 | ((byte1 & 0x3f) <<  6)
+                                                                 | ((byte2 & 0x3f)      );
+                                       }
+                                       else {
+                                               *buffer++ = UNICODE_REPLACEMENT;
+                                               t--;
+                                       }
+                               }
+                               else {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       t--;
+                               }
+                       }
+                       else if ((byte & 0xf8) == 0xf0) {
+                               /* 4-byte: should be 11110... 10...... 10...... 10...... */
+
+                               if (t + 3 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               if (((byte1 = *t++) & 0xc0) == 0x80) {
+                                       if (((byte2 = *t++) & 0xc0) == 0x80) {
+                                               if (((byte3 = *t++) & 0xc0) == 0x80) {
+                                                       /* valid 4-byte UTF-8? */
+                                                       value = ((byte  & 0x07) << 18)
+                                                                 | ((byte1 & 0x3f) << 12)
+                                                                 | ((byte2 & 0x3f) <<  6)
+                                                                 | ((byte3 & 0x3f)      );
+
+                                                       if (value > 0x10FFFF) {
+                                                               *buffer++ = UNICODE_REPLACEMENT;
+                                                       }
+                                                       else if (value > 0xFFFF) {
+                                                               /* we need surrogates */
+                                                               *buffer++ = 0xd800 | ((value >> 10) - 0x40);
+                                                               *buffer++ = 0xdc00 | (value & 0x03ff);
+                                                       }
+                                                       else
+                                                               *buffer++ = value; /* 16bit suffice */
+                                               }
+                                               else {
+                                                       *buffer++ = UNICODE_REPLACEMENT;
+                                                       t--;
+                                               }
+                                       }
+                                       else {
+                                               *buffer++ = UNICODE_REPLACEMENT;
+                                               t--;
+                                       }
+                               }
+                               else {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       t--;
+                               }
+                       }
+                       else if ((byte & 0xfc) == 0xf8) {
+                               if (t + 4 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               skip = 4;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                               *buffer++ = UNICODE_REPLACEMENT;
+                       }
+                       else if ((byte & 0xfe) == 0xfc) {
+                               if (t + 5 > tlimit) {
+                                       *buffer++ = UNICODE_REPLACEMENT;
+                                       return;
+                               }
+
+                               skip = 5;
+                               for (; skip && ((*t & 0xc0) == 0x80); --skip)
+                                       t++;
+                               *buffer++ = UNICODE_REPLACEMENT;
+                       }
+                       else
+                               *buffer++ = UNICODE_REPLACEMENT;
+               }
+               else {
+                       /* NUL */
+
+                       if (byte == 0)
+                               break;
+
+                       /* ASCII character, common case */
+
+                       *buffer++ = byte;
+               }
+       }
+}
+
+
+/* u2_utflength ****************************************************************
+
+   Returns the utf length in bytes of a u2 array.
+
+*******************************************************************************/
+
+u4 u2_utflength(u2 *text, u4 u2_length)
+{
+       u4 result_len = 0;                  /* utf length in bytes                */
+       u2 ch;                              /* current unicode character          */
+       u4 len;
+       
+       for (len = 0; len < u2_length; len++) {
+               /* next unicode character */
+               ch = *text++;
+         
+               /* determine bytes required to store unicode character as utf */
+               if (ch && (ch < 0x80)) 
+                       result_len++;
+               else if (ch < 0x800)
+                       result_len += 2;        
+               else 
+                       result_len += 3;        
+       }
+
+    return result_len;
+}
+
+
+/* utf_copy ********************************************************************
+
+   Copy the given utf string byte-for-byte to a buffer.
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_copy(char *buffer, utf *u)
+{
+       /* our utf strings are zero-terminated (done by utf_new) */
+       MCOPY(buffer, u->text, char, u->blength + 1);
+}
+
+
+/* utf_cat *********************************************************************
+
+   Append the given utf string byte-for-byte to a buffer.
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_cat(char *buffer, utf *u)
+{
+       /* our utf strings are zero-terminated (done by utf_new) */
+       MCOPY(buffer + strlen(buffer), u->text, char, u->blength + 1);
+}
+
+
+/* utf_copy_classname **********************************************************
+
+   Copy the given utf classname byte-for-byte to a buffer.
+   '/' is replaced by '.'
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_copy_classname(char *buffer, utf *u)
+{
+       char *bufptr;
+       char *srcptr;
+       char *endptr;
+       char ch;
+
+       bufptr = buffer;
+       srcptr = u->text;
+       endptr = UTF_END(u) + 1; /* utfs are zero-terminared by utf_new */
+
+       while (srcptr != endptr) {
+               ch = *srcptr++;
+               if (ch == '/')
+                       ch = '.';
+               *bufptr++ = ch;
+       }
+}
+
+
+/* utf_cat *********************************************************************
+
+   Append the given utf classname byte-for-byte to a buffer.
+   '/' is replaced by '.'
+
+   IN:
+      buffer.......the buffer
+         u............the utf string
+
+*******************************************************************************/
+
+void utf_cat_classname(char *buffer, utf *u)
+{
+       utf_copy_classname(buffer + strlen(buffer), u);
+}
+
+/* utf_display_printable_ascii *************************************************
+
+   Write utf symbol to stdout (for debugging purposes).
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_display_printable_ascii(utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+       if (u == NULL) {
+               printf("NULL");
+               fflush(stdout);
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               /* read next unicode character */
+
+               u2 c = utf_nextu2(&utf_ptr);
+
+               if ((c >= 32) && (c <= 127))
+                       printf("%c", c);
+               else
+                       printf("?");
+       }
+
+       fflush(stdout);
+}
+
+
+/* utf_display_printable_ascii_classname ***************************************
+
+   Write utf symbol to stdout with `/' converted to `.' (for debugging
+   purposes).
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_display_printable_ascii_classname(utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+       if (u == NULL) {
+               printf("NULL");
+               fflush(stdout);
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               /* read next unicode character */
+
+               u2 c = utf_nextu2(&utf_ptr);
+
+               if (c == '/')
+                       c = '.';
+
+               if ((c >= 32) && (c <= 127))
+                       printf("%c", c);
+               else
+                       printf("?");
+       }
+
+       fflush(stdout);
+}
+
+
+/* utf_sprint_convert_to_latin1 ************************************************
+       
+   Write utf symbol into c-string (for debugging purposes).
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_sprint_convert_to_latin1(char *buffer, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+       u2 pos = 0;                         /* position in c-string               */
+
+       if (!u) {
+               strcpy(buffer, "NULL");
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) 
+               /* copy next unicode character */       
+               buffer[pos++] = utf_nextu2(&utf_ptr);
+
+       /* terminate string */
+       buffer[pos] = '\0';
+}
+
+
+/* utf_sprint_convert_to_latin1_classname **************************************
+       
+   Write utf symbol into c-string with `/' converted to `.' (for debugging
+   purposes).
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+       u2 pos = 0;                         /* position in c-string               */
+
+       if (!u) {
+               strcpy(buffer, "NULL");
+               return;
+       }
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) {
+               /* copy next unicode character */       
+               u2 c = utf_nextu2(&utf_ptr);
+               if (c == '/') c = '.';
+               buffer[pos++] = c;
+       }
+
+       /* terminate string */
+       buffer[pos] = '\0';
+}
+
+
+/* utf_strcat_convert_to_latin1 ************************************************
+       
+   Like libc strcat, but uses an utf8 string.
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_strcat_convert_to_latin1(char *buffer, utf *u)
+{
+       utf_sprint_convert_to_latin1(buffer + strlen(buffer), u);
+}
+
+
+/* utf_strcat_convert_to_latin1_classname **************************************
+       
+   Like libc strcat, but uses an utf8 string.
+   Characters are converted to 8-bit Latin-1, non-Latin-1 characters yield
+   invalid results.
+
+*******************************************************************************/
+
+void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u)
+{
+       utf_sprint_convert_to_latin1_classname(buffer + strlen(buffer), u);
+}
+
+
+/* utf_fprint_printable_ascii **************************************************
+       
+   Write utf symbol into file.
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_fprint_printable_ascii(FILE *file, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+       if (!u)
+               return;
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) { 
+               /* read next unicode character */                
+               u2 c = utf_nextu2(&utf_ptr);                            
+
+               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
+               else fprintf(file, "?");
+       }
+}
+
+
+/* utf_fprint_printable_ascii_classname ****************************************
+       
+   Write utf symbol into file with `/' converted to `.'.
+   Non-printable and non-ASCII characters are printed as '?'.
+
+*******************************************************************************/
+
+void utf_fprint_printable_ascii_classname(FILE *file, utf *u)
+{
+       char *endpos;                       /* points behind utf string           */
+       char *utf_ptr;                      /* current position in utf text       */
+
+    if (!u)
+               return;
+
+       endpos = UTF_END(u);
+       utf_ptr = u->text;
+
+       while (utf_ptr < endpos) { 
+               /* read next unicode character */                
+               u2 c = utf_nextu2(&utf_ptr);                            
+               if (c == '/') c = '.';
+
+               if (c >= 32 && c <= 127) fprintf(file, "%c", c);
+               else fprintf(file, "?");
+       }
+}
+
+
+/* is_valid_utf ****************************************************************
+
+   Return true if the given string is a valid UTF-8 string.
+
+   utf_ptr...points to first character
+   end_pos...points after last character
+
+*******************************************************************************/
+
+/*  static unsigned long min_codepoint[6] = {0,1L<<7,1L<<11,1L<<16,1L<<21,1L<<26}; */
+
+bool is_valid_utf(char *utf_ptr, char *end_pos)
+{
+       int bytes;
+       int len,i;
+       char c;
+       unsigned long v;
+
+       if (end_pos < utf_ptr) return false;
+       bytes = end_pos - utf_ptr;
+       while (bytes--) {
+               c = *utf_ptr++;
+
+               if (!c) return false;                     /* 0x00 is not allowed */
+               if ((c & 0x80) == 0) continue;            /* ASCII */
+
+               if      ((c & 0xe0) == 0xc0) len = 1;     /* 110x xxxx */
+               else if ((c & 0xf0) == 0xe0) len = 2;     /* 1110 xxxx */
+               else if ((c & 0xf8) == 0xf0) len = 3;     /* 1111 0xxx */
+               else if ((c & 0xfc) == 0xf8) len = 4;     /* 1111 10xx */
+               else if ((c & 0xfe) == 0xfc) len = 5;     /* 1111 110x */
+               else return false;                        /* invalid leading byte */
+
+               if (len > 2) return false;                /* Java limitation */
+
+               v = (unsigned long)c & (0x3f >> len);
+               
+               if ((bytes -= len) < 0) return false;     /* missing bytes */
+
+               for (i = len; i--; ) {
+                       c = *utf_ptr++;
+                       if ((c & 0xc0) != 0x80)               /* 10xx xxxx */
+                               return false;
+                       v = (v << 6) | (c & 0x3f);
+               }
+
+               if (v == 0) {
+                       if (len != 1) return false;           /* Java special */
+
+               } else {
+                       /* Sun Java seems to allow overlong UTF-8 encodings */
+                       
+                       /* if (v < min_codepoint[len]) */
+                               /* XXX throw exception? */
+               }
+
+               /* surrogates in UTF-8 seem to be allowed in Java classfiles */
+               /* if (v >= 0xd800 && v <= 0xdfff) return false; */ /* surrogates */
+
+               /* even these seem to be allowed */
+               /* if (v == 0xfffe || v == 0xffff) return false; */ /* invalid codepoints */
+       }
+
+       return true;
+}
+
+
+/* is_valid_name ***************************************************************
+
+   Return true if the given string may be used as a class/field/method
+   name. (Currently this only disallows empty strings and control
+   characters.)
+
+   NOTE: The string is assumed to have passed is_valid_utf!
+
+   utf_ptr...points to first character
+   end_pos...points after last character
+
+*******************************************************************************/
+
+bool is_valid_name(char *utf_ptr, char *end_pos)
+{
+       if (end_pos <= utf_ptr) return false; /* disallow empty names */
+
+       while (utf_ptr < end_pos) {
+               unsigned char c = *utf_ptr++;
+
+               if (c < 0x20) return false; /* disallow control characters */
+               if (c == 0xc0 && (unsigned char) *utf_ptr == 0x80)  /* disallow zero */
+                       return false;
+       }
+
+       return true;
+}
+
+bool is_valid_name_utf(utf *u)
+{
+       return is_valid_name(u->text, UTF_END(u));
+}
+
+
+/* utf_show ********************************************************************
+
+   Writes the utf symbols in the utfhash to stdout and displays the
+   number of external hash chains grouped according to the chainlength
+   (for debugging purposes).
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void utf_show(void)
+{
+
+#define CHAIN_LIMIT 20               /* limit for seperated enumeration */
+
+       u4 chain_count[CHAIN_LIMIT]; /* numbers of chains */
+       u4 max_chainlength = 0;      /* maximum length of the chains */
+       u4 sum_chainlength = 0;      /* sum of the chainlengths */
+       u4 beyond_limit = 0;         /* number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
+       u4 i;
+
+       printf("UTF-HASH:\n");
+
+       /* show element of utf-hashtable */
+
+       for (i = 0; i < hashtable_utf->size; i++) {
+               utf *u = hashtable_utf->ptr[i];
+
+               if (u) {
+                       printf("SLOT %d: ", (int) i);
+
+                       while (u) {
+                               printf("'");
+                               utf_display_printable_ascii(u);
+                               printf("' ");
+                               u = u->hashlink;
+                       }       
+                       printf("\n");
+               }
+       }
+
+       printf("UTF-HASH: %d slots for %d entries\n", 
+                  (int) hashtable_utf->size, (int) hashtable_utf->entries );
+
+       if (hashtable_utf->entries == 0)
+               return;
+
+       printf("chains:\n  chainlength    number of chains    %% of utfstrings\n");
+
+       for (i=0;i<CHAIN_LIMIT;i++)
+               chain_count[i]=0;
+
+       /* count numbers of hashchains according to their length */
+       for (i=0; i<hashtable_utf->size; i++) {
+                 
+               utf *u = (utf*) hashtable_utf->ptr[i];
+               u4 chain_length = 0;
+
+               /* determine chainlength */
+               while (u) {
+                       u = u->hashlink;
+                       chain_length++;
+               }
+
+               /* update sum of all chainlengths */
+               sum_chainlength+=chain_length;
+
+               /* determine the maximum length of the chains */
+               if (chain_length>max_chainlength)
+                       max_chainlength = chain_length;
+
+               /* update number of utf-symbols in chains with length>=CHAIN_LIMIT-1 */
+               if (chain_length>=CHAIN_LIMIT) {
+                       beyond_limit+=chain_length;
+                       chain_length=CHAIN_LIMIT-1;
+               }
+
+               /* update number of hashchains of current length */
+               chain_count[chain_length]++;
+       }
+
+       /* display results */  
+       for (i=1;i<CHAIN_LIMIT-1;i++) 
+               printf("       %2d %17d %18.2f%%\n",i,chain_count[i],(((float) chain_count[i]*i*100)/hashtable_utf->entries));
+         
+       printf("     >=%2d %17d %18.2f%%\n",CHAIN_LIMIT-1,chain_count[CHAIN_LIMIT-1],((float) beyond_limit*100)/hashtable_utf->entries);
+
+
+       printf("max. chainlength:%5d\n",max_chainlength);
+
+       /* avg. chainlength = sum of chainlengths / number of chains */
+       printf("avg. chainlength:%5.2f\n",(float) sum_chainlength / (hashtable_utf->size-chain_count[0]));
+}
+#endif /* !defined(NDEBUG) */
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/utf8.h b/src/vmcore/utf8.h
new file mode 100644 (file)
index 0000000..4e469bd
--- /dev/null
@@ -0,0 +1,282 @@
+/* src/vmcore/utf8.h - utf8 string functions
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: utf8.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _UTF_H
+#define _UTF_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct utf utf;
+
+#include "config.h"
+
+#include <stdio.h>
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
+/* data structure for utf8 symbols ********************************************/
+
+struct utf {
+       utf  *hashlink;                     /* link for external hash chain       */
+       s4    blength;                      /* text length in bytes               */
+       char *text;                         /* pointer to text                    */
+};
+
+/* to determine the end of utf strings */
+
+#define UTF_END(u)    ((char *) u->text + u->blength)
+
+
+/* utf-symbols for pointer comparison of frequently used strings **************/
+
+extern utf *utf_java_lang_Object;
+
+extern utf *utf_java_lang_Class;
+extern utf *utf_java_lang_ClassLoader;
+extern utf *utf_java_lang_Cloneable;
+extern utf *utf_java_lang_SecurityManager;
+extern utf *utf_java_lang_String;
+extern utf *utf_java_lang_System;
+extern utf *utf_java_lang_ThreadGroup;
+extern utf *utf_java_io_Serializable;
+
+extern utf *utf_java_lang_Throwable;
+extern utf *utf_java_lang_Error;
+extern utf *utf_java_lang_ClassCircularityError;
+extern utf *utf_java_lang_ClassFormatError;
+extern utf *utf_java_lang_ExceptionInInitializerError;
+extern utf *utf_java_lang_IncompatibleClassChangeError;
+extern utf *utf_java_lang_InstantiationError;
+extern utf *utf_java_lang_InternalError;
+extern utf *utf_java_lang_LinkageError;
+extern utf *utf_java_lang_NoClassDefFoundError;
+extern utf *utf_java_lang_OutOfMemoryError;
+extern utf *utf_java_lang_UnsatisfiedLinkError;
+extern utf *utf_java_lang_UnsupportedClassVersionError;
+extern utf *utf_java_lang_VerifyError;
+extern utf *utf_java_lang_VirtualMachineError;
+
+#if defined(ENABLE_JAVASE)
+extern utf *utf_java_lang_AbstractMethodError;
+extern utf *utf_java_lang_NoSuchFieldError;
+extern utf *utf_java_lang_NoSuchMethodError;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+extern utf *utf_java_lang_VMThrowable;
+#endif
+
+extern utf *utf_java_lang_Exception;
+extern utf *utf_java_lang_ArithmeticException;
+extern utf *utf_java_lang_ArrayIndexOutOfBoundsException;
+extern utf *utf_java_lang_ArrayStoreException;
+extern utf *utf_java_lang_ClassCastException;
+extern utf *utf_java_lang_ClassNotFoundException;
+extern utf *utf_java_lang_CloneNotSupportedException;
+extern utf *utf_java_lang_IllegalAccessException;
+extern utf *utf_java_lang_IllegalArgumentException;
+extern utf *utf_java_lang_IllegalMonitorStateException;
+extern utf *utf_java_lang_InstantiationException;
+extern utf *utf_java_lang_InterruptedException;
+extern utf *utf_java_lang_InvocationTargetException;
+extern utf *utf_java_lang_NegativeArraySizeException;
+extern utf *utf_java_lang_NullPointerException;
+extern utf *utf_java_lang_StringIndexOutOfBoundsException;
+
+#if defined(ENABLE_JAVASE)
+extern utf* utf_java_lang_Void;
+#endif
+
+extern utf* utf_java_lang_Boolean;
+extern utf* utf_java_lang_Byte;
+extern utf* utf_java_lang_Character;
+extern utf* utf_java_lang_Short;
+extern utf* utf_java_lang_Integer;
+extern utf* utf_java_lang_Long;
+extern utf* utf_java_lang_Float;
+extern utf* utf_java_lang_Double;
+
+#if defined(ENABLE_JAVASE)
+extern utf *utf_java_lang_StackTraceElement;
+extern utf *utf_java_lang_reflect_Constructor;
+extern utf *utf_java_lang_reflect_Field;
+extern utf *utf_java_lang_reflect_Method;
+extern utf *utf_java_util_Vector;
+#endif
+
+extern utf *utf_InnerClasses;
+extern utf *utf_ConstantValue;
+extern utf *utf_Code;
+extern utf *utf_Exceptions;
+extern utf *utf_LineNumberTable;
+extern utf *utf_SourceFile;
+
+#if defined(ENABLE_JAVASE)
+extern utf *utf_EnclosingMethod;
+extern utf *utf_Signature;
+extern utf *utf_RuntimeVisibleAnnotations;
+extern utf *utf_StackMapTable;
+#endif
+
+extern utf *utf_init;
+extern utf *utf_clinit;
+extern utf *utf_clone;
+extern utf *utf_finalize;
+extern utf *utf_run;
+
+extern utf *utf_add;
+extern utf *utf_remove;
+extern utf *utf_addThread;
+extern utf *utf_removeThread;
+extern utf *utf_put;
+extern utf *utf_get;
+extern utf *utf_value;
+
+extern utf *utf_fillInStackTrace;
+extern utf *utf_getSystemClassLoader;
+extern utf *utf_loadClass;
+extern utf *utf_printStackTrace;
+
+extern utf *utf_Z;
+extern utf *utf_B;
+extern utf *utf_C;
+extern utf *utf_S;
+extern utf *utf_I;
+extern utf *utf_J;
+extern utf *utf_F;
+extern utf *utf_D;
+
+extern utf *utf_void__void;
+extern utf *utf_boolean__void;
+extern utf *utf_byte__void;
+extern utf *utf_char__void;
+extern utf *utf_short__void;
+extern utf *utf_int__void;
+extern utf *utf_long__void;
+extern utf *utf_float__void;
+extern utf *utf_double__void;
+
+extern utf *utf_void__java_lang_ClassLoader;
+extern utf *utf_void__java_lang_Object;
+extern utf *utf_void__java_lang_Throwable;
+extern utf *utf_java_lang_Object__java_lang_Object;
+extern utf *utf_java_lang_String__void;
+extern utf *utf_java_lang_String__java_lang_Class;
+extern utf *utf_java_lang_Thread__V;
+extern utf *utf_java_lang_Throwable__void;
+
+extern utf *utf_not_named_yet;
+extern utf *utf_null;
+extern utf *array_packagename;
+
+
+/* function prototypes ********************************************************/
+
+/* initialize the utf8 subsystem */
+bool utf8_init(void);
+
+u4 utf_hashkey(const char *text, u4 length);
+u4 utf_full_hashkey(const char *text, u4 length);
+
+/* determine hashkey of a unicode-symbol */
+u4 unicode_hashkey(u2 *text, u2 length);
+
+/* create new utf-symbol */
+utf *utf_new(const char *text, u2 length);
+
+/* make utf symbol from u2 array */
+utf *utf_new_u2(u2 *unicodedata, u4 unicodelength, bool isclassname);
+
+utf *utf_new_char(const char *text);
+utf *utf_new_char_classname(const char *text);
+
+/* get number of bytes */
+u4 utf_bytes(utf *u);
+
+/* get next unicode character of a utf-string */
+u2 utf_nextu2(char **utf);
+
+/* get (number of) unicode characters of a utf string (safe) */
+s4 utf8_safe_number_of_u2s(const char *text, s4 nbytes);
+void utf8_safe_convert_to_u2s(const char *text, s4 nbytes, u2 *buffer);
+
+/* get (number of) unicode characters of a utf string (UNSAFE!) */
+u4 utf_get_number_of_u2s(utf *u);
+u4 utf_get_number_of_u2s_for_buffer(const char *buffer, u4 blength);
+
+/* determine utf length in bytes of a u2 array */
+u4 u2_utflength(u2 *text, u4 u2_length);
+
+void utf_copy(char *buffer, utf *u);
+void utf_cat(char *buffer, utf *u);
+void utf_copy_classname(char *buffer, utf *u);
+void utf_cat_classname(char *buffer, utf *u);
+
+/* write utf symbol to file/buffer */
+void utf_display_printable_ascii(utf *u);
+void utf_display_printable_ascii_classname(utf *u);
+
+void utf_sprint_convert_to_latin1(char *buffer, utf *u);
+void utf_sprint_convert_to_latin1_classname(char *buffer, utf *u);
+
+void utf_strcat_convert_to_latin1(char *buffer, utf *u);
+void utf_strcat_convert_to_latin1_classname(char *buffer, utf *u);
+
+void utf_fprint_printable_ascii(FILE *file, utf *u);
+void utf_fprint_printable_ascii_classname(FILE *file, utf *u);
+
+/* check if a UTF-8 string is valid */
+bool is_valid_utf(char *utf_ptr, char *end_pos);
+
+/* check if a UTF-8 string may be used as a class/field/method name */
+bool is_valid_name(char *utf_ptr, char *end_pos);
+bool is_valid_name_utf(utf *u);
+
+/* show utf-table */
+void utf_show(void);
+
+#endif /* _UTF_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:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vmcore/zip.c b/src/vmcore/zip.c
new file mode 100644 (file)
index 0000000..6aa5eec
--- /dev/null
@@ -0,0 +1,498 @@
+/* src/vmcore/zip.c - ZIP file handling for bootstrap classloader
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Christian Thalinger
+            Edwin Steiner
+
+   $Id: zip.c 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <zlib.h>
+#include <sys/mman.h>
+
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+#include "mm/memory.h"
+#include "vm/global.h"
+#include "vmcore/suck.h"
+#include "vmcore/utf8.h"
+#include "vmcore/zip.h"
+
+
+/* start size for classes hashtable *******************************************/
+
+#define HASHTABLE_CLASSES_SIZE    (1 << 10)
+
+
+/* info taken from:
+   http://www.pkware.com/business_and_developers/developer/popups/appnote.txt
+*/
+
+/* all signatures in the ZIP file have a length of 4 bytes ********************/
+
+#define SIGNATURE_LENGTH    4
+
+
+/* Local file header ***********************************************************
+
+   local file header signature     4 bytes  (0x04034b50)
+   version needed to extract       2 bytes
+   general purpose bit flag        2 bytes
+   compression method              2 bytes
+   last mod file time              2 bytes
+   last mod file date              2 bytes
+   crc-32                          4 bytes
+   compressed size                 4 bytes
+   uncompressed size               4 bytes
+   file name length                2 bytes
+   extra field length              2 bytes
+
+   file name (variable size)
+   extra field (variable size)
+
+*******************************************************************************/
+
+#define LFH_HEADER_SIZE              30
+
+#define LFH_SIGNATURE                0x04034b50
+#define LFH_FILE_NAME_LENGTH         26
+#define LFH_EXTRA_FIELD_LENGTH       28
+
+typedef struct lfh lfh;
+
+struct lfh {
+       u2 compressionmethod;
+       u4 compressedsize;
+       u4 uncompressedsize;
+       u2 filenamelength;
+       u2 extrafieldlength;
+};
+
+
+/* Central directory structure *************************************************
+
+   [file header 1]
+   .
+   .
+   . 
+   [file header n]
+   [digital signature] 
+   
+   File header:
+   
+     central file header signature   4 bytes  (0x02014b50)
+     version made by                 2 bytes
+     version needed to extract       2 bytes
+     general purpose bit flag        2 bytes
+     compression method              2 bytes
+     last mod file time              2 bytes
+     last mod file date              2 bytes
+     crc-32                          4 bytes
+     compressed size                 4 bytes
+     uncompressed size               4 bytes
+     file name length                2 bytes
+     extra field length              2 bytes
+     file comment length             2 bytes
+     disk number start               2 bytes
+     internal file attributes        2 bytes
+     external file attributes        4 bytes
+     relative offset of local header 4 bytes
+   
+     file name (variable size)
+     extra field (variable size)
+     file comment (variable size)
+
+   Digital signature:
+   
+     header signature                4 bytes  (0x05054b50)
+     size of data                    2 bytes
+     signature data (variable size)
+
+*******************************************************************************/
+
+#define CDSFH_HEADER_SIZE            46
+
+#define CDSFH_SIGNATURE              0x02014b50
+#define CDSFH_COMPRESSION_METHOD     10
+#define CDSFH_COMPRESSED_SIZE        20
+#define CDSFH_UNCOMPRESSED_SIZE      24
+#define CDSFH_FILE_NAME_LENGTH       28
+#define CDSFH_EXTRA_FIELD_LENGTH     30
+#define CDSFH_FILE_COMMENT_LENGTH    32
+#define CDSFH_RELATIVE_OFFSET        42
+#define CDSFH_FILENAME               46
+
+typedef struct cdsfh cdsfh;
+
+struct cdsfh {
+       u2 compressionmethod;
+       u4 compressedsize;
+       u4 uncompressedsize;
+       u2 filenamelength;
+       u2 extrafieldlength;
+       u2 filecommentlength;
+       u4 relativeoffset;
+};
+
+
+/* End of central directory record *********************************************
+
+   end of central dir signature    4 bytes  (0x06054b50)
+   number of this disk             2 bytes
+   number of the disk with the
+   start of the central directory  2 bytes
+   total number of entries in the
+   central directory on this disk  2 bytes
+   total number of entries in
+   the central directory           2 bytes
+   size of the central directory   4 bytes
+   offset of start of central
+   directory with respect to
+   the starting disk number        4 bytes
+   .ZIP file comment length        2 bytes
+   .ZIP file comment       (variable size)
+
+*******************************************************************************/
+
+#define EOCDR_SIGNATURE              0x06054b50
+#define EOCDR_ENTRIES                10
+#define EOCDR_OFFSET                 16
+
+typedef struct eocdr eocdr;
+
+struct eocdr {
+       u2 entries;
+       u4 offset;
+};
+
+
+/* zip_open ********************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+hashtable *zip_open(char *path)
+{
+       hashtable               *ht;
+       hashtable_zipfile_entry *htzfe;
+       int                      fd;
+       u1                       lfh_signature[SIGNATURE_LENGTH];
+       off_t                    len;
+       u1                      *filep;
+       s4                       i;
+       u1                      *p;
+       eocdr                    eocdr;
+       cdsfh                    cdsfh;
+       const char              *filename;
+       const char              *classext;
+       utf                     *u;
+       u4                       key;       /* hashkey computed from utf-text     */
+       u4                       slot;      /* slot in hashtable                  */
+
+       /* first of all, open the file */
+
+       if ((fd = open(path, O_RDONLY)) == -1)
+               return NULL;
+
+       /* check for signature in first local file header */
+
+       if (read(fd, lfh_signature, SIGNATURE_LENGTH) != SIGNATURE_LENGTH)
+               return NULL;
+
+       if (SUCK_LE_U4(lfh_signature) != LFH_SIGNATURE)
+               return NULL;
+
+       /* get the file length */
+
+       if ((len = lseek(fd, 0, SEEK_END)) == -1)
+               return NULL;
+
+       /* we better mmap the file */
+
+       filep = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
+
+       /* some older compilers, like DEC OSF cc, don't like comparisons
+       on void* types */
+
+       if ((ptrint) filep == (ptrint) MAP_FAILED)
+               return NULL;
+
+       /* find end of central directory record */
+
+       for (p = filep + len; p >= filep; p--)
+               if (SUCK_LE_U4(p) == EOCDR_SIGNATURE)
+                       break;
+
+       /* get number of entries in central directory */
+
+       eocdr.entries = SUCK_LE_U2(p + EOCDR_ENTRIES);
+       eocdr.offset  = SUCK_LE_U4(p + EOCDR_OFFSET);
+
+       /* create hashtable for filenames */
+
+       ht = NEW(hashtable);
+
+       hashtable_create(ht, HASHTABLE_CLASSES_SIZE);
+
+       /* add all file entries into the hashtable */
+
+       for (i = 0, p = filep + eocdr.offset; i < eocdr.entries; i++) {
+               /* check file header signature */
+
+               if (SUCK_LE_U4(p) != CDSFH_SIGNATURE)
+                       return NULL;
+
+               /* we found an entry */
+
+               cdsfh.compressionmethod = SUCK_LE_U2(p + CDSFH_COMPRESSION_METHOD);
+               cdsfh.compressedsize    = SUCK_LE_U4(p + CDSFH_COMPRESSED_SIZE);
+               cdsfh.uncompressedsize  = SUCK_LE_U4(p + CDSFH_UNCOMPRESSED_SIZE);
+               cdsfh.filenamelength    = SUCK_LE_U2(p + CDSFH_FILE_NAME_LENGTH);
+               cdsfh.extrafieldlength  = SUCK_LE_U2(p + CDSFH_EXTRA_FIELD_LENGTH);
+               cdsfh.filecommentlength = SUCK_LE_U2(p + CDSFH_FILE_COMMENT_LENGTH);
+               cdsfh.relativeoffset    = SUCK_LE_U4(p + CDSFH_RELATIVE_OFFSET);
+
+               /* create utf8 string of filename, strip .class from classes */
+
+               filename = (const char *) (p + CDSFH_FILENAME);
+               classext = filename + cdsfh.filenamelength - strlen(".class");
+
+               /* skip directory entries */
+
+               if (filename[cdsfh.filenamelength - 1] != '/') {
+                       if (strncmp(classext, ".class", strlen(".class")) == 0)
+                               u = utf_new(filename, cdsfh.filenamelength - strlen(".class"));
+                       else
+                               u = utf_new(filename, cdsfh.filenamelength);
+
+                       /* insert class into hashtable */
+
+                       htzfe = NEW(hashtable_zipfile_entry);
+
+                       htzfe->filename          = u;
+                       htzfe->compressionmethod = cdsfh.compressionmethod;
+                       htzfe->compressedsize    = cdsfh.compressedsize;
+                       htzfe->uncompressedsize  = cdsfh.uncompressedsize;
+                       htzfe->data              = filep + cdsfh.relativeoffset;
+
+                       /* get hashtable slot */
+
+                       key  = utf_hashkey(u->text, u->blength);
+                       slot = key & (ht->size - 1);
+
+                       /* insert into external chain */
+
+                       htzfe->hashlink = ht->ptr[slot];
+
+                       /* insert hashtable zipfile entry */
+
+                       ht->ptr[slot] = htzfe;
+                       ht->entries++;
+               }
+
+               /* move to next central directory structure file header */
+
+               p = p +
+                       CDSFH_HEADER_SIZE +
+                       cdsfh.filenamelength +
+                       cdsfh.extrafieldlength +
+                       cdsfh.filecommentlength;
+       }
+
+       /* return pointer to hashtable */
+
+       return ht;
+}
+
+
+/* zip_find ********************************************************************
+
+   Search for the given filename in the classpath entries of a zip file.
+
+   NOTE: The '.class' extension is stripped when reading a zip file, so if
+   you want to find a .class file, you must search for its name _without_
+   the '.class' extension. 
+   XXX I dont like that, it makes foo and foo.class ambiguous. -Edwin
+
+   IN:
+      lce..........the classpath entries for the zip file
+         u............the filename to look for
+
+   RETURN VALUE:
+      hashtable_zipfile_entry * of the entry if found, or
+         NULL if not found
+
+*******************************************************************************/
+
+hashtable_zipfile_entry *zip_find(list_classpath_entry *lce, utf *u)
+{
+       hashtable               *ht;
+       u4                       key;       /* hashkey computed from utf-text     */
+       u4                       slot;      /* slot in hashtable                  */
+       hashtable_zipfile_entry *htzfe;     /* hashtable element                  */
+
+       /* get classes hashtable from the classpath entry */
+
+       ht = lce->htclasses;
+
+       /* get the hashtable slot of the name searched */
+
+       key   = utf_hashkey(u->text, u->blength);
+       slot  = key & (ht->size - 1);
+       htzfe = ht->ptr[slot];
+
+       /* search external hash chain for utf-symbol */
+
+       while (htzfe) {
+               if (htzfe->filename == u)
+                       return htzfe;
+
+               /* next element in external chain */
+
+               htzfe = htzfe->hashlink;
+       }
+
+       /* file not found in this archive */
+
+       return NULL;
+}
+
+
+/* zip_get ********************************************************************
+
+   XXX
+
+*******************************************************************************/
+
+classbuffer *zip_get(list_classpath_entry *lce, classinfo *c)
+{
+       hashtable_zipfile_entry *htzfe;
+       lfh                      lfh;
+       u1                      *indata;
+       u1                      *outdata;
+       z_stream                 zs;
+       int                      err;
+       classbuffer             *cb;
+
+       /* try to find the class in the current archive */
+
+       if ((htzfe = zip_find(lce, c->name)) == NULL)
+               return NULL;
+
+       /* read stuff from local file header */
+
+       lfh.filenamelength   = SUCK_LE_U2(htzfe->data + LFH_FILE_NAME_LENGTH);
+       lfh.extrafieldlength = SUCK_LE_U2(htzfe->data + LFH_EXTRA_FIELD_LENGTH);
+
+       indata = htzfe->data +
+               LFH_HEADER_SIZE +
+               lfh.filenamelength +
+               lfh.extrafieldlength;
+
+       /* allocate buffer for uncompressed data */
+
+       outdata = MNEW(u1, htzfe->uncompressedsize);
+
+       /* how is the file stored? */
+
+       switch (htzfe->compressionmethod) {
+       case Z_DEFLATED:
+               /* fill z_stream structure */
+
+               zs.next_in   = indata;
+               zs.avail_in  = htzfe->compressedsize;
+               zs.next_out  = outdata;
+               zs.avail_out = htzfe->uncompressedsize;
+
+               zs.zalloc = Z_NULL;
+               zs.zfree  = Z_NULL;
+               zs.opaque = Z_NULL;
+
+               /* initialize this inflate run */
+
+               if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
+                       assert(0);
+
+               /* decompress the file into buffer */
+
+               err = inflate(&zs, Z_SYNC_FLUSH);
+
+               if ((err != Z_STREAM_END) && (err != Z_OK))
+                       assert(0);
+
+               /* finish this inflate run */
+
+               if (inflateEnd(&zs) != Z_OK)
+                       assert(0);
+               break;
+
+       case 0:
+               /* uncompressed file, just copy the data */
+               MCOPY(outdata, indata, u1, htzfe->compressedsize);
+               break;
+
+       default:
+               assert(0);
+       }
+       
+       /* allocate classbuffer */
+
+       cb = NEW(classbuffer);
+
+       cb->class = c;
+       cb->size  = htzfe->uncompressedsize;
+       cb->data  = outdata;
+       cb->pos   = outdata;
+       cb->path  = lce->path;
+
+       /* return the filled classbuffer structure */
+
+       return cb;
+}
+
+
+/*
+ * 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:
+ */
diff --git a/src/vmcore/zip.h b/src/vmcore/zip.h
new file mode 100644 (file)
index 0000000..97e9e00
--- /dev/null
@@ -0,0 +1,79 @@
+/* src/vmcore/zip.c - ZIP file handling for bootstrap classloader
+
+   Copyright (C) 1996-2005, 2006, 2007 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.
+
+   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.
+
+   $Id: zip.h 7246 2007-01-29 18:49:05Z twisti $
+
+*/
+
+
+#ifndef _ZIP_H
+#define _ZIP_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+
+#include "vm/global.h"
+
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/suck.h"
+#include "vmcore/utf8.h"
+
+
+/* hashtable_zipfile_entry ****************************************************/
+
+typedef struct hashtable_zipfile_entry hashtable_zipfile_entry;
+
+struct hashtable_zipfile_entry {
+       utf                     *filename;
+       u2                       compressionmethod;
+       u4                       compressedsize;
+       u4                       uncompressedsize;
+       u1                      *data;
+       hashtable_zipfile_entry *hashlink;
+};
+
+
+/* function prototypes ********************************************************/
+
+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);
+
+#endif /* _ZIP_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:
+ */