* src/vm/initialize.c: Moved to C++.
authorMichael Starzinger <michi@complang.tuwien.ac.at>
Tue, 23 Sep 2008 11:08:02 +0000 (13:08 +0200)
committerMichael Starzinger <michi@complang.tuwien.ac.at>
Tue, 23 Sep 2008 11:08:02 +0000 (13:08 +0200)
* src/vm/initialize.h: Likewise.
* src/vm/resolve.c: Likewise.
* src/vm/resolve.h: Likewise.

* src/vm/initialize.cpp: Likewise.
* src/vm/initialize.hpp: Likewise.
* src/vm/resolve.cpp: New file.
* src/vm/resolve.hpp: Likewise.

* src/native/jni.cpp,
src/native/native.cpp,
src/native/vm/cldc1.1/java_lang_Class.cpp,
src/native/vm/gnuclasspath/java_lang_VMClass.cpp,
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp,
src/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp,
src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp,
src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp,
src/native/vm/nativevm.cpp,
src/native/vm/openjdk/jvm.cpp,
src/native/vm/reflection.cpp,
src/native/vm/sun_misc_Unsafe.cpp,
src/vm/Makefile.am,
src/vm/class.c,
src/vm/javaobjects.cpp,
src/vm/jit/allocator/liveness.c,
src/vm/jit/allocator/lsra.c,
src/vm/jit/allocator/simplereg.c,
src/vm/jit/alpha/patcher.c,
src/vm/jit/argument.cpp,
src/vm/jit/arm/patcher.c,
src/vm/jit/builtin.cpp,
src/vm/jit/i386/patcher.c,
src/vm/jit/inline/inline.c,
src/vm/jit/intrp/intrp.h,
src/vm/jit/intrp/patcher.c,
src/vm/jit/jit.cpp,
src/vm/jit/jit.hpp,
src/vm/jit/loop/tracing.c,
src/vm/jit/m68k/patcher.c,
src/vm/jit/mips/patcher.c,
src/vm/jit/optimizing/bytecode_escape.c,
src/vm/jit/optimizing/lifetimes.c,
src/vm/jit/parse.c,
src/vm/jit/patcher-common.cpp,
src/vm/jit/powerpc/patcher.c,
src/vm/jit/powerpc64/patcher.c,
src/vm/jit/s390/patcher.c,
src/vm/jit/sparc64/patcher.c,
src/vm/jit/stack.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/jit/x86_64/patcher.c,
src/vm/linker.c,
src/vm/loader.cpp,
src/vm/method.c,
src/vm/vm.cpp: Adapted to above changes.

--HG--
rename : src/vm/initialize.c => src/vm/initialize.cpp
rename : src/vm/initialize.h => src/vm/initialize.hpp
rename : src/vm/resolve.c => src/vm/resolve.cpp
rename : src/vm/resolve.h => src/vm/resolve.hpp

57 files changed:
src/native/jni.cpp
src/native/native.cpp
src/native/vm/cldc1.1/java_lang_Class.cpp
src/native/vm/gnuclasspath/java_lang_VMClass.cpp
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp
src/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp
src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp
src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp
src/native/vm/nativevm.cpp
src/native/vm/openjdk/jvm.cpp
src/native/vm/reflection.cpp
src/native/vm/sun_misc_Unsafe.cpp
src/vm/Makefile.am
src/vm/class.c
src/vm/initialize.c [deleted file]
src/vm/initialize.cpp [new file with mode: 0644]
src/vm/initialize.h [deleted file]
src/vm/initialize.hpp [new file with mode: 0644]
src/vm/javaobjects.cpp
src/vm/jit/allocator/liveness.c
src/vm/jit/allocator/lsra.c
src/vm/jit/allocator/simplereg.c
src/vm/jit/alpha/patcher.c
src/vm/jit/argument.cpp
src/vm/jit/arm/patcher.c
src/vm/jit/builtin.cpp
src/vm/jit/i386/patcher.c
src/vm/jit/inline/inline.c
src/vm/jit/intrp/intrp.h
src/vm/jit/intrp/patcher.c
src/vm/jit/jit.cpp
src/vm/jit/jit.hpp
src/vm/jit/loop/tracing.c
src/vm/jit/m68k/patcher.c
src/vm/jit/mips/patcher.c
src/vm/jit/optimizing/bytecode_escape.c
src/vm/jit/optimizing/lifetimes.c
src/vm/jit/parse.c
src/vm/jit/patcher-common.cpp
src/vm/jit/powerpc/patcher.c
src/vm/jit/powerpc64/patcher.c
src/vm/jit/s390/patcher.c
src/vm/jit/sparc64/patcher.c
src/vm/jit/stack.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/jit/x86_64/patcher.c
src/vm/linker.c
src/vm/loader.cpp
src/vm/method.c
src/vm/resolve.c [deleted file]
src/vm/resolve.cpp [new file with mode: 0644]
src/vm/resolve.h [deleted file]
src/vm/resolve.hpp [new file with mode: 0644]
src/vm/vm.cpp

index c88888fed4680812a67dae23e7244ad3feb07705..674f3b8b0d4e51084dbb7eb0b7570289fc029a55 100644 (file)
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/statistics.h"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
index 89a530ca7e5ff7215748e24f5b10cfd110999118..7f0f078ba55f0bd3cfb029a05def1836b3408198 100644 (file)
@@ -50,7 +50,7 @@
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/os.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
index a5d928dd78679e21e069443a72633cfc332b1095..4a2d0eee6ee57de090ff3e71ac018a295035b507 100644 (file)
@@ -36,7 +36,7 @@
 #endif
 
 #include "vm/exceptions.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 
 
 // Native functions are exported as C functions.
index 5e2136aa53ab47da8d4ffc0ab6459128f3f34556..6da3ea9b9c475c67778ee18e573d01c86b1506ee 100644 (file)
@@ -38,7 +38,7 @@
 #include "vm/class.h"
 #include "vm/exceptions.hpp"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/string.hpp"
 
index 926d825f8c16e117562e5d4b38ab60fbb6e3bed0..377e967da93a0090fbf220b3c21e0aaf39eba418 100644 (file)
@@ -51,7 +51,7 @@
 #include "vm/classcache.h"
 #include "vm/exceptions.hpp"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/linker.h"
 #include "vm/loader.hpp"
index 0d49fa0a3ea24b3e08e5c6bacdfdacf03189dc90..4d2edb56b0bd4048f68e627f0d289b02612d8800 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/loader.hpp"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/string.hpp"
 #include "vm/utf8.h"
 
index c569915f28f61579d3912c69b574a68ee8a6dd13..310bb0d0fa7d46e9038aa4f4da1944041a42227b 100644 (file)
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/method.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/string.hpp"
 
 
index 418fb50f92687c38540ae3af5f540dd6159e1d7a..f2bfa026b951c774048e4ef23cde10992f7e00b1 100644 (file)
@@ -56,7 +56,7 @@
 #include "vm/class.h"
 #include "vm/exceptions.hpp"
 #include "vm/javaobjects.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/string.hpp"
 #include "vm/utf8.h"
 #include "vm/vm.hpp"
index 43973647335608e4c80f7f61d4e416099e40f1bc..2086e37c445e8725690fd2610f3bff44fc7809e5 100644 (file)
@@ -30,7 +30,7 @@
 #include "native/vm/nativevm.hpp"
 
 #include "vm/class.h"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/method.h"
 #include "vm/options.h"
 #include "vm/os.hpp"
index d23997e8144bc1e0c7a96ffa9635b3471d901fa3..0ed70979bee69b493f0791f248c3a3269286ebe1 100644 (file)
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/options.h"
 #include "vm/os.hpp"
 #include "vm/package.hpp"
 #include "vm/primitive.hpp"
 #include "vm/properties.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/signallocal.h"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
index 48c181a3fb226afadacc28a692056173a0bf26fe..c2745b9fbd3c1c0eaac1ae04b850039e207eb641 100644 (file)
@@ -41,7 +41,7 @@
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/method.h"
 #include "vm/string.hpp"
index 439afc2cd3b5818cbcbdd986333c385ebef6b7aa..232ab7559db8d35d6b7d635ef25f0aebeb27129c 100644 (file)
@@ -42,7 +42,7 @@
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/os.hpp"
 #include "vm/string.hpp"
index 9867cc83625af1543a0d53a8a836ce61fb7ab2af..24b8cc6dd3dce21376716e87e1696305919daa76 100644 (file)
@@ -98,8 +98,8 @@ libvm_la_SOURCES = \
        finalizer.h \
        globals.cpp \
        globals.hpp \
-       initialize.c \
-       initialize.h \
+       initialize.cpp \
+       initialize.hpp \
        javaobjects.cpp \
        javaobjects.hpp \
        linker.c \
@@ -119,8 +119,8 @@ libvm_la_SOURCES = \
        properties.cpp \
        properties.hpp \
        references.h \
-       resolve.c \
-       resolve.h \
+       resolve.cpp \
+       resolve.hpp \
        $(RT_TIMING_SOURCES) \
        signal.c \
        signallocal.h \
index 1774c3ac0f6fdd46d20cd2578176fae8b9538a12..f5a6ffd1c031c5ee9940aa3b7f28a78a08cdcbdf 100644 (file)
@@ -54,7 +54,7 @@
 #include "vm/linker.h"
 #include "vm/loader.hpp"
 #include "vm/options.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #if defined(ENABLE_STATISTICS)
 # include "vm/statistics.h"
diff --git a/src/vm/initialize.c b/src/vm/initialize.c
deleted file mode 100644 (file)
index 4f540e3..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/* src/vm/initialize.c - static class initializer functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "threads/lock.hpp"
-
-#include "vm/jit/builtin.hpp"
-#include "vm/class.h"
-#include "vm/exceptions.hpp"
-#include "vm/global.h"
-#include "vm/globals.hpp"
-#include "vm/initialize.h"
-#include "vm/loader.hpp"
-#include "vm/options.h"
-#include "vm/vm.hpp"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-#include "vm/jit/asmpart.h"
-
-
-/* private functions **********************************************************/
-
-static bool initialize_class_intern(classinfo *c);
-
-
-/* initialize_init *************************************************************
-
-   Initialize important system classes.
-
-*******************************************************************************/
-
-void initialize_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("initialize_init");
-
-#if defined(ENABLE_JAVASE)
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-
-       /* Nothing. */
-
-# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-
-       if (!initialize_class(class_java_lang_String))
-               vm_abort("initialize_init: Initialization failed: java.lang.String");
-
-       if (!initialize_class(class_java_lang_System))
-               vm_abort("initialize_init: Initialization failed: java.lang.System");
-
-       if (!initialize_class(class_java_lang_ThreadGroup))
-               vm_abort("initialize_init: Initialization failed: java.lang.ThreadGroup");
-
-       if (!initialize_class(class_java_lang_Thread))
-               vm_abort("initialize_init: Initialization failed: java.lang.Thread");
-
-# else
-#  error unknown classpath configuration
-# endif
-
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-
-       /* Nothing. */
-
-#else
-# error unknown Java configuration
-#endif
-}
-
-/* initialize_class ************************************************************
-
-   In Java, every class can have a static initialization
-   function. This function has to be called BEFORE calling other
-   methods or accessing static variables.
-
-*******************************************************************************/
-
-bool initialize_class(classinfo *c)
-{
-       bool r;
-
-       if (!makeinitializations)
-               return true;
-
-       LOCK_MONITOR_ENTER(c);
-
-       /* maybe the class is already initalized or the current thread, which can
-          pass the monitor, is currently initalizing this class */
-
-       if (CLASS_IS_OR_ALMOST_INITIALIZED(c)) {
-               LOCK_MONITOR_EXIT(c);
-
-               return true;
-       }
-
-       /* if <clinit> throw an Error before, the class was marked with an
-       error and we have to throw a NoClassDefFoundError */
-
-       if (c->state & CLASS_ERROR) {
-               exceptions_throw_noclassdeffounderror(c->name);
-
-               LOCK_MONITOR_EXIT(c);
-
-               /* ...but return true, this is ok (mauve test) */
-
-               return true;
-       }
-
-       /* this initalizing run begins NOW */
-
-       c->state |= CLASS_INITIALIZING;
-
-       /* call the internal function */
-
-       r = initialize_class_intern(c);
-
-       /* if return value is not NULL everything was ok and the class is
-          initialized */
-
-       if (r)
-               c->state |= CLASS_INITIALIZED;
-
-       /* this initalizing run is done */
-
-       c->state &= ~CLASS_INITIALIZING;
-
-       LOCK_MONITOR_EXIT(c);
-
-       return r;
-}
-
-
-/* initialize_class_intern *****************************************************
-
-   This function MUST NOT be called directly, because of thread
-   <clinit> race conditions.
-
-*******************************************************************************/
-
-static bool initialize_class_intern(classinfo *c)
-{
-       methodinfo    *m;
-       java_handle_t *cause;
-       classinfo     *class;
-
-       /* maybe the class is not already linked */
-
-       if (!(c->state & CLASS_LINKED))
-               if (!link_class(c))
-                       return false;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_class_inits++;
-#endif
-
-       /* Initialize super class. */
-
-       if (c->super != NULL) {
-               if (!(c->super->state & CLASS_INITIALIZED)) {
-#if !defined(NDEBUG)
-                       if (initverbose)
-                               log_message_class_message_class("Initialize super class ",
-                                                                                               c->super,
-                                                                                               " from ",
-                                                                                               c);
-#endif
-
-                       if (!initialize_class(c->super))
-                               return false;
-               }
-       }
-
-       /* interfaces implemented need not to be initialized (VM Spec 2.17.4) */
-
-       m = class_findmethod(c, utf_clinit, utf_void__void);
-
-       if (m == NULL) {
-#if !defined(NDEBUG)
-               if (initverbose)
-                       log_message_class("Class has no static class initializer: ", c);
-#endif
-
-               return true;
-       }
-
-       /* Sun's and IBM's JVM don't care about the static flag */
-/*     if (!(m->flags & ACC_STATIC)) { */
-/*             log_text("Class initializer is not static!"); */
-
-#if !defined(NDEBUG)
-       if (initverbose)
-               log_message_class("Starting static class initializer for class: ", c);
-#endif
-
-       /* now call the initializer */
-
-       (void) vm_call_method(m, NULL);
-
-       /* we have an exception or error */
-
-       cause = exceptions_get_exception();
-
-       if (cause != NULL) {
-               /* class is NOT initialized and is marked with error */
-
-               c->state |= CLASS_ERROR;
-
-               /* Load java/lang/Exception for the instanceof check. */
-
-               class = load_class_bootstrap(utf_java_lang_Exception);
-
-               if (class == NULL)
-                       return false;
-
-               /* Is this an exception?  Yes, than wrap it. */
-
-               if (builtin_instanceof(cause, class)) {
-                       /* clear exception, because we are calling jit code again */
-
-                       exceptions_clear_exception();
-
-                       /* wrap the exception */
-
-                       exceptions_throw_exceptionininitializererror(cause);
-               }
-
-               return false;
-       }
-
-#if !defined(NDEBUG)
-       if (initverbose)
-               log_message_class("Finished static class initializer for class: ", c);
-#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:
- */
diff --git a/src/vm/initialize.cpp b/src/vm/initialize.cpp
new file mode 100644 (file)
index 0000000..648f333
--- /dev/null
@@ -0,0 +1,279 @@
+/* src/vm/initialize.cpp - static class initializer functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "threads/lock.hpp"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/class.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.hpp"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/vm.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/jit/asmpart.h"
+
+
+/* private functions **********************************************************/
+
+static bool initialize_class_intern(classinfo *c);
+
+
+/* initialize_init *************************************************************
+
+   Initialize important system classes.
+
+*******************************************************************************/
+
+void initialize_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("initialize_init");
+
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+
+       /* Nothing. */
+
+# elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+
+       if (!initialize_class(class_java_lang_String))
+               vm_abort("initialize_init: Initialization failed: java.lang.String");
+
+       if (!initialize_class(class_java_lang_System))
+               vm_abort("initialize_init: Initialization failed: java.lang.System");
+
+       if (!initialize_class(class_java_lang_ThreadGroup))
+               vm_abort("initialize_init: Initialization failed: java.lang.ThreadGroup");
+
+       if (!initialize_class(class_java_lang_Thread))
+               vm_abort("initialize_init: Initialization failed: java.lang.Thread");
+
+# else
+#  error unknown classpath configuration
+# endif
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+       /* Nothing. */
+
+#else
+# error unknown Java configuration
+#endif
+}
+
+/* initialize_class ************************************************************
+
+   In Java, every class can have a static initialization
+   function. This function has to be called BEFORE calling other
+   methods or accessing static variables.
+
+*******************************************************************************/
+
+bool initialize_class(classinfo *c)
+{
+       bool r;
+
+       if (!makeinitializations)
+               return true;
+
+       LOCK_MONITOR_ENTER(c);
+
+       /* maybe the class is already initalized or the current thread, which can
+          pass the monitor, is currently initalizing this class */
+
+       if (CLASS_IS_OR_ALMOST_INITIALIZED(c)) {
+               LOCK_MONITOR_EXIT(c);
+
+               return true;
+       }
+
+       /* if <clinit> throw an Error before, the class was marked with an
+       error and we have to throw a NoClassDefFoundError */
+
+       if (c->state & CLASS_ERROR) {
+               exceptions_throw_noclassdeffounderror(c->name);
+
+               LOCK_MONITOR_EXIT(c);
+
+               /* ...but return true, this is ok (mauve test) */
+
+               return true;
+       }
+
+       /* this initalizing run begins NOW */
+
+       c->state |= CLASS_INITIALIZING;
+
+       /* call the internal function */
+
+       r = initialize_class_intern(c);
+
+       /* if return value is not NULL everything was ok and the class is
+          initialized */
+
+       if (r)
+               c->state |= CLASS_INITIALIZED;
+
+       /* this initalizing run is done */
+
+       c->state &= ~CLASS_INITIALIZING;
+
+       LOCK_MONITOR_EXIT(c);
+
+       return r;
+}
+
+
+/* initialize_class_intern *****************************************************
+
+   This function MUST NOT be called directly, because of thread
+   <clinit> race conditions.
+
+*******************************************************************************/
+
+static bool initialize_class_intern(classinfo *c)
+{
+       methodinfo    *m;
+       java_handle_t *cause;
+       classinfo     *clazz;
+
+       /* maybe the class is not already linked */
+
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return false;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_class_inits++;
+#endif
+
+       /* Initialize super class. */
+
+       if (c->super != NULL) {
+               if (!(c->super->state & CLASS_INITIALIZED)) {
+#if !defined(NDEBUG)
+                       if (initverbose)
+                               log_message_class_message_class("Initialize super class ",
+                                                                                               c->super,
+                                                                                               " from ",
+                                                                                               c);
+#endif
+
+                       if (!initialize_class(c->super))
+                               return false;
+               }
+       }
+
+       /* interfaces implemented need not to be initialized (VM Spec 2.17.4) */
+
+       m = class_findmethod(c, utf_clinit, utf_void__void);
+
+       if (m == NULL) {
+#if !defined(NDEBUG)
+               if (initverbose)
+                       log_message_class("Class has no static class initializer: ", c);
+#endif
+
+               return true;
+       }
+
+       /* Sun's and IBM's JVM don't care about the static flag */
+/*     if (!(m->flags & ACC_STATIC)) { */
+/*             log_text("Class initializer is not static!"); */
+
+#if !defined(NDEBUG)
+       if (initverbose)
+               log_message_class("Starting static class initializer for class: ", c);
+#endif
+
+       /* now call the initializer */
+
+       (void) vm_call_method(m, NULL);
+
+       /* we have an exception or error */
+
+       cause = exceptions_get_exception();
+
+       if (cause != NULL) {
+               /* class is NOT initialized and is marked with error */
+
+               c->state |= CLASS_ERROR;
+
+               /* Load java/lang/Exception for the instanceof check. */
+
+               clazz = load_class_bootstrap(utf_java_lang_Exception);
+
+               if (clazz == NULL)
+                       return false;
+
+               /* Is this an exception?  Yes, than wrap it. */
+
+               if (builtin_instanceof(cause, clazz)) {
+                       /* clear exception, because we are calling jit code again */
+
+                       exceptions_clear_exception();
+
+                       /* wrap the exception */
+
+                       exceptions_throw_exceptionininitializererror(cause);
+               }
+
+               return false;
+       }
+
+#if !defined(NDEBUG)
+       if (initverbose)
+               log_message_class("Finished static class initializer for class: ", c);
+#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:
+ */
diff --git a/src/vm/initialize.h b/src/vm/initialize.h
deleted file mode 100644 (file)
index 88a7ff5..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* src/vm/initialize.h - static class initializer functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _INITIALIZE_H
-#define _INITIALIZE_H
-
-#include "config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm/class.h"
-#include "vm/global.h"
-
-
-/* function prototypes ********************************************************/
-
-void initialize_init(void);
-bool initialize_class(classinfo *c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _INITIALIZE_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/initialize.hpp b/src/vm/initialize.hpp
new file mode 100644 (file)
index 0000000..db332d8
--- /dev/null
@@ -0,0 +1,62 @@
+/* src/vm/initialize.hpp - static class initializer functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _INITIALIZE_HPP
+#define _INITIALIZE_HPP
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/class.h"
+#include "vm/global.h"
+
+
+/* function prototypes ********************************************************/
+
+void initialize_init(void);
+bool initialize_class(classinfo *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _INITIALIZE_HPP */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index cc82bdc6e9a79f7659f784438b60bc216f64b8e1..568d2ffc806fb92499fa65f27550842e17d0e9f8 100644 (file)
@@ -32,7 +32,7 @@
 #include "vm/jit/builtin.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 
 
index 7ceaea22813165d80a9a2593f0337e4fe204eef9..d6bd012daef27a221039a5791988562dfa181ff5 100644 (file)
@@ -39,7 +39,7 @@
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/method.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/jit/codegen-common.hpp"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/allocator/lsra.h"
index f984f57ff95c1ecf582a0d551578059ec202a615..bfe0e16662bf4ef9b86bf1cfe99063b58e75e062 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/options.h"
 #include "vm/statistics.h"
 
index 2e555f62e401e27af66482afbd99a38525fe543c..d1f63af188ae957816b2ca16c77db2ceaa72305b 100644 (file)
@@ -39,7 +39,7 @@
 #include "vm/exceptions.hpp"
 #include "vm/method.h"
 #include "vm/options.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/string.hpp"
 
 #include "vm/jit/abi.h"
index 71368b63e07b3cc79d832905818adc8d4b16818d..daec763f8d30c6a6a53343f65b7a21cc6fbb8ab3 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.hpp"
index 60ddfaf7e115a2528c9282b86f07b5ec9ec23342..a340cf5663552d1a4644ebe8b9cdd120645c8a29 100644 (file)
@@ -39,7 +39,7 @@
 #include "vm/global.h"
 #include "vm/method.h"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/vm.hpp"
 
 #include "vm/jit/abi-asm.h"
index 105fa094468ba9c607cdc72aa5a42d02f855bff6..843c18495d35dd6c8f1a83f5390a91749e1a0c80 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.hpp"
index c735a277c54f1b14aee2f8a5d3de7638f15cd50e..33c9a5e95af167d8581d75f15ca33d93f8296027 100644 (file)
@@ -66,7 +66,7 @@
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/linker.h"
 #include "vm/loader.hpp"
 #include "vm/options.h"
index 47bd53ffbaa95926e63c2d599b10c72589567178..84cfc768b00a5d2920c966e653de191b24e32a21 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/patcher-common.hpp"
 
index f0e71754492bf79e17bf561a1b128d77f7c7ac8f..9549b7d6335b6309df633f4d7d2a2ae5334bf795 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/global.h"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/method.h"
 #include "vm/options.h"
 #include "vm/statistics.h"
index 8b1e0da6e968e89ebc41d970665255c569674d2e..a2522c18cca9a09f82200477d54542ac10b96830 100644 (file)
@@ -49,7 +49,7 @@ typedef s4 Cell;
 #include "vm/linker.h"
 #include "vm/method.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/codegen-common.hpp"
 
index 191c562c2e5c64dc77cf5cd16011fd82ab84304e..0cfb387818bb907ab1e770dd6c41cebeefa5781d 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
index b889cd59ca5d84a701e9918505f92b7631f164dd..cdb5cdffa55c603796f582b1350e3f9b904d0266 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/class.h"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/loader.hpp"
 #include "vm/method.h"
 #include "vm/options.h"
index bb28fceeb5cacf4ca1457f5657b42139c7de224c..4a235519fb49e01bb1acb3b44ef847bee6ef98b0 100644 (file)
@@ -39,7 +39,7 @@ typedef struct exception_entry exception_entry;
 #include "vm/global.h"
 #include "vm/method.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #if defined(ENABLE_STATISTICS)
 # include "vm/statistics.h"
index 83e273e7dffeab92286ba9403d4263a6b6287d1e..b2e295e6bae6245347f063701aec4752b2108eb9 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "mm/memory.h"
 #include "vm/jit/builtin.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/jit/loop/loop.h"
 #include "vm/jit/loop/tracing.h"
 
index d3f27b76f9e618e24da75e28248a66c92dbbfe3c..fb36a7a149bd1f8e6dae8cdb0df9ec486f215355 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.hpp"
index a32f18b9f24b51578aec4681844fdd494220177b..40c59c2c773dbc2027aa6b0e633cb87391bc0254 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher-common.hpp"
index ac9456ab0b40f90a50ad232567b4a36ea7b3c6c4..aa66eb21bfc2aa2a5bc6d8828229f67c387aed8d 100644 (file)
@@ -36,7 +36,7 @@
 #include "vm/descriptor.h"
 #include "vm/global.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/ir/bytecode.h"
 #include "vm/jit/optimizing/escape.h"
index d8f8d349f85cc7d84e88595ead45fd68317b95a9..8abc257417b2040f789d205e178d9a2db701f732 100644 (file)
@@ -34,7 +34,7 @@
 #include "toolbox/worklist.h"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/string.hpp"
 
index 67b9e923454b7320e9725bff8913b25a4aca4466..7b1c1ace3c5921576192acead6f21095936974d8 100644 (file)
@@ -44,7 +44,7 @@
 #include "vm/linker.h"
 #include "vm/loader.hpp"
 #include "vm/options.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #if defined(ENABLE_STATISTICS)
 # include "vm/statistics.h"
index 134ea9057361668756228310d715ba443c731c0d..b4799b3138184ab603afefb94ae348f42dab2a79 100644 (file)
@@ -43,9 +43,9 @@
 #include "toolbox/logging.h"           /* XXX remove me! */
 
 #include "vm/exceptions.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/vm.hpp"                     /* for vm_abort */
 
 #include "vm/jit/code.hpp"
index 0dc24cadd927788661a136b216916118a60a106c..f025d58b5775135695732eeeafe615a2b4fbb11b 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
index 117e2332d4a74bcfc598e125e8959d4e720f3f4e..5e9b9324b20da283e32183f4efa9b3df09c5cef3 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/methodheader.h"
index 4fdd63ff11a6f915739bb15efe512003c035c637..f0525274d40b28f36a6a89b894af8c3ad298ea29 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/types.h"
 
 #include "vm/jit/patcher-common.hpp"
index b8d40910446b085835b2bd9f17e7b179227288cb..8a36a3aa154d2a75794b41290ee258c744e79315 100644 (file)
 #include "vm/class.h"
 #include "vm/exceptions.hpp"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
index b5c15689c40d8c5ade946a28a35491de2996e94e..2420c649f79d1b71c6623dcc486eeffdc7692436 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/options.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/string.hpp"
 #include "vm/types.h"
 
index f63d37fd808ca00a37345f385b167e573b5f092b..8dfbd4f747ae4e9669836b2334cbc6ef72d3393b 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/vm.hpp"
 
 #include "vm/jit/jit.hpp"
index 51b789fdedd5caec7d7bafb9beb5589454bdf9df..842f89f16eb2927b608bb9be83505e432777c613 100644 (file)
@@ -156,7 +156,7 @@ error reporting.
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/jit.hpp"
 #include "vm/jit/parse.h"
index 6cf7f6556fc678324481529421d80a62c1e123ee..f9b32b092704b8de96956e132fef6277addaab0e 100644 (file)
@@ -39,7 +39,7 @@
 #include "vm/globals.hpp"
 #include "vm/loader.hpp"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/jit.hpp"
 #include "vm/jit/verify/typeinfo.h"
index 70bfcc11fe1110d6b15630a9723dab72b019b11b..806bca9732288ecae892b45c689362fd2143bf45 100644 (file)
@@ -429,6 +429,10 @@ struct typedescriptor {
 /* FUNCTIONS                                                                */
 /****************************************************************************/
 
+#ifdef __cplusplus
+extern "C" { 
+#endif
+
 /* typevector functions *****************************************************/
 
 /* element read-only access */
@@ -514,6 +518,10 @@ void typevector_print(FILE *file,varinfo *vec,int size);
 
 #endif /* TYPEINFO_DEBUG */
 
+#ifdef __cplusplus
+} 
+#endif
+
 #endif /* _TYPEINFO_H */
 
 
index b4a3805ccc51af617020b2b55c0358c17d38193e..393731392ef0e87c4d56e2d881389bf4401a4697 100644 (file)
 #include "vm/jit/builtin.hpp"
 #include "vm/class.h"
 #include "vm/field.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/references.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 
 #include "vm/jit/patcher-common.hpp"
 
index cda34a0d183c535256622f0f85e7691375eb2237..b25c0a7e6f654d9adc7ced55d81ae08092920dc6 100644 (file)
@@ -74,7 +74,7 @@
 #endif
 
 
-/* #include "vm/resolve.h" */
+/* #include "vm/resolve.hpp" */
 /* copied prototype to avoid bootstrapping problem: */
 classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
 
index aa0650ea79012109fa28d2cae5bc44099103042e..4f1d36fff68d90f530ec0ac276fe36fd00431f18 100644 (file)
@@ -53,7 +53,7 @@
 #include "vm/options.h"
 #include "vm/package.hpp"
 #include "vm/primitive.hpp"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/rt-timing.h"
 #include "vm/string.hpp"
 #include "vm/suck.hpp"
index 15b808a9992cc3d93fb8f92bfbdf246622aab0ab..8ed22324f203f8b599b6a0afc0f485704e950980 100644 (file)
@@ -47,7 +47,7 @@
 #include "vm/loader.hpp"
 #include "vm/method.h"
 #include "vm/options.h"
-#include "vm/resolve.h"
+#include "vm/resolve.hpp"
 #include "vm/suck.hpp"
 #include "vm/utf8.h"
 #include "vm/vm.hpp"
diff --git a/src/vm/resolve.c b/src/vm/resolve.c
deleted file mode 100644 (file)
index dc8e3e2..0000000
+++ /dev/null
@@ -1,3164 +0,0 @@
-/* src/vm/resolve.c - resolving classes/interfaces/fields/methods
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "vm/access.h"
-#include "vm/classcache.h"
-#include "vm/descriptor.h"
-#include "vm/exceptions.hpp"
-#include "vm/global.h"
-#include "vm/globals.hpp"
-#include "vm/linker.h"
-#include "vm/loader.hpp"
-#include "vm/options.h"
-#include "vm/primitive.hpp"
-#include "vm/resolve.h"
-
-#include "vm/jit/jit.hpp"
-#include "vm/jit/verify/typeinfo.h"
-
-
-/******************************************************************************/
-/* DEBUG HELPERS                                                              */
-/******************************************************************************/
-
-/*#define RESOLVE_VERBOSE*/
-
-/* resolve_handle_pending_exception ********************************************
-
-   Convert a pending ClassNotFoundException into a
-   NoClassDefFoundError if requested.
-
-   See: hotspot/src/share/vm/classfile/systemDictionary.cpp
-   (handle_resolution_exception)
-
-   ARGUMENTS:
-       classname .... name of the class currently resolved
-       throwError ... if true throw a NoClassDefFoundError instead of
-                      a ClassNotFoundException
-
-*******************************************************************************/
-
-void resolve_handle_pending_exception(bool throwError)
-{
-       java_handle_t *e;
-
-       /* Get the current exception. */
-
-       e = exceptions_get_exception();
-
-       if (e != NULL) {
-               if (throwError == true) {
-                       /* Convert ClassNotFoundException to
-                          NoClassDefFoundError. */
-
-                       if (builtin_instanceof(e, class_java_lang_ClassNotFoundException)) {
-                               /* Clear exception, because we are calling Java code
-                                  again. */
-
-                               exceptions_clear_exception();
-
-                               /* create new error */
-
-                               exceptions_throw_noclassdeffounderror_cause(e);
-                       }
-                       else {
-                               return;
-                       }
-               }
-               else {
-                       /* An exception conversion was not requested.  Simply
-                          return. */
-
-                       return;
-               }
-       }
-}
-
-
-/******************************************************************************/
-/* 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;
-       char      *utf_ptr;
-       int        len;
-       char      *msg;
-       s4         msglen;
-       utf       *u;
-
-       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 == NULL) {
-                       cls = load_class_from_classloader(classname, referer->classloader);
-
-                       if (cls == NULL)
-                               return false;
-               }
-       }
-
-       /* 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)) {
-               msglen =
-                       utf_bytes(cls->name) +
-                       utf_bytes(referer->name) +
-                       100;
-
-               msg = MNEW(char, msglen);
-
-               strcpy(msg, "class is not accessible (");
-               utf_cat_classname(msg, cls->name);
-               strcat(msg, " from ");
-               utf_cat_classname(msg, referer->name);
-               strcat(msg, ")");
-
-               u = utf_new_char(msg);
-
-               MFREE(msg, char, msglen);
-
-               exceptions_throw_illegalaccessexception(u);
-
-               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
-
-   NOTE: If given, refmethod->clazz is used as the referring class.
-         Otherwise, cls.ref->referer is used.
-
-   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;
-       classinfo         *referer;
-       
-       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 */
-
-               /* determine which class to use as the referer */
-
-               /* Common cases are refmethod == NULL or both referring classes */
-               /* being the same, so the referer usually is cls.ref->referer.    */
-               /* There is one important case where it is not: When we do a      */
-               /* deferred assignability check to a formal argument of a method, */
-               /* we must use refmethod->clazz (the caller's class) to resolve   */
-               /* the type of the formal argument.                               */
-
-               referer = (refmethod) ? refmethod->clazz : cls.ref->referer;
-
-               if (!resolve_class_from_name(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_classref_or_classinfo_eager *****************************************
-   Resolve a symbolic class reference eagerly if necessary.
-   No attempt is made to link the class.
-
-   IN:
-       cls..............class reference or classinfo
-       checkaccess......if true, access rights to the class are checked
-  
-   RETURN VALUE:
-       classinfo *......the resolved class
-       NULL.............an exception has been thrown
-   
-*******************************************************************************/
-
-classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
-                                                                                          bool checkaccess)
-{
-       classinfo *c;
-
-       if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
-               return NULL;
-
-       return c;
-}
-
-
-/* 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 = Primitive_get_class_by_type(d->primitivetype);
-
-               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_t          subti;
-       typecheck_result  r;
-       char             *msg;
-       s4                msglen;
-       utf              *u;
-
-       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 */
-
-#if defined(RESOLVE_VERBOSE)
-               printf("SUBTYPE CHECK FAILED!\n");
-#endif
-
-               msglen =
-                       utf_bytes(subclass->name) +
-                       utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
-                       + 200;
-
-               msg = MNEW(char, msglen);
-
-               strcpy(msg, (error == resolveIllegalAccessError) ?
-                          "illegal access to protected member (" :
-                          "subtype constraint violated (");
-
-               utf_cat_classname(msg, subclass->name);
-               strcat(msg, " is not a subclass of ");
-               utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
-               strcat(msg, ")");
-
-               u = utf_new_char(msg);
-
-               if (error == resolveIllegalAccessError)
-                       exceptions_throw_illegalaccessexception(u);
-               else
-                       exceptions_throw_linkageerror(msg, NULL);
-
-               /* ATTENTION: We probably need msg for
-                  exceptions_throw_linkageerror. */
-
-               MFREE(msg, 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_t *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->clazz->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 */
-
-/* resolve_class_eager_no_access_check *****************************************
-   Resolve an unresolved class reference eagerly. The class is also linked.
-   Access rights are _not_ 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_no_access_check(unresolved_class *ref)
-{
-       classinfo *c;
-
-       if (!resolve_class(ref, resolveEager, false, &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_t *instanceti,
-                                                                                          typeinfo_t *valueti,
-                                                                                          bool isstatic,
-                                                                                          bool isput)
-{
-       classinfo         *declarer;
-       classinfo         *referer;
-       resolve_result_t   result;
-       constant_classref *fieldtyperef;
-       char              *msg;
-       s4                 msglen;
-       utf               *u;
-
-       assert(refmethod);
-       assert(fieldref);
-       assert(container);
-       assert(fi);
-
-       /* get the classinfos and the field type */
-
-       referer = refmethod->clazz;
-       assert(referer);
-
-       declarer = fi->clazz;
-       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)) {
-               msglen =
-                       utf_bytes(declarer->name) +
-                       utf_bytes(fi->name) +
-                       utf_bytes(referer->name) +
-                       100;
-
-               msg = MNEW(char, msglen);
-
-               strcpy(msg, "field is not accessible (");
-               utf_cat_classname(msg, declarer->name);
-               strcat(msg, ".");
-               utf_cat(msg, fi->name);
-               strcat(msg, " from ");
-               utf_cat_classname(msg, referer->name);
-               strcat(msg, ")");
-
-               u = utf_new_char(msg);
-
-               MFREE(msg, char, msglen);
-
-               exceptions_throw_illegalaccessexception(u);
-
-               return resolveFailed; /* exception */
-       }
-
-       /* for non-static methods we have to check the constraints on the         */
-       /* instance type                                                          */
-
-       if (instanceti) {
-               typeinfo_t *insttip;
-               typeinfo_t 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->clazz */
-                       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->clazz;
-       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);
-       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->clazz;
-       assert(referer);
-
-       /* check if the field itself is already resolved */
-       if (IS_FMIREF_RESOLVED(ref->fieldref)) {
-               fi = ref->fieldref->p.field;
-               container = fi->clazz;
-               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);
-       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->clazz;
-               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->clazz;
-       assert(referer);
-
-       declarer = mi->clazz;
-       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,
-                                                                        mi->name,
-                                                                        mi->descriptor);
-
-                       if (mi == NULL) {
-                               /* the spec calls for an AbstractMethodError in this case */
-
-                               exceptions_throw_abstractmethoderror();
-
-                               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;
-       char      *msg;
-       s4         msglen;
-       utf       *u;
-
-       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->clazz;
-       assert(referer);
-
-       declarer = mi->clazz;
-       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)) {
-               /* 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;
-
-               msg = MNEW(char, msglen);
-
-               strcpy(msg, "method is not accessible (");
-               utf_cat_classname(msg, declarer->name);
-               strcat(msg, ".");
-               utf_cat(msg, mi->name);
-               utf_cat(msg, mi->descriptor);
-               strcat(msg, " from ");
-               utf_cat_classname(msg, referer->name);
-               strcat(msg, ")");
-
-               u = utf_new_char(msg);
-
-               MFREE(msg, char, msglen);
-
-               exceptions_throw_illegalaccessexception(u);
-
-               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_t *instanceti,
-                                                                                                        bool invokespecial)
-{
-       typeinfo_t         tinfo;
-       typeinfo_t        *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->clazz);
-               tip = &tinfo;
-               if (!typeinfo_init_class(tip, initclass))
-                       return false;
-       }
-       else {
-               tip = instanceti;
-       }
-
-       result = resolve_lazy_subtype_checks(refmethod,
-                                                                                tip,
-                                                                                CLASSREF_OR_CLASSINFO(mi->clazz),
-                                                                                resolveLinkageError);
-       if (result != resolveSucceeded)
-               return result;
-
-       /* check protected access */
-
-       /* XXX use other `declarer` than mi->clazz? */
-       if (((mi->flags & ACC_PROTECTED) != 0)
-                       && !SAME_PACKAGE(mi->clazz, refmethod->clazz))
-       {
-               result = resolve_lazy_subtype_checks(refmethod,
-                               tip,
-                               CLASSREF_OR_CLASSINFO(refmethod->clazz),
-                               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_t *stack)
-{
-       typedescriptor_t  *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->clazz->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->clazz->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->clazz->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->clazz;
-       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->clazz;
-       assert(referer);
-
-       /* check if the method itself is already resolved */
-
-       if (IS_FMIREF_RESOLVED(ref->methodref)) {
-               mi = ref->methodref->p.method;
-               container = mi->clazz;
-               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->clazz;
-               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_t *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_t *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_t *instanceti,
-                                                                           typeinfo_t *valueti)
-{
-       constant_FMIref *fieldref;
-       int type;
-       typeinfo_t 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_t *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->clazz */
-                       initclass = refmethod->clazz; /* 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_t *instanceti,
-                                                                                                 bool invokespecial)
-{
-       constant_FMIref   *methodref;
-       constant_classref *instanceref;
-       typeinfo_t           tinfo;
-       typeinfo_t          *tip;
-
-       assert(ref);
-       methodref = ref->methodref;
-       assert(methodref);
-
-       /* XXX clean this up */
-       instanceref = IS_FMIREF_RESOLVED(methodref)
-               ? class_get_self_classref(methodref->p.method->clazz)
-               : 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->clazz);
-               tip = &tinfo;
-               if (!typeinfo_init_class(tip, initclass))
-                       return false;
-       }
-       else {
-               tip = instanceti;
-       }
-
-       if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, 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->clazz, 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_t *stack)
-{
-       constant_FMIref *methodref;
-       typedescriptor_t *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->clazz, 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->clazz->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->clazz->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.cpp b/src/vm/resolve.cpp
new file mode 100644 (file)
index 0000000..1d1173a
--- /dev/null
@@ -0,0 +1,3164 @@
+/* src/vm/resolve.cpp - resolving classes/interfaces/fields/methods
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "vm/access.h"
+#include "vm/classcache.h"
+#include "vm/descriptor.h"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/linker.h"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/resolve.hpp"
+
+#include "vm/jit/jit.hpp"
+#include "vm/jit/verify/typeinfo.h"
+
+
+/******************************************************************************/
+/* DEBUG HELPERS                                                              */
+/******************************************************************************/
+
+/*#define RESOLVE_VERBOSE*/
+
+/* resolve_handle_pending_exception ********************************************
+
+   Convert a pending ClassNotFoundException into a
+   NoClassDefFoundError if requested.
+
+   See: hotspot/src/share/vm/classfile/systemDictionary.cpp
+   (handle_resolution_exception)
+
+   ARGUMENTS:
+       classname .... name of the class currently resolved
+       throwError ... if true throw a NoClassDefFoundError instead of
+                      a ClassNotFoundException
+
+*******************************************************************************/
+
+void resolve_handle_pending_exception(bool throwError)
+{
+       java_handle_t *e;
+
+       /* Get the current exception. */
+
+       e = exceptions_get_exception();
+
+       if (e != NULL) {
+               if (throwError == true) {
+                       /* Convert ClassNotFoundException to
+                          NoClassDefFoundError. */
+
+                       if (builtin_instanceof(e, class_java_lang_ClassNotFoundException)) {
+                               /* Clear exception, because we are calling Java code
+                                  again. */
+
+                               exceptions_clear_exception();
+
+                               /* create new error */
+
+                               exceptions_throw_noclassdeffounderror_cause(e);
+                       }
+                       else {
+                               return;
+                       }
+               }
+               else {
+                       /* An exception conversion was not requested.  Simply
+                          return. */
+
+                       return;
+               }
+       }
+}
+
+
+/******************************************************************************/
+/* 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;
+       char      *utf_ptr;
+       int        len;
+       char      *msg;
+       s4         msglen;
+       utf       *u;
+
+       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 == NULL) {
+                       cls = load_class_from_classloader(classname, referer->classloader);
+
+                       if (cls == NULL)
+                               return false;
+               }
+       }
+
+       /* 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)) {
+               msglen =
+                       utf_bytes(cls->name) +
+                       utf_bytes(referer->name) +
+                       100;
+
+               msg = MNEW(char, msglen);
+
+               strcpy(msg, "class is not accessible (");
+               utf_cat_classname(msg, cls->name);
+               strcat(msg, " from ");
+               utf_cat_classname(msg, referer->name);
+               strcat(msg, ")");
+
+               u = utf_new_char(msg);
+
+               MFREE(msg, char, msglen);
+
+               exceptions_throw_illegalaccessexception(u);
+
+               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
+
+   NOTE: If given, refmethod->clazz is used as the referring class.
+         Otherwise, cls.ref->referer is used.
+
+   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;
+       classinfo         *referer;
+       
+       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 */
+
+               /* determine which class to use as the referer */
+
+               /* Common cases are refmethod == NULL or both referring classes */
+               /* being the same, so the referer usually is cls.ref->referer.    */
+               /* There is one important case where it is not: When we do a      */
+               /* deferred assignability check to a formal argument of a method, */
+               /* we must use refmethod->clazz (the caller's class) to resolve   */
+               /* the type of the formal argument.                               */
+
+               referer = (refmethod) ? refmethod->clazz : cls.ref->referer;
+
+               if (!resolve_class_from_name(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_classref_or_classinfo_eager *****************************************
+   Resolve a symbolic class reference eagerly if necessary.
+   No attempt is made to link the class.
+
+   IN:
+       cls..............class reference or classinfo
+       checkaccess......if true, access rights to the class are checked
+  
+   RETURN VALUE:
+       classinfo *......the resolved class
+       NULL.............an exception has been thrown
+   
+*******************************************************************************/
+
+classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
+                                                                                          bool checkaccess)
+{
+       classinfo *c;
+
+       if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
+               return NULL;
+
+       return c;
+}
+
+
+/* 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 = Primitive::get_class_by_type(d->primitivetype);
+
+               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_t        subti;
+       typecheck_result  r;
+       char             *msg;
+       s4                msglen;
+       utf              *u;
+
+       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 */
+
+#if defined(RESOLVE_VERBOSE)
+               printf("SUBTYPE CHECK FAILED!\n");
+#endif
+
+               msglen =
+                       utf_bytes(subclass->name) +
+                       utf_bytes(CLASSREF_OR_CLASSINFO_NAME(supertype))
+                       + 200;
+
+               msg = MNEW(char, msglen);
+
+               strcpy(msg, (error == resolveIllegalAccessError) ?
+                          "illegal access to protected member (" :
+                          "subtype constraint violated (");
+
+               utf_cat_classname(msg, subclass->name);
+               strcat(msg, " is not a subclass of ");
+               utf_cat_classname(msg, CLASSREF_OR_CLASSINFO_NAME(supertype));
+               strcat(msg, ")");
+
+               u = utf_new_char(msg);
+
+               if (error == resolveIllegalAccessError)
+                       exceptions_throw_illegalaccessexception(u);
+               else
+                       exceptions_throw_linkageerror(msg, NULL);
+
+               /* ATTENTION: We probably need msg for
+                  exceptions_throw_linkageerror. */
+
+               MFREE(msg, 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_t *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->clazz->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;
+       resolve_result_t 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 */
+
+/* resolve_class_eager_no_access_check *****************************************
+   Resolve an unresolved class reference eagerly. The class is also linked.
+   Access rights are _not_ 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_no_access_check(unresolved_class *ref)
+{
+       classinfo *c;
+
+       if (!resolve_class(ref, resolveEager, false, &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_t *instanceti,
+                                                                                          typeinfo_t *valueti,
+                                                                                          bool isstatic,
+                                                                                          bool isput)
+{
+       classinfo         *declarer;
+       classinfo         *referer;
+       resolve_result_t   result;
+       constant_classref *fieldtyperef;
+       char              *msg;
+       s4                 msglen;
+       utf               *u;
+
+       assert(refmethod);
+       assert(fieldref);
+       assert(container);
+       assert(fi);
+
+       /* get the classinfos and the field type */
+
+       referer = refmethod->clazz;
+       assert(referer);
+
+       declarer = fi->clazz;
+       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)) {
+               msglen =
+                       utf_bytes(declarer->name) +
+                       utf_bytes(fi->name) +
+                       utf_bytes(referer->name) +
+                       100;
+
+               msg = MNEW(char, msglen);
+
+               strcpy(msg, "field is not accessible (");
+               utf_cat_classname(msg, declarer->name);
+               strcat(msg, ".");
+               utf_cat(msg, fi->name);
+               strcat(msg, " from ");
+               utf_cat_classname(msg, referer->name);
+               strcat(msg, ")");
+
+               u = utf_new_char(msg);
+
+               MFREE(msg, char, msglen);
+
+               exceptions_throw_illegalaccessexception(u);
+
+               return resolveFailed; /* exception */
+       }
+
+       /* for non-static methods we have to check the constraints on the         */
+       /* instance type                                                          */
+
+       if (instanceti) {
+               typeinfo_t *insttip;
+               typeinfo_t 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->clazz */
+                       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->clazz;
+       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);
+       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->clazz;
+       assert(referer);
+
+       /* check if the field itself is already resolved */
+       if (IS_FMIREF_RESOLVED(ref->fieldref)) {
+               fi = ref->fieldref->p.field;
+               container = fi->clazz;
+               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);
+       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->clazz;
+               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->clazz;
+       assert(referer);
+
+       declarer = mi->clazz;
+       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,
+                                                                        mi->name,
+                                                                        mi->descriptor);
+
+                       if (mi == NULL) {
+                               /* the spec calls for an AbstractMethodError in this case */
+
+                               exceptions_throw_abstractmethoderror();
+
+                               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;
+       char      *msg;
+       s4         msglen;
+       utf       *u;
+
+       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->clazz;
+       assert(referer);
+
+       declarer = mi->clazz;
+       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)) {
+               /* 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;
+
+               msg = MNEW(char, msglen);
+
+               strcpy(msg, "method is not accessible (");
+               utf_cat_classname(msg, declarer->name);
+               strcat(msg, ".");
+               utf_cat(msg, mi->name);
+               utf_cat(msg, mi->descriptor);
+               strcat(msg, " from ");
+               utf_cat_classname(msg, referer->name);
+               strcat(msg, ")");
+
+               u = utf_new_char(msg);
+
+               MFREE(msg, char, msglen);
+
+               exceptions_throw_illegalaccessexception(u);
+
+               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_t *instanceti,
+                                                                                                        bool invokespecial)
+{
+       typeinfo_t         tinfo;
+       typeinfo_t        *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->clazz);
+               tip = &tinfo;
+               if (!typeinfo_init_class(tip, initclass))
+                       return resolveFailed;
+       }
+       else {
+               tip = instanceti;
+       }
+
+       result = resolve_lazy_subtype_checks(refmethod,
+                                                                                tip,
+                                                                                CLASSREF_OR_CLASSINFO(mi->clazz),
+                                                                                resolveLinkageError);
+       if (result != resolveSucceeded)
+               return result;
+
+       /* check protected access */
+
+       /* XXX use other `declarer` than mi->clazz? */
+       if (((mi->flags & ACC_PROTECTED) != 0)
+                       && !SAME_PACKAGE(mi->clazz, refmethod->clazz))
+       {
+               result = resolve_lazy_subtype_checks(refmethod,
+                               tip,
+                               CLASSREF_OR_CLASSINFO(refmethod->clazz),
+                               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_t *stack)
+{
+       typedescriptor_t  *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->clazz->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->clazz->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->clazz->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->clazz;
+       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->clazz;
+       assert(referer);
+
+       /* check if the method itself is already resolved */
+
+       if (IS_FMIREF_RESOLVED(ref->methodref)) {
+               mi = ref->methodref->p.method;
+               container = mi->clazz;
+               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->clazz;
+               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_t *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_t *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_t *instanceti,
+                                                                           typeinfo_t *valueti)
+{
+       constant_FMIref *fieldref;
+       int type;
+       typeinfo_t 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_t *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->clazz */
+                       initclass = refmethod->clazz; /* 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_t *instanceti,
+                                                                                                 bool invokespecial)
+{
+       constant_FMIref   *methodref;
+       constant_classref *instanceref;
+       typeinfo_t           tinfo;
+       typeinfo_t          *tip;
+
+       assert(ref);
+       methodref = ref->methodref;
+       assert(methodref);
+
+       /* XXX clean this up */
+       instanceref = IS_FMIREF_RESOLVED(methodref)
+               ? class_get_self_classref(methodref->p.method->clazz)
+               : 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->clazz);
+               tip = &tinfo;
+               if (!typeinfo_init_class(tip, initclass))
+                       return false;
+       }
+       else {
+               tip = instanceti;
+       }
+
+       if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, 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->clazz, 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_t *stack)
+{
+       constant_FMIref *methodref;
+       typedescriptor_t *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->clazz, 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->clazz->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->clazz->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 cfa0b92..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-/* src/vm/resolve.h - resolving classes/interfaces/fields/methods
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _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.hpp"
-#include "vm/global.h"
-#include "vm/method.h"
-#include "vm/references.h"
-
-#include "vm/jit/jit.hpp"
-#include "vm/jit/reg.h"
-
-#include "vm/jit/ir/instruction.hpp"
-#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 ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void resolve_handle_pending_exception(bool throwError);
-
-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);
-
-classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
-
-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);
-classinfo * resolve_class_eager_no_access_check(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_t *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_t *instanceti,
-                                                                                          typeinfo_t *valueti,
-                                                                                          bool isstatic,
-                                                                                          bool isput);
-
-bool resolve_constrain_unresolved_field(unresolved_field *ref,
-                                                                               classinfo *referer, 
-                                                                               methodinfo *refmethod,
-                                                                           typeinfo_t *instanceti,
-                                                                           typeinfo_t *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_t *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_t *stack);
-
-bool resolve_method_loading_constraints(classinfo *referer,
-                                                                               methodinfo *mi);
-
-bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
-                                                                                                 methodinfo *refmethod,
-                                                                                                 typeinfo_t *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_t *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
-
-#ifdef __cplusplus
-}
-#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/resolve.hpp b/src/vm/resolve.hpp
new file mode 100644 (file)
index 0000000..121d8de
--- /dev/null
@@ -0,0 +1,284 @@
+/* src/vm/resolve.hpp - resolving classes/interfaces/fields/methods
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _RESOLVE_HPP
+#define _RESOLVE_HPP
+
+/* 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.hpp"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
+
+#include "vm/jit/jit.hpp"
+#include "vm/jit/reg.h"
+
+#include "vm/jit/ir/instruction.hpp"
+#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 ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void resolve_handle_pending_exception(bool throwError);
+
+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);
+
+classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
+
+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);
+classinfo * resolve_class_eager_no_access_check(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_t *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_t *instanceti,
+                                                                                          typeinfo_t *valueti,
+                                                                                          bool isstatic,
+                                                                                          bool isput);
+
+bool resolve_constrain_unresolved_field(unresolved_field *ref,
+                                                                               classinfo *referer, 
+                                                                               methodinfo *refmethod,
+                                                                           typeinfo_t *instanceti,
+                                                                           typeinfo_t *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_t *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_t *stack);
+
+bool resolve_method_loading_constraints(classinfo *referer,
+                                                                               methodinfo *mi);
+
+bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
+                                                                                                 methodinfo *refmethod,
+                                                                                                 typeinfo_t *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_t *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
+
+#ifdef __cplusplus
+}
+#endif
+       
+#endif /* _RESOLVE_HPP */
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+
index 4721b8549ad6526ed0fa5663ea49ddfac99d04a0..ce544a58d11f6e61f338b422bf24c8ee73ae7a06 100644 (file)
@@ -69,7 +69,7 @@
 #include "vm/finalizer.h"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/options.h"
 #include "vm/os.hpp"
 #include "vm/primitive.hpp"