* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / verify / typecheck.c
index 2a11f722a8790693c440a7d198d5f4e42a498c2e..00e3cfdea6226839a867092752a4ba86cf93d906 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Edwin Steiner
-
-   Changes: Christian Thalinger
-
-   $Id: typecheck.c 5746 2006-10-12 10:10:06Z edwin $
-
 */
 
 /*
@@ -141,27 +131,36 @@ error reporting.
     citeseer.ist.psu.edu/article/coglio03improving.html
 */
 
+
 #include "config.h"
-#include "vm/types.h"
-#include "vm/global.h"
 
 #include <assert.h>
 #include <string.h>
 
+#include "vm/types.h"
+
 #ifdef ENABLE_VERIFIER
 
 #include "mm/memory.h"
+
+#include "native/native.hpp"
+
 #include "toolbox/logging.h"
-#include "native/native.h"
-#include "vm/builtin.h"
-#include "vm/jit/patcher.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/show.h"
+
 #include "vm/access.h"
-#include "vm/resolve.h"
-#include "vm/exceptions.h"
+#include "vm/array.hpp"
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/resolve.hpp"
+
+#include "vm/jit/jit.hpp"
+#include "vm/jit/parse.hpp"
+#include "vm/jit/show.hpp"
 
 #include <typecheck-common.h>
 
@@ -196,233 +195,6 @@ error reporting.
 #define TYPECHECK_ADR_OP(o)  TYPECHECK_ADR((o).varindex)
 
 
-/****************************************************************************/
-/* TYPESTACK MACROS AND FUNCTIONS                                           */
-/*                                                                          */
-/* These macros and functions act on the 'type stack', which is a shorthand */
-/* for the types of the stackslots of the current stack. The type of a      */
-/* stack slot is usually described by a TYPE_* constant and -- for TYPE_ADR */
-/* -- by the typeinfo of the slot. The only thing that makes the type stack */
-/* more complicated are returnAddresses of local subroutines, because a     */
-/* single stack slot may contain a set of more than one possible return     */
-/* address. This is handled by 'return address sets'. A return address set  */
-/* is kept as a linked list dangling off the typeinfo of the stack slot.    */
-/****************************************************************************/
-
-/* typecheck_copy_types ********************************************************
-   Copy the types of the source variables to the destination variables.
-
-   IN:
-          state............current verifier state
-          srcvars..........array of variable indices to copy
-          dstvars..........array of the destination variables
-          n................number of variables to copy
-
-   RETURN VALUE:
-       true.............success
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-static bool
-typecheck_copy_types(verifier_state *state, s4 *srcvars, s4 *dstvars, s4 n)
-{
-       s4 i;
-       varinfo *sv;
-       varinfo *dv;
-       jitdata *jd = state->jd;
-
-       for (i=0; i < n; ++i, ++srcvars, ++dstvars) {
-               sv = VAR(*srcvars);
-               dv = VAR(*dstvars);
-
-               dv->type = sv->type;
-               if (dv->type == TYPE_ADR) {
-                       TYPEINFO_CLONE(sv->typeinfo,dv->typeinfo);
-               }
-       }
-       return true;
-}
-
-
-/* typecheck_merge_types *******************************************************
-   Merge the types of the source variables into the destination variables.
-
-   IN:
-       state............current state of the verifier
-          srcvars..........source variable indices
-          dstvars..........destination variable indices
-          n................number of variables
-
-   RETURN VALUE:
-       typecheck_TRUE...the destination variables have been modified
-          typecheck_FALSE..the destination variables are unchanged
-          typecheck_FAIL...an exception has been thrown
-
-*******************************************************************************/
-
-static typecheck_result
-typecheck_merge_types(verifier_state *state,s4 *srcvars, s4 *dstvars, s4 n)
-{
-       s4 i;
-       varinfo *sv;
-       varinfo *dv;
-       jitdata *jd = state->jd;
-       typecheck_result r;
-       bool changed = false;
-       
-       for (i=0; i < n; ++i, ++srcvars, ++dstvars) {
-               sv = VAR(*srcvars);
-               dv = VAR(*dstvars);
-
-               if (dv->type != sv->type) {
-                       exceptions_throw_verifyerror(state->m,"Stack type mismatch");
-                       return typecheck_FAIL;
-               }
-               if (dv->type == TYPE_ADR) {
-                       if (TYPEINFO_IS_PRIMITIVE(dv->typeinfo)) {
-                               /* dv has returnAddress type */
-                               if (!TYPEINFO_IS_PRIMITIVE(sv->typeinfo)) {
-                                       exceptions_throw_verifyerror(state->m,"Merging returnAddress with reference");
-                                       return typecheck_FAIL;
-                               }
-                       }
-                       else {
-                               /* dv has reference type */
-                               if (TYPEINFO_IS_PRIMITIVE(sv->typeinfo)) {
-                                       exceptions_throw_verifyerror(state->m,"Merging reference with returnAddress");
-                                       return typecheck_FAIL;
-                               }
-                               r = typeinfo_merge(state->m,&(dv->typeinfo),&(sv->typeinfo));
-                               if (r == typecheck_FAIL)
-                                       return r;
-                               changed |= r;
-                       }
-               }
-       }
-       return changed;
-}
-
-
-/* typestate_merge *************************************************************
-   Merge the types of one state into the destination state.
-
-   IN:
-       state............current state of the verifier
-          dstvars..........indices of the destinations invars
-          dstlocals........the destinations inlocals
-          srcvars..........indices of the source's outvars
-          srclocals........the source locals
-          n................number of invars (== number of outvars)
-
-   RETURN VALUE:
-       typecheck_TRUE...destination state has been modified
-          typecheck_FALSE..destination state has not been modified
-          typecheck_FAIL...an exception has been thrown
-
-*******************************************************************************/
-
-static typecheck_result
-typestate_merge(verifier_state *state,
-                               s4 *srcvars, varinfo *srclocals,
-                               s4 *dstvars, varinfo *dstlocals,
-                               s4 n)
-{
-       bool changed = false;
-       typecheck_result r;
-       
-       /* The stack is always merged. If there are returnAddresses on
-        * the stack they are ignored in this step. */
-
-       r = typecheck_merge_types(state, srcvars, dstvars, n);
-       if (r == typecheck_FAIL)
-               return r;
-       changed |= r;
-
-       /* merge the locals */
-
-       r = typevector_merge(state->m, dstlocals, srclocals, state->numlocals);
-       if (r == typecheck_FAIL)
-               return r;
-       return changed | r;
-}
-
-
-/* typestate_reach *************************************************************
-   Reach a destination block and propagate stack and local variable types
-
-   IN:
-       state............current state of the verifier
-          destblock........destination basic block
-          srcvars..........variable indices of the outvars to propagate
-          srclocals........local variables to propagate
-          n................number of srcvars
-
-   OUT:
-       state->repeat....set to true if the verifier must iterate again
-                           over the basic blocks
-          
-   RETURN VALUE:
-       true.............success
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-static bool
-typestate_reach(verifier_state *state,
-                               basicblock *destblock,
-                               s4 *srcvars, varinfo *srclocals, s4 n)
-{
-       varinfo *destloc;
-       bool changed = false;
-       typecheck_result r;
-
-       LOG1("reaching block L%03d",destblock->nr);
-       TYPECHECK_COUNT(stat_reached);
-       
-       destloc = destblock->inlocals;
-
-       if (destblock->flags == BBTYPECHECK_UNDEF) {
-               /* The destblock has never been reached before */
-
-               TYPECHECK_COUNT(stat_copied);
-               LOG1("block L%03d reached first time",destblock->nr);
-               
-               if (!typecheck_copy_types(state, srcvars, destblock->invars, n))
-                       return false;
-               typevector_copy_inplace(srclocals, destloc, state->numlocals);
-               changed = true;
-       }
-       else {
-               /* The destblock has already been reached before */
-               
-               TYPECHECK_COUNT(stat_merged);
-               LOG1("block L%03d reached before", destblock->nr);
-               
-               r = typestate_merge(state, srcvars, srclocals, 
-                               destblock->invars, destblock->inlocals, n);
-               if (r == typecheck_FAIL)
-                       return false;
-               changed = r;
-               TYPECHECK_COUNTIF(changed,stat_merging_changed);
-       }
-
-       if (changed) {
-               LOG("changed!");
-               destblock->flags = BBTYPECHECK_REACHED;
-               if (destblock <= state->bptr) {
-                       LOG("REPEAT!"); 
-                       state->repeat = true;
-               }
-       }
-       return true;
-}
-
-
 /* typestate_save_invars *******************************************************
  
    Save the invars of the current basic block in the space reserved by
@@ -500,18 +272,41 @@ typestate_restore_invars(verifier_state *state)
 }
 
 
-/****************************************************************************/
-/* MISC MACROS                                                              */
-/****************************************************************************/
+/* handle_fieldaccess **********************************************************
+   Verify an ICMD_{GET,PUT}{STATIC,FIELD}(CONST)?
+  
+   IN:
+       state............the current state of the verifier
 
-#define COPYTYPE(source,dest)                                        \
-    {if (VAROP(source)->type == TYPE_ADR)                            \
-            TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
+   RETURN VALUE:
+       true.............successful verification,
+          false............an exception has been thrown.
 
-#define ISBUILTIN(v)   (bte->fp == (functionptr) (v))
+*******************************************************************************/
 
+static bool
+handle_fieldaccess(verifier_state *state,
+                                  varinfo *instance,
+                                  varinfo *value)
+{
+       jitdata *jd;
 
-/* verify_invocation ***********************************************************
+       jd = state->jd;
+
+#define TYPECHECK_VARIABLESBASED
+#define EXCEPTION  do { return false; } while (0)
+#define VERIFY_ERROR(msg)  TYPECHECK_VERIFYERROR_bool(msg)
+#include <typecheck-fields.inc>
+#undef  EXCEPTION
+#undef  VERIFY_ERROR
+#undef  TYPECHECK_VARIABLESBASED
+
+       return true;
+}
+
+
+/* handle_invocation ***********************************************************
  
    Verify an ICMD_INVOKE* instruction.
   
@@ -525,21 +320,25 @@ typestate_restore_invars(verifier_state *state)
 *******************************************************************************/
 
 static bool
-verify_invocation(verifier_state *state)
+handle_invocation(verifier_state *state)
 {
        jitdata *jd;
-       varinfo *dv;
+    varinfo *dv;               /* output variable of current instruction */
 
        jd = state->jd;
        dv = VAROP(state->iptr->dst);
 
+#define TYPECHECK_VARIABLESBASED
+#define OP1   VAR(state->iptr->sx.s23.s2.args[0])
 #include <typecheck-invoke.inc>
+#undef  OP1
+#undef  TYPECHECK_VARIABLESBASED
 
        return true;
 }
 
 
-/* verify_builtin **************************************************************
+/* handle_builtin **************************************************************
  
    Verify the call of a builtin method.
   
@@ -553,21 +352,24 @@ verify_invocation(verifier_state *state)
 *******************************************************************************/
 
 static bool
-verify_builtin(verifier_state *state)
+handle_builtin(verifier_state *state)
 {
-       varinfo *dv;
        jitdata *jd;
+    varinfo *dv;               /* output variable of current instruction */
 
        jd = state->jd;
        dv = VAROP(state->iptr->dst);
 
+#define TYPECHECK_VARIABLESBASED
+#define OP1   state->iptr->sx.s23.s2.args[0]
 #include <typecheck-builtins.inc>
+#undef  OP1
+#undef  TYPECHECK_VARIABLESBASED
 
        return true;
 }
 
-
-/* verify_multianewarray *******************************************************
+/* handle_multianewarray *******************************************************
  
    Verify a MULTIANEWARRAY instruction.
   
@@ -581,67 +383,23 @@ verify_builtin(verifier_state *state)
 *******************************************************************************/
 
 static bool
-verify_multianewarray(verifier_state *state)
+handle_multianewarray(verifier_state *state)
 {
-       classinfo *arrayclass;
-       arraydescriptor *desc;
-       s4 i;
-       jitdata *jd = state->jd;
-
-       /* check the array lengths on the stack */
-       i = state->iptr->s1.argcount;
-       if (i < 1)
-               TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
-
-       while (i--) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[i]);
-       }
-
-       /* check array descriptor */
-       if (INSTRUCTION_IS_RESOLVED(state->iptr)) {
-               /* the array class reference has already been resolved */
-               arrayclass = state->iptr->sx.s23.s3.c.cls;
-               if (!arrayclass)
-                       TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
-               if ((desc = arrayclass->vftbl->arraydesc) == NULL)
-                       TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
-               if (desc->dimension < state->iptr->s1.argcount)
-                       TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
-
-               /* set the array type of the result */
-               typeinfo_init_classinfo(&(VAROP(state->iptr->dst)->typeinfo), arrayclass);
-       }
-       else {
-               const char *p;
-               constant_classref *cr;
-               
-               /* the array class reference is still unresolved */
-               /* check that the reference indicates an array class of correct dimension */
-               cr = state->iptr->sx.s23.s3.c.ref;
-               i = 0;
-               p = cr->name->text;
-               while (p[i] == '[')
-                       i++;
-               /* { the dimension of the array class == i } */
-               if (i < 1)
-                       TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
-               if (i < state->iptr->s1.argcount)
-                       TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
-
-               /* set the array type of the result */
-               if (!typeinfo_init_class(&(VAROP(state->iptr->dst)->typeinfo),CLASSREF_OR_CLASSINFO(cr)))
-                       return false;
-       }
+       jitdata *jd;
+    varinfo *dv;               /* output variable of current instruction */
 
-       /* set return type */
+       jd = state->jd;
+       dv = VAROP(state->iptr->dst);
 
-       VAROP(state->iptr->dst)->type = TYPE_ADR;
+#define TYPECHECK_VARIABLESBASED
+#define VERIFY_ERROR(msg)  TYPECHECK_VERIFYERROR_bool(msg)
+#include <typecheck-multianewarray.inc>
+#undef VERIFY_ERROR
+#undef  TYPECHECK_VARIABLESBASED
 
-       /* everything ok */
        return true;
 }
 
-
 /* typecheck_invalidate_locals *************************************************
  
    Invalidate locals that are overwritten by writing to the given local.
@@ -655,56 +413,92 @@ verify_multianewarray(verifier_state *state)
 
 static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool twoword)
 {
-       s4 i;
+       s4 javaindex;
        s4 t;
-       s4 mapped;
+       s4 varindex;
        jitdata *jd = state->jd;
        s4 *localmap = jd->local_map;
        varinfo *vars = jd->var;
 
-       i = state->reverselocalmap[index];
+       javaindex = jd->reverselocalmap[index];
 
-       /* invalidate locals of two-word type at index i-1 */
+       /* invalidate locals of two-word type at index javaindex-1 */
 
-       if (i > 0) {
-               localmap += 5 * (i-1);
+       if (javaindex > 0) {
+               localmap += 5 * (javaindex-1);
                for (t=0; t<5; ++t) {
-                       mapped = *localmap++;
-                       if (mapped >= 0 && IS_2_WORD_TYPE(vars[mapped].type)) {
-                               LOG1("invalidate local %d", mapped);
-                               vars[mapped].type = TYPE_VOID;
+                       varindex = *localmap++;
+                       if (varindex >= 0 && IS_2_WORD_TYPE(vars[varindex].type)) {
+                               LOG1("invalidate local %d", varindex);
+                               vars[varindex].type = TYPE_VOID;
                        }
                }
        }
        else {
-               localmap += 5 * i;
+               localmap += 5 * javaindex;
        }
 
-       /* invalidate locals at index i */
+       /* invalidate locals at index javaindex */
 
        for (t=0; t<5; ++t) {
-               mapped = *localmap++;
-               if (mapped >= 0) {
-                       LOG1("invalidate local %d", mapped);
-                       vars[mapped].type = TYPE_VOID;
+               varindex = *localmap++;
+               if (varindex >= 0) {
+                       LOG1("invalidate local %d", varindex);
+                       vars[varindex].type = TYPE_VOID;
                }
        }
 
-       /* if a two-word type is written, invalidate locals at index i+1 */
+       /* if a two-word type is written, invalidate locals at index javaindex+1 */
 
        if (twoword) {
                for (t=0; t<5; ++t) {
-                       mapped = *localmap++;
-                       if (mapped >= 0) {
-                               LOG1("invalidate local %d", mapped);
-                               vars[mapped].type = TYPE_VOID;
+                       varindex = *localmap++;
+                       if (varindex >= 0) {
+                               LOG1("invalidate local %d", varindex);
+                               vars[varindex].type = TYPE_VOID;
                        }
                }
        }
 }
 
 
-/* verify_basic_block **********************************************************
+/* macros used by the generated code ******************************************/
+
+#define EXCEPTION          do { return false; } while (0)
+#define VERIFY_ERROR(msg)  TYPECHECK_VERIFYERROR_bool(msg)
+
+#define CHECK_LOCAL_TYPE(index, t)                                   \
+    do {                                                             \
+        if (!typevector_checktype(jd->var, (index), (t)))            \
+             VERIFY_ERROR("Local variable type mismatch");           \
+    } while (0)
+
+#define STORE_LOCAL(t, index)                                        \
+    do {                                                             \
+         s4 temp_t = (t);                                            \
+         typecheck_invalidate_locals(state, (index), false);         \
+         typevector_store(jd->var, (index), (temp_t), NULL);         \
+    } while (0)
+
+#define STORE_LOCAL_2_WORD(t, index)                                 \
+    do {                                                             \
+         s4 temp_t = (t);                                            \
+         typecheck_invalidate_locals(state, (index), true);          \
+         typevector_store(jd->var, (index), (temp_t), NULL);         \
+    } while (0)
+
+#define REACH_BLOCK(target)                                          \
+    do {                                                             \
+        if (!typestate_reach(state, (target),                        \
+                             state->bptr->outvars, jd->var,          \
+                             state->bptr->outdepth))                 \
+                return false;                                        \
+    } while (0)
+
+#define REACH(target)   REACH_BLOCK((target).block)
+
+
+/* handle_basic_block **********************************************************
  
    Perform bytecode verification of a basic block.
   
@@ -718,7 +512,7 @@ static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool tw
 *******************************************************************************/
 
 static bool
-verify_basic_block(verifier_state *state)
+handle_basic_block(verifier_state *state)
 {
     int opcode;                                      /* current opcode */
     int len;                        /* for counting instructions, etc. */
@@ -726,33 +520,29 @@ verify_basic_block(verifier_state *state)
        instruction *iptr;                      /* the current instruction */
     basicblock *tbptr;                   /* temporary for target block */
     bool maythrow;               /* true if this instruction may throw */
-       unresolved_field *uf;                        /* for field accesses */
-       constant_FMIref *fieldref;                   /* for field accesses */
        s4 i;
        typecheck_result r;
-       resolve_result_t result;
        branch_target_t *table;
        lookup_target_t *lookup;
        jitdata *jd = state->jd;
-       varinfo *dv;
-       exceptiontable *ex;
+       exception_entry *ex;
+       varinfo constvalue;                               /* for PUT*CONST */
+       constant_FMIref *fieldref;
 
        LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
        LOGFLUSH;
-       DOLOG(show_basicblock(jd, state->bptr, SHOW_STACK));
 
        superblockend = false;
        state->bptr->flags = BBFINISHED;
 
        /* prevent compiler warnings */
 
-       dv = NULL;
 
        /* determine the active exception handlers for this block */
        /* XXX could use a faster algorithm with sorted lists or  */
        /* something?                                             */
        len = 0;
-       for (ex = state->cd->exceptiontable; ex ; ex = ex->down) {
+       for (ex = state->jd->exceptiontable; ex ; ex = ex->down) {
                if ((ex->start->nr <= state->bptr->nr) && (ex->end->nr > state->bptr->nr)) {
                        LOG1("active handler L%03d", ex->handler->nr);
                        state->handlers[len++] = ex;
@@ -763,6 +553,7 @@ verify_basic_block(verifier_state *state)
        /* init variable types at the start of this block */
        typevector_copy_inplace(state->bptr->inlocals, jd->var, state->numlocals);
 
+       DOLOG(show_basicblock(jd, state->bptr, SHOW_STACK));
        DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->invars, 
                                state->bptr->indepth));
        DOLOG(typevector_print(stdout, jd->var, state->numlocals));
@@ -781,729 +572,26 @@ verify_basic_block(verifier_state *state)
                DOLOG(show_icmd(jd, state->iptr, false, SHOW_STACK)); LOGNL; LOGFLUSH;
 
                opcode = iptr->opc;
-               dv = VAROP(iptr->dst);
                maythrow = false;
 
                switch (opcode) {
 
-                       /****************************************/
-                       /* STACK MANIPULATIONS                  */
-
-                       /* We just need to copy the typeinfo */
-                       /* for slots containing addresses.   */
-
-                       case ICMD_MOVE:
-                       case ICMD_COPY:
-                               TYPECHECK_COUNT(stat_ins_stack);
-                               COPYTYPE(iptr->s1, iptr->dst);
-                               dv->type = VAROP(iptr->s1)->type;
-                               break;
-
-                               /****************************************/
-                               /* PRIMITIVE VARIABLE ACCESS            */
-
-                       case ICMD_ILOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT)) 
-                                                                TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
-                                                        dv->type = TYPE_INT;
-                                                        break;
-                       case ICMD_IINC:  if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
-                                                                TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
-                                                        dv->type = TYPE_INT;
-                                                        break;
-                       case ICMD_FLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_FLT))
-                                                                TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
-                                                        dv->type = TYPE_FLT;
-                                                        break;
-                       case ICMD_LLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_LNG))
-                                                                TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
-                                                        dv->type = TYPE_LNG;
-                                                        break;
-                       case ICMD_DLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_DBL))
-                                                                TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
-                                                        dv->type = TYPE_DBL;
-                                                        break;
-
-                       case ICMD_ISTORE: 
-                                                        typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
-                                                        typevector_store(jd->var,state->iptr->dst.varindex,TYPE_INT,NULL); 
-                                                        break;
-                       case ICMD_FSTORE: 
-                                                        typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
-                                                        typevector_store(jd->var,state->iptr->dst.varindex,TYPE_FLT,NULL); 
-                                                        break;
-                       case ICMD_LSTORE: 
-                                                        typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
-                                                        typevector_store(jd->var,state->iptr->dst.varindex,TYPE_LNG,NULL); 
-                                                        break;
-                       case ICMD_DSTORE: 
-                                                        typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
-                                                        typevector_store(jd->var,state->iptr->dst.varindex,TYPE_DBL,NULL); 
-                                                        break;
-
-                               /****************************************/
-                               /* LOADING ADDRESS FROM VARIABLE        */
-
-                       case ICMD_ALOAD:
-                               TYPECHECK_COUNT(stat_ins_aload);
-
-                               /* loading a returnAddress is not allowed */
-                               if (!TYPEDESC_IS_REFERENCE(*VAROP(state->iptr->s1))) {
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
-                               }
-                               TYPEINFO_COPY(VAROP(state->iptr->s1)->typeinfo,dv->typeinfo);
-                               dv->type = TYPE_ADR;
-                               break;
-
-                               /****************************************/
-                               /* STORING ADDRESS TO VARIABLE          */
-
-                       case ICMD_ASTORE:
-                               typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
-
-                               if (TYPEINFO_IS_PRIMITIVE(VAROP(state->iptr->s1)->typeinfo)) {
-                                       typevector_store_retaddr(jd->var,state->iptr->dst.varindex,&(VAROP(state->iptr->s1)->typeinfo));
-                               }
-                               else {
-                                       typevector_store(jd->var,state->iptr->dst.varindex,TYPE_ADR,
-                                                       &(VAROP(state->iptr->s1)->typeinfo));
-                               }
-                               break;
-
-                               /****************************************/
-                               /* LOADING ADDRESS FROM ARRAY           */
-
-                       case ICMD_AALOAD:
-                               if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
-
-                               if (!typeinfo_init_component(&VAROP(state->iptr->s1)->typeinfo,&dv->typeinfo))
-                                       return false;
-                               dv->type = TYPE_ADR;
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* FIELD ACCESS                         */
-
-                       case ICMD_PUTFIELD:
-                       case ICMD_PUTSTATIC:
-                       case ICMD_PUTFIELDCONST:
-                       case ICMD_PUTSTATICCONST:
-                       case ICMD_GETFIELD:
-                       case ICMD_GETSTATIC:
-
-#include <typecheck-fields.inc>
-
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* PRIMITIVE ARRAY ACCESS               */
-
-                       case ICMD_ARRAYLENGTH:
-                               if (!TYPEINFO_MAYBE_ARRAY(VAROP(state->iptr->s1)->typeinfo)
-                                               && VAROP(state->iptr->s1)->typeinfo.typeclass.cls != pseudo_class_Arraystub)
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
-                               dv->type = TYPE_INT;
-                               maythrow = true;
-                               break;
-
-                       case ICMD_BALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
-                                               && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_INT;
-                               maythrow = true;
-                               break;
-                       case ICMD_CALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_INT;
-                               maythrow = true;
-                               break;
-                       case ICMD_DALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_DBL;
-                               maythrow = true;
-                               break;
-                       case ICMD_FALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_FLT;
-                               maythrow = true;
-                               break;
-                       case ICMD_IALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_INT;
-                               maythrow = true;
-                               break;
-                       case ICMD_SALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_INT;
-                               maythrow = true;
-                               break;
-                       case ICMD_LALOAD:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               dv->type = TYPE_LNG;
-                               maythrow = true;
-                               break;
-
-                       case ICMD_BASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
-                                               && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-                       case ICMD_CASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-                       case ICMD_DASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-                       case ICMD_FASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-                       case ICMD_IASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-                       case ICMD_SASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-                       case ICMD_LASTORE:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-
-                       case ICMD_AASTORE:
-                               /* we just check the basic input types and that the           */
-                               /* destination is an array of references. Assignability to    */
-                               /* the actual array must be checked at runtime, each time the */
-                               /* instruction is performed. (See builtin_canstore.)          */
-                               TYPECHECK_ADR_OP(state->iptr->sx.s23.s3);
-                               TYPECHECK_INT_OP(state->iptr->sx.s23.s2);
-                               TYPECHECK_ADR_OP(state->iptr->s1);
-                               if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
-                               maythrow = true;
-                               break;
-
-                       case ICMD_IASTORECONST:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_INT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-
-                       case ICMD_LASTORECONST:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_LONG))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-
-                       case ICMD_BASTORECONST:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BOOLEAN)
-                                               && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BYTE))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-
-                       case ICMD_CASTORECONST:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_CHAR))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-
-                       case ICMD_SASTORECONST:
-                               if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_SHORT))
-                                       TYPECHECK_VERIFYERROR_bool("Array type mismatch");
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* ADDRESS CONSTANTS                    */
-
-                       case ICMD_ACONST:
-                               if (state->iptr->flags.bits & INS_FLAG_CLASS) {
-                                       /* a java.lang.Class reference */
-                                       TYPEINFO_INIT_JAVA_LANG_CLASS(dv->typeinfo,state->iptr->sx.val.c);
-                               }
-                               else {
-                                       if (state->iptr->sx.val.anyptr == NULL)
-                                               TYPEINFO_INIT_NULLTYPE(dv->typeinfo);
-                                       else {
-                                               /* string constant (or constant for builtin function) */
-                                               typeinfo_init_classinfo(&(dv->typeinfo),class_java_lang_String);
-                                       }
-                               }
-                               dv->type = TYPE_ADR;
-                               break;
-
-                               /****************************************/
-                               /* CHECKCAST AND INSTANCEOF             */
-
-                       case ICMD_CHECKCAST:
-                               TYPECHECK_ADR_OP(state->iptr->s1);
-                               /* returnAddress is not allowed */
-                               if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
-                                       TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
-
-                               if (!typeinfo_init_class(&(dv->typeinfo),state->iptr->sx.s23.s3.c))
-                                               return false;
-                               dv->type = TYPE_ADR;
-                               maythrow = true;
-                               break;
-
-                       case ICMD_INSTANCEOF:
-                               TYPECHECK_ADR_OP(state->iptr->s1);
-                               /* returnAddress is not allowed */
-                               if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
-                                       TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
-                               dv->type = TYPE_INT;
-                               break;
-
-                               /****************************************/
-                               /* BRANCH INSTRUCTIONS                  */
-
-                       case ICMD_INLINE_GOTO:
-                               COPYTYPE(state->iptr->s1,state->iptr->dst);
-                               /* FALLTHROUGH! */
-                       case ICMD_GOTO:
-                               superblockend = true;
-                               /* FALLTHROUGH! */
-                       case ICMD_IFNULL:
-                       case ICMD_IFNONNULL:
-                       case ICMD_IFEQ:
-                       case ICMD_IFNE:
-                       case ICMD_IFLT:
-                       case ICMD_IFGE:
-                       case ICMD_IFGT:
-                       case ICMD_IFLE:
-                       case ICMD_IF_ICMPEQ:
-                       case ICMD_IF_ICMPNE:
-                       case ICMD_IF_ICMPLT:
-                       case ICMD_IF_ICMPGE:
-                       case ICMD_IF_ICMPGT:
-                       case ICMD_IF_ICMPLE:
-                       case ICMD_IF_ACMPEQ:
-                       case ICMD_IF_ACMPNE:
-
-                       case ICMD_IF_LEQ:
-                       case ICMD_IF_LNE:
-                       case ICMD_IF_LLT:
-                       case ICMD_IF_LGE:
-                       case ICMD_IF_LGT:
-                       case ICMD_IF_LLE:
-
-                       case ICMD_IF_LCMPEQ:
-                       case ICMD_IF_LCMPNE:
-                       case ICMD_IF_LCMPLT:
-                       case ICMD_IF_LCMPGE:
-                       case ICMD_IF_LCMPGT:
-                       case ICMD_IF_LCMPLE:
-
-                       case ICMD_IF_FCMPEQ:
-                       case ICMD_IF_FCMPNE:
-
-                       case ICMD_IF_FCMPL_LT:
-                       case ICMD_IF_FCMPL_GE:
-                       case ICMD_IF_FCMPL_GT:
-                       case ICMD_IF_FCMPL_LE:
-
-                       case ICMD_IF_FCMPG_LT:
-                       case ICMD_IF_FCMPG_GE:
-                       case ICMD_IF_FCMPG_GT:
-                       case ICMD_IF_FCMPG_LE:
-
-                       case ICMD_IF_DCMPEQ:
-                       case ICMD_IF_DCMPNE:
-
-                       case ICMD_IF_DCMPL_LT:
-                       case ICMD_IF_DCMPL_GE:
-                       case ICMD_IF_DCMPL_GT:
-                       case ICMD_IF_DCMPL_LE:
-
-                       case ICMD_IF_DCMPG_LT:
-                       case ICMD_IF_DCMPG_GE:
-                       case ICMD_IF_DCMPG_GT:
-                       case ICMD_IF_DCMPG_LE:
-                               TYPECHECK_COUNT(stat_ins_branch);
-
-                               /* propagate stack and variables to the target block */
-                               if (!typestate_reach(state, state->iptr->dst.block,
-                                                                        state->bptr->outvars, jd->var, 
-                                                                        state->bptr->outdepth))
-                                       return false;
-                               break;
-
-                               /****************************************/
-                               /* SWITCHES                             */
-
-                       case ICMD_TABLESWITCH:
-                               TYPECHECK_COUNT(stat_ins_switch);
-
-                               table = iptr->dst.table;
-                               i = iptr->sx.s23.s3.tablehigh
-                                       - iptr->sx.s23.s2.tablelow + 1 + 1; /* plus default */
-
-                               while (--i >= 0) {
-                                       tbptr = (table++)->block;
-                                       LOG2("target %d is block %04d",i,tbptr->nr);
-                                       if (!typestate_reach(state, tbptr, state->bptr->outvars,
-                                                                                jd->var, state->bptr->outdepth))
-                                               return false;
-                               }
-
-                               LOG("switch done");
-                               superblockend = true;
-                               break;
-
-                       case ICMD_LOOKUPSWITCH:
-                               TYPECHECK_COUNT(stat_ins_switch);
-
-                               lookup = iptr->dst.lookup;
-                               i = iptr->sx.s23.s2.lookupcount;
-
-                               if (!typestate_reach(state,iptr->sx.s23.s3.lookupdefault.block,
-                                                                        state->bptr->outvars, jd->var,
-                                                                        state->bptr->outdepth))
-                                       return false;
-
-                               while (--i >= 0) {
-                                       tbptr = (lookup++)->target.block;
-                                       LOG2("target %d is block %04d",i,tbptr->nr);
-                                       if (!typestate_reach(state, tbptr, state->bptr->outvars,
-                                                               jd->var, state->bptr->outdepth))
-                                               return false;
-                               }
-
-                               LOG("switch done");
-                               superblockend = true;
-                               break;
-
-
-                               /****************************************/
-                               /* ADDRESS RETURNS AND THROW            */
-
-                       case ICMD_ATHROW:
-                               TYPECHECK_COUNT(stat_ins_athrow);
-                               r = typeinfo_is_assignable_to_class(&VAROP(state->iptr->s1)->typeinfo,
-                                               CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
-                               if (r == typecheck_FALSE)
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
-                               if (r == typecheck_FAIL)
-                                       return false;
-                               if (r == typecheck_MAYBE) {
-                                       /* the check has to be postponed. we need a patcher */
-                                       TYPECHECK_COUNT(stat_ins_athrow_unresolved);
-                                       iptr->sx.s23.s2.uc = create_unresolved_class(
-                                                       state->m, 
-                                                       /* XXX make this more efficient, use class_java_lang_Throwable
-                                                        * directly */
-                                                       class_get_classref(state->m->class,utf_java_lang_Throwable),
-                                                       &VAROP(state->iptr->s1)->typeinfo);
-                                       iptr->flags.bits |= INS_FLAG_UNRESOLVED;
-                               }
-                               superblockend = true;
-                               maythrow = true;
-                               break;
-
-                       case ICMD_ARETURN:
-                               TYPECHECK_COUNT(stat_ins_areturn);
-                               if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
-
-                               if (state->returntype.type != TYPE_ADR
-                                               || (r = typeinfo_is_assignable(&VAROP(state->iptr->s1)->typeinfo,&(state->returntype.typeinfo))) 
-                                                               == typecheck_FALSE)
-                                       TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-                               if (r == typecheck_FAIL)
-                                       return false;
-                               if (r == typecheck_MAYBE) {
-                                       /* the check has to be postponed, we need a patcher */
-                                       TYPECHECK_COUNT(stat_ins_areturn_unresolved);
-                                       iptr->sx.s23.s2.uc = create_unresolved_class(
-                                                       state->m, 
-                                                       state->m->parseddesc->returntype.classref,
-                                                       &VAROP(state->iptr->s1)->typeinfo);
-                                       iptr->flags.bits |= INS_FLAG_UNRESOLVED;
-                               }
-                               goto return_tail;
-
-                               /****************************************/
-                               /* PRIMITIVE RETURNS                    */
-
-                       case ICMD_IRETURN:
-                               if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-                               goto return_tail;
-
-                       case ICMD_LRETURN:
-                               if (state->returntype.type != TYPE_LNG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-                               goto return_tail;
-
-                       case ICMD_FRETURN:
-                               if (state->returntype.type != TYPE_FLT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-                               goto return_tail;
-
-                       case ICMD_DRETURN:
-                               if (state->returntype.type != TYPE_DBL) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-                               goto return_tail;
-
-                       case ICMD_RETURN:
-                               if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-return_tail:
-                               TYPECHECK_COUNT(stat_ins_primitive_return);
-
-                               if (state->initmethod && state->m->class != class_java_lang_Object) {
-                                       /* Check if the 'this' instance has been initialized. */
-                                       LOG("Checking <init> marker");
-                                       if (!typevector_checktype(jd->var,state->numlocals-1,TYPE_INT))
-                                               TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
-                               }
-
-                               superblockend = true;
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* SUBROUTINE INSTRUCTIONS              */
-
-                       case ICMD_JSR:
-                               LOG("jsr");
-
-                               tbptr = state->iptr->sx.s23.s3.jsrtarget.block;
-                               TYPEINFO_INIT_RETURNADDRESS(dv->typeinfo, state->bptr->next);
-                               if (!typestate_reach(state, tbptr, state->bptr->outvars, jd->var,
-                                                       state->bptr->outdepth))
-                                       return false;
-
-                               superblockend = true;
-                               break;
-
-                       case ICMD_RET:
-                               /* check returnAddress variable */
-                               if (!typevector_checkretaddr(jd->var,state->iptr->s1.varindex))
-                                       TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
-
-                               if (!typestate_reach(state, iptr->dst.block, state->bptr->outvars, jd->var,
-                                                       state->bptr->outdepth))
-                                       return false;
-
-                               superblockend = true;
-                               break;
-
-                               /****************************************/
-                               /* INVOKATIONS                          */
-
-                       case ICMD_INVOKEVIRTUAL:
-                       case ICMD_INVOKESPECIAL:
-                       case ICMD_INVOKESTATIC:
-                       case ICMD_INVOKEINTERFACE:
-                               TYPECHECK_COUNT(stat_ins_invoke);
-                               if (!verify_invocation(state))
-                                       return false;
-                               TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(iptr), stat_ins_invoke_unresolved);
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* MULTIANEWARRAY                       */
-
-                       case ICMD_MULTIANEWARRAY:
-                               if (!verify_multianewarray(state))
-                                       return false;           
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* BUILTINS                             */
-
-                       case ICMD_BUILTIN:
-                               TYPECHECK_COUNT(stat_ins_builtin);
-                               if (!verify_builtin(state))
-                                       return false;
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* SIMPLE EXCEPTION THROWING TESTS      */
-
-                       case ICMD_CHECKNULL:
-                               /* CHECKNULL just requires that the stack top
-                                * is an address. This is checked in stack.c */
-                               maythrow = true;
-                               break;
-
-                               /****************************************/
-                               /* INSTRUCTIONS WHICH SHOULD HAVE BEEN  */
-                               /* REPLACED BY OTHER OPCODES            */
-
-#ifdef TYPECHECK_DEBUG
-                       case ICMD_NEW:
-                       case ICMD_NEWARRAY:
-                       case ICMD_ANEWARRAY:
-                       case ICMD_MONITORENTER:
-                       case ICMD_MONITOREXIT:
-                               LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
-                               LOG("Should have been converted to builtin function call.");
-                               TYPECHECK_ASSERT(false);
-                               break;
-#endif
+                       /* include generated code for ICMDs verification */
 
-                               /****************************************/
-                               /* UNCHECKED OPERATIONS                 */
-
-                               /*********************************************
-                                * Instructions below...
-                                *     *) don't operate on local variables,
-                                *     *) don't operate on references,
-                                *     *) don't operate on returnAddresses,
-                                *     *) don't affect control flow (except
-                                *        by throwing exceptions).
-                                *
-                                * (These instructions are typechecked in
-                                *  analyse_stack.)
-                                ********************************************/
-
-                               /* Instructions which may throw a runtime exception: */
-
-                       case ICMD_IDIV:
-                       case ICMD_IREM:
-                               dv->type = TYPE_INT;
-                               maythrow = true;
-                               break;
-
-                       case ICMD_LDIV:
-                       case ICMD_LREM:
-                               dv->type = TYPE_LNG;
-                               maythrow = true;
-                               break;
-
-                               /* Instructions which never throw a runtime exception: */
-                       case ICMD_NOP:
-                       case ICMD_POP:
-                       case ICMD_POP2:
-                               break;
-
-                       case ICMD_ICONST:
-                       case ICMD_IADD:
-                       case ICMD_ISUB:
-                       case ICMD_IMUL:
-                       case ICMD_INEG:
-                       case ICMD_IAND:
-                       case ICMD_IOR:
-                       case ICMD_IXOR:
-                       case ICMD_ISHL:
-                       case ICMD_ISHR:
-                       case ICMD_IUSHR:
-                       case ICMD_IMULPOW2:
-                       case ICMD_IDIVPOW2:
-                       case ICMD_IADDCONST:
-                       case ICMD_ISUBCONST:
-                       case ICMD_IMULCONST:
-                       case ICMD_IANDCONST:
-                       case ICMD_IORCONST:
-                       case ICMD_IXORCONST:
-                       case ICMD_ISHLCONST:
-                       case ICMD_ISHRCONST:
-                       case ICMD_IUSHRCONST:
-                       case ICMD_IREMPOW2:
-                       case ICMD_INT2BYTE:
-                       case ICMD_INT2CHAR:
-                       case ICMD_INT2SHORT:
-                       case ICMD_L2I:
-                       case ICMD_F2I:
-                       case ICMD_D2I:
-                       case ICMD_LCMP:
-                       case ICMD_LCMPCONST:
-                       case ICMD_FCMPL:
-                       case ICMD_FCMPG:
-                       case ICMD_DCMPL:
-                       case ICMD_DCMPG:
-                               dv->type = TYPE_INT;
-                               break;
-
-                       case ICMD_LCONST:
-                       case ICMD_LADD:
-                       case ICMD_LSUB:
-                       case ICMD_LMUL:
-                       case ICMD_LNEG:
-                       case ICMD_LAND:
-                       case ICMD_LOR:
-                       case ICMD_LXOR:
-                       case ICMD_LSHL:
-                       case ICMD_LSHR:
-                       case ICMD_LUSHR:
-                       case ICMD_LMULPOW2:
-                       case ICMD_LDIVPOW2:
-                       case ICMD_LADDCONST:
-                       case ICMD_LSUBCONST:
-                       case ICMD_LMULCONST:
-                       case ICMD_LANDCONST:
-                       case ICMD_LORCONST:
-                       case ICMD_LXORCONST:
-                       case ICMD_LSHLCONST:
-                       case ICMD_LSHRCONST:
-                       case ICMD_LUSHRCONST:
-                       case ICMD_LREMPOW2:
-                       case ICMD_I2L:
-                       case ICMD_F2L:
-                       case ICMD_D2L:
-                               dv->type = TYPE_LNG;
-                               break;
-
-                       case ICMD_FCONST:
-                       case ICMD_I2F:
-                       case ICMD_L2F:
-                       case ICMD_D2F:
-                       case ICMD_FADD:
-                       case ICMD_FSUB:
-                       case ICMD_FMUL:
-                       case ICMD_FDIV:
-                       case ICMD_FREM:
-                       case ICMD_FNEG:
-                               dv->type = TYPE_FLT;
-                               break;
-
-                       case ICMD_DCONST:
-                       case ICMD_I2D:
-                       case ICMD_L2D:
-                       case ICMD_F2D:
-                       case ICMD_DADD:
-                       case ICMD_DSUB:
-                       case ICMD_DMUL:
-                       case ICMD_DDIV:
-                       case ICMD_DREM:
-                       case ICMD_DNEG:
-                               dv->type = TYPE_DBL;
-                               break;
-
-                       case ICMD_INLINE_START:
-                       case ICMD_INLINE_END:
-                               break;
-
-                               /* XXX What shall we do with the following ?*/
-                       case ICMD_AASTORECONST:
-                               TYPECHECK_COUNT(stat_ins_unchecked);
-                               break;
-
-                               /****************************************/
+#define TYPECHECK_VARIABLESBASED
+#define STATE  state
+#define METHOD (state->m)
+#define IPTR   iptr
+#define BPTR   (state->bptr)
+#include <typecheck-variablesbased-gen.inc>
+#undef  STATE
+#undef  METHOD
+#undef  IPTR
+#undef  BPTR
+#undef  TYPECHECK_VARIABLESBASED
 
                        default:
-                               LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
+                               LOG1("ICMD %d\n", opcode);
                                TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
                }
 
@@ -1567,80 +655,6 @@ return_tail:
 }
 
 
-/* verify_init_locals **********************************************************
-   Initialize the local variables in the verifier state.
-  
-   IN:
-       state............the current state of the verifier
-
-   RETURN VALUE:
-       true.............success,
-          false............an exception has been thrown.
-
-*******************************************************************************/
-
-static bool
-verify_init_locals(verifier_state *state)
-{
-       int i;
-       int index;
-       varinfo *locals;
-       varinfo *v;
-       jitdata *jd = state->jd;
-       int skip = 0;
-
-       locals = state->basicblocks[0].inlocals;
-
-       /* allocate parameter descriptors if necessary */
-       
-       if (!state->m->parseddesc->params)
-               if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
-                       return false;
-
-       /* pre-initialize variables as TYPE_VOID */
-       
-       i = state->numlocals;
-       v = locals;
-       while (i--) {
-               v->type = TYPE_VOID;
-               v++;
-       }
-
-    /* if this is an instance method initialize the "this" ref type */
-       
-    if (!(state->m->flags & ACC_STATIC)) {
-               index = jd->local_map[5*0 + TYPE_ADR];
-               if (index != UNUSED) {
-                       if (state->validlocals < 1)
-                               TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
-                       v = locals + index;
-                       v->type = TYPE_ADR;
-                       if (state->initmethod)
-                               TYPEINFO_INIT_NEWOBJECT(v->typeinfo, NULL);
-                       else
-                               typeinfo_init_classinfo(&(v->typeinfo), state->m->class);
-               }
-
-               skip = 1;
-    }
-
-    LOG("'this' argument set.\n");
-
-    /* the rest of the arguments and the return type */
-       
-    if (!typeinfo_init_varinfos_from_methoddesc(locals, state->m->parseddesc,
-                                                                                         state->validlocals,
-                                                                                         skip, /* skip 'this' pointer */
-                                                                                         jd->local_map,
-                                                                                         &state->returntype))
-               return false;
-
-    LOG("Arguments set.\n");
-       return true;
-}
-
-
 /****************************************************************************/
 /* typecheck()                                                              */
 /* This is the main function of the bytecode verifier. It is called         */
@@ -1665,15 +679,13 @@ bool typecheck(jitdata *jd)
        codegendata    *cd;
        varinfo        *savedlocals;
        verifier_state  state;             /* current state of the verifier */
-       s4              i;
-       s4              t;
 
        /* collect statistics */
 
 #ifdef TYPECHECK_STATISTICS
        int count_iterations = 0;
        TYPECHECK_COUNT(stat_typechecked);
-       TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
+       TYPECHECK_COUNT_FREQ(stat_locals,jd->maxlocals,STAT_LOCALS);
        TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
        TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
        state.stat_maythrow = false;
@@ -1702,13 +714,19 @@ bool typecheck(jitdata *jd)
        state.savedindices = NULL;
        state.savedinvars = NULL;
 
+       /* check that the basicblock numbers are valid */
+
+#if !defined(NDEBUG)
+       jit_check_basicblock_numbers(jd);
+#endif
+
        /* check if this method is an instance initializer method */
 
     state.initmethod = (state.m->name == utf_init);
 
        /* initialize the basic block flags for the following CFG traversal */
 
-       typecheck_init_flags(&state);
+       typecheck_init_flags(&state, BBFINISHED);
 
     /* number of local variables */
     
@@ -1722,23 +740,17 @@ bool typecheck(jitdata *jd)
     if (state.initmethod) 
                state.numlocals++; /* VERIFIER_EXTRA_LOCALS */
 
-       state.reverselocalmap = DMNEW(s4, state.validlocals);
-       for (i=0; i<jd->m->maxlocals; ++i)
-               for (t=0; t<5; ++t) {
-                       s4 mapped = jd->local_map[5*i + t];
-                       if (mapped >= 0)
-                               state.reverselocalmap[mapped] = i;
-               }
-
        DOLOG(
+               s4 i;
+               s4 t;
                LOG("reverselocalmap:");
                for (i=0; i<state.validlocals; ++i) {
-                       LOG2("    %i => javaindex %i", i, state.reverselocalmap[i]);
+                       LOG2("    %i => javaindex %i", i, jd->reverselocalmap[i]);
                });
 
     /* allocate the buffer of active exception handlers */
        
-    state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
+    state.handlers = DMNEW(exception_entry*, state.jd->exceptiontablelength + 1);
 
        /* save local variables */
 
@@ -1747,7 +759,7 @@ bool typecheck(jitdata *jd)
 
        /* initialized local variables of first block */
 
-       if (!verify_init_locals(&state))
+       if (!typecheck_init_locals(&state, true))
                return false;
 
     /* initialize invars of exception handlers */
@@ -1774,7 +786,7 @@ bool typecheck(jitdata *jd)
             
                    /* verify reached block */  
             if (state.bptr->flags == BBTYPECHECK_REACHED) {
-                if (!verify_basic_block(&state))
+                if (!handle_basic_block(&state))
                                        return false;
             }
         } /* for blocks */