* src/vm/builtin.c: Moved to .cpp.
[cacao.git] / src / vm / jit / verify / typeinfo.c
index c61cb45ec5b28a0640859d281612f4e73b23a7fb..78407dbbd863b28ac0c1d4c72d1bbb0084a17a73 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
 
 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
 
-   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.
 
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
+*/
 
 
-   $Id: typeinfo.c 5309 2006-09-05 11:20:04Z edwin $
 
 
-*/
+#include "config.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include "mm/memory.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include "mm/memory.h"
+
 #include "toolbox/logging.h"
 #include "toolbox/logging.h"
+
+#include "vm/array.h"
 #include "vm/class.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/descriptor.h"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.h"
+#include "vm/primitive.hpp"
 #include "vm/resolve.h"
 #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! */
 
 
 /* check if a linked class is an array class. Only use for linked classes! */
 #endif
 
 /**********************************************************************/
 #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
   
    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
 
           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));
        
        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;
 }
 
        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:
    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
           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));
 {
        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
   
    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:
           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
           false otherwise
 
 *******************************************************************************/
 
 bool
-typevectorset_checktype(typevector *vec,int index,int type)
+typevector_checktype(varinfo *vec,int index,int type)
 {
        TYPEINFO_ASSERT(vec);
 {
        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:
   
    IN:
-          vec..............typevector set, must be != NULL
+          vec..............typevector, must be != NULL
           index............index of component to check
 
    RETURN VALUE:
           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
           false otherwise
 
 *******************************************************************************/
 
 bool
-typevectorset_checkreference(typevector *vec,int index)
+typevector_checkreference(varinfo *vec, int index)
 {
        TYPEINFO_ASSERT(vec);
 {
        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 **************************************************
  
 }
 
 /* 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:
   
    IN:
-          vec..............typevector set, must be != NULL
+          vec..............typevector, must be != NULL
           index............index of component to check
 
    RETURN VALUE:
           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
           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(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_ADR) {
-                               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
   
    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
 
           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
 *******************************************************************************/
 
 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(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
   
    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
 
 *******************************************************************************/
 
 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));
        
        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_ADR;
-               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_LNG, TYPE_DBL)
-
-   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_LNG || type == TYPE_DBL);
-
-       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.
  
    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
 *******************************************************************************/
 
 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;
 
 {
        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;
                }
        }
        return true;
@@ -468,24 +282,24 @@ typevectorset_init_object(typevector *set,void *ins,
 *******************************************************************************/
 
 typecheck_result
 *******************************************************************************/
 
 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;
        
 {
        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_ADR) {
        while (size--) {
                if (a->type != TYPE_VOID && a->type != b->type) {
                        a->type = TYPE_VOID;
                        changed = true;
                }
                else if (a->type == TYPE_ADR) {
-                       if (TYPEINFO_IS_PRIMITIVE(a->info)) {
+                       if (TYPEINFO_IS_PRIMITIVE(a->typeinfo)) {
                                /* 'a' is a returnAddress */
                                /* '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;
                                {
                                        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 */
                        }
                        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.  */
                                        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;
                                        if (r == typecheck_FAIL)
                                                return r;
                                        changed |= r;
@@ -513,190 +327,6 @@ typevector_merge(methodinfo *m,typevector *dst,typevector *y,int size)
        return changed;
 }
 
        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.                */
 /**********************************************************************/
 /* READ-ONLY FUNCTIONS                                                */
 /* The following functions don't change typeinfo data.                */
@@ -715,7 +345,7 @@ typevectorset_collapse(methodinfo *m,typevector *dst,int size)
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 bool
-typeinfo_is_array(typeinfo *info)
+typeinfo_is_array(typeinfo_t *info)
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY(*info);
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY(*info);
@@ -734,7 +364,7 @@ typeinfo_is_array(typeinfo *info)
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 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);
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_PRIMITIVE_ARRAY(*info,arraytype);
@@ -753,7 +383,7 @@ typeinfo_is_primitive_array(typeinfo *info,int arraytype)
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 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);
 {
        TYPEINFO_ASSERT(info);
     return TYPEINFO_IS_ARRAY_OF_REFS(*info);
@@ -786,13 +416,13 @@ interface_extends_interface(classinfo *cls,classinfo *interf)
 
     /* first check direct superinterfaces */
     for (i=0; i<cls->interfacescount; ++i) {
 
     /* 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) {
             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;
     }
     
             return true;
     }
     
@@ -858,7 +488,7 @@ classinfo_implements_interface(classinfo *cls,classinfo *interf)
 *******************************************************************************/
 
 static typecheck_result
 *******************************************************************************/
 
 static typecheck_result
-mergedlist_implements_interface(typeinfo_mergedlist *merged,
+mergedlist_implements_interface(typeinfo_mergedlist_t *merged,
                                 classinfo *interf)
 {
     int i;
                                 classinfo *interf)
 {
     int i;
@@ -908,7 +538,7 @@ mergedlist_implements_interface(typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 static typecheck_result
 *******************************************************************************/
 
 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;
                             classinfo *interf)
 {
        typecheck_result r;
@@ -955,7 +585,7 @@ merged_implements_interface(classinfo *typeclass,typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 static typecheck_result
 *******************************************************************************/
 
 static typecheck_result
-merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
+merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist_t *merged,
                classinfo *cls)
 {
     int i;
                classinfo *cls)
 {
     int i;
@@ -1020,7 +650,7 @@ merged_is_subclass(classinfo *typeclass,typeinfo_mergedlist *merged,
 *******************************************************************************/
 
 typecheck_result
 *******************************************************************************/
 
 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;
 {
        classref_or_classinfo c;
     classinfo *cls;
@@ -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)
                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))
                        
         /* 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
 *******************************************************************************/
 
 typecheck_result
-typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
+typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest)
 {
        TYPEINFO_ASSERT(value);
        TYPEINFO_ASSERT(dest);
 {
        TYPEINFO_ASSERT(value);
        TYPEINFO_ASSERT(dest);
@@ -1237,11 +867,11 @@ typeinfo_is_assignable(typeinfo *value,typeinfo *dest)
 *******************************************************************************/
 
 void
 *******************************************************************************/
 
 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)
 {
        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;
                else
                        info->elementclass.any = NULL;
                info->dimension = c->vftbl->arraydesc->dimension;
@@ -1272,7 +902,7 @@ typeinfo_init_classinfo(typeinfo *info, classinfo *c)
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 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;
 {
        char *utf_ptr;
        int len;
@@ -1343,7 +973,7 @@ typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 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);
 
 {
        TYPEINFO_ASSERT(desc);
 
@@ -1401,9 +1031,9 @@ typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info)
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 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,
                               int buflen,bool twoword,
-                              u1 *returntype,typeinfo *returntypeinfo)
+                              u1 *returntype,typeinfo_t *returntypeinfo)
 {
        int i;
     int args = 0;
 {
        int i;
     int args = 0;
@@ -1421,7 +1051,7 @@ typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
     /* check arguments */
     for (i=0; i<desc->paramcount; ++i) {
                if (++args > buflen) {
     /* 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;
                }
 
                        return false;
                }
 
@@ -1430,7 +1060,7 @@ typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
                
                if (twoword && (typebuf[-1] == TYPE_LNG || typebuf[-1] == TYPE_DBL)) {
                        if (++args > buflen) {
                
                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;
                        }
 
                                return false;
                        }
 
@@ -1467,7 +1097,7 @@ typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,typeinfo *infobuf,
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 bool
-typedescriptor_init_from_typedesc(typedescriptor *td,
+typedescriptor_init_from_typedesc(typedescriptor_t *td,
                                                                  typedesc *desc)
 {
        TYPEINFO_ASSERT(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) {
 
        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 {
                        return false;
        }
        else {
-               TYPEINFO_INIT_PRIMITIVE(td->info);
+               TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
        }
        return true;
 }
 
        }
        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.
 /* typedescriptors_init_from_methoddesc ****************************************
  
    Initialize an array of typedescriptors from a methoddesc.
@@ -1516,10 +1262,10 @@ typedescriptor_init_from_typedesc(typedescriptor *td,
 *******************************************************************************/
 
 int
 *******************************************************************************/
 
 int
-typedescriptors_init_from_methoddesc(typedescriptor *td,
+typedescriptors_init_from_methoddesc(typedescriptor_t *td,
                                                                         methoddesc *desc,
                                                                         int buflen,bool twoword,int startindex,
                                                                         methoddesc *desc,
                                                                         int buflen,bool twoword,int startindex,
-                                                                        typedescriptor *returntype)
+                                                                        typedescriptor_t *returntype)
 {
        int i;
     int args = 0;
 {
        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) {
     /* 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;
                }
 
                        return -1;
                }
 
@@ -1537,12 +1283,12 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
 
                if (twoword && (td[-1].type == TYPE_LNG || td[-1].type == TYPE_DBL)) {
                        if (++args > buflen) {
 
                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;
                                return -1;
                        }
 
                        td->type = TYPE_VOID;
-                       TYPEINFO_INIT_PRIMITIVE(td->info);
+                       TYPEINFO_INIT_PRIMITIVE(td->typeinfo);
                        td++;
                }
     }
                        td++;
                }
     }
@@ -1573,8 +1319,10 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
 *******************************************************************************/
 
 bool
 *******************************************************************************/
 
 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);
 
        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? */
     
     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;
        }
 
                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);
        if (IS_CLASSREF(srcarray->typeclass)) {
                constant_classref *comp;
                comp = class_get_classref_component_of(srcarray->typeclass.ref);
@@ -1615,12 +1367,12 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 
                comp = srcarray->typeclass.cls->vftbl->arraydesc->componentvftbl;
                if (comp)
 
                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);
        }
     
                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;
 }
 
        return true;
 }
 
@@ -1640,7 +1392,7 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 *******************************************************************************/
 
 void
 *******************************************************************************/
 
 void
-typeinfo_clone(typeinfo *src,typeinfo *dest)
+typeinfo_clone(typeinfo_t *src,typeinfo_t *dest)
 {
     int count;
     classref_or_classinfo *srclist,*destlist;
 {
     int count;
     classref_or_classinfo *srclist,*destlist;
@@ -1677,7 +1429,7 @@ typeinfo_clone(typeinfo *src,typeinfo *dest)
 *******************************************************************************/
 
 void
 *******************************************************************************/
 
 void
-typeinfo_free(typeinfo *info)
+typeinfo_free(typeinfo_t *info)
 {
     TYPEINFO_FREEMERGED_IF_ANY(info->merged);
     info->merged = NULL;
 {
     TYPEINFO_FREEMERGED_IF_ANY(info->merged);
     info->merged = NULL;
@@ -1691,16 +1443,16 @@ typeinfo_free(typeinfo *info)
 
 static
 void
 
 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);
 #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
 
 #endif
 
-    log_text(str);
        exceptions_throw_verifyerror(m, str);
 }
 
        exceptions_throw_verifyerror(m, str);
 }
 
@@ -1708,7 +1460,7 @@ typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
 /* Returns: true if dest was changed (currently always true). */
 static
 bool
 /* 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);
 {
        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
 /* 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;
 {
     int count;
-    typeinfo_mergedlist *newmerged;
+    typeinfo_mergedlist_t *newmerged;
     classref_or_classinfo *mlist,*newlist;
 
     count = m->count;
     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
 /* 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;
 {
     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 */
     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
 *******************************************************************************/
 
 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,
                          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;
 {
        classref_or_classinfo t;
     classinfo *tcls,*common;
-    typeinfo_mergedlist *tmerged;
+    typeinfo_mergedlist_t *tmerged;
     bool changed;
        typecheck_result r;
        utf *xname;
     bool changed;
        typecheck_result r;
        utf *xname;
@@ -1970,7 +1722,7 @@ typeinfo_merge_nonarrays(typeinfo *dest,
 
 #ifdef TYPEINFO_VERBOSE
        {
 
 #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_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");
                fprintf(stderr,"merge_nonarrays:\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");
@@ -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. */
     /* {We know: y is at least as deep in the hierarchy as x.} */
 
     /* Find nearest common anchestor for the classes. */
+
     common = x.cls;
     common = x.cls;
-    tcls = y.cls;
+    tcls   = y.cls;
+
     while (tcls->index > common->index)
     while (tcls->index > common->index)
-        tcls = tcls->super.cls;
+        tcls = tcls->super;
+
     while (common != tcls) {
     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.} */
     }
 
     /* {common == nearest common anchestor of x and y.} */
@@ -2156,10 +1911,10 @@ merge_with_simple_x:
 *******************************************************************************/
 
 typecheck_result
 *******************************************************************************/
 
 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;
     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) {
             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;
                                }
 
                                        return typecheck_FAIL;
                                }
 
@@ -2328,7 +2083,7 @@ return_simple:
                                else {
                                        common.cls = class_multiarray_of(dimension,elementclass.cls,true);
                                        if (!common.cls) {
                                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;
                                        }
                                }
                                                return typecheck_FAIL;
                                        }
                                }
@@ -2378,6 +2133,7 @@ return_simple:
 
     return changed;
 }
 
     return changed;
 }
+#endif /* ENABLE_VERIFER */
 
 
 /**********************************************************************/
 
 
 /**********************************************************************/
@@ -2396,11 +2152,11 @@ typeinfo_test_compare(classref_or_classinfo *a,classref_or_classinfo *b)
 }
 
 static void
 }
 
 static void
-typeinfo_test_parse(typeinfo *info,char *str)
+typeinfo_test_parse(typeinfo_t *info,char *str)
 {
     int num;
     int i;
 {
     int num;
     int i;
-    typeinfo *infobuf;
+    typeinfo_t *infobuf;
     u1 *typebuf;
     int returntype;
     utf *desc = utf_new_char(str);
     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);
     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);
         
         typeinfo_init_from_method_args(desc,typebuf,infobuf,num,false,
                                        &returntype,info);
@@ -2437,7 +2193,7 @@ typeinfo_test_parse(typeinfo *info,char *str)
 #define TYPEINFO_TEST_BUFLEN  4000
 
 static bool
 #define TYPEINFO_TEST_BUFLEN  4000
 
 static bool
-typeinfo_equal(typeinfo *x,typeinfo *y)
+typeinfo_equal(typeinfo_t *x,typeinfo_t *y)
 {
     int i;
     
 {
     int i;
     
@@ -2464,9 +2220,9 @@ typeinfo_equal(typeinfo *x,typeinfo *y)
 }
 
 static void
 }
 
 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;
 
     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
 
 #if 0
 static void
-typeinfo_inc_dimension(typeinfo *info)
+typeinfo_inc_dimension(typeinfo_t *info)
 {
     if (info->dimension++ == 0) {
         info->elementtype = ARRAYTYPE_OBJECT;
 {
     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];
     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");
     int maxdim;
     int failed = 0;
     FILE *file = fopen(filename,"rt");
@@ -2598,7 +2354,7 @@ typeinfo_test()
 
 #if 0
 void
 
 #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));
 }
 {
     typeinfo_init_from_descriptor(info,desc,desc+strlen(desc));
 }
@@ -2626,11 +2382,11 @@ typeinfo_print_class(FILE *file,classref_or_classinfo c)
 }
 
 void
 }
 
 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];
 {
     int i;
     char ind[TYPEINFO_MAXINDENT + 1];
-    new_instruction *ins;
+    instruction *ins;
        basicblock *bptr;
 
     if (indent > TYPEINFO_MAXINDENT) indent = TYPEINFO_MAXINDENT;
        basicblock *bptr;
 
     if (indent > TYPEINFO_MAXINDENT) indent = TYPEINFO_MAXINDENT;
@@ -2654,7 +2410,7 @@ typeinfo_print(FILE *file,typeinfo *info,int indent)
     }
 
     if (TYPEINFO_IS_NEWOBJECT(*info)) {
     }
 
     if (TYPEINFO_IS_NEWOBJECT(*info)) {
-        ins = (new_instruction *)TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
+        ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
         if (ins) {
             fprintf(file,"%sNEW(%p):",ind,(void*)ins);
                        typeinfo_print_class(file,ins[-1].sx.val.c);
         if (ins) {
             fprintf(file,"%sNEW(%p):",ind,(void*)ins);
                        typeinfo_print_class(file,ins[-1].sx.val.c);
@@ -2704,10 +2460,10 @@ typeinfo_print(FILE *file,typeinfo *info,int indent)
 }
 
 void
 }
 
 void
-typeinfo_print_short(FILE *file,typeinfo *info)
+typeinfo_print_short(FILE *file,typeinfo_t *info)
 {
     int i;
 {
     int i;
-    new_instruction *ins;
+    instruction *ins;
        basicblock *bptr;
 
        /*fprintf(file,"<typeinfo %p>",info);*/
        basicblock *bptr;
 
        /*fprintf(file,"<typeinfo %p>",info);*/
@@ -2732,7 +2488,7 @@ typeinfo_print_short(FILE *file,typeinfo *info)
     }
     
     if (TYPEINFO_IS_NEWOBJECT(*info)) {
     }
     
     if (TYPEINFO_IS_NEWOBJECT(*info)) {
-        ins = (new_instruction *)TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
+        ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(*info);
         if (ins) {
                        /*fprintf(file,"<ins %p>",ins);*/
             fprintf(file,"NEW(%p):",(void*)ins);
         if (ins) {
                        /*fprintf(file,"<ins %p>",ins);*/
             fprintf(file,"NEW(%p):",(void*)ins);
@@ -2756,7 +2512,7 @@ typeinfo_print_short(FILE *file,typeinfo *info)
 }
 
 void
 }
 
 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;
 {
     switch (type) {
       case TYPE_VOID: fprintf(file,"V"); break;
@@ -2764,6 +2520,7 @@ typeinfo_print_type(FILE *file,int type,typeinfo *info)
       case TYPE_FLT:  fprintf(file,"F"); break;
       case TYPE_DBL:  fprintf(file,"D"); break;
       case TYPE_LNG:  fprintf(file,"J"); 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;
       case TYPE_ADR:
                  typeinfo_print_short(file,info);
           break;
@@ -2774,71 +2531,19 @@ typeinfo_print_type(FILE *file,int type,typeinfo *info)
 }
 
 void
 }
 
 void
-typeinfo_print_stacktype(FILE *file,int type,typeinfo *info)
-{
-       TYPEINFO_ASSERT(file);
-       TYPEINFO_ASSERT(type != TYPE_ADR || info != NULL);
-       if (type == TYPE_ADR && TYPEINFO_IS_PRIMITIVE(*info)) { 
-               typeinfo_retaddr_set *set = (typeinfo_retaddr_set*)
-                       TYPEINFO_RETURNADDRESS(*info);
-               if (set) {
-                       fprintf(file,"ret(L%03d",((basicblock*)(set->addr))->nr);
-                       set = set->alt;
-                       while (set) {
-                               fprintf(file,"|L%03d",((basicblock*)(set->addr))->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
 }
 
 void
-typevectorset_print(FILE *file,typevector *set,int size)
+typevector_print(FILE *file,varinfo *vec,int size)
 {
     int i;
 {
     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);
     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));
     }
 }
 
     }
 }