* Removed all Id tags.
[cacao.git] / src / vm / jit / verify / typeinfo.c
index 1568279800fb9156a1aaa418502cad18eb133c2a..3d0a47888fc582644cd9ca2a1e5292a6735a8e8e 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/verify/typeinfo.c - type system used by the type checker
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
+*/
 
-   $Id: typeinfo.c 5166 2006-07-21 10:09:33Z twisti $
 
-*/
+#include "config.h"
 
 #include <assert.h>
 #include <string.h>
 
 #include "mm/memory.h"
+
 #include "toolbox/logging.h"
-#include "vm/class.h"
-#include "vm/loader.h"
+
+#include "vm/array.h"
+#include "vm/exceptions.h"
+#include "vm/primitive.h"
+#include "vm/resolve.h"
+
 #include "vm/jit/jit.h"
 #include "vm/jit/verify/typeinfo.h"
-#include "vm/descriptor.h"
-#include "vm/resolve.h"
-#include "vm/exceptions.h"
+
+#include "vmcore/class.h"
+#include "vmcore/descriptor.h"
+#include "vmcore/loader.h"
 
 
 /* check if a linked class is an array class. Only use for linked classes! */
 #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 +124,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;
+       return TYPEDESC_IS_RETURNADDRESS(vec[index]);
 }
 
-/* typevectorset_mergedtype ****************************************************
+/* typevector_store ************************************************************
  
-   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;
-}
-
-/* typevectorset_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 +190,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 *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 *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 +244,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 +284,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 +309,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 +329,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.                */
@@ -1421,16 +1053,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;
                        }
 
@@ -1475,15 +1107,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 *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.
@@ -1527,7 +1275,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 +1283,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++;
                }
     }
@@ -1575,6 +1323,8 @@ typedescriptors_init_from_methoddesc(typedescriptor *td,
 bool
 typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
 {
+       typeinfo_mergedlist *merged;
+
        TYPEINFO_ASSERT(srcarray);
        TYPEINFO_ASSERT(dst);
 
@@ -1585,10 +1335,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);
@@ -1620,7 +1374,7 @@ typeinfo_init_component(typeinfo *srcarray,typeinfo *dst)
                        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;
 }
 
@@ -1698,9 +1452,9 @@ typeinfo_merge_error(methodinfo *m,char *str,typeinfo *x,typeinfo *y) {
     typeinfo_print(stderr,x,1);
     fprintf(stderr,"Typeinfo y:\n");
     typeinfo_print(stderr,y,1);
+    log_text(str);
 #endif
 
-    log_text(str);
        exceptions_throw_verifyerror(m, str);
 }
 
@@ -2297,7 +2051,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,7 +2082,7 @@ 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;
                                        }
                                }
@@ -2378,6 +2132,7 @@ return_simple:
 
     return changed;
 }
+#endif /* ENABLE_VERIFER */
 
 
 /**********************************************************************/
@@ -2417,7 +2172,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);
                        }
@@ -2642,7 +2397,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 +2409,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,ICMD_ACONST_CLASSREF_OR_CLASSINFO(ins-1));
+                       typeinfo_print_class(file,ins[-1].sx.val.c);
             fprintf(file,"\n");
         }
         else {
@@ -2720,7 +2475,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 +2487,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,ICMD_ACONST_CLASSREF_OR_CLASSINFO(ins-1));
+                       typeinfo_print_class(file,ins[-1].sx.val.c);
         }
         else
             fprintf(file,"NEW(this)");
@@ -2759,12 +2514,13 @@ void
 typeinfo_print_type(FILE *file,int type,typeinfo *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;
           
@@ -2773,72 +2529,20 @@ 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)
-{
-    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));
     }
 }