* src/vm/jit/jit.c: Moved to .cpp.
[cacao.git] / src / vm / jit / verify / typeinfo.c
index 1981994fab2feae308f1eece451296a2291407d8..78407dbbd863b28ac0c1d4c72d1bbb0084a17a73 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Edwin Steiner
+*/
 
-   $Id: typeinfo.c 3829 2005-12-01 19:47:56Z twisti $
 
-*/
+#include "config.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include "mm/memory.h"
+
 #include "toolbox/logging.h"
+
+#include "vm/array.h"
 #include "vm/class.h"
-#include "vm/loader.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/verify/typeinfo.h"
 #include "vm/descriptor.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
-#include "vm/exceptions.h"
+
+#include "vm/jit/jit.hpp"
+#include "vm/jit/verify/typeinfo.h"
 
 
 /* check if a linked class is an array class. Only use for linked classes! */
@@ -50,7 +51,7 @@
 /* check if a linked class implements the interface with the given index */
 #define CLASSINFO_IMPLEMENTS_INTERFACE(cls,index)                   \
     ( ((index) < (cls)->vftbl->interfacetablelength)            \
-      && (VFTBLINTERFACETABLE((cls)->vftbl,(index)) != NULL) )
+      && ( (cls)->vftbl->interfacetable[-(index)] != NULL ) )
 
 /******************************************************************************/
 /* DEBUG HELPERS                                                              */
 #endif
 
 /**********************************************************************/
-/* TYPEVECTOR (SET) FUNCTIONS                                         */
+/* TYPEVECTOR FUNCTIONS                                               */
 /**********************************************************************/
 
-/* typevectorset_copy **********************************************************
+#if defined(ENABLE_VERIFIER)
+
+/* typevector_copy *************************************************************
  
-   Return a copy of the given typevector set.
+   Return a copy of the given typevector.
   
    IN:
           src..............typevector set to copy, must be != NULL
-          k................k-index to set in first typevector of resulting set
           size.............number of elements per typevector
 
    RETURN VALUE:
        a pointer to the new typevector set
 
-   NOTE:
-       This function recursively invokes itself with increasing k-index to
-          copy the alternative typevectors in the given set.
-
 *******************************************************************************/
 
-typevector *
-typevectorset_copy(typevector *src,int k,int size)
+varinfo *
+typevector_copy(varinfo *src, int size)
 {
-       typevector *dst;
+       varinfo *dst;
        
        TYPEINFO_ASSERT(src);
        
        dst = DNEW_TYPEVECTOR(size);
        memcpy(dst,src,TYPEVECTOR_SIZE(size));
-       dst->k = k;
-       if (src->alt)
-               dst->alt = typevectorset_copy(src->alt,k+1,size);
+
        return dst;
 }
 
-/* typevectorset_copy_inplace **************************************************
+/* typevector_copy_inplace *****************************************************
  
-   Return a copy of the given typevector set.
+   Copy a typevector to a given destination.
 
-   The DST typevector is overwritten, but alternative vectors, if SRC has any,
-   are newly allocated.
-  
    IN:
-          src..............typevector set to copy, must be != NULL
+          src..............typevector to copy, must be != NULL
           dst..............destination to write the copy to
           size.............number of elements per typevector
 
 *******************************************************************************/
 
 void
-typevectorset_copy_inplace(typevector *src,typevector *dst,int size)
+typevector_copy_inplace(varinfo *src,varinfo *dst,int size)
 {
        memcpy(dst,src,TYPEVECTOR_SIZE(size));
-       dst->k = 0; 
-       if ((src)->alt) {
-               (dst)->alt = typevectorset_copy((src)->alt,1,size);
-       }
 }
 
-/* typevectorset_checktype *****************************************************
+/* typevector_checktype ********************************************************
  
-   Check if all typevectors contain a given type at a given index.
+   Check if the typevector contains a given type at a given index.
   
    IN:
           vec..............typevector set, must be != NULL
@@ -133,177 +122,64 @@ typevectorset_copy_inplace(typevector *src,typevector *dst,int size)
           type.............TYPE_* constant to check against
 
    RETURN VALUE:
-       true if all typevectors in the set contain TYPE at INDEX,
+       true if the typevector contains TYPE at INDEX,
           false otherwise
 
 *******************************************************************************/
 
 bool
-typevectorset_checktype(typevector *vec,int index,int type)
+typevector_checktype(varinfo *vec,int index,int type)
 {
        TYPEINFO_ASSERT(vec);
-       do {
-               if (vec->td[index].type != type)
-                       return false;
-       } while ((vec = vec->alt) != NULL);
-       return true;
+
+       return vec[index].type == type;
 }
 
-/* typevectorset_checkreference ************************************************
+/* typevector_checkreference ***************************************************
  
-   Check if all typevectors contain a reference at a given index.
+   Check if the typevector contains a reference at a given index.
   
    IN:
-          vec..............typevector set, must be != NULL
+          vec..............typevector, must be != NULL
           index............index of component to check
 
    RETURN VALUE:
-       true if all typevectors in the set contain a reference at INDEX,
+       true if the typevector contains a reference at INDEX,
           false otherwise
 
 *******************************************************************************/
 
 bool
-typevectorset_checkreference(typevector *vec,int index)
+typevector_checkreference(varinfo *vec, int index)
 {
        TYPEINFO_ASSERT(vec);
-       do {
-               if (!TYPEDESC_IS_REFERENCE(vec->td[index]))
-                       return false;
-       } while ((vec = vec->alt) != NULL);
-       return true;
+       return TYPEDESC_IS_REFERENCE(vec[index]);
 }
 
 /* typevectorset_checkretaddr **************************************************
  
-   Check if all typevectors contain a returnAddress at a given index.
+   Check if the typevectors contains a returnAddress at a given index.
   
    IN:
-          vec..............typevector set, must be != NULL
+          vec..............typevector, must be != NULL
           index............index of component to check
 
    RETURN VALUE:
-       true if all typevectors in the set contain a returnAddress at INDEX,
+       true if the typevector contains a returnAddress at INDEX,
           false otherwise
 
 *******************************************************************************/
 
 bool
-typevectorset_checkretaddr(typevector *vec,int index)
-{
-       TYPEINFO_ASSERT(vec);
-       do {
-               if (!TYPEDESC_IS_RETURNADDRESS(vec->td[index]))
-                       return false;
-       } while ((vec = vec->alt) != NULL);
-       return true;
-}
-
-/* typevectorset_copymergedtype ************************************************
-   Merge the types at a given index in the typevectors of a set and
-   copy the result to a destination typeinfo.
-  
-   IN:
-       m................method for exception messages
-          vec..............typevector set, must be != NULL
-          index............index of component to merge
-
-   OUT:
-       *dst.............destination typeinfo, receives the merge result
-
-   RETURN VALUE:
-       the TYPE_* constant of the resulting type
-          TYPE_VOID if incompatible types were contained at INDEX in VEC, or
-          -1...............an exception has been thrown
-
-*******************************************************************************/
-
-int
-typevectorset_copymergedtype(methodinfo *m,typevector *vec,int index,typeinfo *dst)
+typevector_checkretaddr(varinfo *vec,int index)
 {
-       int type;
-       typedescriptor *td;
-
        TYPEINFO_ASSERT(vec);
-       TYPEINFO_ASSERT(dst);
-
-       td = vec->td + index;
-       type = td->type;
-       TYPEINFO_COPY(td->info,*dst);
-       
-       if (vec->alt) {
-               int primitive;
-               
-               primitive = TYPEINFO_IS_PRIMITIVE(*dst) ? 1 : 0;
-               
-               while ((vec = vec->alt) != NULL) {
-                       td = vec->td + index;
-                       if (type != td->type)
-                               return TYPE_VOID;
-
-                       if (type == TYPE_ADDRESS) {
-                               if ((TYPEINFO_IS_PRIMITIVE(td->info) ? 1 : 0) != primitive)
-                                       return TYPE_VOID;
-                               /* there cannot be any merge errors now. In the worst case */
-                               /* we either get a returnAddress type or a j.l.O reference */
-                               if (typeinfo_merge(m,dst,&(td->info)) == typecheck_FAIL)
-                                       return -1;
-                       }
-               }
-       }
-       return type;
-}
-
-/* typevectorset_mergedtype ****************************************************
-   Return the merged type of the types at a given index in the typevectors 
-   of a set.
-  
-   IN:
-          m................method for exception messages
-          vec..............typevector set, must be != NULL
-          index............index of component to merge
-          temp.............pointer to a typeinfo that may be used to merge the
-                           result if necessary
-
-   OUT:
-       *result..........set to the address of a typeinfo containing the
-                           merged type.
-
-   RETURN VALUE:
-       the TYPE_* constant of the resulting type
-          TYPE_VOID if incompatible types were contained at INDEX in VEC, or
-          -1...............an exception has been thrown
-
-   NOTE:
-       This function should be more efficient than typevectorset_copymergedtype
-          assuming that most typevector sets contain exactly one typevector.
-
-*******************************************************************************/
-
-int
-typevectorset_mergedtype(methodinfo *m,typevector *vec,int index,typeinfo *temp,typeinfo **result)
-{
-       TYPEINFO_ASSERT(vec);
-       TYPEINFO_ASSERT(temp);
-       TYPEINFO_ASSERT(result);
-       
-       if (vec->alt) {
-               *result = temp;
-               return typevectorset_copymergedtype(m,vec,index,temp);
-       }
-
-       *result = &(vec->td[index].info);
-       return vec->td[index].type;
+       return TYPEDESC_IS_RETURNADDRESS(vec[index]);
 }
 
-/* typevectorset_store *********************************************************
+/* typevector_store ************************************************************
  
-   Store a type at a given index in the typevectors of a set.
-   This function stores the same type in all typevectors of the set.
-   DO NOT use it to store returnAddress types!
-   DO NOT use it to store two-word types!
+   Store a type at a given index in the typevector.
   
    IN:
           vec..............typevector set, must be != NULL
@@ -312,101 +188,41 @@ typevectorset_mergedtype(methodinfo *m,typevector *vec,int index,typeinfo *temp,
           info.............typeinfo of type to set, may be NULL, 
                            if TYPE != TYPE_ADR
 
-   NOTE:
-       If there is a two-word type stored at INDEX-1 in any typevector, it is
-          changed to TYPE_VOID (because its upper half has become invalid).
-
-          The components at INDEX+1 are _not_ touched, regardless of TYPE.
-
 *******************************************************************************/
 
 void
-typevectorset_store(typevector *vec,int index,int type,typeinfo *info)
+typevector_store(varinfo *vec,int index,int type,typeinfo_t *info)
 {
        TYPEINFO_ASSERT(vec);
-       TYPEINFO_ASSERT((info && !TYPEINFO_IS_PRIMITIVE(*info)) || type != TYPE_ADR);
-
-       do {
-               vec->td[index].type = type;
-               if (info)
-                       TYPEINFO_COPY(*info,vec->td[index].info);
-               if (index > 0 && IS_2_WORD_TYPE(vec->td[index-1].type))
-                       vec->td[index-1].type = TYPE_VOID;
-       } while ((vec = vec->alt) != NULL);
+
+       vec[index].type = type;
+       if (info)
+               TYPEINFO_COPY(*info,vec[index].typeinfo);
 }
 
-/* typevectorset_store_retaddr *************************************************
+/* typevector_store_retaddr ****************************************************
  
-   Store a returnAddress type at a given index in the typevectors of a set.
-   Each possible returnAddress of the type is stored in the corresponding
-   typevector of the set.
+   Store a returnAddress type at a given index in the typevector.
   
    IN:
           vec..............typevector set, must be != NULL
           index............index of component to set
-          info.............typeinfo of the returnAddress. This typeinfo must
-                           contain a return address set with at least as many
-                                               entries as there are typevectors in VEC.
-
-   NOTE:
-       If there is a two-word type stored at INDEX-1 in any typevector, it is
-          changed to TYPE_VOID (because its upper half has become invalid).
+          info.............typeinfo of the returnAddress.
 
 *******************************************************************************/
 
 void
-typevectorset_store_retaddr(typevector *vec,int index,typeinfo *info)
+typevector_store_retaddr(varinfo *vec,int index,typeinfo_t *info)
 {
-       typeinfo_retaddr_set *adr;
-
        TYPEINFO_ASSERT(vec);
        TYPEINFO_ASSERT(TYPEINFO_IS_PRIMITIVE(*info));
        
-       adr = (typeinfo_retaddr_set*) TYPEINFO_RETURNADDRESS(*info);
-       do {
-               TYPEINFO_ASSERT(adr);
-
-               vec->td[index].type = TYPE_ADDRESS;
-               TYPEINFO_INIT_RETURNADDRESS(vec->td[index].info,adr->addr);
-               if (index > 0 && IS_2_WORD_TYPE(vec->td[index-1].type))
-                       vec->td[index-1].type = TYPE_VOID;
-               adr = adr->alt;
-       } while ((vec = vec->alt) != NULL);
+       vec[index].type = TYPE_ADR;
+       TYPEINFO_INIT_RETURNADDRESS(vec[index].typeinfo,
+                       TYPEINFO_RETURNADDRESS(*info));
 }
 
-/* typevectorset_store_twoword *************************************************
-   Store a two-word type at a given index in the typevectors of a set.
-   This function stores the same type in all typevectors of the set.
-  
-   IN:
-          vec..............typevector set, must be != NULL
-          index............index of component to set
-          type.............TYPE_* constant of type to set (TYPE_LONG, TYPE_DOUBLE)
-
-   NOTE:
-       If there is a two-word type stored at INDEX-1 in any typevector, it is
-          changed to TYPE_VOID (because its upper half has become invalid).
-
-          The components at INDEX+1 are set to TYPE_VOID.
-
-*******************************************************************************/
-
-void
-typevectorset_store_twoword(typevector *vec,int index,int type)
-{
-       TYPEINFO_ASSERT(vec);
-       TYPEINFO_ASSERT(type == TYPE_LONG || type == TYPE_DOUBLE);
-
-       do {
-               vec->td[index].type = type;
-               vec->td[index+1].type = TYPE_VOID;
-               if (index > 0 && IS_2_WORD_TYPE(vec->td[index-1].type))
-                       vec->td[index-1].type = TYPE_VOID;
-       } while ((vec = vec->alt) != NULL);
-}
-
-/* typevectorset_init_object ***************************************************
+/* typevector_init_object ******************************************************
  
    Replace all uninitialized object types in the typevector set which were 
    created by the given instruction by initialized object types.
@@ -426,21 +242,19 @@ typevectorset_store_twoword(typevector *vec,int index,int type)
 *******************************************************************************/
 
 bool
-typevectorset_init_object(typevector *set,void *ins,
-                                                 classref_or_classinfo initclass,
-                                                 int size)
+typevector_init_object(varinfo *set,void *ins,
+                                          classref_or_classinfo initclass,
+                                          int size)
 {
        int i;
 
-       for (;set; set=set->alt) {
-               for (i=0; i<size; ++i) {
-                       if (set->td[i].type == TYPE_ADR
-                               && TYPEINFO_IS_NEWOBJECT(set->td[i].info)
-                               && TYPEINFO_NEWOBJECT_INSTRUCTION(set->td[i].info) == ins)
-                       {
-                               if (!typeinfo_init_class(&(set->td[i].info),initclass))
-                                       return false;
-                       }
+       for (i=0; i<size; ++i) {
+               if (set[i].type == TYPE_ADR
+                       && TYPEINFO_IS_NEWOBJECT(set[i].typeinfo)
+                       && TYPEINFO_NEWOBJECT_INSTRUCTION(set[i].typeinfo) == ins)
+               {
+                       if (!typeinfo_init_class(&(set[i].typeinfo),initclass))
+                               return false;
                }
        }
        return true;
@@ -468,24 +282,24 @@ typevectorset_init_object(typevector *set,void *ins,
 *******************************************************************************/
 
 typecheck_result
-typevector_merge(methodinfo *m,typevector *dst,typevector *y,int size)
+typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size)
 {
        bool changed = false;
        typecheck_result r;
        
-       typedescriptor *a = dst->td;
-       typedescriptor *b = y->td;
+       varinfo *a = dst;
+       varinfo *b = y;
        while (size--) {
                if (a->type != TYPE_VOID && a->type != b->type) {
                        a->type = TYPE_VOID;
                        changed = true;
                }
-               else if (a->type == TYPE_ADDRESS) {
-                       if (TYPEINFO_IS_PRIMITIVE(a->info)) {
+               else if (a->type == TYPE_ADR) {
+                       if (TYPEINFO_IS_PRIMITIVE(a->typeinfo)) {
                                /* 'a' is a returnAddress */
-                               if (!TYPEINFO_IS_PRIMITIVE(b->info)
-                                       || (TYPEINFO_RETURNADDRESS(a->info)
-                                               != TYPEINFO_RETURNADDRESS(b->info)))
+                               if (!TYPEINFO_IS_PRIMITIVE(b->typeinfo)
+                                       || (TYPEINFO_RETURNADDRESS(a->typeinfo)
+                                               != TYPEINFO_RETURNADDRESS(b->typeinfo)))
                                {
                                        a->type = TYPE_VOID;
                                        changed = true;
@@ -493,14 +307,14 @@ typevector_merge(methodinfo *m,typevector *dst,typevector *y,int size)
                        }
                        else {
                                /* 'a' is a reference */
-                               if (TYPEINFO_IS_PRIMITIVE(b->info)) {
+                               if (TYPEINFO_IS_PRIMITIVE(b->typeinfo)) {
                                        a->type = TYPE_VOID;
                                        changed = true;
                                }
                                else {
                                        /* two reference types are merged. There cannot be */
                                        /* a merge error. In the worst case we get j.l.O.  */
-                                       r = typeinfo_merge(m,&(a->info),&(b->info));
+                                       r = typeinfo_merge(m,&(a->typeinfo),&(b->typeinfo));
                                        if (r == typecheck_FAIL)
                                                return r;
                                        changed |= r;
@@ -513,190 +327,6 @@ typevector_merge(methodinfo *m,typevector *dst,typevector *y,int size)
        return changed;
 }
 
-/* typevector_separable_from ***************************************************
-   Check if two typevectors are separable. Two typevectors are considered
-   separable if there is an index i for which both typevectors contain a
-   returnAddress type and the return addresses of the types are different.
-   The typevectors must have the same number of components.
-  
-   IN:
-          a................the first typevector
-          b................the second typevector
-          size.............number of elements per typevector
-
-   RETURN VALUE:
-       true.............typevectors are separable
-          false............typevectors are not separable
-
-*******************************************************************************/
-
-bool 
-typevector_separable_from(typevector *a,typevector *b,int size)
-{
-       typedescriptor *tda = a->td;
-       typedescriptor *tdb = b->td;
-       for (;size--; tda++,tdb++) {
-               if (TYPEDESC_IS_RETURNADDRESS(*tda)
-                       && TYPEDESC_IS_RETURNADDRESS(*tdb)
-                       && TYPEINFO_RETURNADDRESS(tda->info)
-                          != TYPEINFO_RETURNADDRESS(tdb->info))
-                       return true;
-       }
-       return false;
-}
-
-/* typevectorset_add ***********************************************************
-   Add a typevector to a typevector set. The typevector is added at the end of
-   the set and the k-index of the typevector is set accordingly.
-  
-   IN:
-          dst..............the typevector set to modify
-          v................the typevector to add
-          size.............number of elements per typevector
-
-*******************************************************************************/
-
-void
-typevectorset_add(typevector *dst,typevector *v,int size)
-{
-       TYPEINFO_ASSERT(dst);
-       TYPEINFO_ASSERT(v);
-
-       while (dst->alt)
-               dst = dst->alt;
-       dst->alt = DNEW_TYPEVECTOR(size);
-       memcpy(dst->alt,v,TYPEVECTOR_SIZE(size));
-       dst->alt->alt = NULL;
-       dst->alt->k = dst->k + 1;
-}
-
-/* typevectorset_select ********************************************************
-   Pick the typevectors from a set which contain a given return address.
-  
-   IN:
-          set..............points to the location containing the typevector set.
-                           *set may be NULL.
-          index............index to check against the return address. All
-                           typevectors must contain a returnAddress type at
-                                               this index.
-          retaddr..........the return address to select
-
-   OUT:
-       *set.............receives the typevector set after removing the
-                           selected typevectors.
-
-   RETURN VALUE:
-       a typevector set consisting of the selected typevectors.
-
-*******************************************************************************/
-
-typevector *
-typevectorset_select(typevector **set,int index,void *retaddr)
-{
-       typevector *selected;
-
-       if (!*set) return NULL;
-       
-       if (TYPEINFO_RETURNADDRESS((*set)->td[index].info) == retaddr) {
-               selected = *set;
-               *set = selected->alt;
-               selected->alt = typevectorset_select(set,index,retaddr);
-       }
-       else {
-               selected = typevectorset_select(&((*set)->alt),index,retaddr);
-       }
-       return selected;
-}
-
-/* typevector_separable_with ***************************************************
-   Check if a typevector set would be separable after adding a given
-   typevector. A typevector set is considered separable if there is an
-   index i for which all typevectors in the set contain a returnAddress type,
-   and at least two different return addresses occurr at index i.
-   The typevectors must have the same number of components.
-  
-   IN:
-          set..............the typevector set
-          add..............the typevector
-          size.............number of elements per typevector
-
-   RETURN VALUE:
-       true.............result would be separable
-          false............result would not be separable
-
-*******************************************************************************/
-
-bool
-typevectorset_separable_with(typevector *set,typevector *add,int size)
-{
-       int i;
-       typevector *v;
-       void *addr;
-       bool separable;
-
-       TYPEINFO_ASSERT(set);
-       TYPEINFO_ASSERT(add);
-
-       for (i=0; i<size; ++i) {
-               if (!TYPEDESC_IS_RETURNADDRESS(add->td[i]))
-                       continue;
-               addr = TYPEINFO_RETURNADDRESS(add->td[i].info);
-               
-               v = set;
-               separable = false;
-               do {
-                       if (!TYPEDESC_IS_RETURNADDRESS(v->td[i]))
-                               goto next_index;
-                       if (TYPEINFO_RETURNADDRESS(v->td[i].info) != addr)
-                               separable = true;
-                       v = v->alt;
-               } while (v);
-               if (separable) return true;
-       next_index:
-               ;
-       }
-       return false;
-}
-
-/* typevectorset_collapse ******************************************************
-   Collapse a typevector set into a single typevector by merging the
-   components of the typevectors at each index.
-   
-   IN:
-          dst..............the type vector set
-          size.............number of elements per typevector
-
-   OUT:
-       *dst.............the resulting typevector set (a single typevector)
-
-   RETURN VALUE:
-       typecheck_TRUE...dst has been modified
-          typecheck_FALSE..dst has not been modified
-          typecheck_FAIL...an exception has been thrown
-
-*******************************************************************************/
-
-typecheck_result
-typevectorset_collapse(methodinfo *m,typevector *dst,int size)
-{
-       bool changed = false;
-
-       TYPEINFO_ASSERT(dst);
-       
-       while (dst->alt) {
-               if (typevector_merge(m,dst,dst->alt,size) == typecheck_FAIL)
-                       return typecheck_FAIL;
-               dst->alt = dst->alt->alt;
-               changed = true;
-       }
-       return changed;
-}
-
 /**********************************************************************/
 /* READ-ONLY FUNCTIONS                                                */
 /* The following functions don't change typeinfo data.                */
@@ -715,7 +345,7 @@ typevectorset_collapse(methodinfo *m,typevector *dst,int size)
 *******************************************************************************/
 
 bool
-typeinfo_is_array(typeinfo *info)
+typeinfo_is_array(typeinfo_t *info)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY(*info);
@@ -734,7 +364,7 @@ typeinfo_is_array(typeinfo *info)
 *******************************************************************************/
 
 bool
-typeinfo_is_primitive_array(typeinfo *info,int arraytype)
+typeinfo_is_primitive_array(typeinfo_t *info,int arraytype)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
@@ -753,7 +383,7 @@ typeinfo_is_primitive_array(typeinfo *info,int arraytype)
 *******************************************************************************/
 
 bool
-typeinfo_is_array_of_refs(typeinfo *info)
+typeinfo_is_array_of_refs(typeinfo_t *info)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY_OF_REFS(*info);
@@ -782,17 +412,17 @@ interface_extends_interface(classinfo *cls,classinfo *interf)
        TYPEINFO_ASSERT(interf);
        TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
        TYPEINFO_ASSERT((cls->flags & ACC_INTERFACE) != 0);
-       TYPEINFO_ASSERT(cls->linked);
+       TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
 
     /* first check direct superinterfaces */
     for (i=0; i<cls->interfacescount; ++i) {
-        if (cls->interfaces[i].cls == interf)
+        if (cls->interfaces[i] == interf)
             return true;
     }
     
     /* check indirect superinterfaces */
     for (i=0; i<cls->interfacescount; ++i) {
-        if (interface_extends_interface(cls->interfaces[i].cls,interf))
+        if (interface_extends_interface(cls->interfaces[i],interf))
             return true;
     }
     
@@ -821,7 +451,7 @@ classinfo_implements_interface(classinfo *cls,classinfo *interf)
        TYPEINFO_ASSERT(interf);
        TYPEINFO_ASSERT((interf->flags & ACC_INTERFACE) != 0);
 
-       if (!cls->linked)
+       if (!(cls->state & CLASS_LINKED))
                if (!link_class(cls))
                        return typecheck_FAIL;
 
@@ -834,7 +464,7 @@ classinfo_implements_interface(classinfo *cls,classinfo *interf)
         return interface_extends_interface(cls,interf);
     }
 
-       TYPEINFO_ASSERT(cls->linked);
+       TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
     return CLASSINFO_IMPLEMENTS_INTERFACE(cls,interf->index);
 }
 
@@ -858,7 +488,7 @@ classinfo_implements_interface(classinfo *cls,classinfo *interf)
 *******************************************************************************/
 
 static typecheck_result
-mergedlist_implements_interface(typeinfo_mergedlist *merged,
+mergedlist_implements_interface(typeinfo_mergedlist_t *merged,
                                 classinfo *interf)
 {
     int i;
@@ -908,7 +538,7 @@ mergedlist_implements_interface(typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 static typecheck_result
-merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist_t *merged,
                             classinfo *interf)
 {
        typecheck_result r;
@@ -955,7 +585,7 @@ merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 static typecheck_result
-merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist_t *merged,
                classinfo *cls)
 {
     int i;
@@ -971,8 +601,8 @@ merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
     if (typeclass == pseudo_class_Null)
         return typecheck_TRUE;
 
-       TYPEINFO_ASSERT(typeclass->loaded);
-       TYPEINFO_ASSERT(typeclass->linked);
+       TYPEINFO_ASSERT(typeclass->state & CLASS_LOADED);
+       TYPEINFO_ASSERT(typeclass->state & CLASS_LINKED);
 
     /* check if the common typeclass is a subclass of CLS. */
        if (class_issubclass(typeclass,cls))
@@ -992,7 +622,7 @@ merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
                if (IS_CLASSREF(*mlist)) {
                        return typecheck_MAYBE;
                }
-               if (!mlist->cls->linked)
+               if (!(mlist->cls->state & CLASS_LINKED))
                        if (!link_class(mlist->cls))
                                return typecheck_FAIL;
                if (!class_issubclass(mlist->cls,cls))
@@ -1020,7 +650,7 @@ merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 typecheck_result
-typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
+typeinfo_is_assignable_to_class(typeinfo_t *value,classref_or_classinfo dest)
 {
        classref_or_classinfo c;
     classinfo *cls;
@@ -1089,20 +719,20 @@ typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
 
        cls = c.cls;
        
-       TYPEINFO_ASSERT(cls->loaded);
-       TYPEINFO_ASSERT(dest.cls->loaded);
+       TYPEINFO_ASSERT(cls->state & CLASS_LOADED);
+       TYPEINFO_ASSERT(dest.cls->state & CLASS_LOADED);
 
        /* maybe we need to link the classes */
-       if (!cls->linked)
+       if (!(cls->state & CLASS_LINKED))
                if (!link_class(cls))
                        return typecheck_FAIL;
-       if (!dest.cls->linked)
+       if (!(dest.cls->state & CLASS_LINKED))
                if (!link_class(dest.cls))
                        return typecheck_FAIL;
 
        /* { we know that both c and dest are linked classes } */
-       TYPEINFO_ASSERT(cls->linked);
-       TYPEINFO_ASSERT(dest.cls->linked);
+       TYPEINFO_ASSERT(cls->state & CLASS_LINKED);
+       TYPEINFO_ASSERT(dest.cls->state & CLASS_LINKED);
 
     if (dest.cls->flags & ACC_INTERFACE) {
         /* We are assigning to an interface type. */
@@ -1113,7 +743,7 @@ typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
                arraydescriptor *arraydesc = dest.cls->vftbl->arraydesc;
                int dimension = arraydesc->dimension;
                classinfo *elementclass = (arraydesc->elementvftbl)
-                       ? arraydesc->elementvftbl->class : NULL;
+                       ? arraydesc->elementvftbl->clazz : NULL;
                        
         /* We are assigning to an array type. */
         if (!TYPEINFO_IS_ARRAY(*value))
@@ -1206,7 +836,7 @@ typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
 *******************************************************************************/
 
 typecheck_result
-typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
+typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest)
 {
        TYPEINFO_ASSERT(value);
        TYPEINFO_ASSERT(dest);
@@ -1237,11 +867,11 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
 *******************************************************************************/
 
 void
-typeinfo_init_classinfo(typeinfo *info, classinfo *c)
+typeinfo_init_classinfo(typeinfo_t *info, classinfo *c)
 {
        if ((info->typeclass.cls = c)->vftbl->arraydesc) {
                if (c->vftbl->arraydesc->elementvftbl)
-                       info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->class;
+                       info->elementclass.cls = c->vftbl->arraydesc->elementvftbl->clazz;
                else
                        info->elementclass.any = NULL;
                info->dimension = c->vftbl->arraydesc->dimension;
@@ -1272,7 +902,7 @@ typeinfo_init_classinfo(typeinfo *info, classinfo *c)
 *******************************************************************************/
 
 bool
-typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
+typeinfo_init_class(typeinfo_t *info,classref_or_classinfo c)
 {
        char *utf_ptr;
        int len;
@@ -1282,7 +912,7 @@ typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
        TYPEINFO_ASSERT(info);
 
        /* if necessary, try to resolve lazily */
-       if (!resolve_classref_or_classinfo(NULL /* XXX should now method */,
+       if (!resolve_classref_or_classinfo(NULL /* XXX should know method */,
                                c,resolveLazy,false,true,&cls))
        {
                return false;
@@ -1343,7 +973,7 @@ typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
 *******************************************************************************/
 
 bool
-typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
+typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo_t *info)
 {
        TYPEINFO_ASSERT(desc);
 
@@ -1401,9 +1031,9 @@ typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
 *******************************************************************************/
 
 bool
-typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
+typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo_t *infobuf,
                               int buflen,bool twoword,
-                              u1 *returntype,typeinfo *returntypeinfo)
+                              u1 *returntype,typeinfo_t *returntypeinfo)
 {
        int i;
     int args = 0;
@@ -1421,16 +1051,16 @@ typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
     /* check arguments */
     for (i=0; i<desc->paramcount; ++i) {
                if (++args > buflen) {
-                       *exceptionptr = new_internalerror("Buffer too small for method arguments.");
+                       exceptions_throw_internalerror("Buffer too small for method arguments.");
                        return false;
                }
 
                if (!typeinfo_init_from_typedesc(desc->paramtypes + i,typebuf++,infobuf++))
                        return false;
                
-               if (twoword && (typebuf[-1] == TYPE_LONG || typebuf[-1] == TYPE_DOUBLE)) {
+               if (twoword && (typebuf[-1] == TYPE_LNG || typebuf[-1] == TYPE_DBL)) {
                        if (++args > buflen) {
-                               *exceptionptr = new_internalerror("Buffer too small for method arguments.");
+                               exceptions_throw_internalerror("Buffer too small for method arguments.");
                                return false;
                        }
 
@@ -1467,7 +1097,7 @@ typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
 *******************************************************************************/
 
 bool
-typedescriptor_init_from_typedesc(typedescriptor *td,
+typedescriptor_init_from_typedesc(typedescriptor_t *td,
                                                                  typedesc *desc)
 {
        TYPEINFO_ASSERT(td);
@@ -1475,15 +1105,131 @@ typedescriptor_init_from_typedesc(typedescriptor *td,
 
        td->type = desc->type;
        if (td->type == TYPE_ADR) {
-               if (!typeinfo_init_class(&(td->info),CLASSREF_OR_CLASSINFO(desc->classref)))
+               if (!typeinfo_init_class(&(td->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
                        return false;
        }
        else {
-               TYPEINFO_INIT_PRIMITIVE(td->info);
+               TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
        }
        return true;
 }
 
+/* typeinfo_init_varinfo_from_typedesc *****************************************
+   Initialize a varinfo from a typedesc.
+   
+   IN:
+          desc.............the typedesc
+
+   OUT:
+       *var.............receives the type
+                           var must be != NULL
+
+   RETURN VALUE:
+       true.............success
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+bool
+typeinfo_init_varinfo_from_typedesc(varinfo *var,
+                                                                 typedesc *desc)
+{
+       TYPEINFO_ASSERT(var);
+       TYPEINFO_ASSERT(desc);
+
+       var->type = desc->type;
+       if (var->type == TYPE_ADR) {
+               if (!typeinfo_init_class(&(var->typeinfo),CLASSREF_OR_CLASSINFO(desc->classref)))
+                       return false;
+       }
+       else {
+               TYPEINFO_INIT_PRIMITIVE(var->typeinfo);
+       }
+       return true;
+}
+
+/* typeinfo_init_varinfos_from_methoddesc **************************************
+   Initialize an array of varinfos from a methoddesc.
+   
+   IN:
+       desc.............the methoddesc
+       buflen...........number of parameters the buffer can hold
+          startindex.......the zero-based index of the first parameter to
+                           write to the array. In other words the number of
+                                               parameters to skip at the beginning of the methoddesc.
+          map..............map from parameter indices to varinfo indices
+                           (indexed like jitdata.local_map)
+
+   OUT:
+       *vars............array receiving the varinfos
+                           td[0] receives the type of the
+                                               (startindex+1)th parameter of the method
+       *returntype......receives the typedescriptor of the return type.
+                           returntype may be NULL
+
+   RETURN VALUE:
+       true.............everything ok
+          false............an exception has been thrown
+
+   NOTE:
+       If (according to BUFLEN) the buffer is to small to hold the
+          parameter types, an internal error is thrown. This must be
+          avoided by checking the number of parameters and allocating enough
+          space before calling this function.
+
+*******************************************************************************/
+
+bool
+typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
+                                                                        methoddesc *desc,
+                                                                        int buflen, int startindex,
+                                                                        s4 *map,
+                                                                        typedescriptor_t *returntype)
+{
+       s4 i;
+    s4 varindex;
+       s4 type;
+       s4 slot = 0;
+
+       /* skip arguments */
+       for (i=0; i<startindex; ++i) {
+               slot++;
+               if (IS_2_WORD_TYPE(desc->paramtypes[i].type))
+                       slot++;
+       }
+
+    /* check arguments */
+    for (i=startindex; i<desc->paramcount; ++i) {
+               type = desc->paramtypes[i].type;
+               varindex = map[5*slot + type];
+
+               slot++;
+               if (IS_2_WORD_TYPE(type))
+                       slot++;
+
+               if (varindex == UNUSED)
+                       continue;
+
+               if (varindex >= buflen) {
+                       exceptions_throw_internalerror("Buffer too small for method arguments.");
+                       return false;
+               }
+
+               if (!typeinfo_init_varinfo_from_typedesc(vars + varindex, desc->paramtypes + i))
+                       return false;
+    }
+
+    /* check returntype */
+    if (returntype) {
+               if (!typedescriptor_init_from_typedesc(returntype,&(desc->returntype)))
+                       return false;
+       }
+
+       return true;
+}
+
 /* typedescriptors_init_from_methoddesc ****************************************
  
    Initialize an array of typedescriptors from a methoddesc.
@@ -1516,10 +1262,10 @@ typedescriptor_init_from_typedesc(typedescriptor *td,
 *******************************************************************************/
 
 int
-typedescriptors_init_from_methoddesc(typedescriptor *td,
+typedescriptors_init_from_methoddesc(typedescriptor_t *td,
                                                                         methoddesc *desc,
                                                                         int buflen,bool twoword,int startindex,
-                                                                        typedescriptor *returntype)
+                                                                        typedescriptor_t *returntype)
 {
        int i;
     int args = 0;
@@ -1527,7 +1273,7 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
     /* check arguments */
     for (i=startindex; i<desc->paramcount; ++i) {
                if (++args > buflen) {
-                       *exceptionptr = new_internalerror("Buffer too small for method arguments.");
+                       exceptions_throw_internalerror("Buffer too small for method arguments.");
                        return -1;
                }
 
@@ -1535,14 +1281,14 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
                        return -1;
                td++;
 
-               if (twoword && (td[-1].type == TYPE_LONG || td[-1].type == TYPE_DOUBLE)) {
+               if (twoword && (td[-1].type == TYPE_LNG || td[-1].type == TYPE_DBL)) {
                        if (++args > buflen) {
-                               *exceptionptr = new_internalerror("Buffer too small for method arguments.");
+                               exceptions_throw_internalerror("Buffer too small for method arguments.");
                                return -1;
                        }
 
                        td->type = TYPE_VOID;
-                       TYPEINFO_INIT_PRIMITIVE(td->info);
+                       TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
                        td++;
                }
     }
@@ -1573,8 +1319,10 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
 *******************************************************************************/
 
 bool
-typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
+typeinfo_init_component(typeinfo_t *srcarray,typeinfo_t *dst)
 {
+       typeinfo_mergedlist_t *merged;
+
        TYPEINFO_ASSERT(srcarray);
        TYPEINFO_ASSERT(dst);
 
@@ -1585,10 +1333,14 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
     
     if (!TYPEINFO_IS_ARRAY(*srcarray)) {
                /* XXX should we make that a verify error? */
-               *exceptionptr = new_internalerror("Trying to access component of non-array");
+               exceptions_throw_internalerror("Trying to access component of non-array");
                return false;
        }
 
+       /* save the mergedlist (maybe dst == srcarray) */
+
+       merged = srcarray->merged;
+
        if (IS_CLASSREF(srcarray->typeclass)) {
                constant_classref *comp;
                comp = class_get_classref_component_of(srcarray->typeclass.ref);
@@ -1604,7 +1356,7 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
        else {
                vftbl_t *comp;
                
-               if (!srcarray->typeclass.cls->linked) {
+               if (!(srcarray->typeclass.cls->state & CLASS_LINKED)) {
                        if (!link_class(srcarray->typeclass.cls)) {
                                return false;
                        }
@@ -1615,12 +1367,12 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 
                comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
                if (comp)
-                       typeinfo_init_classinfo(dst,comp->class);
+                       typeinfo_init_classinfo(dst,comp->clazz);
                else
                        TYPEINFO_INIT_PRIMITIVE(*dst);
        }
     
-    dst->merged = srcarray->merged; /* XXX should we do a deep copy? */
+    dst->merged = merged; /* XXX should we do a deep copy? */
        return true;
 }
 
@@ -1640,7 +1392,7 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 *******************************************************************************/
 
 void
-typeinfo_clone(typeinfo *src,typeinfo *dest)
+typeinfo_clone(typeinfo_t *src,typeinfo_t *dest)
 {
     int count;
     classref_or_classinfo *srclist,*destlist;
@@ -1677,7 +1429,7 @@ typeinfo_clone(typeinfo *src,typeinfo *dest)
 *******************************************************************************/
 
 void
-typeinfo_free(typeinfo *info)
+typeinfo_free(typeinfo_t *info)
 {
     TYPEINFO_FREEMERGED_IF_ANY(info->merged);
     info->merged = NULL;
@@ -1691,24 +1443,24 @@ typeinfo_free(typeinfo *info)
 
 static
 void
-typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
+typeinfo_merge_error(methodinfo *m,char *str,typeinfo_t *x,typeinfo_t *y) {
 #ifdef TYPEINFO_VERBOSE
     fprintf(stderr,"Error in typeinfo_merge: %s\n",str);
     fprintf(stderr,"Typeinfo x:\n");
     typeinfo_print(stderr,x,1);
     fprintf(stderr,"Typeinfo y:\n");
     typeinfo_print(stderr,y,1);
+    log_text(str);
 #endif
 
-    log_text(str);
-       *exceptionptr = new_verifyerror(m,str);
+       exceptions_throw_verifyerror(m, str);
 }
 
 /* Condition: clsx != clsy. */
 /* Returns: true if dest was changed (currently always true). */
 static
 bool
-typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
+typeinfo_merge_two(typeinfo_t *dest,classref_or_classinfo clsx,classref_or_classinfo clsy)
 {
        TYPEINFO_ASSERT(dest);
     TYPEINFO_FREEMERGED_IF_ANY(dest->merged);
@@ -1732,10 +1484,10 @@ typeinfo_merge_two(typeinfo *dest,classref_or_classinfo clsx,classref_or_classin
 /* Returns: true if dest was changed. */
 static
 bool
-typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo cls)
+typeinfo_merge_add(typeinfo_t *dest,typeinfo_mergedlist_t *m,classref_or_classinfo cls)
 {
     int count;
-    typeinfo_mergedlist *newmerged;
+    typeinfo_mergedlist_t *newmerged;
     classref_or_classinfo *mlist,*newlist;
 
     count = m->count;
@@ -1789,12 +1541,12 @@ typeinfo_merge_add(typeinfo *dest,typeinfo_mergedlist *m,classref_or_classinfo c
 /* Returns: true if dest was changed. */
 static
 bool
-typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
-                           typeinfo_mergedlist *y)
+typeinfo_merge_mergedlists(typeinfo_t *dest,typeinfo_mergedlist_t *x,
+                           typeinfo_mergedlist_t *y)
 {
     int count = 0;
     int countx,county;
-    typeinfo_mergedlist *temp,*result;
+    typeinfo_mergedlist_t *temp,*result;
     classref_or_classinfo *clsx,*clsy,*newlist;
 
     /* count the elements that will be in the resulting list */
@@ -1913,15 +1665,15 @@ typeinfo_merge_mergedlists(typeinfo *dest,typeinfo_mergedlist *x,
 *******************************************************************************/
 
 static typecheck_result
-typeinfo_merge_nonarrays(typeinfo *dest,
+typeinfo_merge_nonarrays(typeinfo_t *dest,
                          classref_or_classinfo *result,
                          classref_or_classinfo x,classref_or_classinfo y,
-                         typeinfo_mergedlist *mergedx,
-                         typeinfo_mergedlist *mergedy)
+                         typeinfo_mergedlist_t *mergedx,
+                         typeinfo_mergedlist_t *mergedy)
 {
        classref_or_classinfo t;
     classinfo *tcls,*common;
-    typeinfo_mergedlist *tmerged;
+    typeinfo_mergedlist_t *tmerged;
     bool changed;
        typecheck_result r;
        utf *xname;
@@ -1970,10 +1722,10 @@ typeinfo_merge_nonarrays(typeinfo *dest,
 
 #ifdef TYPEINFO_VERBOSE
        {
-               typeinfo dbgx,dbgy;
+               typeinfo_t dbgx,dbgy;
                fprintf(stderr,"merge_nonarrays:\n");
-               fprintf(stderr,"    ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint(stderr,xname);fprintf(stderr,"\n");
-               fprintf(stderr,"    ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint(stderr,yname);fprintf(stderr,"\n");
+               fprintf(stderr,"    ");if(IS_CLASSREF(x))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,xname);fprintf(stderr,"\n");
+               fprintf(stderr,"    ");if(IS_CLASSREF(y))fprintf(stderr,"<ref>");utf_fprint_printable_ascii(stderr,yname);fprintf(stderr,"\n");
                fflush(stderr);
                typeinfo_init_class(&dbgx,x);
                dbgx.merged = mergedx;
@@ -1985,8 +1737,8 @@ typeinfo_merge_nonarrays(typeinfo *dest,
        }
 #endif
 
-       TYPEINFO_ASSERT(IS_CLASSREF(x) || x.cls->loaded);
-       TYPEINFO_ASSERT(IS_CLASSREF(y) || y.cls->loaded);
+       TYPEINFO_ASSERT(IS_CLASSREF(x) || (x.cls->state & CLASS_LOADED));
+       TYPEINFO_ASSERT(IS_CLASSREF(y) || (y.cls->state & CLASS_LOADED));
 
     /* If y is unresolved or an interface, swap x and y. */
     if (IS_CLASSREF(y) || (!IS_CLASSREF(x) && y.cls->flags & ACC_INTERFACE))
@@ -2015,8 +1767,8 @@ typeinfo_merge_nonarrays(typeinfo *dest,
     /* {We know: If only one of x,y is an interface it is x.} */
 
        TYPEINFO_ASSERT(!IS_CLASSREF(x) && !IS_CLASSREF(y));
-       TYPEINFO_ASSERT(x.cls->loaded);
-       TYPEINFO_ASSERT(y.cls->loaded);
+       TYPEINFO_ASSERT(x.cls->state & CLASS_LOADED);
+       TYPEINFO_ASSERT(y.cls->state & CLASS_LOADED);
 
     /* Handle merging of interfaces: */
     if (x.cls->flags & ACC_INTERFACE) {
@@ -2044,15 +1796,15 @@ typeinfo_merge_nonarrays(typeinfo *dest,
          */
 
                /* we may have to link the classes */
-               if (!x.cls->linked)
+               if (!(x.cls->state & CLASS_LINKED))
                        if (!link_class(x.cls))
                                return typecheck_FAIL;
-               if (!y.cls->linked)
+               if (!(y.cls->state & CLASS_LINKED))
                        if (!link_class(y.cls))
                                return typecheck_FAIL;
         
-               TYPEINFO_ASSERT(x.cls->linked);
-               TYPEINFO_ASSERT(y.cls->linked);
+               TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
+               TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
 
         if (CLASSINFO_IMPLEMENTS_INTERFACE(y.cls,x.cls->index))
                {
@@ -2079,15 +1831,15 @@ typeinfo_merge_nonarrays(typeinfo *dest,
     /* {We know: x and y are classes (not interfaces).} */
     
        /* we may have to link the classes */
-       if (!x.cls->linked)
+       if (!(x.cls->state & CLASS_LINKED))
                if (!link_class(x.cls))
                        return typecheck_FAIL;
-       if (!y.cls->linked)
+       if (!(y.cls->state & CLASS_LINKED))
                if (!link_class(y.cls))
                        return typecheck_FAIL;
         
-       TYPEINFO_ASSERT(x.cls->linked);
-       TYPEINFO_ASSERT(y.cls->linked);
+       TYPEINFO_ASSERT(x.cls->state & CLASS_LINKED);
+       TYPEINFO_ASSERT(y.cls->state & CLASS_LINKED);
 
     /* If *x is deeper in the inheritance hierarchy swap x and y. */
     if (x.cls->index > y.cls->index) {
@@ -2098,13 +1850,16 @@ typeinfo_merge_nonarrays(typeinfo *dest,
     /* {We know: y is at least as deep in the hierarchy as x.} */
 
     /* Find nearest common anchestor for the classes. */
+
     common = x.cls;
-    tcls = y.cls;
+    tcls   = y.cls;
+
     while (tcls->index > common->index)
-        tcls = tcls->super.cls;
+        tcls = tcls->super;
+
     while (common != tcls) {
-        common = common->super.cls;
-        tcls = tcls->super.cls;
+        common = common->super;
+        tcls = tcls->super;
     }
 
     /* {common == nearest common anchestor of x and y.} */
@@ -2156,10 +1911,10 @@ merge_with_simple_x:
 *******************************************************************************/
 
 typecheck_result
-typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y)
+typeinfo_merge(methodinfo *m,typeinfo_t *dest,typeinfo_t* y)
 {
-    typeinfo *x;
-    typeinfo *tmp;
+    typeinfo_t *x;
+    typeinfo_t *tmp;
     classref_or_classinfo common;
     classref_or_classinfo elementclass;
     int dimension;
@@ -2297,7 +2052,7 @@ return_simple:
             else {
                 common.cls = class_multiarray_of(dimension,pseudo_class_Arraystub,true);
                                if (!common.cls) {
-                                       *exceptionptr = new_internalerror("XXX Coult not create array class");
+                                       exceptions_throw_internalerror("XXX Coult not create array class");
                                        return typecheck_FAIL;
                                }
 
@@ -2328,11 +2083,11 @@ return_simple:
                                else {
                                        common.cls = class_multiarray_of(dimension,elementclass.cls,true);
                                        if (!common.cls) {
-                                               *exceptionptr = new_internalerror("XXX Coult not create array class");
+                                               exceptions_throw_internalerror("XXX Coult not create array class");
                                                return typecheck_FAIL;
                                        }
                                }
-                /* DEBUG */ /* utf_display(common->name); printf("\n"); */
+                /* DEBUG */ /* utf_display_printable_ascii(common->name); printf("\n"); */
             }
                        else {
                                common.any = y->typeclass.any;
@@ -2378,6 +2133,7 @@ return_simple:
 
     return changed;
 }
+#endif /* ENABLE_VERIFER */
 
 
 /**********************************************************************/
@@ -2396,11 +2152,11 @@ typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
 }
 
 static void
-typeinfo_test_parse(typeinfo *info,char *str)
+typeinfo_test_parse(typeinfo_t *info,char *str)
 {
     int num;
     int i;
-    typeinfo *infobuf;
+    typeinfo_t *infobuf;
     u1 *typebuf;
     int returntype;
     utf *desc = utf_new_char(str);
@@ -2408,7 +2164,7 @@ typeinfo_test_parse(typeinfo *info,char *str)
     num = typeinfo_count_method_args(desc,false);
     if (num) {
         typebuf = DMNEW(u1,num);
-        infobuf = DMNEW(typeinfo,num);
+        infobuf = DMNEW(typeinfo_t,num);
         
         typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
                                        &returntype,info);
@@ -2417,7 +2173,7 @@ typeinfo_test_parse(typeinfo *info,char *str)
         info->merged->count = num;
 
         for (i=0; i<num; ++i) {
-            if (typebuf[i] != TYPE_ADDRESS) {
+            if (typebuf[i] != TYPE_ADR) {
                 log_text("non-reference type in mergedlist");
                                assert(0);
                        }
@@ -2437,7 +2193,7 @@ typeinfo_test_parse(typeinfo *info,char *str)
 #define TYPEINFO_TEST_BUFLEN  4000
 
 static bool
-typeinfo_equal(typeinfo *x,typeinfo *y)
+typeinfo_equal(typeinfo_t *x,typeinfo_t *y)
 {
     int i;
     
@@ -2464,9 +2220,9 @@ typeinfo_equal(typeinfo *x,typeinfo *y)
 }
 
 static void
-typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
+typeinfo_testmerge(typeinfo_t *a,typeinfo_t *b,typeinfo_t *result,int *failed)
 {
-    typeinfo dest;
+    typeinfo_t dest;
     bool changed,changed_should_be;
        typecheck_result r;
 
@@ -2510,7 +2266,7 @@ typeinfo_testmerge(typeinfo *a,typeinfo *b,typeinfo *result,int *failed)
 
 #if 0
 static void
-typeinfo_inc_dimension(typeinfo *info)
+typeinfo_inc_dimension(typeinfo_t *info)
 {
     if (info->dimension++ == 0) {
         info->elementtype = ARRAYTYPE_OBJECT;
@@ -2529,7 +2285,7 @@ typeinfo_testrun(char *filename)
     char bufa[TYPEINFO_TEST_BUFLEN];
     char bufb[TYPEINFO_TEST_BUFLEN];
     char bufc[TYPEINFO_TEST_BUFLEN];
-    typeinfo a,b,c;
+    typeinfo_t a,b,c;
     int maxdim;
     int failed = 0;
     FILE *file = fopen(filename,"rt");
@@ -2598,7 +2354,7 @@ typeinfo_test()
 
 #if 0
 void
-typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc)
+typeinfo_init_from_fielddescriptor(typeinfo_t *info,char *desc)
 {
     typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
 }
@@ -2617,16 +2373,16 @@ typeinfo_print_class(FILE *file,classref_or_classinfo c)
        else {
                if (IS_CLASSREF(c)) {
                        fprintf(file,"<ref>");
-                       utf_fprint(file,c.ref->name);
+                       utf_fprint_printable_ascii(file,c.ref->name);
                }
                else {
-                       utf_fprint(file,c.cls->name);
+                       utf_fprint_printable_ascii(file,c.cls->name);
                }
        }
 }
 
 void
-typeinfo_print(FILE *file,typeinfo *info,int indent)
+typeinfo_print(FILE *file,typeinfo_t *info,int indent)
 {
     int i;
     char ind[TYPEINFO_MAXINDENT + 1];
@@ -2642,7 +2398,7 @@ typeinfo_print(FILE *file,typeinfo *info,int indent)
     if (TYPEINFO_IS_PRIMITIVE(*info)) {
                bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
                if (bptr)
-                       fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->debug_nr);
+                       fprintf(file,"%sreturnAddress (L%03d)\n",ind,bptr->nr);
                else
                        fprintf(file,"%sprimitive\n",ind);
         return;
@@ -2654,10 +2410,10 @@ typeinfo_print(FILE *file,typeinfo *info,int indent)
     }
 
     if (TYPEINFO_IS_NEWOBJECT(*info)) {
-        ins = (instruction *)TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
+        ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
         if (ins) {
             fprintf(file,"%sNEW(%p):",ind,(void*)ins);
-                       typeinfo_print_class(file,CLASSREF_OR_CLASSINFO(ins[-1].target));
+                       typeinfo_print_class(file,ins[-1].sx.val.c);
             fprintf(file,"\n");
         }
         else {
@@ -2704,7 +2460,7 @@ typeinfo_print(FILE *file,typeinfo *info,int indent)
 }
 
 void
-typeinfo_print_short(FILE *file,typeinfo *info)
+typeinfo_print_short(FILE *file,typeinfo_t *info)
 {
     int i;
     instruction *ins;
@@ -2720,7 +2476,7 @@ typeinfo_print_short(FILE *file,typeinfo *info)
     if (TYPEINFO_IS_PRIMITIVE(*info)) {
                bptr = (basicblock*) TYPEINFO_RETURNADDRESS(*info);
                if (bptr)
-                       fprintf(file,"ret(L%03d)",bptr->debug_nr);
+                       fprintf(file,"ret(L%03d)",bptr->nr);
                else
                        fprintf(file,"primitive");
         return;
@@ -2732,11 +2488,11 @@ typeinfo_print_short(FILE *file,typeinfo *info)
     }
     
     if (TYPEINFO_IS_NEWOBJECT(*info)) {
-        ins = (instruction *)TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
+        ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
         if (ins) {
                        /*fprintf(file,"<ins %p>",ins);*/
             fprintf(file,"NEW(%p):",(void*)ins);
-                       typeinfo_print_class(file,CLASSREF_OR_CLASSINFO(ins[-1].target));
+                       typeinfo_print_class(file,ins[-1].sx.val.c);
         }
         else
             fprintf(file,"NEW(this)");
@@ -2756,15 +2512,16 @@ typeinfo_print_short(FILE *file,typeinfo *info)
 }
 
 void
-typeinfo_print_type(FILE *file,int type,typeinfo *info)
+typeinfo_print_type(FILE *file,int type,typeinfo_t *info)
 {
     switch (type) {
-      case TYPE_VOID:   fprintf(file,"V"); break;
-      case TYPE_INT:    fprintf(file,"I"); break;
-      case TYPE_FLOAT:  fprintf(file,"F"); break;
-      case TYPE_DOUBLE: fprintf(file,"D"); break;
-      case TYPE_LONG:   fprintf(file,"J"); break;
-      case TYPE_ADDRESS:
+      case TYPE_VOID: fprintf(file,"V"); break;
+      case TYPE_INT:  fprintf(file,"I"); break;
+      case TYPE_FLT:  fprintf(file,"F"); break;
+      case TYPE_DBL:  fprintf(file,"D"); break;
+      case TYPE_LNG:  fprintf(file,"J"); break;
+         case TYPE_RET:  fprintf(file,"R:"); /* FALLTHROUGH! */
+      case TYPE_ADR:
                  typeinfo_print_short(file,info);
           break;
           
@@ -2774,71 +2531,19 @@ typeinfo_print_type(FILE *file,int type,typeinfo *info)
 }
 
 void
-typeinfo_print_stacktype(FILE *file,int type,typeinfo *info)
-{
-       TYPEINFO_ASSERT(file);
-       TYPEINFO_ASSERT(type != TYPE_ADDRESS || info != NULL);
-       if (type == TYPE_ADDRESS && TYPEINFO_IS_PRIMITIVE(*info)) {     
-               typeinfo_retaddr_set *set = (typeinfo_retaddr_set*)
-                       TYPEINFO_RETURNADDRESS(*info);
-               if (set) {
-                       fprintf(file,"ret(L%03d",((basicblock*)(set->addr))->debug_nr);
-                       set = set->alt;
-                       while (set) {
-                               fprintf(file,"|L%03d",((basicblock*)(set->addr))->debug_nr);
-                               set = set->alt;
-                       }
-               }
-               else {
-                       fprintf(file,"ret(<NULL>");
-               }
-               fprintf(file,")");
-       }
-       else
-               typeinfo_print_type(file,type,info);
-}
-
-void
-typedescriptor_print(FILE *file,typedescriptor *td)
-{
-       typeinfo_print_type(file,td->type,&(td->info));
-}
-
-void
-typevector_print(FILE *file,typevector *vec,int size)
+typedescriptor_print(FILE *file,typedescriptor_t *td)
 {
-    int i;
-
-       fprintf(file,"[%d]",vec->k);
-    for (i=0; i<size; ++i) {
-               fprintf(file," %d=",i);
-        typedescriptor_print(file,vec->td + i);
-    }
+       typeinfo_print_type(file,td->type,&(td->typeinfo));
 }
 
 void
-typevectorset_print(FILE *file,typevector *set,int size)
+typevector_print(FILE *file,varinfo *vec,int size)
 {
     int i;
-       typevector *vec;
 
-       fprintf(file,"[%d",set->k);
-       vec = set->alt;
-       while (vec) {
-               fprintf(file,"|%d",vec->k);
-               vec = vec->alt;
-       }
-       fprintf(file,"]");
-       
     for (i=0; i<size; ++i) {
                fprintf(file," %d=",i);
-        typedescriptor_print(file,set->td + i);
-               vec = set->alt;
-               while (vec) {
-                       fprintf(file,"|");
-                       typedescriptor_print(file,vec->td + i);
-                       vec = vec->alt;
-               }
+        typeinfo_print_type(file, vec[i].type, &(vec[i].typeinfo));
     }
 }