GNU header update.
[cacao.git] / src / vm / jit / verify / typecheck.c
index 82cce1556549353c0ff8c864d48417dfe192809a..900262a3512d3c92cffcbffb930e3ca1dfa70732 100644 (file)
@@ -1,9 +1,9 @@
-/* jit/typecheck.c - typechecking (part of bytecode verification)
+/* vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    Authors: Edwin Steiner
 
-   $Id: typecheck.c 1067 2004-05-18 10:25:51Z stefan $
+   $Id: typecheck.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
-#include "global.h" /* must be here because of CACAO_TYPECHECK */
+#include <string.h>
+
+#include "vm/global.h" /* must be here because of CACAO_TYPECHECK */
 
 #ifdef CACAO_TYPECHECK
 
-#include <string.h>
-#include "main.h"
-#include "jit.h"
-#include "builtin.h"
-#include "tables.h"
-#include "loader.h"
 #include "types.h"
+/*  #include "main.h" */
+#include "mm/memory.h"
 #include "toolbox/logging.h"
-#include "toolbox/memory.h"
+#include "native/native.h"
+#include "vm/builtin.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/tables.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/stack.h"
+
 
 /****************************************************************************/
 /* DEBUG HELPERS                                                            */
@@ -242,9 +247,9 @@ typestack_copy(stackptr dst,stackptr y,typevector *selected)
        int k;
        
        for (;dst; dst=dst->prev, y=y->prev) {
-               if (!y) panic("Stack depth mismatch");
+               if (!y) panic("Stack depth mismatch 1");
                if (dst->type != y->type)
-                       panic("Stack type mismatch");
+                       panic("Stack type mismatch 1");
                LOG3("copy %p -> %p (type %d)",y,dst,dst->type);
                if (dst->type == TYPE_ADDRESS) {
                        if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
@@ -272,7 +277,7 @@ typestack_copy(stackptr dst,stackptr y,typevector *selected)
                        }
                }
        }
-       if (y) panic("Stack depth mismatch");
+       if (y) panic("Stack depth mismatch 2");
 }
 
 static void
@@ -306,8 +311,9 @@ typestack_merge(stackptr dst,stackptr y)
 {
        bool changed = false;
        for (; dst; dst = dst->prev, y=y->prev) {
-               if (!y) panic("Stack depth mismatch");
-               if (dst->type != y->type) panic("Stack type mismatch");
+               if (!y)
+                       panic("Stack depth mismatch 3");
+               if (dst->type != y->type) panic("Stack type mismatch 2");
                if (dst->type == TYPE_ADDRESS) {
                        if (TYPEINFO_IS_PRIMITIVE(dst->typeinfo)) {
                                /* dst has returnAddress type */
@@ -322,7 +328,7 @@ typestack_merge(stackptr dst,stackptr y)
                        }
                }
        }
-       if (y) panic("Stack depth mismatch");
+       if (y) panic("Stack depth mismatch 4");
        return changed;
 }
 
@@ -491,11 +497,9 @@ typestate_merge(stackptr deststack,typevector *destloc,
        return changed;
 }
 
-/* Globals used:
- *     block
- */
+
 static bool
-typestate_reach(void *localbuf,
+typestate_reach(codegendata *cd, registerdata *rd,void *localbuf,
                                basicblock *current,
                                basicblock *destblock,
                                stackptr ystack,typevector *yloc,
@@ -508,7 +512,7 @@ typestate_reach(void *localbuf,
        LOG1("reaching block L%03d",destblock->debug_nr);
        TYPECHECK_COUNT(stat_reached);
        
-       destidx = destblock - block;
+       destidx = destblock - cd->method->basicblocks;
        destloc = MGET_TYPEVECTOR(localbuf,destidx,locsize);
 
        /* When branching backwards we have to check for uninitialized objects */
@@ -516,19 +520,26 @@ typestate_reach(void *localbuf,
        if (destblock <= current) {
                stackptr sp;
                int i;
-               
-               TYPECHECK_COUNT(stat_backwards);
-        LOG("BACKWARDS!");
-        for (sp = ystack; sp; sp=sp->prev)
-            if (sp->type == TYPE_ADR &&
-                TYPEINFO_IS_NEWOBJECT(sp->typeinfo))
-                panic("Branching backwards with uninitialized object on stack");
-
-        for (i=0; i<locsize; ++i)
-            if (yloc->td[i].type == TYPE_ADR &&
-                TYPEINFO_IS_NEWOBJECT(yloc->td[i].info))
-                panic("Branching backwards with uninitialized object in local variable");
-    }
+#if defined(__GNUC__)
+#warning FIXME FOR INLINING
+#endif
+               if (!useinlining) {
+                       TYPECHECK_COUNT(stat_backwards);
+                       LOG("BACKWARDS!");
+                       for (sp = ystack; sp; sp=sp->prev)
+                               if (sp->type == TYPE_ADR &&
+                               TYPEINFO_IS_NEWOBJECT(sp->typeinfo)) {
+                                       show_icmd_method(cd->method,cd,rd);
+                               printf("current: %ld, dest: %ld\n",current->debug_nr,destblock->debug_nr);
+                               panic("Branching backwards with uninitialized object on stack");
+                       }
+
+                       for (i=0; i<locsize; ++i)
+                               if (yloc->td[i].type == TYPE_ADR &&
+                               TYPEINFO_IS_NEWOBJECT(yloc->td[i].info))
+                                       panic("Branching backwards with uninitialized object in local variable");
+               }
+       }
        
        if (destblock->flags == BBTYPECHECK_UNDEF) {
                /* The destblock has never been reached before */
@@ -560,11 +571,9 @@ typestate_reach(void *localbuf,
        return false;
 }
 
-/* Globals used:
- *     see typestate_reach
- */
+
 static bool
-typestate_ret(void *localbuf,
+typestate_ret(codegendata *cd,registerdata *rd, void *localbuf,
                          basicblock *current,
                          stackptr ystack,typevector *yloc,
                          int retindex,int locsize)
@@ -582,7 +591,7 @@ typestate_ret(void *localbuf,
 
                selected = typevectorset_select(&yvec,retindex,destblock);
                
-               repeat |= typestate_reach(localbuf,current,destblock,
+               repeat |= typestate_reach(cd, rd,  localbuf,current,destblock,
                                                                  ystack,selected,locsize,true);
        }
        return repeat;
@@ -679,23 +688,41 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
 #define STORE_TWOWORD(num,type)                                                                                \
        do {typevectorset_store_twoword(localset,num,type);} while(0)
 
+
+#define WORDCHECKFAULT \
+       do { \
+               show_icmd_method(m, cd, rd); \
+               dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n", \
+               iptr->op1,iptr->method->class->name->text, \
+                       iptr->method->name->text,m->class->name->text,m->name->text); \
+               show_icmd(iptr++, false); \
+               show_icmd(iptr, false); \
+       } while (0)
+
+
 #define CHECK_ONEWORD(num,tp)                                                                                  \
        do {TYPECHECK_COUNT(stat_ins_primload);                                                         \
                if (jsrencountered) {                                                                                   \
-                       if (!typevectorset_checktype(localset,num,tp))                          \
+                       if (!typevectorset_checktype(localset,num,tp)) {                                \
+                               WORDCHECKFAULT; \
                                panic("Variable type mismatch");                                                \
+                       }       \
                }                                                                                                                               \
                else {                                                                                                                  \
-                       if (localset->td[num].type != tp)                                                       \
+                       if (localset->td[num].type != tp) {                                                     \
                                panic("Variable type mismatch");                                                \
+                               WORDCHECKFAULT; \
+                       } \
                }                                                                                                                               \
                } while(0)
 
 #define CHECK_TWOWORD(num,type)                                                                                        \
        do {TYPECHECK_COUNT(stat_ins_primload);                                                         \
-               if (!typevectorset_checktype(localset,num,type))                \
-            panic("Variable type mismatch");                           \
-               } while(0)
+               if (!typevectorset_checktype(localset,num,type)) {                \
+                       WORDCHECKFAULT; \
+                       panic("Variable type mismatch");                                \
+               } \
+       } while(0)
 
 /****************************************************************************/
 /* MACROS FOR STACK TYPE CHECKING                                           */
@@ -730,7 +757,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
        {if ((source)->type == TYPE_ADR)                                                                \
                        TYPEINFO_COPY((source)->typeinfo,(dest)->typeinfo);}
 
-#define ISBUILTIN(v)   (iptr->val.a == (functionptr)(v))
+#define ISBUILTIN(v)   (iptr->val.fp == (functionptr) (v))
 
 /* TYPECHECK_REACH: executed, when the target block (tbptr) can be reached
  *     from the current block (bptr). The types of local variables and
@@ -749,7 +776,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
  */
 #define TYPECHECK_REACH                                                 \
     do {                                                                \
-    repeat |= typestate_reach(localbuf,bptr,tbptr,dst,                  \
+    repeat |= typestate_reach(cd,rd, localbuf,bptr,tbptr,dst,               \
                                                          localset,numlocals,jsrencountered);       \
     LOG("done.");                                                       \
     } while (0)
@@ -763,7 +790,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
  */
 #define TYPECHECK_LEAVE                                                 \
     do {                                                                \
-        if (initmethod && class != class_java_lang_Object) {            \
+        if (initmethod && m->class != class_java_lang_Object) {         \
             /* check the marker variable */                             \
             LOG("Checking <init> marker");                              \
             if (!typevectorset_checktype(localset,numlocals-1,TYPE_INT))\
@@ -778,8 +805,8 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
 #define MAXPARAMS 255
 
 /* typecheck is called directly after analyse_stack */
-void
-typecheck()
+
+methodinfo *typecheck(methodinfo *m, codegendata *cd, registerdata *rd)
 {
     int b_count, b_index;
     stackptr curstack;      /* input stack top for current instruction */
@@ -813,7 +840,7 @@ typecheck()
        
     stackptr dst;               /* output stack of current instruction */
     basicblock **tptr;    /* pointer into target list of switch instr. */
-    xtable **handlers;                    /* active exception handlers */
+    exceptiontable **handlers;            /* active exception handlers */
     classinfo *cls;                                       /* temporary */
     bool maythrow;               /* true if this instruction may throw */
     static utf *name_init;                                 /* "<init>" */
@@ -823,21 +850,11 @@ typecheck()
 
     classinfo *myclass;
 
-       if (compileverbose) {
-               char logtext[MAXLOGTEXT];
-               sprintf(logtext, "Typechecking: ");
-               utf_sprint_classname(logtext + strlen(logtext), method->class->name);
-               sprintf(logtext + strlen(logtext), ".");
-               utf_sprint(logtext + strlen(logtext), method->name);
-               utf_sprint_classname(logtext + strlen(logtext), method->descriptor);
-               log_text(logtext);
-       }
-
 #ifdef TYPECHECK_STATISTICS
        int count_iterations = 0;
        TYPECHECK_COUNT(stat_typechecked);
-       TYPECHECK_COUNT_FREQ(stat_locals,maxlocals,STAT_LOCALS);
-       TYPECHECK_COUNT_FREQ(stat_blocks,block_count/10,STAT_BLOCKS);
+       TYPECHECK_COUNT_FREQ(stat_locals,m->codegendata->maxlocals,STAT_LOCALS);
+       TYPECHECK_COUNT_FREQ(stat_blocks,m->basicblockcount/10,STAT_BLOCKS);
 #endif
 
     LOGSTR("\n==============================================================================\n");
@@ -854,7 +871,7 @@ typecheck()
 
        if (!name_init)
                name_init = utf_new_char("<init>");
-    initmethod = (method->name == name_init);
+    initmethod = (m->name == name_init);
 
        /* Allocate buffer for method arguments */
        
@@ -864,8 +881,8 @@ typecheck()
     LOG("Buffer allocated.\n");
 
     /* reset all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
-    b_count = block_count;
-    bptr = block;
+    b_count = m->basicblockcount;
+    bptr = m->basicblocks;
     while (--b_count >= 0) {
 #ifdef TYPECHECK_DEBUG
         if (bptr->flags != BBFINISHED && bptr->flags != BBDELETED
@@ -883,8 +900,8 @@ typecheck()
     }
 
     /* The first block is always reached */
-    if (block_count && block[0].flags == BBTYPECHECK_UNDEF)
-        block[0].flags = BBTYPECHECK_REACHED;
+    if (m->basicblockcount && m->basicblocks[0].flags == BBTYPECHECK_UNDEF)
+        m->basicblocks[0].flags = BBTYPECHECK_REACHED;
 
     LOG("Blocks reset.\n");
 
@@ -892,18 +909,18 @@ typecheck()
     
     /* In <init> methods we use an extra local variable to signal if
      * the 'this' reference has been initialized. */
-    numlocals = maxlocals;
+    numlocals = cd->maxlocals;
        validlocals = numlocals;
     if (initmethod) numlocals++;
 
     /* allocate the buffers for local variables */
-       localbuf = DMNEW_TYPEVECTOR(block_count+1, numlocals);
-       localset = MGET_TYPEVECTOR(localbuf,block_count,numlocals);
+       localbuf = DMNEW_TYPEVECTOR(m->basicblockcount+1, numlocals);
+       localset = MGET_TYPEVECTOR(localbuf,m->basicblockcount,numlocals);
 
     LOG("Variable buffer allocated.\n");
 
     /* allocate the buffer of active exception handlers */
-    handlers = DMNEW(xtable*,method->exceptiontablelength + 1);
+    handlers = DMNEW(exceptiontable*, cd->exceptiontablelength + 1);
 
     /* initialize the variable types of the first block */
     /* to the types of the arguments */
@@ -914,14 +931,14 @@ typecheck()
        i = validlocals;
 
     /* if this is an instance method initialize the "this" ref type */
-    if (!(method->flags & ACC_STATIC)) {
+    if (!(m->flags & ACC_STATIC)) {
                if (!i)
                        panic("Not enough local variables for method arguments");
         td->type = TYPE_ADDRESS;
         if (initmethod)
             TYPEINFO_INIT_NEWOBJECT(td->info,NULL);
         else
-            TYPEINFO_INIT_CLASSINFO(td->info,class);
+            TYPEINFO_INIT_CLASSINFO(td->info, m->class);
         td++;
                i--;
     }
@@ -929,7 +946,7 @@ typecheck()
     LOG("'this' argument set.\n");
 
     /* the rest of the arguments and the return type */
-    i = typedescriptors_init_from_method_args(td,method->descriptor,
+    i = typedescriptors_init_from_method_args(td, m->descriptor,
                                                                                          i,
                                                                                          true, /* two word types use two slots */
                                                                                          &returntype);
@@ -956,8 +973,8 @@ typecheck()
 
         repeat = false;
         
-        b_count = block_count;
-        bptr = block;
+        b_count = m->basicblockcount;
+        bptr = m->basicblocks;
 
         while (--b_count >= 0) {
             LOGSTR1("---- BLOCK %04d, ",bptr-block);
@@ -970,7 +987,7 @@ typecheck()
                 
                 superblockend = false;
                 bptr->flags = BBFINISHED;
-                b_index = bptr - block;
+                b_index = bptr - m->basicblocks;
 
                 /* init stack at the start of this block */
                 curstack = bptr->instack;
@@ -979,10 +996,10 @@ typecheck()
                 /* XXX could use a faster algorithm with sorted lists or
                  * something? */
                 len = 0;
-                for (i=0; i<method->exceptiontablelength; ++i) {
-                    if ((extable[i].start <= bptr) && (extable[i].end > bptr)) {
-                        LOG1("active handler L%03d",extable[i].handler->debug_nr);
-                        handlers[len++] = extable + i;
+                for (i = 0; i < cd->exceptiontablelength; ++i) {
+                    if ((cd->exceptiontable[i].start <= bptr) && (cd->exceptiontable[i].end > bptr)) {
+                        LOG1("active handler L%03d", cd->exceptiontable[i].handler->debug_nr);
+                        handlers[len++] = cd->exceptiontable + i;
                     }
                 }
                 handlers[len] = NULL;
@@ -990,12 +1007,19 @@ typecheck()
                 /* init variable types at the start of this block */
                                COPY_TYPEVECTORSET(MGET_TYPEVECTOR(localbuf,b_index,numlocals),
                                                                   localset,numlocals);
+#if defined(__GNUC__)
+#warning FIXME FOR INLINING
+#endif
+               if(!useinlining) {
                                if (handlers[0])
                                        for (i=0; i<numlocals; ++i)
                                                if (localset->td[i].type == TYPE_ADR
-                                                       && TYPEINFO_IS_NEWOBJECT(localset->td[i].info))
-                                                       panic("Uninitialized object in local variable inside try block");
-
+                                                       && TYPEINFO_IS_NEWOBJECT(localset->td[i].info)) {
+                                                               show_icmd_method(m, cd, rd);
+                                                               printf("Uninitialized variale:%ld, block:%ld\n",i,bptr->debug_nr);
+                                                               panic("Uninitialized object in local variable inside try block");
+                                                       }
+               }
                                DOLOG(typestate_print(get_logfile(),curstack,localset,numlocals));
                                LOGNL; LOGFLUSH;
 
@@ -1007,7 +1031,7 @@ typecheck()
                     DOLOG(show_icmd(iptr,false)); LOGNL; LOGFLUSH;
                         
                     opcode = iptr->opc;
-                   myclass = iptr->clazz;
+                   myclass = iptr->method->class;
                     dst = iptr->dst;
                     maythrow = false;
                                                
@@ -1106,8 +1130,14 @@ typecheck()
                                                          typevectorset_copymergedtype(localset,iptr->op1,&(dst->typeinfo));
                                                  }
                                                  else {
-                                                         if (!TYPEDESC_IS_REFERENCE(localset->td[iptr->op1]))
+                                                         if (!TYPEDESC_IS_REFERENCE(localset->td[iptr->op1])) {
+                                                                 show_icmd_method(m, cd, rd);
+                                                                 dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n",
+                                                                       iptr->op1,iptr->method->class->name->text,
+                                                                       iptr->method->name->text,m->class->name->text,m->name->text);
+                                                                 show_icmd(iptr, false);
                                                                  panic("illegal instruction: ALOAD loading non-reference");
+                                                         }
                                                          TYPEINFO_COPY(localset->td[iptr->op1].info,dst->typeinfo);
                                                  }
                           break;
@@ -1157,7 +1187,7 @@ typecheck()
                                                                          && !TYPEINFO_NEWOBJECT_INSTRUCTION(curstack->prev->typeinfo))
                                                                  {
                                                                          /* uninitialized "this" instance */
-                                                                         if (fi->class != class || (fi->flags & ACC_STATIC) != 0)
+                                                                         if (fi->class != m->class || (fi->flags & ACC_STATIC) != 0)
                                                                                  panic("Setting unaccessible field in uninitialized object");
                                                                  }
                                                                  else {
@@ -1331,6 +1361,38 @@ typecheck()
                           maythrow = true;
                           break;
 
+                      case ICMD_IASTORECONST:
+                          if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_INT))
+                              panic("Array type mismatch");
+                          maythrow = true;
+                          break;
+
+                      case ICMD_LASTORECONST:
+                          if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_LONG))
+                              panic("Array type mismatch");
+                          maythrow = true;
+                          break;
+
+                      case ICMD_BASTORECONST:
+                          if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_BOOLEAN)
+                              && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_BYTE))
+                              panic("Array type mismatch");
+                          maythrow = true;
+                          break;
+
+                      case ICMD_CASTORECONST:
+                          if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_CHAR))
+                              panic("Array type mismatch");
+                          maythrow = true;
+                          break;
+
+                      case ICMD_SASTORECONST:
+                          if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_SHORT))
+                              panic("Array type mismatch");
+                          maythrow = true;
+                          break;
+
+
                           /****************************************/
                           /* ADDRESS CONSTANTS                    */
 
@@ -1493,10 +1555,10 @@ typecheck()
                           dst = (stackptr) iptr->val.a;
                           
                           tbptr = (basicblock *) iptr->target;
-                                                 if (bptr+1 == last_block)
+                                                 if (bptr + 1 == (m->basicblocks + m->basicblockcount + 1))
                                                          panic("Illegal instruction: JSR at end of bytecode");
                                                  typestack_put_retaddr(dst,bptr+1,localset);
-                                                 repeat |= typestate_reach(localbuf,bptr,tbptr,dst,
+                                                 repeat |= typestate_reach(cd, rd,localbuf,bptr,tbptr,dst,
                                                                                                        localset,numlocals,true);
 
                                                  superblockend = true;
@@ -1507,7 +1569,7 @@ typecheck()
                                                  if (!typevectorset_checkretaddr(localset,iptr->op1))
                               panic("illegal instruction: RET using non-returnAddress variable");
 
-                                                 repeat |= typestate_ret(localbuf,bptr,curstack,
+                                                 repeat |= typestate_ret(cd,rd, localbuf,bptr,curstack,
                                                                                                  localset,iptr->op1,numlocals);
 
                           superblockend = true;
@@ -1536,7 +1598,7 @@ typecheck()
                                                                  
                                                                  /* (If callinginit the class is checked later.) */
                                                                  if (!callinginit) { 
-                                                                         if (!builtin_isanysubclass(class,mi->class)) 
+                                                                         if (!builtin_isanysubclass(myclass,mi->class)) 
                                                                                  panic("Illegal instruction: INVOKESPECIAL calling non-superclass method"); 
                                                                  } 
                                                          }
@@ -1571,7 +1633,7 @@ typecheck()
                                           /* get the address of the NEW instruction */
                                           LOGINFO(&(srcstack->typeinfo));
                                           ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(srcstack->typeinfo);
-                                          initclass = (ins) ? (classinfo*)ins[-1].val.a : method->class;
+                                          initclass = (ins) ? (classinfo*)ins[-1].val.a : m->class;
                                           LOGSTR("class: "); LOGSTRu(initclass->name); LOGNL;
 
                                                                                  /* check type */
@@ -1626,9 +1688,9 @@ typecheck()
                                                                                          LOG("saving input stack types");
                                                                                          if (!savedstackbuf) {
                                                                                                  LOG("allocating savedstack buffer");
-                                                                                                 savedstackbuf = DMNEW(stackelement,maxstack);
+                                                                                                 savedstackbuf = DMNEW(stackelement, cd->maxstack);
                                                                                                  savedstackbuf->prev = NULL;
-                                                                                                 for (i=1; i<maxstack; ++i)
+                                                                                                 for (i = 1; i < cd->maxstack; ++i)
                                                                                                          savedstackbuf[i].prev = savedstackbuf+(i-1);
                                                                                          }
                                                                                          sp = savedstack = bptr->instack;
@@ -1650,7 +1712,7 @@ typecheck()
                                                                                  panic("Internal error: calling <init> on this in non-<init> method.");
 #endif
                                                                          /* must be <init> of current class or direct superclass */
-                                                                         if (mi->class != class && mi->class != class->super)
+                                                                         if (mi->class != m->class && mi->class != m->class->super)
                                                                                  panic("<init> calling <init> of the wrong class");
                                                                          
                                       /* set our marker variable to type int */
@@ -1670,7 +1732,7 @@ typecheck()
                           
                       case ICMD_MULTIANEWARRAY:
                                                  {
-                                                         vftbl *arrayvftbl;
+                                                         vftbl_t *arrayvftbl;
                                                          arraydescriptor *desc;
                                                          
                                                          /* check the array lengths on the stack */
@@ -1686,7 +1748,7 @@ typecheck()
                                                          }
                                                          
                                                          /* check array descriptor */
-                                                         arrayvftbl = (vftbl*) iptr[0].val.a;
+                                                         arrayvftbl = (vftbl_t*) iptr[0].val.a;
                                                          if (!arrayvftbl)
                                                                  panic("MULTIANEWARRAY with unlinked class");
                                                          if ((desc = arrayvftbl->arraydesc) == NULL)
@@ -1714,9 +1776,9 @@ typecheck()
                                                          TYPECHECK_COUNT(stat_ins_builtin_gen);
                                                          builtindesc = builtin_desc;
                                                          while (builtindesc->opcode && builtindesc->builtin
-                                                                        != (functionptr) iptr->val.a) builtindesc++;
+                                                                        != iptr->val.fp) builtindesc++;
                                                          if (!builtindesc->opcode) {
-                                                                 dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+                                                                 dolog("Builtin not in table: %s",icmd_builtin_name(iptr->val.fp));
                                                                  panic("Internal error: builtin not found in table");
                                                          }
                                                          TYPECHECK_ARGS3(builtindesc->type_s3,builtindesc->type_s2,builtindesc->type_s1);
@@ -1728,11 +1790,11 @@ typecheck()
                                                  TYPECHECK_COUNT(stat_ins_builtin);
                           if (ISBUILTIN(BUILTIN_newarray))
                           {
-                                                         vftbl *vft;
+                                                         vftbl_t *vft;
                                                          TYPECHECK_INT(curstack->prev);
                               if (iptr[-1].opc != ICMD_ACONST)
                                   panic("illegal instruction: builtin_newarray without classinfo");
-                                                         vft = (vftbl *)iptr[-1].val.a;
+                                                         vft = (vftbl_t *)iptr[-1].val.a;
                                                          if (!vft)
                                                                  panic("ANEWARRAY with unlinked class");
                                                          if (!vft->arraydesc)
@@ -1741,22 +1803,22 @@ typecheck()
                           }
                           else if (ISBUILTIN(BUILTIN_arrayinstanceof))
                           {
-                                                         vftbl *vft;
+                                                         vftbl_t *vft;
                                                          TYPECHECK_ADR(curstack->prev);
                               if (iptr[-1].opc != ICMD_ACONST)
                                   panic("illegal instruction: builtin_arrayinstanceof without classinfo");
-                                                         vft = (vftbl *)iptr[-1].val.a;
+                                                         vft = (vftbl_t *)iptr[-1].val.a;
                                                          if (!vft)
                                                                  panic("INSTANCEOF with unlinked class");
                                                          if (!vft->arraydesc)
                                                                  panic("internal error: builtin_arrayinstanceof with non-array class");
                                                  }
                           else if (ISBUILTIN(BUILTIN_checkarraycast)) {
-                                                         vftbl *vft;
+                                                         vftbl_t *vft;
                                                          TYPECHECK_ADR(curstack->prev);
                               if (iptr[-1].opc != ICMD_ACONST)
                                   panic("illegal instruction: BUILTIN_checkarraycast without classinfo");
-                                                         vft = (vftbl *)iptr[-1].val.a;
+                                                         vft = (vftbl_t *)iptr[-1].val.a;
                                                          if (!vft)
                                                                  panic("CHECKCAST with unlinked class");
                                                          if (!vft->arraydesc)
@@ -1767,9 +1829,9 @@ typecheck()
                                                          TYPECHECK_COUNT(stat_ins_builtin_gen);
                                                          builtindesc = builtin_desc;
                                                          while (builtindesc->opcode && builtindesc->builtin
-                                                                        != (functionptr) iptr->val.a) builtindesc++;
+                                                                        != iptr->val.fp) builtindesc++;
                                                          if (!builtindesc->opcode) {
-                                                                 dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+                                                                 dolog("Builtin not in table: %s",icmd_builtin_name(iptr->val.fp));
                                                                  panic("Internal error: builtin not found in table");
                                                          }
                                                          TYPECHECK_ARGS2(builtindesc->type_s2,builtindesc->type_s1);
@@ -1827,9 +1889,9 @@ typecheck()
                                                          TYPECHECK_COUNT(stat_ins_builtin_gen);
                                                          builtindesc = builtin_desc;
                                                          while (builtindesc->opcode && builtindesc->builtin
-                                                                        != (functionptr) iptr->val.a) builtindesc++;
+                                                                        != iptr->val.fp) builtindesc++;
                                                          if (!builtindesc->opcode) {
-                                                                 dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+                                                                 dolog("Builtin not in table: %s",icmd_builtin_name(iptr->val.fp));
                                                                  panic("Internal error: builtin not found in table");
                                                          }
                                                          TYPECHECK_ARGS1(builtindesc->type_s1);
@@ -2022,7 +2084,7 @@ typecheck()
                                                        cls = handlers[i]->catchtype;
                                                        excstack.typeinfo.typeclass = (cls) ? cls
                                                                : class_java_lang_Throwable;
-                                                       repeat |= typestate_reach(localbuf,bptr,
+                                                       repeat |= typestate_reach(cd,rd, localbuf,bptr,
                                                                                                          handlers[i]->handler,
                                                                                                          &excstack,localset,
                                                                                                          numlocals,
@@ -2046,7 +2108,7 @@ typecheck()
                     while (tbptr->flags == BBDELETED) {
                         tbptr++;
 #ifdef TYPECHECK_DEBUG
-                        if ((tbptr-block) >= block_count)
+                        if ((tbptr-block) >= m->basicblockcount)
                             panic("Control flow falls off the last block");
 #endif
                     }
@@ -2081,38 +2143,32 @@ typecheck()
 #endif
 
 #ifdef TYPECHECK_DEBUG
-       for (i=0; i<block_count; ++i) {
-               if (block[i].flags != BBDELETED
-                       && block[i].flags != BBUNDEF
-                       && block[i].flags != BBFINISHED
-                       && block[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
+       for (i=0; i<m->basicblockcount; ++i) {
+               if (m->basicblocks[i].flags != BBDELETED
+                       && m->basicblocks[i].flags != BBUNDEF
+                       && m->basicblocks[i].flags != BBFINISHED
+                       && m->basicblocks[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
                                                                                                         * some exception handlers,
                                                                                                         * that's ok. */
                {
                        LOG2("block L%03d has invalid flags after typecheck: %d",
-                                block[i].debug_nr,block[i].flags);
+                                m->basicblocks[i].debug_nr,m->basicblocks[i].flags);
                        panic("Invalid block flags after typecheck");
                }
        }
 #endif
        
        /* Reset blocks we never reached */
-       for (i=0; i<block_count; ++i) {
-               if (block[i].flags == BBTYPECHECK_UNDEF)
-                       block[i].flags = BBFINISHED;
+       for (i=0; i<m->basicblockcount; ++i) {
+               if (m->basicblocks[i].flags == BBTYPECHECK_UNDEF)
+                       m->basicblocks[i].flags = BBFINISHED;
        }
                
     LOGimp("exiting typecheck");
 
-       if (compileverbose) {
-               char logtext[MAXLOGTEXT];
-               sprintf(logtext, "Typechecking done: ");
-               utf_sprint_classname(logtext + strlen(logtext), method->class->name);
-               sprintf(logtext + strlen(logtext), ".");
-               utf_sprint(logtext + strlen(logtext), method->name);
-               utf_sprint_classname(logtext + strlen(logtext), method->descriptor);
-               log_text(logtext);
-       }
+       /* just return methodinfo* to signal everything was ok */
+
+       return m;
 }
 
 #undef COPYTYPE