- created jitcache-arm-x86 branch
[cacao.git] / src / vm / resolve.c
index a5811e2d1634dec44ac246cc44438a2911ea3f12..a98388550e533d90431e95ef0b5bd482492122a2 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/resolve.c - resolving classes/interfaces/fields/methods
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: Christan Thalinger
-
-   $Id: resolve.c 4879 2006-05-05 17:34:49Z edwin $
-
 */
 
 
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "mm/memory.h"
-#include "vm/resolve.h"
+
 #include "vm/access.h"
-#include "vm/classcache.h"
-#include "vm/descriptor.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/stringlocal.h"
+#include "vm/primitive.h"
+#include "vm/resolve.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/verify/typeinfo.h"
 
+#include "vmcore/classcache.h"
+#include "vmcore/descriptor.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
 
 /******************************************************************************/
 /* 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                                                           */
 /******************************************************************************/
@@ -104,10 +151,13 @@ bool resolve_class_from_name(classinfo *referer,
                                                         bool link,
                                                         classinfo **result)
 {
-       classinfo *cls = NULL;
-       char *utf_ptr;
-       int len;
-       
+       classinfo *cls;
+       char      *utf_ptr;
+       int        len;
+       char      *msg;
+       s4         msglen;
+       utf       *u;
+
        assert(result);
        assert(referer);
        assert(classname);
@@ -116,11 +166,11 @@ bool resolve_class_from_name(classinfo *referer,
        *result = NULL;
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"resolve_class_from_name(");
-       utf_fprint_printable_ascii(stderr,referer->name);
-       fprintf(stderr,",%p,",referer->classloader);
-       utf_fprint_printable_ascii(stderr,classname);
-       fprintf(stderr,",%d,%d)\n",(int)checkaccess,(int)link);
+       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 */
@@ -128,7 +178,7 @@ bool resolve_class_from_name(classinfo *referer,
        cls = classcache_lookup(referer->classloader, classname);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"    lookup result: %p\n",(void*)cls);
+       printf("    lookup result: %p\n",(void*)cls);
 #endif
 
        if (!cls) {
@@ -169,14 +219,16 @@ bool resolve_class_from_name(classinfo *referer,
                }
 
 #ifdef RESOLVE_VERBOSE
-               fprintf(stderr,"    loading...\n");
+               printf("    loading...\n");
 #endif
 
                /* load the class */
-               if (!cls) {
-                       if (!(cls = load_class_from_classloader(classname,
-                                                                                                       referer->classloader)))
-                               return false; /* exception */
+
+               if (cls == NULL) {
+                       cls = load_class_from_classloader(classname, referer->classloader);
+
+                       if (cls == NULL)
+                               return false;
                }
        }
 
@@ -185,23 +237,31 @@ bool resolve_class_from_name(classinfo *referer,
        assert(cls->state & CLASS_LOADED);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"    checking access rights...\n");
+       printf("    checking access rights...\n");
 #endif
        
        /* check access rights of referer to refered class */
+
        if (checkaccess && !access_is_accessible_class(referer,cls)) {
-               int msglen;
-               char *message;
-
-               msglen = utf_get_number_of_u2s(cls->name) + utf_get_number_of_u2s(referer->name) + 100;
-               message = MNEW(char,msglen);
-               strcpy(message,"class is not accessible (");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),cls->name);
-               strcat(message," from ");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),referer->name);
-               strcat(message,")");
-               *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
-               MFREE(message,char,msglen);
+               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 */
        }
 
@@ -216,7 +276,7 @@ bool resolve_class_from_name(classinfo *referer,
 
        /* resolution succeeds */
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"    success.\n");
+       printf("    success.\n");
 #endif
        *result = cls;
        return true;
@@ -264,7 +324,10 @@ bool resolve_classref(methodinfo *refmethod,
 /* 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)
@@ -298,15 +361,16 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
                                                                   classinfo **result)
 {
        classinfo         *c;
+       classinfo         *referer;
        
        assert(cls.any);
        assert(mode == resolveEager || mode == resolveLazy);
        assert(result);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"resolve_classref_or_classinfo(");
-       utf_fprint_printable_ascii(stderr,(IS_CLASSREF(cls)) ? cls.ref->name : cls.cls->name);
-       fprintf(stderr,",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
+       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;
@@ -314,7 +378,18 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
        if (IS_CLASSREF(cls)) {
                /* we must resolve this reference */
 
-               if (!resolve_class_from_name(cls.ref->referer, refmethod, cls.ref->name,
+               /* 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;
 
@@ -349,6 +424,33 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
 }
 
 
+/* 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
@@ -369,7 +471,7 @@ bool resolve_classref_or_classinfo(methodinfo *refmethod,
        false............an exception has been thrown
 
    NOTE:
-       This function always resolved eagerly.
+       This function always resolves eagerly.
    
 *******************************************************************************/
 
@@ -383,9 +485,9 @@ bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, class
        *result = NULL;
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"resolve_class_from_typedesc(");
-       descriptor_debug_print_typedesc(stderr,d);
-       fprintf(stderr,",%i,%i)\n",(int)checkaccess,(int)link);
+       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) {
@@ -397,18 +499,22 @@ bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, class
        }
        else {
                /* a primitive type */
-               cls = primitivetype_table[d->decltype].class_primitive;
+
+               cls = primitive_class_get_by_type(d->decltype);
+
                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
-       fprintf(stderr,"    result = ");utf_fprint_printable_ascii(stderr,cls->name);fprintf(stderr,"\n");
+       printf("    result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
 #endif
 
        *result = cls;
@@ -459,9 +565,12 @@ static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
                                                                                          resolve_mode_t mode,
                                                                                          resolve_err_t error)
 {
-       classinfo *subclass;
-       typeinfo subti;
-       typecheck_result r;
+       classinfo        *subclass;
+       typeinfo_t          subti;
+       typecheck_result  r;
+       char             *msg;
+       s4                msglen;
+       utf              *u;
 
        assert(refmethod);
        assert(subtype.any);
@@ -475,7 +584,7 @@ static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
                /* the subclass could not be resolved. therefore we are sure that  */
                /* no instances of this subclass will ever exist -> skip this test */
                /* XXX this assumes that class loading has invariant results (as in JVM spec) */
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
                return resolveSucceeded;
        }
        if (!subclass)
@@ -516,23 +625,38 @@ check_again:
        if (!r) {
                /* sub class relationship is false */
 
-               char *message;
-               int msglen;
-
-               msglen = utf_get_number_of_u2s(subclass->name) + utf_get_number_of_u2s(CLASSREF_OR_CLASSINFO_NAME(supertype)) + 200;
-               message = MNEW(char,msglen);
-               strcpy(message,(error == resolveIllegalAccessError) ?
-                               "illegal access to protected member ("
-                               : "subtype constraint violated (");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),subclass->name);
-               strcat(message," is not a subclass of ");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),CLASSREF_OR_CLASSINFO_NAME(supertype));
-               strcat(message,")");
+#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)
-                       *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
+                       exceptions_throw_illegalaccessexception(u);
                else
-                       *exceptionptr = exceptions_new_linkageerror(message,NULL);
-               MFREE(message,char,msglen);
+                       exceptions_throw_linkageerror(msg, NULL);
+
+               /* ATTENTION: We probably need msg for
+                  exceptions_throw_linkageerror. */
+
+               MFREE(msg, char, msglen);
+
                return resolveFailed; /* exception */
        }
 
@@ -576,7 +700,7 @@ check_again:
 
 #if defined(ENABLE_VERIFIER)
 static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
-                                                                                                       typeinfo *subtinfo,
+                                                                                                       typeinfo_t *subtinfo,
                                                                                                        classref_or_classinfo supertype,
                                                                                                        resolve_err_t error)
 {
@@ -592,7 +716,7 @@ static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
        /* returnAddresses are illegal here */
 
        if (TYPEINFO_IS_PRIMITIVE(*subtinfo)) {
-               *exceptionptr = new_verifyerror(refmethod,
+               exceptions_throw_verifyerror(refmethod,
                                "Invalid use of returnAddress");
                return resolveFailed;
        }
@@ -600,7 +724,7 @@ static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
        /* uninitialized objects are illegal here */
 
        if (TYPEINFO_IS_NEWOBJECT(*subtinfo)) {
-               *exceptionptr = new_verifyerror(refmethod,
+               exceptions_throw_verifyerror(refmethod,
                                "Invalid use of uninitialized object");
                return resolveFailed;
        }
@@ -614,7 +738,7 @@ static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
 
        if (supertype.cls == class_java_lang_Object
                || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf_java_lang_Object
-                       && refmethod->class->classloader == NULL))
+                       && refmethod->clazz->classloader == NULL))
        {
                return resolveSucceeded;
        }
@@ -722,6 +846,15 @@ static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
        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 */
@@ -741,6 +874,10 @@ static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
 
        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;
        }
@@ -795,7 +932,7 @@ bool resolve_class(unresolved_class *ref,
        *result = NULL;
 
 #ifdef RESOLVE_VERBOSE
-       unresolved_class_debug_dump(ref,stderr);
+       unresolved_class_debug_dump(ref,stdout);
 #endif
 
        /* first we must resolve the class */
@@ -876,7 +1013,7 @@ classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
        /* ensure that the class is not abstract */
 
        if (c->flags & ACC_ABSTRACT) {
-               *exceptionptr = new_verifyerror(NULL,"creating instance of abstract class");
+               exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
                return NULL;
        }
 
@@ -909,11 +1046,37 @@ classinfo * resolve_class_eager(unresolved_class *ref)
 }
 #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 ***********************************************
+/* resolve_field_verifier_checks *******************************************
  
    Do the verifier checks necessary after field has been resolved.
   
@@ -922,7 +1085,10 @@ classinfo * resolve_class_eager(unresolved_class *ref)
           fieldref.........the field reference
           container........the class where the field was found
           fi...............the fieldinfo of the resolved field
-          opc..............opcode of the {GET,PUT}{STATIC,FIELD} instruction
+          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
@@ -936,17 +1102,18 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
                                                                                           constant_FMIref *fieldref,
                                                                                           classinfo *container,
                                                                                           fieldinfo *fi,
-                                                                                          s4 opc,
-                                                                                          stackptr curstack)
+                                                                                          typeinfo_t *instanceti,
+                                                                                          typeinfo_t *valueti,
+                                                                                          bool isstatic,
+                                                                                          bool isput)
 {
-       classinfo *declarer;
-       classinfo *referer;
-       resolve_result_t result;
-       bool isstatic = false;
-       bool isput = false;
-       stackelement *instanceslot = NULL;
-       stackelement *valueslot = NULL;
+       classinfo         *declarer;
+       classinfo         *referer;
+       resolve_result_t   result;
        constant_classref *fieldtyperef;
+       char              *msg;
+       s4                 msglen;
+       utf               *u;
 
        assert(refmethod);
        assert(fieldref);
@@ -955,51 +1122,15 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
 
        /* get the classinfos and the field type */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       declarer = fi->class;
+       declarer = fi->clazz;
        assert(declarer);
        assert(referer->state & CLASS_LINKED);
 
        fieldtyperef = fieldref->parseddesc.fd->classref;
 
-       /* get opcode dependent values */
-
-       switch (opc) {
-               case ICMD_PUTFIELD:
-                       isput = true;
-                       if (curstack) {
-                               valueslot = curstack;
-                               instanceslot = curstack->prev;
-                       }
-                       break;
-
-               case ICMD_PUTFIELDCONST:
-                       isput = true;
-                       instanceslot = curstack;
-                       break;
-
-               case ICMD_PUTSTATIC:
-                       isput = true;
-                       isstatic = true;
-                       valueslot = curstack;
-                       break;
-
-               case ICMD_PUTSTATICCONST:
-                       isput = true;
-                       isstatic = true;
-                       break;
-
-               case ICMD_GETFIELD:
-                       instanceslot = curstack;
-                       break;
-
-               case ICMD_GETSTATIC:
-                       isstatic = true;
-                       break;
-       }
-
        /* check static */
 
 #if true != 1
@@ -1008,76 +1139,83 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
 
        if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
                /* a static field is accessed via an instance, or vice versa */
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IncompatibleClassChangeError,
-                               (fi->flags & ACC_STATIC) ? "static field accessed via instance"
-                                                        : "instance field  accessed without instance");
+               exceptions_throw_incompatibleclasschangeerror(declarer,
+                                                                                                         (fi->flags & ACC_STATIC)
+                                                                                                         ? "static field accessed via instance"
+                                                                                                         : "instance field  accessed without instance");
+
                return resolveFailed;
        }
 
        /* check access rights */
 
        if (!access_is_accessible_member(referer,declarer,fi->flags)) {
-               int msglen;
-               char *message;
-
-               msglen = utf_get_number_of_u2s(declarer->name) + utf_get_number_of_u2s(fi->name) + utf_get_number_of_u2s(referer->name) + 100;
-               message = MNEW(char,msglen);
-               strcpy(message,"field is not accessible (");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),declarer->name);
-               strcat(message,".");
-               utf_sprint_convert_to_latin1(message+strlen(message),fi->name);
-               strcat(message," from ");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),referer->name);
-               strcat(message,")");
-               *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
-               MFREE(message,char,msglen);
+               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 (instanceslot) {
-               typeinfo *insttip;
-               typeinfo tinfo;
+       if (instanceti) {
+               typeinfo_t *insttip;
+               typeinfo_t tinfo;
 
                /* The instanceslot must contain a reference to a non-array type */
 
-               assert(instanceslot->type == TYPE_ADR); /* checked earlier */
-
-               if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
-                       *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
+               if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
                        return resolveFailed;
                }
-               if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
-                       *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
+               if (TYPEINFO_IS_ARRAY(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
                        return resolveFailed;
                }
 
-               if (isput && TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
+               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(instanceslot->typeinfo);
+                       instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
 
                        if (ins != NULL) {
-                               *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
+                               exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
                                return resolveFailed;
                        }
 
-                       /* XXX check that class of field == refmethod->class */
+                       /* XXX check that class of field == refmethod->clazz */
                        initclass = referer; /* XXX classrefs */
                        assert(initclass->state & CLASS_LINKED);
 
-                       typeinfo_init_classinfo(&tinfo,initclass);
+                       typeinfo_init_classinfo(&tinfo, initclass);
                        insttip = &tinfo;
                }
                else {
-                       insttip = &(instanceslot->typeinfo);
+                       insttip = instanceti;
                }
 
                result = resolve_lazy_subtype_checks(refmethod,
@@ -1092,7 +1230,7 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
                if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
                {
                        result = resolve_lazy_subtype_checks(refmethod,
-                                       &(instanceslot->typeinfo),
+                                       instanceti,
                                        CLASSREF_OR_CLASSINFO(referer),
                                        resolveIllegalAccessError);
                        if (result != resolveSucceeded)
@@ -1103,12 +1241,12 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
 
        /* for PUT* instructions we have to check the constraints on the value type */
 
-       if (valueslot && valueslot->type == TYPE_ADR) {
+       if (valueti) {
                assert(fieldtyperef);
 
                /* check subtype constraints */
                result = resolve_lazy_subtype_checks(refmethod,
-                               &(valueslot->typeinfo),
+                               valueti,
                                CLASSREF_OR_CLASSINFO(fieldtyperef),
                                resolveLinkageError);
 
@@ -1126,7 +1264,7 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
                        return resolveFailed;
        }
 
-       /* XXX impose loading constraing on instance? */
+       /* XXX impose loading constraint on instance? */
 
        /* everything ok */
        return resolveSucceeded;
@@ -1136,11 +1274,14 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
 /* 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:
-       iptr.............instruction containing the field reference
-       curstack.........instack of the instruction
           refmethod........the referer method
+          fieldref.........the field reference
   
    RETURN VALUE:
        resolveSucceeded.....the reference has been resolved
@@ -1149,44 +1290,31 @@ resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
    
 *******************************************************************************/
 
-resolve_result_t resolve_field_lazy(instruction *iptr,stackptr curstack,
-                                                                       methodinfo *refmethod)
+resolve_result_t resolve_field_lazy(methodinfo *refmethod,
+                                                                       constant_FMIref *fieldref)
 {
        classinfo *referer;
        classinfo *container;
        fieldinfo *fi;
-       constant_FMIref *fieldref;
-       resolve_result_t result;
 
-       assert(iptr);
        assert(refmethod);
 
        /* the class containing the reference */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       /* get the field reference */
-
-       if (iptr->opc == ICMD_PUTFIELDCONST || iptr->opc == ICMD_PUTSTATICCONST)
-               INSTRUCTION_GET_FIELDREF(iptr + 1,fieldref);
-       else
-               INSTRUCTION_GET_FIELDREF(iptr,fieldref);
-
        /* check if the field itself is already resolved */
 
-       if (IS_FMIREF_RESOLVED(fieldref)) {
-               fi = fieldref->p.field;
-               container = fi->class;
-               goto resolved_the_field;
-       }
+       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))
+       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 */
@@ -1200,14 +1328,14 @@ resolve_result_t resolve_field_lazy(instruction *iptr,stackptr curstack,
         * or one of its superclasses */
 
        fi = class_resolvefield(container,
-                                                       fieldref->name,fieldref->descriptor,
-                                                       referer,true);
+                                                       fieldref->name, fieldref->descriptor,
+                                                       referer, true);
        if (!fi) {
                /* The field does not exist. But since we were called lazily, */
                /* this error must not be reported now. (It will be reported   */
                /* if eager resolving of this field is ever tried.)           */
 
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
                return resolveDeferred; /* be lazy */
        }
 
@@ -1215,20 +1343,6 @@ resolve_result_t resolve_field_lazy(instruction *iptr,stackptr curstack,
 
        fieldref->p.field = fi;
 
-resolved_the_field:
-
-#if defined(ENABLE_VERIFIER)
-       if (opt_verify) {
-               result = resolve_field_verifier_checks(refmethod,fieldref,container,
-                                                                                          fi,
-                                                                                          iptr->opc,
-                                                                                          curstack);
-
-               if (result != resolveSucceeded)
-                       return result;
-       }
-#endif /* defined(ENABLE_VERIFIER) */
-
        /* everything ok */
        return resolveSucceeded;
 }
@@ -1275,18 +1389,18 @@ bool resolve_field(unresolved_field *ref,
        *result = NULL;
 
 #ifdef RESOLVE_VERBOSE
-       unresolved_field_debug_dump(ref,stderr);
+       unresolved_field_debug_dump(ref,stdout);
 #endif
 
        /* the class containing the reference */
 
-       referer = ref->referermethod->class;
+       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->class;
+               container = fi->clazz;
                goto resolved_the_field;
        }
 
@@ -1308,7 +1422,7 @@ bool resolve_field(unresolved_field *ref,
         * or one of its superclasses */
 
 #ifdef RESOLVE_VERBOSE
-               fprintf(stderr,"    resolving field in class...\n");
+               printf("    resolving field in class...\n");
 #endif
 
        fi = class_resolvefield(container,
@@ -1320,7 +1434,7 @@ bool resolve_field(unresolved_field *ref,
                        /* this error must not be reported now. (It will be reported   */
                        /* if eager resolving of this field is ever tried.)           */
 
-                       *exceptionptr = NULL;
+                       exceptions_clear_exception();
                        return true; /* be lazy */
                }
 
@@ -1333,19 +1447,23 @@ bool resolve_field(unresolved_field *ref,
 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,
+               checkresult = resolve_field_verifier_checks(
+                               ref->referermethod,
                                ref->fieldref,
                                container,
                                fi,
-                               /* XXX pass NULL instruction * */
-                               (ref->flags & RESOLVE_STATIC) ? ICMD_GETSTATIC : ICMD_GETFIELD,
-                               NULL);
+                               NULL, /* instanceti, handled by constraints below */
+                               NULL, /* valueti, handled by constraints below  */
+                               (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
+                               (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
 
                if (checkresult != resolveSucceeded)
                        return (bool) checkresult;
 
-               declarer = fi->class;
+               declarer = fi->clazz;
                assert(declarer);
                assert(declarer->state & CLASS_LOADED);
                assert(declarer->state & CLASS_LINKED);
@@ -1450,10 +1568,10 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
 
        /* get referer and declarer classes */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       declarer = mi->class;
+       declarer = mi->clazz;
        assert(declarer);
        assert(referer->state & CLASS_LINKED);
 
@@ -1466,7 +1584,7 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
                /* check that declarer is a super class of the current class   */
 
                if (!class_issubclass(referer,declarer)) {
-                       *exceptionptr = new_verifyerror(refmethod,
+                       exceptions_throw_verifyerror(refmethod,
                                        "INVOKESPECIAL calling non-super class method");
                        return NULL;
                }
@@ -1475,12 +1593,15 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
                /* lookup starting with the direct super class of referer      */
 
                if ((referer->flags & ACC_SUPER) != 0) {
-                       mi = class_resolvemethod(referer->super.cls,
+                       mi = class_resolvemethod(referer->super,
                                                                         mi->name,
                                                                         mi->descriptor);
-                       if (!mi) {
+
+                       if (mi == NULL) {
                                /* the spec calls for an AbstractMethodError in this case */
-                               *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
+
+                               exceptions_throw_abstractmethoderror();
+
                                return NULL;
                        }
                }
@@ -1490,14 +1611,13 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
        return mi;
 }
 
-/* resolve_method_verifier_checks **********************************************
+/* 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
-          container........the class where the method was found
           mi...............the methodinfo of the resolved method
           invokestatic.....true if the method is invoked by INVOKESTATIC
   
@@ -1511,175 +1631,321 @@ methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
 #if defined(ENABLE_VERIFIER)
 resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
                                                                                                constant_FMIref *methodref,
-                                                                                               classinfo *container,
                                                                                                methodinfo *mi,
-                                                                                               bool invokestatic,
-                                                                                               bool invokespecial,
-                                                                                               stackptr curstack)
+                                                                                               bool invokestatic)
 {
        classinfo *declarer;
        classinfo *referer;
-       resolve_result_t result;
-       int instancecount;
-       typedesc *paramtypes;
-       int i;
-       stackelement *instanceslot = NULL;
-       stackelement *param;
-       methoddesc *md;
-       typeinfo tinfo;
-       int type;
+       char      *msg;
+       s4         msglen;
+       utf       *u;
 
        assert(refmethod);
        assert(methodref);
-       assert(container);
        assert(mi);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"resolve_method_verifier_checks\n");
-       fprintf(stderr,"    flags: %02x\n",mi->flags);
+       printf("resolve_method_verifier_checks\n");
+       printf("    flags: %02x\n",mi->flags);
 #endif
 
        /* get the classinfos and the method descriptor */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       declarer = mi->class;
+       declarer = mi->clazz;
        assert(declarer);
-       assert(referer->state & CLASS_LINKED);
-
-       md = methodref->parseddesc.md;
-       assert(md);
-       assert(md->params);
-
-       instancecount = (invokestatic) ? 0 : 1;
 
        /* check static */
 
        if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
                /* a static method is accessed via an instance, or vice versa */
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IncompatibleClassChangeError,
-                               (mi->flags & ACC_STATIC) ? "static method called via instance"
-                                                        : "instance method called without instance");
+               exceptions_throw_incompatibleclasschangeerror(declarer,
+                                                                                                         (mi->flags & ACC_STATIC)
+                                                                                                         ? "static method called via instance"
+                                                                                                         : "instance method called without instance");
+
                return resolveFailed;
        }
 
        /* check access rights */
 
        if (!access_is_accessible_member(referer,declarer,mi->flags)) {
-               int msglen;
-               char *message;
-
                /* XXX clean this up. this should be in exceptions.c */
-               msglen = utf_get_number_of_u2s(declarer->name) + utf_get_number_of_u2s(mi->name) +
-                       utf_get_number_of_u2s(mi->descriptor) + utf_get_number_of_u2s(referer->name) + 100;
-               message = MNEW(char,msglen);
-               strcpy(message,"method is not accessible (");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),declarer->name);
-               strcat(message,".");
-               utf_sprint_convert_to_latin1(message+strlen(message),mi->name);
-               utf_sprint_convert_to_latin1(message+strlen(message),mi->descriptor);
-               strcat(message," from ");
-               utf_sprint_convert_to_latin1_classname(message+strlen(message),referer->name);
-               strcat(message,")");
-               *exceptionptr = new_exception_message(string_java_lang_IllegalAccessException,message);
-               MFREE(message,char,msglen);
+
+               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 */
        }
 
-       if (curstack) {
-               /* for non-static methods we have to check the constraints on the         */
-               /* instance type                                                          */
+       /* everything ok */
 
-               if (!invokestatic) {
-                       /* find the instance slot under all the parameter slots on the stack */
-                       instanceslot = curstack;
-                       for (i=1; i<md->paramcount; ++i)
-                               instanceslot = instanceslot->prev;
-               }
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
 
-               assert((instanceslot && instancecount == 1) || invokestatic);
 
-               /* record subtype constraints for the instance type, if any */
-               if (instanceslot) {
-                       typeinfo *tip;
+/* resolve_method_instance_type_checks *****************************************
 
-                       assert(instanceslot->type == TYPE_ADR);
+   Check the instance type of a method invocation.
 
-                       if (invokespecial &&
-                                       TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
-                       {   /* XXX clean up */
-                               instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
-                               classref_or_classinfo initclass = (ins) ? ICMD_ACONST_CLASSREF_OR_CLASSINFO(ins-1)
-                                                                                        : CLASSREF_OR_CLASSINFO(refmethod->class);
-                               tip = &tinfo;
-                               if (!typeinfo_init_class(tip,initclass))
-                                       return false;
-                       }
-                       else {
-                               tip = &(instanceslot->typeinfo);
-                       }
+   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,
-                                                                                                tip,
-                                                                                                CLASSREF_OR_CLASSINFO(container),
-                                                                                                resolveLinkageError);
+                                       &(param->typeinfo),
+                                       CLASSREF_OR_CLASSINFO(paramtypes[i+instancecount].classref),
+                                       resolveLinkageError);
                        if (result != resolveSucceeded)
                                return result;
+               }
+       }
 
-                       /* check protected access */
+       /* everything ok */
 
-                       if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
-                       {
-                               result = resolve_lazy_subtype_checks(refmethod,
-                                               tip,
-                                               CLASSREF_OR_CLASSINFO(referer),
-                                               resolveIllegalAccessError);
-                               if (result != resolveSucceeded)
-                                       return result;
-                       }
+       return resolveSucceeded;
+}
+#endif /* defined(ENABLE_VERIFIER) */
 
-               }
 
-               /* check subtype constraints for TYPE_ADR parameters */
+/* resolve_method_param_type_checks_stackbased *********************************
 
-               assert(md->paramcount == methodref->parseddesc.md->paramcount);
-               paramtypes = md->paramtypes;
-               param = curstack;
+   Check non-instance parameter types of a method invocation.
 
-               for (i = md->paramcount-1-instancecount; i>=0; --i, param = param->prev) {
-                       type = md->paramtypes[i+instancecount].type;
+   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
 
-                       assert(param);
-                       assert(type == param->type);
+   RETURN VALUE:
+       resolveSucceeded....everything ok
+          resolveDeferred.....tests could not be done, have been deferred
+       resolveFailed.......exception has been thrown
 
-                       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;
-                       }
+*******************************************************************************/
+
+#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;
                }
 
-       } /* if (curstack) */
+               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) {
-                       utf *name;
-
                        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 = container->name;
+                               name = mi->clazz->name;
                        }
                        else {
                                name = paramtypes[i].classref->name;
@@ -1688,8 +1954,8 @@ resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
                        /* The caller (referer) and the callee (container) must agree */
                        /* on the types of the parameters.                            */
                        if (!classcache_add_constraint(referer->classloader,
-                                                                                  container->classloader, name))
-                               return resolveFailed; /* exception */
+                                                                                  mi->clazz->classloader, name))
+                               return false; /* exception */
                }
        }
 
@@ -1698,24 +1964,31 @@ resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
        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,container->classloader,
-                               md->returntype.classref->name))
-                       return resolveFailed; /* exception */
+               if (!classcache_add_constraint(referer->classloader,
+                                       mi->clazz->classloader,
+                                       md->returntype.classref->name))
+                       return false; /* exception */
        }
 
        /* everything ok */
-       return resolveSucceeded;
+
+       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:
-       iptr.............instruction containing the method reference
-          curstack.........instack of the instruction
           refmethod........the referer method
+          methodref........the method reference
+          invokespecial....true if this is an INVOKESPECIAL instruction
   
    RETURN VALUE:
        resolveSucceeded.....the reference has been resolved
@@ -1724,43 +1997,34 @@ resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
    
 *******************************************************************************/
 
-resolve_result_t resolve_method_lazy(instruction *iptr,stackptr curstack,
-                                                                        methodinfo *refmethod)
+resolve_result_t resolve_method_lazy(methodinfo *refmethod,
+                                                                        constant_FMIref *methodref,
+                                                                        bool invokespecial)
 {
        classinfo *referer;
        classinfo *container;
        methodinfo *mi;
-       constant_FMIref *methodref;
-       resolve_result_t result;
 
-       assert(iptr);
        assert(refmethod);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"resolve_method_lazy\n");
+       printf("resolve_method_lazy\n");
 #endif
 
        /* the class containing the reference */
 
-       referer = refmethod->class;
+       referer = refmethod->clazz;
        assert(referer);
 
-       /* the method reference */
-
-       INSTRUCTION_GET_METHODREF(iptr,methodref);
-
        /* check if the method itself is already resolved */
 
-       if (IS_FMIREF_RESOLVED(methodref)) {
-               mi = methodref->p.method;
-               container = mi->class;
-               goto resolved_the_method;
-       }
+       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))
+       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 */
@@ -1791,12 +2055,12 @@ resolve_result_t resolve_method_lazy(instruction *iptr,stackptr curstack,
                /* this error must not be reported now. (It will be reported   */
                /* if eager resolving of this method is ever tried.)           */
 
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
                return resolveDeferred; /* be lazy */
        }
 
-       if (iptr->opc == ICMD_INVOKESPECIAL) {
-               mi = resolve_method_invokespecial_lookup(refmethod,mi);
+       if (invokespecial) {
+               mi = resolve_method_invokespecial_lookup(refmethod, mi);
                if (!mi)
                        return resolveFailed; /* exception */
        }
@@ -1811,29 +2075,8 @@ resolve_result_t resolve_method_lazy(instruction *iptr,stackptr curstack,
 
        methodref->p.method = mi;
 
-resolved_the_method:
-
-#if defined(ENABLE_VERIFIER)
-       if (opt_verify) {
-               result = resolve_method_verifier_checks(refmethod,methodref,container,
-                                                                                               mi,
-                                                                                               iptr->opc == ICMD_INVOKESTATIC,
-                                                                                               iptr->opc == ICMD_INVOKESPECIAL,
-                                                                                               curstack);
-               if (result != resolveSucceeded)
-                       return result;
-       }
-#endif /* defined(ENABLE_VERIFIER) */
-
-       /* if this call is monomorphic, turn it into an INVOKESPECIAL */
-
-       if ((iptr->opc == ICMD_INVOKEVIRTUAL)
-               && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
-       {
-               iptr->opc = ICMD_INVOKESPECIAL;
-       }
-
        /* succeed */
+
        return resolveSucceeded;
 }
 
@@ -1877,21 +2120,21 @@ bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **re
        assert(mode == resolveLazy || mode == resolveEager);
 
 #ifdef RESOLVE_VERBOSE
-       unresolved_method_debug_dump(ref,stderr);
+       unresolved_method_debug_dump(ref,stdout);
 #endif
 
        *result = NULL;
 
        /* the class containing the reference */
 
-       referer = ref->referermethod->class;
+       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->class;
+               container = mi->clazz;
                goto resolved_the_method;
        }
 
@@ -1931,7 +2174,7 @@ bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **re
                        /* this error must not be reported now. (It will be reported   */
                        /* if eager resolving of this method is ever tried.)           */
 
-                       *exceptionptr = NULL;
+                       exceptions_clear_exception();
                        return true; /* be lazy */
                }
 
@@ -1961,18 +2204,21 @@ resolved_the_method:
 #ifdef ENABLE_VERIFIER
        if (opt_verify) {
 
-               checkresult = resolve_method_verifier_checks(ref->referermethod,
+               checkresult = resolve_method_verifier_checks(
+                               ref->referermethod,
                                ref->methodref,
-                               container,
                                mi,
-                               (ref->flags & RESOLVE_STATIC),
-                               (ref->flags & RESOLVE_SPECIAL),
-                               NULL);
+                               (ref->flags & RESOLVE_STATIC));
 
                if (checkresult != resolveSucceeded)
                        return (bool) checkresult;
 
-               declarer = mi->class;
+               /* 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);
 
@@ -1995,7 +2241,7 @@ resolved_the_method:
 
                /* check subtype constraints for TYPE_ADR parameters */
 
-               assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
+               assert(mi == ref->methodref->p.method || mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
                paramtypes = mi->parseddesc->paramtypes;
 
                for (i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
@@ -2063,8 +2309,8 @@ methodinfo * resolve_method_eager(unresolved_method *ref)
 static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
                                                                                                 methodinfo *refmethod,
                                                                                                 unresolved_subtype_set *stset,
-                                                                                                typeinfo *tinfo,
-                                                                                                constant_classref *declaredtype)
+                                                                                                typeinfo_t *tinfo,
+                                                                                                utf *declaredclassname)
 {
        int count;
        int i;
@@ -2073,22 +2319,22 @@ static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
        assert(tinfo);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"unresolved_subtype_set_from_typeinfo\n");
+       printf("unresolved_subtype_set_from_typeinfo\n");
 #ifdef TYPEINFO_DEBUG
-       typeinfo_print(stderr,tinfo,4);
+       typeinfo_print(stdout,tinfo,4);
 #endif
-       fprintf(stderr,"    declared type:");utf_fprint_printable_ascii(stderr,declaredtype->name);
-       fprintf(stderr,"\n");
+       printf("    declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
+       printf("\n");
 #endif
 
        if (TYPEINFO_IS_PRIMITIVE(*tinfo)) {
-               *exceptionptr = new_verifyerror(refmethod,
+               exceptions_throw_verifyerror(refmethod,
                                "Invalid use of returnAddress");
                return false;
        }
 
        if (TYPEINFO_IS_NEWOBJECT(*tinfo)) {
-               *exceptionptr = new_verifyerror(refmethod,
+               exceptions_throw_verifyerror(refmethod,
                                "Invalid use of uninitialized object");
                return false;
        }
@@ -2098,8 +2344,8 @@ static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
                goto empty_set;
 
        /* every type is assignable to (BOOTSTRAP)java.lang.Object */
-       if (declaredtype->name == utf_java_lang_Object
-                       && referer->classloader == NULL)
+       if (declaredclassname == utf_java_lang_Object
+                       && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
        {
                goto empty_set;
        }
@@ -2127,7 +2373,7 @@ static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
        else {
                if ((IS_CLASSREF(tinfo->typeclass)
                                        ? tinfo->typeclass.ref->name
-                                       : tinfo->typeclass.cls->name) == declaredtype->name)
+                                       : tinfo->typeclass.cls->name) == declaredclassname)
                {
                        /* the class names are the same */
                    /* equality is guaranteed by the loading constraints */
@@ -2167,18 +2413,18 @@ empty_set:
 #ifdef ENABLE_VERIFIER
 unresolved_class * create_unresolved_class(methodinfo *refmethod,
                                                                                   constant_classref *classref,
-                                                                                  typeinfo *valuetype)
+                                                                                  typeinfo_t *valuetype)
 {
        unresolved_class *ref;
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"create_unresolved_class\n");
-       fprintf(stderr,"    referer: ");utf_fprint_printable_ascii(stderr,classref->referer->name);fputc('\n',stderr);
+       printf("create_unresolved_class\n");
+       printf("    referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
        if (refmethod) {
-               fprintf(stderr,"    rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
-               fprintf(stderr,"    rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
+               printf("    rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
+               printf("    rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
        }
-       fprintf(stderr,"    name   : ");utf_fprint_printable_ascii(stderr,classref->name);fputc('\n',stderr);
+       printf("    name   : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
 #endif
 
        ref = NEW(unresolved_class);
@@ -2187,7 +2433,7 @@ unresolved_class * create_unresolved_class(methodinfo *refmethod,
 
        if (valuetype) {
                if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
-                                       &(ref->subtypeconstraints),valuetype,classref))
+                                       &(ref->subtypeconstraints),valuetype,classref->name))
                        return NULL;
        }
        else {
@@ -2198,7 +2444,7 @@ unresolved_class * create_unresolved_class(methodinfo *refmethod,
 }
 #endif /* ENABLE_VERIFIER */
 
-/* create_unresolved_field *****************************************************
+/* resolve_create_unresolved_field *********************************************
  
    Create an unresolved_field struct for the given field access instruction
   
@@ -2213,17 +2459,18 @@ unresolved_class * create_unresolved_class(methodinfo *refmethod,
 
 *******************************************************************************/
 
-unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refmethod,
-                                                                                  instruction *iptr)
+unresolved_field * resolve_create_unresolved_field(classinfo *referer,
+                                                                                                  methodinfo *refmethod,
+                                                                                                  instruction *iptr)
 {
        unresolved_field *ref;
        constant_FMIref *fieldref = NULL;
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"create_unresolved_field\n");
-       fprintf(stderr,"    referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
+       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);
@@ -2231,46 +2478,46 @@ unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refme
        ref->referermethod = refmethod;
        UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
 
-       switch (iptr[0].opc) {
+       switch (iptr->opc) {
                case ICMD_PUTFIELD:
                        ref->flags |= RESOLVE_PUTFIELD;
-                       fieldref = (constant_FMIref *) iptr[0].val.a;
                        break;
 
                case ICMD_PUTFIELDCONST:
                        ref->flags |= RESOLVE_PUTFIELD;
-                       fieldref = (constant_FMIref *) iptr[1].val.a;
                        break;
 
                case ICMD_PUTSTATIC:
                        ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
-                       fieldref = (constant_FMIref *) iptr[0].val.a;
                        break;
 
                case ICMD_PUTSTATICCONST:
                        ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
-                       fieldref = (constant_FMIref *) iptr[1].val.a;
                        break;
 
                case ICMD_GETFIELD:
-                       fieldref = (constant_FMIref *) iptr[0].val.a;
                        break;
 
                case ICMD_GETSTATIC:
                        ref->flags |= RESOLVE_STATIC;
-                       fieldref = (constant_FMIref *) iptr[0].val.a;
                        break;
+
+#if !defined(NDEBUG)
+               default:
+                       assert(false);
+#endif
        }
 
+       fieldref = iptr->sx.s23.s3.fmiref;
+
        assert(fieldref);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"    class  : ");utf_fprint_printable_ascii(stderr,fieldref->classref->name);fputc('\n',stderr);
-       fprintf(stderr,"    name   : ");utf_fprint_printable_ascii(stderr,fieldref->name);fputc('\n',stderr);
-       fprintf(stderr,"    desc   : ");utf_fprint_printable_ascii(stderr,fieldref->descriptor);fputc('\n',stderr);
-       fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
-       fputc('\n',stderr);
-       /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
+/*     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;
@@ -2278,7 +2525,7 @@ unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refme
        return ref;
 }
 
-/* constrain_unresolved_field **************************************************
+/* resolve_constrain_unresolved_field ******************************************
  
    Record subtype constraints for a field access.
   
@@ -2286,8 +2533,8 @@ unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refme
        ref..............the unresolved_field structure of the access
        referer..........the class containing the reference
           refmethod........the method triggering the resolution (if any)
-          iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
-          stack............the input stack of the instruction
+          instanceti.......instance typeinfo, if available
+          valueti..........value typeinfo, if available
 
    RETURN VALUE:
        true.............everything ok
@@ -2295,17 +2542,16 @@ unresolved_field * create_unresolved_field(classinfo *referer, methodinfo *refme
 
 *******************************************************************************/
 
-#ifdef ENABLE_VERIFIER
-bool constrain_unresolved_field(unresolved_field *ref,
-                                                           classinfo *referer, methodinfo *refmethod,
-                                                           instruction *iptr,
-                                                           stackelement *stack)
+#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;
-       stackelement *instanceslot = NULL;
        int type;
-       typeinfo tinfo;
-       typeinfo *tip = NULL;
+       typeinfo_t tinfo;
        typedesc *fd;
 
        assert(ref);
@@ -2314,82 +2560,66 @@ bool constrain_unresolved_field(unresolved_field *ref,
        assert(fieldref);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"constrain_unresolved_field\n");
-       fprintf(stderr,"    referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
-       fprintf(stderr,"    class  : ");utf_fprint_printable_ascii(stderr,fieldref->classref->name);fputc('\n',stderr);
-       fprintf(stderr,"    name   : ");utf_fprint_printable_ascii(stderr,fieldref->name);fputc('\n',stderr);
-       fprintf(stderr,"    desc   : ");utf_fprint_printable_ascii(stderr,fieldref->descriptor);fputc('\n',stderr);
-       fprintf(stderr,"    type   : ");descriptor_debug_print_typedesc(stderr,fieldref->parseddesc.fd);
-       fputc('\n',stderr);
-       /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
+       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
 
-       switch (iptr[0].opc) {
-               case ICMD_PUTFIELD:
-                       instanceslot = stack->prev;
-                       tip = &(stack->typeinfo);
-                       break;
-
-               case ICMD_PUTFIELDCONST:
-                       instanceslot = stack;
-                       break;
-
-               case ICMD_PUTSTATIC:
-                       tip = &(stack->typeinfo);
-                       break;
-
-               case ICMD_GETFIELD:
-                       instanceslot = stack;
-                       break;
-       }
-
-       assert(instanceslot || ((ref->flags & RESOLVE_STATIC) != 0));
+       assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
        fd = fieldref->parseddesc.fd;
        assert(fd);
 
        /* record subtype constraints for the instance type, if any */
-       if (instanceslot) {
-               typeinfo *insttip;
+       if (instanceti) {
+               typeinfo_t *insttip;
 
                /* The instanceslot must contain a reference to a non-array type */
-               if (!TYPEINFO_IS_REFERENCE(instanceslot->typeinfo)) {
-                       *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on non-reference");
+               if (!TYPEINFO_IS_REFERENCE(*instanceti)) {
+                       exceptions_throw_verifyerror(refmethod, 
+                                       "illegal instruction: field access on non-reference");
                        return false;
                }
-               if (TYPEINFO_IS_ARRAY(instanceslot->typeinfo)) {
-                       *exceptionptr = new_verifyerror(refmethod, "illegal instruction: field access on array");
+               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(instanceslot->typeinfo))
+                               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(instanceslot->typeinfo);
+                       instruction *ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*instanceti);
 
                        if (ins != NULL) {
-                               *exceptionptr = new_verifyerror(refmethod,"accessing field of uninitialized object");
+                               exceptions_throw_verifyerror(refmethod, 
+                                               "accessing field of uninitialized object");
                                return false;
                        }
-                       /* XXX check that class of field == refmethod->class */
-                       initclass = refmethod->class; /* XXX classrefs */
+                       /* 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);
+                       typeinfo_init_classinfo(&tinfo, initclass);
                        insttip = &tinfo;
                }
                else {
-                       insttip = &(instanceslot->typeinfo);
+                       insttip = instanceti;
                }
-               if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
-                                       &(ref->instancetypes),insttip,fieldref->p.classref))
+               if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
+                                       &(ref->instancetypes), insttip, 
+                                       FIELDREF_CLASSNAME(fieldref)))
                        return false;
        }
        else {
@@ -2399,20 +2629,10 @@ bool constrain_unresolved_field(unresolved_field *ref,
        /* record subtype constraints for the value type, if any */
        type = fd->type;
        if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
-               if (!tip) {
-                       /* we have a PUTSTATICCONST or PUTFIELDCONST with TYPE_ADR */
-                       tip = &tinfo;
-                       if (INSTRUCTION_PUTCONST_VALUE_ADR(iptr)) {
-                               assert(class_java_lang_String);
-                               assert(class_java_lang_String->state & CLASS_LOADED);
-                               assert(class_java_lang_String->state & CLASS_LINKED);
-                               typeinfo_init_classinfo(&tinfo,class_java_lang_String);
-                       }
-                       else
-                               TYPEINFO_INIT_NULLTYPE(tinfo);
-               }
-               if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
-                                       &(ref->valueconstraints),tip,fieldref->parseddesc.fd->classref))
+               assert(valueti);
+               if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
+                                       &(ref->valueconstraints), valueti, 
+                                       fieldref->parseddesc.fd->classref->name))
                        return false;
        }
        else {
@@ -2423,7 +2643,7 @@ bool constrain_unresolved_field(unresolved_field *ref,
 }
 #endif /* ENABLE_VERIFIER */
 
-/* create_unresolved_method ****************************************************
+/* resolve_create_unresolved_method ********************************************
  
    Create an unresolved_method struct for the given method invocation
   
@@ -2438,38 +2658,35 @@ bool constrain_unresolved_field(unresolved_field *ref,
 
 *******************************************************************************/
 
-unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *refmethod,
-                                                                                        instruction *iptr)
+unresolved_method * resolve_create_unresolved_method(classinfo *referer,
+                                                                                                        methodinfo *refmethod,
+                                                                                                        constant_FMIref *methodref,
+                                                                                                        bool invokestatic,
+                                                                                                        bool invokespecial)
 {
        unresolved_method *ref;
-       constant_FMIref *methodref;
-       bool staticmethod;
 
-       methodref = (constant_FMIref *) iptr[0].val.a;
        assert(methodref);
-       staticmethod = (iptr[0].opc == ICMD_INVOKESTATIC);
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"create_unresolved_method\n");
-       fprintf(stderr,"    referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
-       fprintf(stderr,"    class  : ");utf_fprint_printable_ascii(stderr,methodref->classref->name);fputc('\n',stderr);
-       fprintf(stderr,"    name   : ");utf_fprint_printable_ascii(stderr,methodref->name);fputc('\n',stderr);
-       fprintf(stderr,"    desc   : ");utf_fprint_printable_ascii(stderr,methodref->descriptor);fputc('\n',stderr);
-       /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
+       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,
-                                       (staticmethod) ? ACC_STATIC : ACC_NONE))
+                                       (invokestatic) ? ACC_STATIC : ACC_NONE))
                        return NULL;
 
        /* create the data structure */
        ref = NEW(unresolved_method);
-       ref->flags = ((staticmethod) ? RESOLVE_STATIC : 0)
-                          | ((iptr[0].opc == ICMD_INVOKESPECIAL) ? RESOLVE_SPECIAL : 0);
+       ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
+                          | ((invokespecial) ? RESOLVE_SPECIAL : 0);
        ref->referermethod = refmethod;
        ref->methodref = methodref;
        ref->paramconstraints = NULL;
@@ -2478,16 +2695,16 @@ unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *ref
        return ref;
 }
 
-/* constrain_unresolved_method *************************************************
+
+/* resolve_constrain_unresolved_method_instance ********************************
  
-   Record subtype constraints for the arguments of a method call.
+   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
-          stack............the input stack of the instruction
 
    RETURN VALUE:
        true.............everything ok
@@ -2495,112 +2712,209 @@ unresolved_method * create_unresolved_method(classinfo *referer, methodinfo *ref
 
 *******************************************************************************/
 
-#ifdef ENABLE_VERIFIER
-bool constrain_unresolved_method(unresolved_method *ref,
-                                                                classinfo *referer, methodinfo *refmethod,
-                                                                instruction *iptr,
-                                                                stackelement *stack)
+#if defined(ENABLE_VERIFIER)
+bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
+                                                                                                 methodinfo *refmethod,
+                                                                                                 typeinfo_t *instanceti,
+                                                                                                 bool invokespecial)
 {
-       constant_FMIref *methodref;
+       constant_FMIref   *methodref;
        constant_classref *instanceref;
-       stackelement *instanceslot = NULL;
-       stackelement *param;
-       methoddesc *md;
-       typeinfo tinfo;
-       int i,j;
-       int type;
-       int instancecount;
+       typeinfo_t           tinfo;
+       typeinfo_t          *tip;
 
        assert(ref);
        methodref = ref->methodref;
        assert(methodref);
-       md = methodref->parseddesc.md;
-       assert(md);
-       assert(md->params != NULL);
 
        /* XXX clean this up */
        instanceref = IS_FMIREF_RESOLVED(methodref)
-               ? class_get_self_classref(methodref->p.method->class)
+               ? class_get_self_classref(methodref->p.method->clazz)
                : methodref->p.classref;
 
 #ifdef RESOLVE_VERBOSE
-       fprintf(stderr,"constrain_unresolved_method\n");
-       fprintf(stderr,"    referer: ");utf_fprint_printable_ascii(stderr,referer->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmethod: ");utf_fprint_printable_ascii(stderr,refmethod->name);fputc('\n',stderr);
-       fprintf(stderr,"    rmdesc : ");utf_fprint_printable_ascii(stderr,refmethod->descriptor);fputc('\n',stderr);
-       fprintf(stderr,"    class  : ");utf_fprint_printable_ascii(stderr,methodref->classref->name);fputc('\n',stderr);
-       fprintf(stderr,"    name   : ");utf_fprint_printable_ascii(stderr,methodref->name);fputc('\n',stderr);
-       fprintf(stderr,"    desc   : ");utf_fprint_printable_ascii(stderr,methodref->descriptor);fputc('\n',stderr);
-       /*fprintf(stderr,"    opcode : %d %s\n",iptr[0].opc,icmd_names[iptr[0].opc]);*/
+       printf("resolve_constrain_unresolved_method_instance\n");
+       printf("    rmethod: "); method_println(refmethod);
+       printf("    mref   : "); method_methodref_println(methodref);
 #endif
 
-       if ((ref->flags & RESOLVE_STATIC) == 0) {
-               /* find the instance slot under all the parameter slots on the stack */
-               instanceslot = stack;
-               for (i=1; i<md->paramcount; ++i)
-                       instanceslot = instanceslot->prev;
-               instancecount = 1;
+       /* 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 {
-               instancecount = 0;
+               tip = instanceti;
        }
 
-       assert((instanceslot && instancecount==1) || ((ref->flags & RESOLVE_STATIC) != 0));
+       if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
+                               &(ref->instancetypes),tip,instanceref->name))
+               return false;
 
-       /* record subtype constraints for the instance type, if any */
-       if (instanceslot) {
-               typeinfo *tip;
-
-               assert(instanceslot->type == TYPE_ADR);
-
-               if (iptr[0].opc == ICMD_INVOKESPECIAL &&
-                               TYPEINFO_IS_NEWOBJECT(instanceslot->typeinfo))
-               {   /* XXX clean up */
-                       instruction *ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(instanceslot->typeinfo);
-                       classref_or_classinfo initclass = (ins) ? ICMD_ACONST_CLASSREF_OR_CLASSINFO(ins-1)
-                                                                                : CLASSREF_OR_CLASSINFO(refmethod->class);
-                       tip = &tinfo;
-                       if (!typeinfo_init_class(tip,initclass))
+       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 {
-                       tip = &(instanceslot->typeinfo);
+                       if (ref->paramconstraints)
+                               UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
                }
-               if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
-                                       &(ref->instancetypes),tip,instanceref))
-                       return false;
        }
 
+       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;
-       for (i=md->paramcount-1-instancecount; i>=0; --i, param=param->prev) {
-               type = md->paramtypes[i+instancecount].type;
 
-               assert(param);
+       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=md->paramcount-1-instancecount; j>i; --j)
+                               for (j = 0; j < i - instancecount; ++j)
                                        UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
                        }
                        assert(ref->paramconstraints);
-                       if (!unresolved_subtype_set_from_typeinfo(referer,refmethod,
-                                               ref->paramconstraints + i,&(param->typeinfo),
-                                               md->paramtypes[i+instancecount].classref))
+                       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                                                             */
 /******************************************************************************/
@@ -2766,7 +3080,7 @@ void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
        fprintf(file,"unresolved_field(%p):\n",(void *)ref);
        if (ref) {
                fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
+               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: ");
@@ -2804,7 +3118,7 @@ void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
        fprintf(file,"unresolved_method(%p):\n",(void *)ref);
        if (ref) {
                fprintf(file,"    referer   : ");
-               utf_fprint_printable_ascii(file,ref->referermethod->class->name); fputc('\n',file);
+               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: ");
@@ -2834,6 +3148,7 @@ void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
 }
 #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
@@ -2847,4 +3162,3 @@ void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
  * End:
  * vim:noexpandtab:sw=4:ts=4:
  */
-