* src/vm/jit/verify/typecheck-typeinferer.c: New type inference pass.
authoredwin <none@none>
Wed, 3 Jan 2007 22:39:14 +0000 (22:39 +0000)
committeredwin <none@none>
Wed, 3 Jan 2007 22:39:14 +0000 (22:39 +0000)
* src/vm/jit/verify/typecheck-typeinferer.h: Likewise.

* src/vm/jit/verify/typecheck-common.c: Moved code from typecheck.c
that can be shared between the variables-based verifier and the
type inference pass to this file.
* src/vm/jit/verify/typecheck-common.h: Likewise.

* src/vm/jit/verify/typecheck-multianewarray.inc: Moved code for
type checking/infering MULTIANEWARRAY to this file.

* src/vm/jit/verify/icmds.c: Adapted for generating the type
infererence pass.
* src/vm/jit/verify/typecheck-invoke.inc: Likewise.
* src/vm/jit/verify/typecheck-fields.inc: Likewise.
* src/vm/jit/verify/typecheck.c: Likewise.
* src/vm/jit/verify/Makefile.am: Likewise.
* src/vm/jit/verify/typecheck-builtins.inc: Likewise.

* src/vm/jit/verify/typecheck-typeinferer-gen.inc: Generated.

* src/vm/jit/verify/typecheck-stackbased-gen.inc: Regenerated.
* src/vm/jit/verify/typecheck-variablesbased-gen.inc: Regenerated.

14 files changed:
src/vm/jit/verify/Makefile.am
src/vm/jit/verify/icmds.c
src/vm/jit/verify/typecheck-builtins.inc
src/vm/jit/verify/typecheck-common.c
src/vm/jit/verify/typecheck-common.h
src/vm/jit/verify/typecheck-fields.inc
src/vm/jit/verify/typecheck-invoke.inc
src/vm/jit/verify/typecheck-multianewarray.inc [new file with mode: 0644]
src/vm/jit/verify/typecheck-stackbased-gen.inc
src/vm/jit/verify/typecheck-typeinferer-gen.inc [new file with mode: 0644]
src/vm/jit/verify/typecheck-typeinferer.c [new file with mode: 0644]
src/vm/jit/verify/typecheck-typeinferer.h [new file with mode: 0644]
src/vm/jit/verify/typecheck-variablesbased-gen.inc
src/vm/jit/verify/typecheck.c

index ca7661f3b18bdd7fedf25441095a5491ddfe76cd..7419f19549e2f960d646bb603df0176a314f38a4 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes: Edwin Steiner
 ##
-## $Id: Makefile.am 5773 2006-10-13 14:34:19Z edwin $
+## $Id: Makefile.am 6275 2007-01-03 22:39:14Z edwin $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -46,9 +46,13 @@ libverify_la_SOURCES = \
        typecheck-builtins.inc \
        typecheck-fields.inc \
        typecheck-invoke.inc \
+       typecheck-multianewarray.inc \
        typecheck-stackbased.c \
+       typecheck-typeinferer.c \
+       typecheck-typeinferer.h \
        typecheck-stackbased-gen.inc \
        typecheck-variablesbased-gen.inc \
+       typecheck-typeinferer-gen.inc \
        typeinfo.c \
        typeinfo.h
 
index 6a67a0a71683719a00e6673b1a18c50544b97e73..ac287d6bb98d1b2ea5b544c5f47e43aeac1ec950 100644 (file)
 /* This file contains ICMD-specific code for type checking and type
  * inference. It is an input file for the verifier generator
  * (src/vm/jit/verify/generate.pl). The verifier generator creates
- * code for two compiler passes:
+ * code for three compiler passes:
  *     - stack-based type-infering verification
  *     - vasiables-based type-infering verification
+ *     - type inference pass (no verification - used for optimizing compiler)
  *
  * The rest of this file must consist of "case" clauses starting in
  * the first column. Each clause can be marked with tags like this:
@@ -49,6 +50,8 @@
  * This must be on one line. The following tags are defined:
  *     STACKBASED..........use this clause for the stack-based verifier
  *     VARIABLESBASED......use this clause for the variables-based verifier
+ *     TYPEINFERER.........use this clause for the type inference pass
+ *     ALL.................use for all passes
  *
  * If no tag is specified, {STACKBASED,VARIABLESBASED} is assumed.
  *
@@ -65,6 +68,7 @@
  *
  *     TYPECHECK_STACKBASED.......iff compiling the stack-based verifier
  *     TYPECHECK_VARIABLESBASED...iff compiling the variables-based verifier
+ *     TYPECHECK_TYPEINFERER......iff compiling the type inference pass
  *
 /******************************************************************************/
 #endif /* (end #if 0) */
@@ -81,8 +85,8 @@
 
        /* (These are only used by the variables based verifier.) */
 
-case ICMD_MOVE: /* {VARIABLESBASED} */
-case ICMD_COPY: /* {VARIABLESBASED} */
+case ICMD_MOVE: /* {VARIABLESBASED,TYPEINFERER} */
+case ICMD_COPY: /* {VARIABLESBASED,TYPEINFERER} */
        TYPECHECK_COUNT(stat_ins_stack);
        COPYTYPE(IPTR->s1, IPTR->dst);
        DST->type = OP1->type;
@@ -91,29 +95,33 @@ case ICMD_COPY: /* {VARIABLESBASED} */
        /****************************************/
        /* LOADING ADDRESS FROM VARIABLE        */
 
-case ICMD_ALOAD:
+case ICMD_ALOAD: /* {ALL} */
        TYPECHECK_COUNT(stat_ins_aload);
 
+#if !defined(TYPECHECK_TYPEINFERER)
        /* loading a returnAddress is not allowed */
        if (!TYPEDESC_IS_REFERENCE(*OP1)) {
                VERIFY_ERROR("illegal instruction: ALOAD loading non-reference");
        }
+#endif
        TYPEINFO_COPY(OP1->typeinfo,DST->typeinfo);
        break;
 
        /****************************************/
        /* STORING ADDRESS TO VARIABLE          */
 
-case ICMD_ASTORE:
+case ICMD_ASTORE: /* {ALL} */
        TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
        break;
 
        /****************************************/
        /* LOADING ADDRESS FROM ARRAY           */
 
-case ICMD_AALOAD:
+case ICMD_AALOAD: /* {ALL} */
+#if !defined(TYPECHECK_TYPEINFERER)
        if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
                VERIFY_ERROR("illegal instruction: AALOAD on non-reference array");
+#endif
 
        if (!typeinfo_init_component(&OP1->typeinfo,&DST->typeinfo))
                EXCEPTION;
@@ -159,13 +167,13 @@ case ICMD_GETSTATIC:      /* {STACKBASED} */
        break;
 
 case ICMD_PUTFIELD:       /* {VARIABLESBASED} */
-       if (!verify_fieldaccess(state, VAROP(iptr->s1), VAROP(iptr->sx.s23.s2)))
+       if (!handle_fieldaccess(state, VAROP(iptr->s1), VAROP(iptr->sx.s23.s2)))
                return false;
        maythrow = true;
        break;
 
 case ICMD_PUTSTATIC:      /* {VARIABLESBASED} */
-       if (!verify_fieldaccess(state, NULL, VAROP(iptr->s1)))
+       if (!handle_fieldaccess(state, NULL, VAROP(iptr->s1)))
                return false;
        maythrow = true;
        break;
@@ -186,7 +194,7 @@ case ICMD_PUTFIELDCONST:  /* {VARIABLESBASED} */
                        TYPEINFO_INIT_NULLTYPE(constvalue.typeinfo);
                }
        }
-       if (!verify_fieldaccess(state, VAROP(iptr->s1), &constvalue))
+       if (!handle_fieldaccess(state, VAROP(iptr->s1), &constvalue))
                return false;
        maythrow = true;
        break;
@@ -207,19 +215,19 @@ case ICMD_PUTSTATICCONST: /* {VARIABLESBASED} */
                        TYPEINFO_INIT_NULLTYPE(constvalue.typeinfo);
                }
        }
-       if (!verify_fieldaccess(state, NULL, &constvalue))
+       if (!handle_fieldaccess(state, NULL, &constvalue))
                return false;
        maythrow = true;
        break;
 
-case ICMD_GETFIELD:       /* {VARIABLESBASED} */
-       if (!verify_fieldaccess(state, VAROP(iptr->s1), NULL))
+case ICMD_GETFIELD:       /* {VARIABLESBASED,TYPEINFERER} */
+       if (!handle_fieldaccess(state, VAROP(iptr->s1), NULL))
                return false;
        maythrow = true;
        break;
 
-case ICMD_GETSTATIC:      /* {VARIABLESBASED} */
-       if (!verify_fieldaccess(state, NULL, NULL))
+case ICMD_GETSTATIC:      /* {VARIABLESBASED,TYPEINFERER} */
+       if (!handle_fieldaccess(state, NULL, NULL))
                return false;
        maythrow = true;
        break;
@@ -343,7 +351,7 @@ case ICMD_SASTORECONST:
        /****************************************/
        /* ADDRESS CONSTANTS                    */
 
-case ICMD_ACONST:
+case ICMD_ACONST: /* {ALL} */
        if (IPTR->flags.bits & INS_FLAG_CLASS) {
                /* a java.lang.Class reference */
                TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
@@ -361,11 +369,14 @@ case ICMD_ACONST:
        /****************************************/
        /* CHECKCAST AND INSTANCEOF             */
 
-case ICMD_CHECKCAST:
+case ICMD_CHECKCAST: /* {ALL} */
+#if !defined(TYPECHECK_TYPEINFERER)
        /* returnAddress is not allowed */
        if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
                VERIFY_ERROR("Illegal instruction: CHECKCAST on non-reference");
+#endif
 
+    /* XXX only if narrower */
        if (!typeinfo_init_class(&(DST->typeinfo),IPTR->sx.s23.s3.c))
                EXCEPTION;
        break;
@@ -374,68 +385,70 @@ case ICMD_INSTANCEOF:
        /* returnAddress is not allowed */
        if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
                VERIFY_ERROR("Illegal instruction: INSTANCEOF on non-reference");
+
+       /* XXX should propagate type information to the following if-branches */
        break;
 
        /****************************************/
        /* BRANCH INSTRUCTIONS                  */
 
-case ICMD_GOTO:
-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:
+case ICMD_GOTO:            /* {ALL} */
+case ICMD_IFNULL:          /* {ALL} */
+case ICMD_IFNONNULL:       /* {ALL} */
+case ICMD_IFEQ:            /* {ALL} */
+case ICMD_IFNE:            /* {ALL} */
+case ICMD_IFLT:            /* {ALL} */
+case ICMD_IFGE:            /* {ALL} */
+case ICMD_IFGT:            /* {ALL} */
+case ICMD_IFLE:            /* {ALL} */
+case ICMD_IF_ICMPEQ:       /* {ALL} */
+case ICMD_IF_ICMPNE:       /* {ALL} */
+case ICMD_IF_ICMPLT:       /* {ALL} */
+case ICMD_IF_ICMPGE:       /* {ALL} */
+case ICMD_IF_ICMPGT:       /* {ALL} */
+case ICMD_IF_ICMPLE:       /* {ALL} */
+case ICMD_IF_ACMPEQ:       /* {ALL} */
+case ICMD_IF_ACMPNE:       /* {ALL} */
+
+case ICMD_IF_LEQ:          /* {ALL} */
+case ICMD_IF_LNE:          /* {ALL} */
+case ICMD_IF_LLT:          /* {ALL} */
+case ICMD_IF_LGE:          /* {ALL} */
+case ICMD_IF_LGT:          /* {ALL} */
+case ICMD_IF_LLE:          /* {ALL} */
+
+case ICMD_IF_LCMPEQ:       /* {ALL} */
+case ICMD_IF_LCMPNE:       /* {ALL} */
+case ICMD_IF_LCMPLT:       /* {ALL} */
+case ICMD_IF_LCMPGE:       /* {ALL} */
+case ICMD_IF_LCMPGT:       /* {ALL} */
+case ICMD_IF_LCMPLE:       /* {ALL} */
+
+case ICMD_IF_FCMPEQ:       /* {ALL} */
+case ICMD_IF_FCMPNE:       /* {ALL} */
+
+case ICMD_IF_FCMPL_LT:     /* {ALL} */
+case ICMD_IF_FCMPL_GE:     /* {ALL} */
+case ICMD_IF_FCMPL_GT:     /* {ALL} */
+case ICMD_IF_FCMPL_LE:     /* {ALL} */
+
+case ICMD_IF_FCMPG_LT:     /* {ALL} */
+case ICMD_IF_FCMPG_GE:     /* {ALL} */
+case ICMD_IF_FCMPG_GT:     /* {ALL} */
+case ICMD_IF_FCMPG_LE:     /* {ALL} */
+
+case ICMD_IF_DCMPEQ:       /* {ALL} */
+case ICMD_IF_DCMPNE:       /* {ALL} */
+
+case ICMD_IF_DCMPL_LT:     /* {ALL} */
+case ICMD_IF_DCMPL_GE:     /* {ALL} */
+case ICMD_IF_DCMPL_GT:     /* {ALL} */
+case ICMD_IF_DCMPL_LE:     /* {ALL} */
+
+case ICMD_IF_DCMPG_LT:     /* {ALL} */
+case ICMD_IF_DCMPG_GE:     /* {ALL} */
+case ICMD_IF_DCMPG_GT:     /* {ALL} */
+case ICMD_IF_DCMPG_LE:     /* {ALL} */
        /* {RESULTNOW} */
        TYPECHECK_COUNT(stat_ins_branch);
 
@@ -446,7 +459,7 @@ case ICMD_IF_DCMPG_LE:
        /****************************************/
        /* SWITCHES                             */
 
-case ICMD_TABLESWITCH:
+case ICMD_TABLESWITCH:     /* {ALL} */
        /* {RESULTNOW} */
        TYPECHECK_COUNT(stat_ins_switch);
 
@@ -462,7 +475,7 @@ case ICMD_TABLESWITCH:
        LOG("switch done");
        break;
 
-case ICMD_LOOKUPSWITCH:
+case ICMD_LOOKUPSWITCH:    /* {ALL} */
        /* {RESULTNOW} */
        TYPECHECK_COUNT(stat_ins_switch);
 
@@ -570,7 +583,7 @@ return_tail:
        /****************************************/
        /* SUBROUTINE INSTRUCTIONS              */
 
-case ICMD_JSR: /* {VARIABLESBASED} */
+case ICMD_JSR: /* {VARIABLESBASED,TYPEINFERER} */
        TYPEINFO_INIT_RETURNADDRESS(DST->typeinfo, BPTR->next);
        REACH(IPTR->sx.s23.s3.jsrtarget);
        break;
@@ -587,10 +600,12 @@ case ICMD_JSR: /* {STACKBASED} */
                EXCEPTION;
        break;
 
-case ICMD_RET: /* {VARIABLESBASED} */
+case ICMD_RET: /* {VARIABLESBASED,TYPEINFERER} */
+#if !defined(TYPECHECK_TYPEINFERER)
        /* check returnAddress variable */
        if (!typevector_checkretaddr(jd->var,IPTR->s1.varindex))
                VERIFY_ERROR("illegal instruction: RET using non-returnAddress variable");
+#endif
        REACH(IPTR->dst);
        break;
 
@@ -607,12 +622,12 @@ case ICMD_RET: /* {STACKBASED} */
        /****************************************/
        /* INVOKATIONS                          */
 
-case ICMD_INVOKEVIRTUAL:   /* {VARIABLESBASED} */
-case ICMD_INVOKESPECIAL:   /* {VARIABLESBASED} */
-case ICMD_INVOKESTATIC:    /* {VARIABLESBASED} */
-case ICMD_INVOKEINTERFACE: /* {VARIABLESBASED} */
+case ICMD_INVOKEVIRTUAL:   /* {VARIABLESBASED,TYPEINFERER} */
+case ICMD_INVOKESPECIAL:   /* {VARIABLESBASED,TYPEINFERER} */
+case ICMD_INVOKESTATIC:    /* {VARIABLESBASED,TYPEINFERER} */
+case ICMD_INVOKEINTERFACE: /* {VARIABLESBASED,TYPEINFERER} */
        TYPECHECK_COUNT(stat_ins_invoke);
-       if (!verify_invocation(state))
+       if (!handle_invocation(state))
                EXCEPTION;
        TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(IPTR), stat_ins_invoke_unresolved);
        break;
@@ -650,8 +665,8 @@ case ICMD_INVOKEINTERFACE: /* {STACKBASED} */
        /****************************************/
        /* MULTIANEWARRAY                       */
 
-case ICMD_MULTIANEWARRAY: /* {VARIABLESBASED} */
-       if (!verify_multianewarray(STATE))
+case ICMD_MULTIANEWARRAY: /* {VARIABLESBASED,TYPEINFERER} */
+       if (!handle_multianewarray(STATE))
                EXCEPTION;
        break;
 
@@ -665,9 +680,9 @@ case ICMD_MULTIANEWARRAY: /* {STACKBASED} */
        /****************************************/
        /* BUILTINS                             */
 
-case ICMD_BUILTIN: /* {VARIABLESBASED} */
+case ICMD_BUILTIN: /* {VARIABLESBASED,TYPEINFERER} */
        TYPECHECK_COUNT(stat_ins_builtin);
-       if (!verify_builtin(state))
+       if (!handle_builtin(state))
                EXCEPTION;
        break;
 
index 37fcc77d0d2a8261ba3927ad0491d4d2027e43e7..43b339ff7108e68ebccdaf915b787ed2b3053dc5 100644 (file)
        /* pointer in builtintable_entry for this, so here you go.. ;)     */
 
        if (ISBUILTIN(BUILTIN_new)) {
+               dv->type = TYPE_ADR;
+#if defined(TYPECHECK_TYPEINFERER)
+               assert(state->iptr[-1].opc == ICMD_ACONST);
+               typeinfo_init_class(&(dv->typeinfo), state->iptr[-1].sx.val.c);
+#else
                if (state->iptr[-1].opc != ICMD_ACONST)
                        TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
-               dv->type = TYPE_ADR;
                TYPEINFO_INIT_NEWOBJECT(dv->typeinfo,state->iptr);
+#endif
        }
        else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
                TYPECHECK_INT(OP1);
        }
        else {
                methoddesc *md;
-               s4 i;
                u1 rtype;
+#if !defined(TYPECHECK_TYPEINFERER)
+               s4 i;
+#endif
 #if defined(TYPECHECK_STACKBASED)
                typedescriptor *av;
 #endif
                TYPECHECK_COUNT(stat_ins_builtin_gen);
 
                md = bte->md;
+#if !defined(TYPECHECK_TYPEINFERER)
                i = md->paramcount;
 
                /* check the types of the arguments on the stack */
                        av += (IS_2_WORD_TYPE(av->type)) ? 2 : 1;
 #endif
                }
+#endif /* !defined(TYPECHECK_TYPEINFERER) */
 
                /* set the return type */
 
index ea2cf60836ff6636d926a48841638f9246671859..3abc21e97c88dadef78d8c31f5b6305d07a6c12c 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <assert.h>
 
+#include <vm/exceptions.h>
 #include <vm/jit/show.h>
 #include <typecheck-common.h>
 
@@ -241,6 +242,307 @@ void typecheck_reset_flags(verifier_state *state)
 }
 
 
+/****************************************************************************/
+/* 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
+
+*******************************************************************************/
+
+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
+
+*******************************************************************************/
+
+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
+
+*******************************************************************************/
+
+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
+
+*******************************************************************************/
+
+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->nr <= state->bptr->nr) {
+                       LOG("REPEAT!");
+                       state->repeat = true;
+               }
+       }
+       return true;
+}
+
+
+/* typecheck_init_locals *******************************************************
+
+   Initialize the local variables in the verifier state.
+
+   IN:
+       state............the current state of the verifier
+          newthis..........if true, mark the instance in <init> methods as
+                           uninitialized object.
+
+   RETURN VALUE:
+       true.............success,
+          false............an exception has been thrown.
+
+*******************************************************************************/
+
+bool typecheck_init_locals(verifier_state *state, bool newthis)
+{
+       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 && newthis)
+                               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;
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index 163534162290a50c5c0d895cabc52912b412e281..e6a02dec479d75a5b09969e3a0f9e2e992fe10ef 100644 (file)
@@ -119,7 +119,7 @@ void typecheck_print_vararray(FILE *file, jitdata *jd, s4 *vars, int len);
 /* STATISTICS                                                               */
 /****************************************************************************/
 
-#ifdef TYPECHECK_DEBUG
+#if defined(TYPECHECK_DEBUG) && !defined(TYPECHECK_NO_STATISTICS)
 /*#define TYPECHECK_STATISTICS*/
 #endif
 
@@ -196,6 +196,15 @@ void typecheck_print_statistics(FILE *file);
 #define TYPECHECK_VERIFYERROR_bool(msg)  TYPECHECK_VERIFYERROR_ret(state->m,(msg),false)
 
 
+/****************************************************************************/
+/* MISC MACROS                                                              */
+/****************************************************************************/
+
+#define COPYTYPE(source,dest)                                        \
+    {if (VAROP(source)->type == TYPE_ADR)                            \
+            TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
+
+
 /****************************************************************************/
 /* JSR VERIFICATION (stack-based verifier)                                  */
 /****************************************************************************/
@@ -274,6 +283,25 @@ typedef struct verifier_state {
 void typecheck_init_flags(verifier_state *state, s4 minflags);
 void typecheck_reset_flags(verifier_state *state);
 
+bool typecheck_copy_types(verifier_state *state,
+                                                 s4 *srcvars, s4 *dstvars, s4 n);
+
+typecheck_result typecheck_merge_types(verifier_state *state,
+                                                                          s4 *srcvars,
+                                                                          s4 *dstvars,
+                                                                          s4 n);
+
+typecheck_result typestate_merge(verifier_state *state,
+                                                s4 *srcvars, varinfo *srclocals,
+                                                s4 *dstvars, varinfo *dstlocals,
+                                                s4 n);
+
+bool typestate_reach(verifier_state *state,
+                                        basicblock *destblock,
+                                        s4 *srcvars, varinfo *srclocals, s4 n);
+
+bool typecheck_init_locals(verifier_state *state, bool newthis);
+
 #endif /* _TYPECHECK_COMMON_H */
 
 /*
index b777385b570a475187bfb2fd61dca47b0913baf6..bac879428e65b22908213d3db7b542d4d69227d8 100644 (file)
 {
        unresolved_field *uf;
        constant_FMIref *fieldref;
-       resolve_result_t result;
        typeinfo *instanceti;
        typeinfo *valueti;
+#if !defined(TYPECHECK_TYPEINFERER)
+       resolve_result_t result;
+#endif
 
        TYPECHECK_COUNT(stat_ins_field);
 
@@ -56,6 +58,7 @@
                fieldref = state->iptr->sx.s23.s3.fmiref;
        }
 
+#if !defined(TYPECHECK_TYPEINFERER)
        /* check the basic value type for PUT instructions */
 
        if (value && value->type != fieldref->parseddesc.fd->type)
                                !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,
                                stat_ins_field_uninitialized);
        }
+#endif /* !defined(TYPECHECK_TYPEINFERER) */
                
        /* write the result type */
 
index a8257c22bc9d92d8ed2d508382ccfeed1fc25b0c..bad9f4af6d2d29f9d41cb5c2cf4b72ea4ac8e67d 100644 (file)
 {
        unresolved_method *um;      /* struct describing the called method */
        constant_FMIref *mref;           /* reference to the called method */
-       methodinfo *mi;                        /* resolved method (if any) */
        methoddesc *md;                 /* descriptor of the called method */
        utf *mname;                                         /* method name */
+    u1 rtype;                          /* return type of called method */
+#if !defined(TYPECHECK_TYPEINFERER)
+       methodinfo *mi;                        /* resolved method (if any) */
        utf *mclassname;                     /* name of the method's class */
        bool specialmethod;            /* true if a <...> method is called */
        int opcode;                                   /* invocation opcode */
        typedescriptor *av;                         /* argument stack slot */
 #endif
        int i;                                                  /* counter */
-    u1 rtype;                          /* return type of called method */
        resolve_result_t result;
        bool invokestatic;
        bool invokespecial;
+#endif /* !defined(TYPECHECK_TYPEINFERER) */
 
        /* get the FMIref and the unresolved_method struct (if any) */
        /* from the instruction                                     */
@@ -77,6 +79,7 @@
        md = mref->parseddesc.md;
        mname = mref->name;
 
+#if !defined(TYPECHECK_TYPEINFERER)
        /* get method info (if resolved) and classname */
 
        if (IS_FMIREF_RESOLVED(mref)) {
                state->iptr->sx.s23.s3.um = um;
                state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
        }
+#endif /* !defined(TYPECHECK_TYPEINFERER) */
 
        /* set the return type */
 
diff --git a/src/vm/jit/verify/typecheck-multianewarray.inc b/src/vm/jit/verify/typecheck-multianewarray.inc
new file mode 100644 (file)
index 0000000..8f4969f
--- /dev/null
@@ -0,0 +1,107 @@
+/* src/vm/jit/verify/typecheck-multianewarray.inc - type checking for MULTIANEWARRAY
+
+   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
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Edwin Steiner
+
+   $Id$
+
+*/
+
+
+{
+       classinfo *arrayclass;
+       arraydescriptor *desc;
+       s4 i;
+
+       /* check the array lengths on the stack */
+       i = state->iptr->s1.argcount;
+
+#if !defined(TYPECHECK_TYPEINFERER)
+       if (i < 1)
+               VERIFY_ERROR("Illegal dimension argument");
+
+       while (i--) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[i]);
+       }
+#endif /* !defined(TYPECHECK_TYPEINFERER) */
+
+       /* 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)
+                       VERIFY_ERROR("MULTIANEWARRAY with unlinked class");
+               if ((desc = arrayclass->vftbl->arraydesc) == NULL)
+                       VERIFY_ERROR("MULTIANEWARRAY with non-array class");
+               if (desc->dimension < state->iptr->s1.argcount)
+                       VERIFY_ERROR("MULTIANEWARRAY dimension to high");
+
+               /* set the array type of the result */
+               typeinfo_init_classinfo(&(dv->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 !defined(TYPECHECK_TYPEINFERER)
+               if (i < 1)
+                       VERIFY_ERROR("MULTIANEWARRAY with non-array class");
+               if (i < state->iptr->s1.argcount)
+                       VERIFY_ERROR("MULTIANEWARRAY dimension to high");
+#endif /* !defined(TYPECHECK_TYPEINFERER) */
+
+               /* set the array type of the result */
+               if (!typeinfo_init_class(&(dv->typeinfo),CLASSREF_OR_CLASSINFO(cr)))
+                       return false;
+       }
+
+       /* set return type */
+
+       dv->type = TYPE_ADR;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:filetype=c:
+ */
index 0ab00c413850e72f8ea21b4c723ba191b758d4e5..49da6225a7ebb8b92cab7502a53aebf027ddb112 100644 (file)
@@ -14,7 +14,7 @@
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 347 "src/vm/jit/verify/icmds.c"
+#              line 355 "src/vm/jit/verify/icmds.c"
   GENERATED    if (IPTR->flags.bits & INS_FLAG_CLASS) {
   GENERATED            /* a java.lang.Class reference */
   GENERATED            TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 95 "src/vm/jit/verify/icmds.c"
+#              line 99 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_aload);
   GENERATED  
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* loading a returnAddress is not allowed */
   GENERATED    if (!TYPEDESC_IS_REFERENCE(*OP1)) {
   GENERATED            VERIFY_ERROR("illegal instruction: ALOAD loading non-reference");
   GENERATED    }
+  GENERATED  
+#            endif
   GENERATED    TYPEINFO_COPY(OP1->typeinfo,DST->typeinfo);
   GENERATED  
-#              line 142 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 146 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 1;
   GENERATED    stack[0].type = TYPE_ADR;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 258 "src/vm/jit/verify/icmds.c"
+#              line 266 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 173 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 177 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    stack[0].type = TYPE_INT;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 268 "src/vm/jit/verify/icmds.c"
+#              line 276 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 206 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 210 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack[0].type = TYPE_VOID;
   GENERATED    stack[-1].type = TYPE_LNG;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 253 "src/vm/jit/verify/icmds.c"
+#              line 261 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 239 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 243 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    stack[0].type = TYPE_FLT;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 248 "src/vm/jit/verify/icmds.c"
+#              line 256 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 272 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 276 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack[0].type = TYPE_VOID;
   GENERATED    stack[-1].type = TYPE_DBL;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 115 "src/vm/jit/verify/icmds.c"
+#              line 121 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: AALOAD on non-reference array");
   GENERATED  
+#            endif
+  GENERATED  
   GENERATED    if (!typeinfo_init_component(&OP1->typeinfo,&DST->typeinfo))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 308 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 316 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    break;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 237 "src/vm/jit/verify/icmds.c"
+#              line 245 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 341 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 349 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    stack[0].type = TYPE_INT;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 243 "src/vm/jit/verify/icmds.c"
+#              line 251 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 374 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 382 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    stack[0].type = TYPE_INT;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 263 "src/vm/jit/verify/icmds.c"
+#              line 271 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 407 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 415 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    stack[0].type = TYPE_INT;
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 108 "src/vm/jit/verify/icmds.c"
+#              line 114 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
   GENERATED  
-#              line 471 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 479 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 294 "src/vm/jit/verify/icmds.c"
+#              line 302 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 502 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 510 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -3;
   GENERATED    break;
   GENERATED    /* may use stack[-3] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 304 "src/vm/jit/verify/icmds.c"
+#              line 312 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 535 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 543 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -4;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 289 "src/vm/jit/verify/icmds.c"
+#              line 297 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 568 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 576 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -3;
   GENERATED    break;
   GENERATED    /* may use stack[-3] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 284 "src/vm/jit/verify/icmds.c"
+#              line 292 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 601 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 609 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -4;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 309 "src/vm/jit/verify/icmds.c"
+#              line 317 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we just check the basic input types and that the           */
   GENERATED    /* destination is an array of references. Assignability to    */
   GENERATED    /* the actual array must be checked at runtime, each time the */
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: AASTORE to non-reference array");
   GENERATED  
-#              line 638 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 646 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -3;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 273 "src/vm/jit/verify/icmds.c"
+#              line 281 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 672 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 680 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -3;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 279 "src/vm/jit/verify/icmds.c"
+#              line 287 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 705 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 713 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -3;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 299 "src/vm/jit/verify/icmds.c"
+#              line 307 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 738 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 746 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -3;
   GENERATED    break;
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 695 "src/vm/jit/verify/icmds.c"
+#              line 710 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we pop 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED  
-#              line 761 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 769 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    break;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 700 "src/vm/jit/verify/icmds.c"
+#              line 715 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we pop either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED  
-#              line 778 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 786 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -2;
   GENERATED    break;
   GENERATED    /* may use stack[0] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 715 "src/vm/jit/verify/icmds.c"
+#              line 730 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED  
   GENERATED    COPY_SLOT(stack[ 0], stack[ 1]);
   GENERATED  
-#              line 799 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 807 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 1;
   GENERATED    break;
   GENERATED    /* may use stack[-1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 722 "src/vm/jit/verify/icmds.c"
+#              line 737 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED    /* we skip 1 */
   GENERATED    COPY_SLOT(stack[-1], stack[ 0]);
   GENERATED    COPY_SLOT(stack[ 1], stack[-1]);
   GENERATED  
-#              line 827 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 835 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 1;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 733 "src/vm/jit/verify/icmds.c"
+#              line 748 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup 1 */
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED    /* we skip either 11 or 2 */
   GENERATED    COPY_SLOT(stack[-2], stack[-1]);
   GENERATED    COPY_SLOT(stack[ 1], stack[-2]);
   GENERATED  
-#              line 855 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 863 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 1;
   GENERATED    break;
   GENERATED    /* may use stack[-1] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 746 "src/vm/jit/verify/icmds.c"
+#              line 761 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    COPY_SLOT(stack[ 0], stack[ 2]);
   GENERATED    COPY_SLOT(stack[-1], stack[ 1]);
   GENERATED  
-#              line 876 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 884 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 2;
   GENERATED    break;
   GENERATED    /* may use stack[-2] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 755 "src/vm/jit/verify/icmds.c"
+#              line 770 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    COPY_SLOT(stack[ 2], stack[-1]);
   GENERATED    COPY_SLOT(stack[ 1], stack[-2]);
   GENERATED  
-#              line 902 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 910 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 2;
   GENERATED    break;
   GENERATED    /* may use stack[-3] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 769 "src/vm/jit/verify/icmds.c"
+#              line 784 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we dup either 11 or 2 */
   GENERATED    if (IS_CAT1(stack[0]))
   GENERATED            CHECK_CAT1(stack[-1]);
   GENERATED    COPY_SLOT(stack[ 2], stack[-2]);
   GENERATED    COPY_SLOT(stack[ 1], stack[-3]);
   GENERATED  
-#              line 930 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 938 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += 2;
   GENERATED    break;
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 706 "src/vm/jit/verify/icmds.c"
+#              line 721 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_CAT1(stack[0]);
   GENERATED    CHECK_CAT1(stack[-1]);
   GENERATED  
   GENERATED    COPY_SLOT(stack[-1], stack[ 0]);
   GENERATED    COPY_SLOT(temp     , stack[-1]);
   GENERATED  
-#              line 952 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 960 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 386 "src/vm/jit/verify/icmds.c"
+#              line 399 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 1256 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1264 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 392 "src/vm/jit/verify/icmds.c"
+#              line 405 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 1290 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1298 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[2] */
   GENERATED  
   GENERATED  
-#              line 398 "src/vm/jit/verify/icmds.c"
+#              line 411 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 1322 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1330 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 383 "src/vm/jit/verify/icmds.c"
+#              line 396 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 1344 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1352 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 579 "src/vm/jit/verify/icmds.c"
+#              line 592 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    tbptr = BLOCK_OF(IPTR->sx.s23.s3.jsrtarget.insindex);
   GENERATED  
   GENERATED    if (stack == NULL)
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1373 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1381 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 598 "src/vm/jit/verify/icmds.c"
+#              line 613 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    CHECK_LOCAL_TYPE(IPTR->s1.varindex, TYPE_RET);
   GENERATED    if (!TYPEINFO_IS_PRIMITIVE(STATE->locals[IPTR->s1.varindex].typeinfo))
   GENERATED    if (!typecheck_stackbased_ret(STATE, stack, stackfloor))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1395 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1403 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 450 "src/vm/jit/verify/icmds.c"
+#              line 463 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
   GENERATED  
   GENERATED    LOG("switch done");
   GENERATED  
-#              line 1427 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1435 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 466 "src/vm/jit/verify/icmds.c"
+#              line 479 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
   GENERATED  
   GENERATED    LOG("switch done");
   GENERATED  
-#              line 1462 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1470 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 532 "src/vm/jit/verify/icmds.c"
+#              line 545 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_INT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 1484 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1492 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 537 "src/vm/jit/verify/icmds.c"
+#              line 550 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_LNG)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 1506 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1514 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 542 "src/vm/jit/verify/icmds.c"
+#              line 555 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_FLT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 1528 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1536 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
   GENERATED    /* may use stack[-1] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 547 "src/vm/jit/verify/icmds.c"
+#              line 560 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_DBL)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 1550 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1558 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 507 "src/vm/jit/verify/icmds.c"
+#              line 520 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_areturn);
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: ARETURN on non-reference");
   GENERATED            IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
   GENERATED    }
   GENERATED  
-#              line 1590 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1598 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 552 "src/vm/jit/verify/icmds.c"
+#              line 565 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_VOID)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED                    VERIFY_ERROR("<init> method does not initialize 'this'");
   GENERATED    }
   GENERATED  
-#              line 1624 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1632 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 156 "src/vm/jit/verify/icmds.c"
+#              line 164 "src/vm/jit/verify/icmds.c"
   GENERATED    stack = typecheck_stackbased_verify_fieldaccess(STATE, NULL, NULL, stack);
   GENERATED    if (stack == NULL)
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1640 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1648 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* variable number of inslots! */
   GENERATED  
   GENERATED  
-#              line 138 "src/vm/jit/verify/icmds.c"
+#              line 146 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_STACK_DEPTH(1);
   GENERATED    if (!IS_CAT1(stack[0])) {
   GENERATED            /* (stack depth >= 2 is guaranteed) */
   GENERATED    if (stack == NULL)
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1661 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1669 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 149 "src/vm/jit/verify/icmds.c"
+#              line 157 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_STACK_TYPE(stack[0], TYPE_ADR);
   GENERATED    stack = typecheck_stackbased_verify_fieldaccess(STATE, stack, NULL, stack-1);
   GENERATED    if (stack == NULL)
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1679 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1687 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* variable number of inslots! */
   GENERATED  
   GENERATED  
-#              line 126 "src/vm/jit/verify/icmds.c"
+#              line 134 "src/vm/jit/verify/icmds.c"
   GENERATED    CHECK_STACK_DEPTH(2);
   GENERATED    if (!IS_CAT1(stack[0])) {
   GENERATED            CHECK_STACK_DEPTH(3);
   GENERATED    if (stack == NULL)
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1701 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1709 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 621 "src/vm/jit/verify/icmds.c"
+#              line 636 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_invoke);
   GENERATED  
   GENERATED    INSTRUCTION_GET_METHODDESC(IPTR, md);
   GENERATED    }
   GENERATED    TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(IPTR), stat_ins_invoke_unresolved);
   GENERATED  
-#              line 1742 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1750 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 231 "src/vm/jit/verify/icmds.c"
+#              line 239 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY(OP1->typeinfo)
   GENERATED                    && OP1->typeinfo.typeclass.cls != pseudo_class_Arraystub)
   GENERATED            VERIFY_ERROR("illegal instruction: ARRAYLENGTH on non-array");
   GENERATED  
-#              line 1764 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1772 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack[0].type = TYPE_INT;
   GENERATED    break;
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 486 "src/vm/jit/verify/icmds.c"
+#              line 499 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_athrow);
   GENERATED    r = typeinfo_is_assignable_to_class(&OP1->typeinfo,
   GENERATED                    CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
   GENERATED            IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
   GENERATED    }
   GENERATED  
-#              line 1806 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1814 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack += -1;
   GENERATED    break;
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 365 "src/vm/jit/verify/icmds.c"
+#              line 373 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* returnAddress is not allowed */
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("Illegal instruction: CHECKCAST on non-reference");
   GENERATED  
+#            endif
+  GENERATED  
+  GENERATED      /* XXX only if narrower */
   GENERATED    if (!typeinfo_init_class(&(DST->typeinfo),IPTR->sx.s23.s3.c))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1835 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1848 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[0] ... stack[0] */
   GENERATED  
   GENERATED  
-#              line 374 "src/vm/jit/verify/icmds.c"
+#              line 385 "src/vm/jit/verify/icmds.c"
   GENERATED    /* returnAddress is not allowed */
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("Illegal instruction: INSTANCEOF on non-reference");
   GENERATED  
-#              line 1862 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+  GENERATED    /* XXX should propagate type information to the following if-branches */
+  GENERATED  
+#              line 1877 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    stack[0].type = TYPE_INT;
   GENERATED    break;
   GENERATED    /* variable number of inslots! */
   GENERATED  
   GENERATED  
-#              line 659 "src/vm/jit/verify/icmds.c"
+#              line 674 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!typecheck_stackbased_multianewarray(STATE, stack, stackfloor))
   GENERATED            EXCEPTION;
   GENERATED    stack -= (IPTR->s1.argcount - 1);
   GENERATED    stack[0].type = TYPE_ADR;
   GENERATED  
-#              line 1885 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1900 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* may use stack[1] ... stack[1] */
   GENERATED  
   GENERATED  
-#              line 384 "src/vm/jit/verify/icmds.c"
+#              line 397 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 1909 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1924 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    /* variable number of outslots! */
   GENERATED  
   GENERATED  
-#              line 675 "src/vm/jit/verify/icmds.c"
+#              line 690 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_builtin);
   GENERATED    if (!typecheck_stackbased_verify_builtin(STATE, stack, stackfloor))
   GENERATED            EXCEPTION;
   GENERATED            }
   GENERATED    }
   GENERATED  
-#              line 1941 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
+#              line 1956 "src/vm/jit/verify/typecheck-stackbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
diff --git a/src/vm/jit/verify/typecheck-typeinferer-gen.inc b/src/vm/jit/verify/typecheck-typeinferer-gen.inc
new file mode 100644 (file)
index 0000000..e36b92b
--- /dev/null
@@ -0,0 +1,626 @@
+#define GENERATED
+
+  GENERATED  case ICMD_NOP:
+  GENERATED  case ICMD_ICONST:
+  GENERATED  case ICMD_IDIVPOW2:
+  GENERATED  case ICMD_LDIVPOW2:
+  GENERATED  case ICMD_LCONST:
+  GENERATED  case ICMD_LCMPCONST:
+  GENERATED  case ICMD_FCONST:
+  GENERATED  case ICMD_DCONST:
+  GENERATED  case ICMD_ILOAD:
+  GENERATED  case ICMD_LLOAD:
+  GENERATED  case ICMD_FLOAD:
+  GENERATED  case ICMD_DLOAD:
+  GENERATED  case ICMD_IADDCONST:
+  GENERATED  case ICMD_ISUBCONST:
+  GENERATED  case ICMD_IMULCONST:
+  GENERATED  case ICMD_IANDCONST:
+  GENERATED  case ICMD_IORCONST:
+  GENERATED  case ICMD_IXORCONST:
+  GENERATED  case ICMD_ISHLCONST:
+  GENERATED  case ICMD_ISHRCONST:
+  GENERATED  case ICMD_IUSHRCONST:
+  GENERATED  case ICMD_IREMPOW2:
+  GENERATED  case ICMD_LADDCONST:
+  GENERATED  case ICMD_LSUBCONST:
+  GENERATED  case ICMD_LMULCONST:
+  GENERATED  case ICMD_LANDCONST:
+  GENERATED  case ICMD_LORCONST:
+  GENERATED  case ICMD_LXORCONST:
+  GENERATED  case ICMD_LSHLCONST:
+  GENERATED  case ICMD_LSHRCONST:
+  GENERATED  case ICMD_LUSHRCONST:
+  GENERATED  case ICMD_LREMPOW2:
+  GENERATED  case ICMD_ISTORE:
+  GENERATED  case ICMD_LSTORE:
+  GENERATED  case ICMD_FSTORE:
+  GENERATED  case ICMD_DSTORE:
+  GENERATED  case ICMD_POP:
+  GENERATED  case ICMD_POP2:
+  GENERATED  case ICMD_IADD:
+  GENERATED  case ICMD_LADD:
+  GENERATED  case ICMD_FADD:
+  GENERATED  case ICMD_DADD:
+  GENERATED  case ICMD_ISUB:
+  GENERATED  case ICMD_LSUB:
+  GENERATED  case ICMD_FSUB:
+  GENERATED  case ICMD_DSUB:
+  GENERATED  case ICMD_IMUL:
+  GENERATED  case ICMD_LMUL:
+  GENERATED  case ICMD_FMUL:
+  GENERATED  case ICMD_DMUL:
+  GENERATED  case ICMD_FDIV:
+  GENERATED  case ICMD_DDIV:
+  GENERATED  case ICMD_FREM:
+  GENERATED  case ICMD_DREM:
+  GENERATED  case ICMD_INEG:
+  GENERATED  case ICMD_LNEG:
+  GENERATED  case ICMD_FNEG:
+  GENERATED  case ICMD_DNEG:
+  GENERATED  case ICMD_ISHL:
+  GENERATED  case ICMD_LSHL:
+  GENERATED  case ICMD_ISHR:
+  GENERATED  case ICMD_LSHR:
+  GENERATED  case ICMD_IUSHR:
+  GENERATED  case ICMD_LUSHR:
+  GENERATED  case ICMD_IAND:
+  GENERATED  case ICMD_LAND:
+  GENERATED  case ICMD_IOR:
+  GENERATED  case ICMD_LOR:
+  GENERATED  case ICMD_IXOR:
+  GENERATED  case ICMD_LXOR:
+  GENERATED  case ICMD_IINC:
+  GENERATED  case ICMD_I2L:
+  GENERATED  case ICMD_I2F:
+  GENERATED  case ICMD_I2D:
+  GENERATED  case ICMD_L2I:
+  GENERATED  case ICMD_L2F:
+  GENERATED  case ICMD_L2D:
+  GENERATED  case ICMD_F2I:
+  GENERATED  case ICMD_F2L:
+  GENERATED  case ICMD_F2D:
+  GENERATED  case ICMD_D2I:
+  GENERATED  case ICMD_D2L:
+  GENERATED  case ICMD_D2F:
+  GENERATED  case ICMD_INT2BYTE:
+  GENERATED  case ICMD_INT2CHAR:
+  GENERATED  case ICMD_INT2SHORT:
+  GENERATED  case ICMD_LCMP:
+  GENERATED  case ICMD_FCMPL:
+  GENERATED  case ICMD_FCMPG:
+  GENERATED  case ICMD_DCMPL:
+  GENERATED  case ICMD_DCMPG:
+  GENERATED  case ICMD_IMULPOW2:
+  GENERATED  case ICMD_LMULPOW2:
+  GENERATED  case ICMD_INLINE_START:
+  GENERATED  case ICMD_INLINE_END:
+  GENERATED  case ICMD_INLINE_BODY:
+  GENERATED    /* (--), (--I), (I--I), (L--L), (--L), (L--I), (--F), (--D), (I--), (L--), (F--), (D--), (1--), (11--|2--), (II--I), (LL--L), (FF--F), (DD--D), (F--F), (D--D), (LI--L), (I--L), (I--F), (I--D), (L--F), (L--D), (F--I), (F--L), (F--D), (D--I), (D--L), (D--F), (LL--I), (FF--I), (DD--I) */
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_ACONST:
+  GENERATED    /* (--A) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 355 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (IPTR->flags.bits & INS_FLAG_CLASS) {
+  GENERATED            /* a java.lang.Class reference */
+  GENERATED            TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
+  GENERATED    }
+  GENERATED    else {
+  GENERATED            if (IPTR->sx.val.anyptr == NULL)
+  GENERATED                    TYPEINFO_INIT_NULLTYPE(DST->typeinfo);
+  GENERATED            else {
+  GENERATED                    /* string constant (or constant for builtin function) */
+  GENERATED                    typeinfo_init_classinfo(&(DST->typeinfo),class_java_lang_String);
+  GENERATED            }
+  GENERATED    }
+  GENERATED  
+#              line 125 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_CHECKNULL:
+  GENERATED  case ICMD_IALOAD:
+  GENERATED  case ICMD_LALOAD:
+  GENERATED  case ICMD_FALOAD:
+  GENERATED  case ICMD_DALOAD:
+  GENERATED  case ICMD_BALOAD:
+  GENERATED  case ICMD_CALOAD:
+  GENERATED  case ICMD_SALOAD:
+  GENERATED  case ICMD_IASTORE:
+  GENERATED  case ICMD_LASTORE:
+  GENERATED  case ICMD_FASTORE:
+  GENERATED  case ICMD_DASTORE:
+  GENERATED  case ICMD_AASTORE:
+  GENERATED  case ICMD_BASTORE:
+  GENERATED  case ICMD_CASTORE:
+  GENERATED  case ICMD_SASTORE:
+  GENERATED  case ICMD_IDIV:
+  GENERATED  case ICMD_LDIV:
+  GENERATED  case ICMD_IREM:
+  GENERATED  case ICMD_LREM:
+  GENERATED  case ICMD_PUTSTATIC:
+  GENERATED  case ICMD_PUTFIELD:
+  GENERATED  case ICMD_ARRAYLENGTH:
+  GENERATED  case ICMD_INSTANCEOF:
+  GENERATED  case ICMD_IASTORECONST:
+  GENERATED  case ICMD_LASTORECONST:
+  GENERATED  case ICMD_FASTORECONST:
+  GENERATED  case ICMD_DASTORECONST:
+  GENERATED  case ICMD_AASTORECONST:
+  GENERATED  case ICMD_BASTORECONST:
+  GENERATED  case ICMD_CASTORECONST:
+  GENERATED  case ICMD_SASTORECONST:
+  GENERATED  case ICMD_PUTSTATICCONST:
+  GENERATED  case ICMD_PUTFIELDCONST:
+  GENERATED    /* (A--A), (AI--I), (AI--L), (AI--F), (AI--D), (AII--), (AIL--), (AIF--), (AID--), (AIA--), (II--I), (LL--L), (1--|2--), (A1--|A2--), (A--I), (AI--), (--), (A--) */
+  GENERATED    maythrow = true;
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_COPY:
+  GENERATED    /* (1--1) */
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 90 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPECHECK_COUNT(stat_ins_stack);
+  GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
+  GENERATED    DST->type = OP1->type;
+  GENERATED  
+#              line 185 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_MOVE:
+  GENERATED    /* (1--1) */
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 89 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPECHECK_COUNT(stat_ins_stack);
+  GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
+  GENERATED    DST->type = OP1->type;
+  GENERATED  
+#              line 208 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_ALOAD:
+  GENERATED    /* (--A) */
+  GENERATED  
+#              define OP1  VAROP(IPTR->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 99 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPECHECK_COUNT(stat_ins_aload);
+  GENERATED  
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
+  GENERATED    /* loading a returnAddress is not allowed */
+  GENERATED    if (!TYPEDESC_IS_REFERENCE(*OP1)) {
+  GENERATED            VERIFY_ERROR("illegal instruction: ALOAD loading non-reference");
+  GENERATED    }
+  GENERATED  
+#            endif
+  GENERATED    TYPEINFO_COPY(OP1->typeinfo,DST->typeinfo);
+  GENERATED  
+#              line 239 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_AALOAD:
+  GENERATED    /* (AI--A) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 121 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
+  GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
+  GENERATED            VERIFY_ERROR("illegal instruction: AALOAD on non-reference array");
+  GENERATED  
+#            endif
+  GENERATED  
+  GENERATED    if (!typeinfo_init_component(&OP1->typeinfo,&DST->typeinfo))
+  GENERATED            EXCEPTION;
+  GENERATED  
+#              line 269 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_ASTORE:
+  GENERATED    /* (A--|R--) */
+  GENERATED  
+#              define DST  VAROP(IPTR->dst)
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+  GENERATED  
+#              line 114 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
+  GENERATED  
+#              line 290 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef DST
+  GENERATED  
+#              undef OP1
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_IF_LEQ:
+  GENERATED  case ICMD_IF_LNE:
+  GENERATED  case ICMD_IF_LLT:
+  GENERATED  case ICMD_IF_LGE:
+  GENERATED  case ICMD_IF_LGT:
+  GENERATED  case ICMD_IF_LLE:
+  GENERATED  case ICMD_IF_LCMPEQ:
+  GENERATED  case ICMD_IF_LCMPNE:
+  GENERATED  case ICMD_IF_LCMPLT:
+  GENERATED  case ICMD_IF_LCMPGE:
+  GENERATED  case ICMD_IF_LCMPGT:
+  GENERATED  case ICMD_IF_LCMPLE:
+  GENERATED  case ICMD_IFEQ:
+  GENERATED  case ICMD_IFNE:
+  GENERATED  case ICMD_IFLT:
+  GENERATED  case ICMD_IFGE:
+  GENERATED  case ICMD_IFGT:
+  GENERATED  case ICMD_IFLE:
+  GENERATED  case ICMD_IF_ICMPEQ:
+  GENERATED  case ICMD_IF_ICMPNE:
+  GENERATED  case ICMD_IF_ICMPLT:
+  GENERATED  case ICMD_IF_ICMPGE:
+  GENERATED  case ICMD_IF_ICMPGT:
+  GENERATED  case ICMD_IF_ICMPLE:
+  GENERATED  case ICMD_IF_ACMPEQ:
+  GENERATED  case ICMD_IF_ACMPNE:
+  GENERATED  case ICMD_IFNULL:
+  GENERATED  case ICMD_IFNONNULL:
+  GENERATED    /* (L--), (LL--), (I--), (II--), (AA--), (A--) */
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+  GENERATED  
+#              line 414 "src/vm/jit/verify/icmds.c"
+  GENERATED    /* {RESULTNOW} */
+  GENERATED    TYPECHECK_COUNT(stat_ins_branch);
+  GENERATED  
+  GENERATED    /* propagate stack and variables to the target block */
+  GENERATED    REACH(IPTR->dst);
+  GENERATED  
+#              line 340 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_GOTO:
+  GENERATED    /* (--) */
+  GENERATED    superblockend = true;
+  GENERATED  
+  GENERATED  
+#              line 396 "src/vm/jit/verify/icmds.c"
+  GENERATED    /* {RESULTNOW} */
+  GENERATED    TYPECHECK_COUNT(stat_ins_branch);
+  GENERATED  
+  GENERATED    /* propagate stack and variables to the target block */
+  GENERATED    REACH(IPTR->dst);
+  GENERATED  
+#              line 360 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_JSR:
+  GENERATED    /* (--R) */
+  GENERATED    superblockend = true;
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 587 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPEINFO_INIT_RETURNADDRESS(DST->typeinfo, BPTR->next);
+  GENERATED    REACH(IPTR->sx.s23.s3.jsrtarget);
+  GENERATED  
+#              line 376 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_RET:
+  GENERATED    /* (--) */
+  GENERATED    superblockend = true;
+  GENERATED  
+  GENERATED  
+#              line 604 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
+  GENERATED    /* check returnAddress variable */
+  GENERATED    if (!typevector_checkretaddr(jd->var,IPTR->s1.varindex))
+  GENERATED            VERIFY_ERROR("illegal instruction: RET using non-returnAddress variable");
+  GENERATED  
+#            endif
+  GENERATED    REACH(IPTR->dst);
+  GENERATED  
+#              line 399 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_TABLESWITCH:
+  GENERATED    /* (I--) */
+  GENERATED    superblockend = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+  GENERATED  
+#              line 463 "src/vm/jit/verify/icmds.c"
+  GENERATED    /* {RESULTNOW} */
+  GENERATED    TYPECHECK_COUNT(stat_ins_switch);
+  GENERATED  
+  GENERATED    table = IPTR->dst.table;
+  GENERATED    i = IPTR->sx.s23.s3.tablehigh
+  GENERATED    - IPTR->sx.s23.s2.tablelow + 1 + 1; /* plus default */
+  GENERATED  
+  GENERATED    while (--i >= 0) {
+  GENERATED            REACH(*table);
+  GENERATED            table++;
+  GENERATED    }
+  GENERATED  
+  GENERATED    LOG("switch done");
+  GENERATED  
+#              line 426 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_LOOKUPSWITCH:
+  GENERATED    /* (I--) */
+  GENERATED    superblockend = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+  GENERATED  
+#              line 479 "src/vm/jit/verify/icmds.c"
+  GENERATED    /* {RESULTNOW} */
+  GENERATED    TYPECHECK_COUNT(stat_ins_switch);
+  GENERATED  
+  GENERATED    lookup = IPTR->dst.lookup;
+  GENERATED    i = IPTR->sx.s23.s2.lookupcount;
+  GENERATED    REACH(IPTR->sx.s23.s3.lookupdefault);
+  GENERATED  
+  GENERATED    while (--i >= 0) {
+  GENERATED            REACH(lookup->target);
+  GENERATED            lookup++;
+  GENERATED    }
+  GENERATED  
+  GENERATED    LOG("switch done");
+  GENERATED  
+#              line 456 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_IRETURN:
+  GENERATED  case ICMD_LRETURN:
+  GENERATED  case ICMD_FRETURN:
+  GENERATED  case ICMD_DRETURN:
+  GENERATED  case ICMD_RETURN:
+  GENERATED    /* (I--), (L--), (F--), (D--), (--) */
+  GENERATED    superblockend = true;
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_ARETURN:
+  GENERATED  case ICMD_ATHROW:
+  GENERATED    /* (A--) */
+  GENERATED    maythrow = true;
+  GENERATED    superblockend = true;
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_GETSTATIC:
+  GENERATED    /* (--1|--2) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 230 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_fieldaccess(state, NULL, NULL))
+  GENERATED            return false;
+  GENERATED    maythrow = true;
+  GENERATED  
+#              line 494 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_GETFIELD:
+  GENERATED    /* (A--1|A--2) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 224 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), NULL))
+  GENERATED            return false;
+  GENERATED    maythrow = true;
+  GENERATED  
+#              line 516 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_INVOKEVIRTUAL:
+  GENERATED  case ICMD_INVOKESPECIAL:
+  GENERATED  case ICMD_INVOKESTATIC:
+  GENERATED  case ICMD_INVOKEINTERFACE:
+  GENERATED    /* (.--1|.--2|.--) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+  GENERATED  
+#              line 626 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPECHECK_COUNT(stat_ins_invoke);
+  GENERATED    if (!handle_invocation(state))
+  GENERATED            EXCEPTION;
+  GENERATED    TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(IPTR), stat_ins_invoke_unresolved);
+  GENERATED  
+#              line 542 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_CHECKCAST:
+  GENERATED    /* (A--A) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 373 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
+  GENERATED    /* returnAddress is not allowed */
+  GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
+  GENERATED            VERIFY_ERROR("Illegal instruction: CHECKCAST on non-reference");
+  GENERATED  
+#            endif
+  GENERATED  
+  GENERATED      /* XXX only if narrower */
+  GENERATED    if (!typeinfo_init_class(&(DST->typeinfo),IPTR->sx.s23.s3.c))
+  GENERATED            EXCEPTION;
+  GENERATED  
+#              line 572 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_MULTIANEWARRAY:
+  GENERATED    /* (.--A) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+#              define DST  VAROP(iptr->dst)
+  GENERATED  
+  GENERATED  
+#              line 669 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_multianewarray(STATE))
+  GENERATED            EXCEPTION;
+  GENERATED  
+#              line 595 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+#              undef DST
+  GENERATED  
+  GENERATED  
+  GENERATED  case ICMD_BUILTIN:
+  GENERATED    /* (.--1|.--2|.--) */
+  GENERATED    maythrow = true;
+  GENERATED  
+#              define OP1  VAROP(iptr->s1)
+  GENERATED  
+  GENERATED  
+#              line 684 "src/vm/jit/verify/icmds.c"
+  GENERATED    TYPECHECK_COUNT(stat_ins_builtin);
+  GENERATED    if (!handle_builtin(state))
+  GENERATED            EXCEPTION;
+  GENERATED  
+#              line 617 "src/vm/jit/verify/typecheck-typeinferer-gen.inc"
+  GENERATED  
+  GENERATED    break;
+  GENERATED  
+  GENERATED  
+#              undef OP1
+  GENERATED  
+  GENERATED  
+#undef GENERATED
+/* vim:filetype=c:
+ */
diff --git a/src/vm/jit/verify/typecheck-typeinferer.c b/src/vm/jit/verify/typecheck-typeinferer.c
new file mode 100644 (file)
index 0000000..5de1a62
--- /dev/null
@@ -0,0 +1,485 @@
+/* src/vm/jit/verify/typecheck-typeinferer.c - type inference pass
+
+   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
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Edwin Steiner
+
+   $Id$
+
+*/
+
+#include "config.h"
+#include "vm/types.h"
+#include "vm/global.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "mm/memory.h"
+#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/jit/parse.h"
+#include "vm/access.h"
+#include "vm/resolve.h"
+#include "vm/exceptions.h"
+#include "vm/vm.h"
+#include "vm/jit/verify/typecheck-typeinferer.h"
+
+#define TYPECHECK_NO_STATISTICS
+#include <typecheck-common.h>
+
+
+/* macros used by the generated code ******************************************/
+
+#define EXCEPTION          do { return false; } while (0)
+#define VERIFY_ERROR(msg)  assert(false)
+
+#define CHECK_LOCAL_TYPE(index, t)
+
+#define STORE_LOCAL(t, index)                                        \
+    do {                                                             \
+         typevector_store(jd->var, (index), (t), NULL);              \
+    } while (0)
+
+#define STORE_LOCAL_2_WORD(t, index)                                 \
+    do {                                                             \
+         typevector_store(jd->var, (index), (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)
+
+#define TYPECHECK_INT(v)  assert(jd->var[(v)].type == TYPE_INT)
+#define TYPECHECK_ADR(v)  assert(jd->var[(v)].type == TYPE_ADR)
+
+
+/* handle_fieldaccess **********************************************************
+   Verify an ICMD_{GET,PUT}{STATIC,FIELD}(CONST)?
+  
+   IN:
+       state............the current state of the verifier
+
+   RETURN VALUE:
+       true.............successful verification,
+          false............an exception has been thrown.
+
+*******************************************************************************/
+
+static bool
+handle_fieldaccess(verifier_state *state, 
+                                  varinfo *instance,
+                                  varinfo *value)
+{
+       jitdata *jd;
+
+       jd = state->jd;
+
+#define TYPECHECK_TYPEINFERER
+#include <typecheck-fields.inc>
+#undef  TYPECHECK_TYPEINFERER
+
+       return true;
+}
+
+
+/* handle_invocation ***********************************************************
+   Verify an ICMD_INVOKE* instruction.
+  
+   IN:
+       state............the current state of the verifier
+
+   RETURN VALUE:
+       true.............successful verification,
+          false............an exception has been thrown.
+
+*******************************************************************************/
+
+static bool
+handle_invocation(verifier_state *state)
+{
+       jitdata *jd;
+    varinfo *dv;               /* output variable of current instruction */
+
+       jd = state->jd;
+       dv = VAROP(state->iptr->dst);
+
+#define TYPECHECK_TYPEINFERER
+#define OP1   VAR(state->iptr->sx.s23.s2.args[0])
+#include <typecheck-invoke.inc>
+#undef  OP1
+#undef  TYPECHECK_TYPEINFERER
+
+       return true;
+}
+
+
+/* handle_builtin **************************************************************
+   Verify the call of a builtin method.
+  
+   IN:
+       state............the current state of the verifier
+
+   RETURN VALUE:
+       true.............successful verification,
+          false............an exception has been thrown.
+
+*******************************************************************************/
+
+static bool
+handle_builtin(verifier_state *state)
+{
+       jitdata *jd;
+    varinfo *dv;               /* output variable of current instruction */
+
+       jd = state->jd;
+       dv = VAROP(state->iptr->dst);
+
+#define TYPECHECK_TYPEINFERER
+#define OP1   state->iptr->sx.s23.s2.args[0]
+#include <typecheck-builtins.inc>
+#undef  OP1
+#undef  TYPECHECK_TYPEINFERER
+
+       return true;
+}
+
+/* handle_multianewarray *******************************************************
+   Verify a MULTIANEWARRAY instruction.
+  
+   IN:
+       state............the current state of the verifier
+
+   RETURN VALUE:
+       true.............successful verification,
+          false............an exception has been thrown.
+
+*******************************************************************************/
+
+static bool
+handle_multianewarray(verifier_state *state)
+{
+       jitdata *jd;
+    varinfo *dv;               /* output variable of current instruction */
+
+       jd = state->jd;
+       dv = VAROP(state->iptr->dst);
+
+#define TYPECHECK_TYPEINFERER
+#include <typecheck-multianewarray.inc>
+#undef  TYPECHECK_TYPEINFERER
+
+       return true;
+}
+
+
+/* handle_basic_block **********************************************************
+   Perform bytecode verification of a basic block.
+  
+   IN:
+       state............the current state of the verifier
+
+   RETURN VALUE:
+       true.............successful verification,
+          false............an exception has been thrown.
+
+*******************************************************************************/
+
+static bool
+handle_basic_block(verifier_state *state)
+{
+    int opcode;                                      /* current opcode */
+    int len;                        /* for counting instructions, etc. */
+    bool superblockend;        /* true if no fallthrough to next block */
+       instruction *iptr;                      /* the current instruction */
+    basicblock *tbptr;                   /* temporary for target block */
+    bool maythrow;               /* true if this instruction may throw */
+       s4 i;
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       jitdata *jd = state->jd;
+       exception_entry *ex;
+
+       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 */
+
+
+       /* determine the active exception handlers for this block */
+       /* XXX could use a faster algorithm with sorted lists or  */
+       /* something?                                             */
+       len = 0;
+       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;
+               }
+       }
+       state->handlers[len] = NULL;
+
+       /* init variable types at the start of this block */
+       typevector_copy_inplace(state->bptr->inlocals, jd->var, state->numlocals);
+
+       DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->invars, 
+                               state->bptr->indepth));
+       DOLOG(typevector_print(stdout, jd->var, state->numlocals));
+       LOGNL; LOGFLUSH;
+
+       /* loop over the instructions */
+       len = state->bptr->icount;
+       state->iptr = state->bptr->iinstr;
+       while (--len >= 0)  {
+               TYPECHECK_COUNT(stat_ins);
+
+               iptr = state->iptr;
+
+               DOLOG(typevector_print(stdout, jd->var, state->numlocals));
+               LOGNL; LOGFLUSH;
+               DOLOG(show_icmd(jd, state->iptr, false, SHOW_STACK)); LOGNL; LOGFLUSH;
+
+               opcode = iptr->opc;
+               maythrow = false;
+
+               switch (opcode) {
+
+                       /* include generated code for ICMDs verification */
+
+#define TYPECHECK_TYPEINFERER
+#define STATE  state
+#define METHOD (state->m)
+#define IPTR   iptr
+#define BPTR   (state->bptr)
+#include <typecheck-typeinferer-gen.inc>
+#undef  STATE
+#undef  METHOD
+#undef  IPTR
+#undef  BPTR
+#undef  TYPECHECK_TYPEINFERER
+
+                       default:
+                               vm_abort("missing ICMD in type inferer: %d\n", opcode);
+               }
+
+               /* reach exception handlers for this instruction */
+
+               if (maythrow) {
+                       TYPECHECK_COUNT(stat_ins_maythrow);
+                       TYPECHECK_MARK(state->stat_maythrow);
+                       LOG("reaching exception handlers");
+                       i = 0;
+                       while (state->handlers[i]) {
+                               TYPECHECK_COUNT(stat_handlers_reached);
+                               if (state->handlers[i]->catchtype.any)
+                                       VAR(state->exinvars)->typeinfo.typeclass = state->handlers[i]->catchtype;
+                               else
+                                       VAR(state->exinvars)->typeinfo.typeclass.cls = class_java_lang_Throwable;
+                               if (!typestate_reach(state,
+                                               state->handlers[i]->handler,
+                                               &(state->exinvars), jd->var, 1))
+                                       return false;
+                               i++;
+                       }
+               }
+
+               LOG("\t\tnext instruction");
+               state->iptr++;
+       } /* while instructions */
+
+       LOG("instructions done");
+       LOGSTR("RESULT=> ");
+       DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->outvars,
+                               state->bptr->outdepth));
+       DOLOG(typevector_print(stdout, jd->var, state->numlocals));
+       LOGNL; LOGFLUSH;
+
+       /* propagate stack and variables to the following block */
+       if (!superblockend) {
+               LOG("reaching following block");
+               tbptr = state->bptr->next;
+               while (tbptr->flags == BBDELETED) {
+                       tbptr = tbptr->next;
+               }
+               if (!typestate_reach(state,tbptr,state->bptr->outvars, jd->var,
+                                       state->bptr->outdepth))
+                       return false;
+       }
+
+       return true;
+}
+
+
+bool typecheck_infer_types(jitdata *jd)
+{
+       methodinfo     *meth;
+       codegendata    *cd;
+       varinfo        *savedlocals;
+       verifier_state  state;             /* current state of the verifier */
+
+       /* get required compiler data */
+
+       meth = jd->m;
+       cd   = jd->cd;
+
+       /* some logging on entry */
+
+
+    LOGSTR("\n==============================================================================\n");
+    DOLOG( show_method(jd, SHOW_STACK) );
+    LOGSTR("\n==============================================================================\n");
+    LOGMETHOD("Entering type inference: ",cd->method);
+
+       /* initialize the verifier state */
+
+       state.m = meth;
+       state.jd = jd;
+       state.cd = cd;
+       state.basicblockcount = jd->basicblockcount;
+       state.basicblocks = jd->basicblocks;
+       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, BBFINISHED);
+
+    /* number of local variables */
+    
+    /* In <init> methods we use an extra local variable to indicate whether */
+    /* the 'this' reference has been initialized.                           */
+       /*         TYPE_VOID...means 'this' has not been initialized,           */
+       /*         TYPE_INT....means 'this' has been initialized.               */
+
+    state.numlocals = state.jd->localcount;
+       state.validlocals = state.numlocals;
+    if (state.initmethod) 
+               state.numlocals++; /* VERIFIER_EXTRA_LOCALS */
+
+    /* allocate the buffer of active exception handlers */
+       
+    state.handlers = DMNEW(exception_entry*, state.jd->exceptiontablelength + 1);
+
+       /* save local variables */
+
+       savedlocals = DMNEW(varinfo, state.numlocals);
+       MCOPY(savedlocals, jd->var, varinfo, state.numlocals);
+
+       /* initialized local variables of first block */
+
+       if (!typecheck_init_locals(&state, false))
+               return false;
+
+    /* initialize invars of exception handlers */
+       
+       state.exinvars = state.numlocals;
+       VAR(state.exinvars)->type = TYPE_ADR;
+       typeinfo_init_classinfo(&(VAR(state.exinvars)->typeinfo),
+                                                       class_java_lang_Throwable); /* changed later */
+
+    LOG("Exception handler stacks set.\n");
+
+    /* loop while there are still blocks to be checked */
+    do {
+               TYPECHECK_COUNT(count_iterations);
+
+        state.repeat = false;
+        
+        state.bptr = state.basicblocks;
+
+        for (; state.bptr; state.bptr = state.bptr->next) {
+            LOGSTR1("---- BLOCK %04d, ",state.bptr->nr);
+            LOGSTR1("blockflags: %d\n",state.bptr->flags);
+            LOGFLUSH;
+            
+                   /* verify reached block */  
+            if (state.bptr->flags == BBTYPECHECK_REACHED) {
+                if (!handle_basic_block(&state))
+                                       return false;
+            }
+        } /* for blocks */
+
+        LOGIF(state.repeat,"state.repeat == true");
+    } while (state.repeat);
+
+       /* statistics */
+       
+       /* reset the flags of blocks we haven't reached */
+
+       typecheck_reset_flags(&state);
+
+       /* restore locals */
+
+       MCOPY(jd->var, savedlocals, varinfo, state.numlocals);
+
+       /* everything's ok */
+
+    LOGimp("exiting type inference");
+       return true;
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/vm/jit/verify/typecheck-typeinferer.h b/src/vm/jit/verify/typecheck-typeinferer.h
new file mode 100644 (file)
index 0000000..387ab19
--- /dev/null
@@ -0,0 +1,63 @@
+/* src/vm/jit/verify/typecheck-typeinferer.h - type inference header
+
+   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
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Edwin Steiner
+
+   $Id$
+
+*/
+
+
+#ifndef _TYPECHECK_TYPEINFERER_H
+#define _TYPECHECK_TYPEINFERER_H
+
+#include "config.h"
+
+#include "vm/global.h"
+#include "vm/jit/jit.h"
+
+
+/* function prototypes ********************************************************/
+
+#if defined(ENABLE_VERIFIER)
+bool typecheck_infer_types(jitdata *jd);
+#endif
+
+#endif /* _TYPECHECK_TYPEINFERER_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index ff069ba9078eb35defb1a4ce37dad11442df8308..d982267cadc7e899a09606ce3b215e49c642aed6 100644 (file)
@@ -15,7 +15,7 @@
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 347 "src/vm/jit/verify/icmds.c"
+#              line 355 "src/vm/jit/verify/icmds.c"
   GENERATED    if (IPTR->flags.bits & INS_FLAG_CLASS) {
   GENERATED            /* a java.lang.Class reference */
   GENERATED            TYPEINFO_INIT_JAVA_LANG_CLASS(DST->typeinfo,IPTR->sx.val.c);
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 86 "src/vm/jit/verify/icmds.c"
+#              line 90 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_stack);
   GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
   GENERATED    DST->type = OP1->type;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 85 "src/vm/jit/verify/icmds.c"
+#              line 89 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_stack);
   GENERATED    COPYTYPE(IPTR->s1, IPTR->dst);
   GENERATED    DST->type = OP1->type;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 95 "src/vm/jit/verify/icmds.c"
+#              line 99 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_aload);
   GENERATED  
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* loading a returnAddress is not allowed */
   GENERATED    if (!TYPEDESC_IS_REFERENCE(*OP1)) {
   GENERATED            VERIFY_ERROR("illegal instruction: ALOAD loading non-reference");
   GENERATED    }
+  GENERATED  
+#            endif
   GENERATED    TYPEINFO_COPY(OP1->typeinfo,DST->typeinfo);
   GENERATED  
-#              line 242 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 246 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_ADR;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 258 "src/vm/jit/verify/icmds.c"
+#              line 266 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 266 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 270 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_INT;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 268 "src/vm/jit/verify/icmds.c"
+#              line 276 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 290 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 294 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_LNG;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 253 "src/vm/jit/verify/icmds.c"
+#              line 261 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 314 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 318 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_FLT;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 248 "src/vm/jit/verify/icmds.c"
+#              line 256 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 338 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 342 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_DBL;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 115 "src/vm/jit/verify/icmds.c"
+#              line 121 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: AALOAD on non-reference array");
   GENERATED  
+#            endif
+  GENERATED  
   GENERATED    if (!typeinfo_init_component(&OP1->typeinfo,&DST->typeinfo))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 365 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 373 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_ADR;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 237 "src/vm/jit/verify/icmds.c"
+#              line 245 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 390 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 398 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_INT;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 243 "src/vm/jit/verify/icmds.c"
+#              line 251 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 414 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 422 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_INT;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 263 "src/vm/jit/verify/icmds.c"
+#              line 271 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 438 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 446 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_INT;
   GENERATED    break;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 108 "src/vm/jit/verify/icmds.c"
+#              line 114 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_COPY(OP1->typeinfo, DST->typeinfo);
   GENERATED  
-#              line 485 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 493 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 401 "src/vm/jit/verify/icmds.c"
+#              line 414 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 535 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 543 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 294 "src/vm/jit/verify/icmds.c"
+#              line 302 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 554 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 562 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 304 "src/vm/jit/verify/icmds.c"
+#              line 312 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 573 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 581 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 289 "src/vm/jit/verify/icmds.c"
+#              line 297 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_FLOAT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 592 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 600 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 284 "src/vm/jit/verify/icmds.c"
+#              line 292 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_DOUBLE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 611 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 619 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 309 "src/vm/jit/verify/icmds.c"
+#              line 317 "src/vm/jit/verify/icmds.c"
   GENERATED    /* we just check the basic input types and that the           */
   GENERATED    /* destination is an array of references. Assignability to    */
   GENERATED    /* the actual array must be checked at runtime, each time the */
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: AASTORE to non-reference array");
   GENERATED  
-#              line 634 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 642 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 273 "src/vm/jit/verify/icmds.c"
+#              line 281 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 654 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 662 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 279 "src/vm/jit/verify/icmds.c"
+#              line 287 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 673 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 681 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 299 "src/vm/jit/verify/icmds.c"
+#              line 307 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo,ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 692 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 700 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 383 "src/vm/jit/verify/icmds.c"
+#              line 396 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_branch);
   GENERATED  
   GENERATED    /* propagate stack and variables to the target block */
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 744 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 752 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 574 "src/vm/jit/verify/icmds.c"
+#              line 587 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPEINFO_INIT_RETURNADDRESS(DST->typeinfo, BPTR->next);
   GENERATED    REACH(IPTR->sx.s23.s3.jsrtarget);
   GENERATED  
-#              line 760 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 768 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_RET;
   GENERATED    break;
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 591 "src/vm/jit/verify/icmds.c"
+#              line 604 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* check returnAddress variable */
   GENERATED    if (!typevector_checkretaddr(jd->var,IPTR->s1.varindex))
   GENERATED            VERIFY_ERROR("illegal instruction: RET using non-returnAddress variable");
+  GENERATED  
+#            endif
   GENERATED    REACH(IPTR->dst);
   GENERATED  
-#              line 780 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 792 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 450 "src/vm/jit/verify/icmds.c"
+#              line 463 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
   GENERATED  
   GENERATED    LOG("switch done");
   GENERATED  
-#              line 807 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 819 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 466 "src/vm/jit/verify/icmds.c"
+#              line 479 "src/vm/jit/verify/icmds.c"
   GENERATED    /* {RESULTNOW} */
   GENERATED    TYPECHECK_COUNT(stat_ins_switch);
   GENERATED  
   GENERATED  
   GENERATED    LOG("switch done");
   GENERATED  
-#              line 837 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 849 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 532 "src/vm/jit/verify/icmds.c"
+#              line 545 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_INT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 856 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 868 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 537 "src/vm/jit/verify/icmds.c"
+#              line 550 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_LNG)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 875 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 887 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 542 "src/vm/jit/verify/icmds.c"
+#              line 555 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_FLT)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 894 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 906 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 547 "src/vm/jit/verify/icmds.c"
+#              line 560 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_DBL)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
-#              line 913 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 925 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 507 "src/vm/jit/verify/icmds.c"
+#              line 520 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_areturn);
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("illegal instruction: ARETURN on non-reference");
   GENERATED            IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
   GENERATED    }
   GENERATED  
-#              line 950 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 962 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    goto return_tail;
   GENERATED  
   GENERATED    superblockend = true;
   GENERATED  
   GENERATED  
-#              line 552 "src/vm/jit/verify/icmds.c"
+#              line 565 "src/vm/jit/verify/icmds.c"
   GENERATED    if (STATE->returntype.type != TYPE_VOID)
   GENERATED            VERIFY_ERROR("Return type mismatch");
   GENERATED  
   GENERATED                    VERIFY_ERROR("<init> method does not initialize 'this'");
   GENERATED    }
   GENERATED  
-#              line 984 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 996 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 222 "src/vm/jit/verify/icmds.c"
-  GENERATED    if (!verify_fieldaccess(state, NULL, NULL))
+#              line 230 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_fieldaccess(state, NULL, NULL))
   GENERATED            return false;
   GENERATED    maythrow = true;
   GENERATED  
-#              line 1001 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1013 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 168 "src/vm/jit/verify/icmds.c"
-  GENERATED    if (!verify_fieldaccess(state, NULL, VAROP(iptr->s1)))
+#              line 176 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_fieldaccess(state, NULL, VAROP(iptr->s1)))
   GENERATED            return false;
   GENERATED    maythrow = true;
   GENERATED  
-#              line 1021 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1033 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 216 "src/vm/jit/verify/icmds.c"
-  GENERATED    if (!verify_fieldaccess(state, VAROP(iptr->s1), NULL))
+#              line 224 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), NULL))
   GENERATED            return false;
   GENERATED    maythrow = true;
   GENERATED  
-#              line 1043 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1055 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 162 "src/vm/jit/verify/icmds.c"
-  GENERATED    if (!verify_fieldaccess(state, VAROP(iptr->s1), VAROP(iptr->sx.s23.s2)))
+#              line 170 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), VAROP(iptr->sx.s23.s2)))
   GENERATED            return false;
   GENERATED    maythrow = true;
   GENERATED  
-#              line 1065 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1077 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 611 "src/vm/jit/verify/icmds.c"
+#              line 626 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_invoke);
-  GENERATED    if (!verify_invocation(state))
+  GENERATED    if (!handle_invocation(state))
   GENERATED            EXCEPTION;
   GENERATED    TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(IPTR), stat_ins_invoke_unresolved);
   GENERATED  
-#              line 1089 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1101 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 231 "src/vm/jit/verify/icmds.c"
+#              line 239 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_ARRAY(OP1->typeinfo)
   GENERATED                    && OP1->typeinfo.typeclass.cls != pseudo_class_Arraystub)
   GENERATED            VERIFY_ERROR("illegal instruction: ARRAYLENGTH on non-array");
   GENERATED  
-#              line 1111 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1123 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_INT;
   GENERATED    break;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 486 "src/vm/jit/verify/icmds.c"
+#              line 499 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_athrow);
   GENERATED    r = typeinfo_is_assignable_to_class(&OP1->typeinfo,
   GENERATED                    CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
   GENERATED            IPTR->flags.bits |= INS_FLAG_UNRESOLVED;
   GENERATED    }
   GENERATED  
-#              line 1150 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1162 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 365 "src/vm/jit/verify/icmds.c"
+#              line 373 "src/vm/jit/verify/icmds.c"
+  GENERATED  
+#            if !defined(TYPECHECK_TYPEINFERER)
   GENERATED    /* returnAddress is not allowed */
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("Illegal instruction: CHECKCAST on non-reference");
   GENERATED  
+#            endif
+  GENERATED  
+  GENERATED      /* XXX only if narrower */
   GENERATED    if (!typeinfo_init_class(&(DST->typeinfo),IPTR->sx.s23.s3.c))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1175 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1192 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_ADR;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 374 "src/vm/jit/verify/icmds.c"
+#              line 385 "src/vm/jit/verify/icmds.c"
   GENERATED    /* returnAddress is not allowed */
   GENERATED    if (!TYPEINFO_IS_REFERENCE(OP1->typeinfo))
   GENERATED            VERIFY_ERROR("Illegal instruction: INSTANCEOF on non-reference");
   GENERATED  
-#              line 1200 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+  GENERATED    /* XXX should propagate type information to the following if-branches */
+  GENERATED  
+#              line 1219 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_INT;
   GENERATED    break;
 #              define DST  VAROP(iptr->dst)
   GENERATED  
   GENERATED  
-#              line 654 "src/vm/jit/verify/icmds.c"
-  GENERATED    if (!verify_multianewarray(STATE))
+#              line 669 "src/vm/jit/verify/icmds.c"
+  GENERATED    if (!handle_multianewarray(STATE))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1224 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1243 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    VAROP(iptr->dst)->type = TYPE_ADR;
   GENERATED    break;
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 318 "src/vm/jit/verify/icmds.c"
+#              line 326 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_INT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 1246 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1265 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 323 "src/vm/jit/verify/icmds.c"
+#              line 331 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_LONG))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 1265 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1284 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 328 "src/vm/jit/verify/icmds.c"
+#              line 336 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_BOOLEAN)
   GENERATED                    && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_BYTE))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 1293 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1312 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 334 "src/vm/jit/verify/icmds.c"
+#              line 342 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_CHAR))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 1312 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1331 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 339 "src/vm/jit/verify/icmds.c"
+#              line 347 "src/vm/jit/verify/icmds.c"
   GENERATED    if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(OP1->typeinfo, ARRAYTYPE_SHORT))
   GENERATED            VERIFY_ERROR("Array type mismatch");
   GENERATED  
-#              line 1331 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1350 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
   GENERATED    maythrow = true;
   GENERATED  
   GENERATED  
-#              line 195 "src/vm/jit/verify/icmds.c"
+#              line 203 "src/vm/jit/verify/icmds.c"
   GENERATED    /* XXX this mess will go away with const operands */
   GENERATED    INSTRUCTION_GET_FIELDREF(state->iptr, fieldref);
   GENERATED    constvalue.type = fieldref->parseddesc.fd->type;
   GENERATED                    TYPEINFO_INIT_NULLTYPE(constvalue.typeinfo);
   GENERATED            }
   GENERATED    }
-  GENERATED    if (!verify_fieldaccess(state, NULL, &constvalue))
+  GENERATED    if (!handle_fieldaccess(state, NULL, &constvalue))
   GENERATED            return false;
   GENERATED    maythrow = true;
   GENERATED  
-#              line 1364 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1383 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 174 "src/vm/jit/verify/icmds.c"
+#              line 182 "src/vm/jit/verify/icmds.c"
   GENERATED    /* XXX this mess will go away with const operands */
   GENERATED    INSTRUCTION_GET_FIELDREF(state->iptr, fieldref);
   GENERATED    constvalue.type = fieldref->parseddesc.fd->type;
   GENERATED                    TYPEINFO_INIT_NULLTYPE(constvalue.typeinfo);
   GENERATED            }
   GENERATED    }
-  GENERATED    if (!verify_fieldaccess(state, VAROP(iptr->s1), &constvalue))
+  GENERATED    if (!handle_fieldaccess(state, VAROP(iptr->s1), &constvalue))
   GENERATED            return false;
   GENERATED    maythrow = true;
   GENERATED  
-#              line 1396 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1415 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
 #              define OP1  VAROP(iptr->s1)
   GENERATED  
   GENERATED  
-#              line 669 "src/vm/jit/verify/icmds.c"
+#              line 684 "src/vm/jit/verify/icmds.c"
   GENERATED    TYPECHECK_COUNT(stat_ins_builtin);
-  GENERATED    if (!verify_builtin(state))
+  GENERATED    if (!handle_builtin(state))
   GENERATED            EXCEPTION;
   GENERATED  
-#              line 1416 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
+#              line 1435 "src/vm/jit/verify/typecheck-variablesbased-gen.inc"
   GENERATED  
   GENERATED    break;
   GENERATED  
index ac392840d2bac907019ca70040f0fbee88df8eef..da521e1b1bc501a9aecf070ba58ea7650c1d3129 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: typecheck.c 6008 2006-11-15 23:44:01Z edwin $
+   $Id: typecheck.c 6275 2007-01-03 22:39:14Z edwin $
 
 */
 
@@ -197,233 +197,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->nr <= state->bptr->nr) {
-                       LOG("REPEAT!"); 
-                       state->repeat = true;
-               }
-       }
-       return true;
-}
-
-
 /* typestate_save_invars *******************************************************
  
    Save the invars of the current basic block in the space reserved by
@@ -501,16 +274,7 @@ typestate_restore_invars(verifier_state *state)
 }
 
 
-/****************************************************************************/
-/* MISC MACROS                                                              */
-/****************************************************************************/
-
-#define COPYTYPE(source,dest)                                        \
-    {if (VAROP(source)->type == TYPE_ADR)                            \
-            TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
-
-
-/* verify_fieldaccess **********************************************************
+/* handle_fieldaccess **********************************************************
  
    Verify an ICMD_{GET,PUT}{STATIC,FIELD}(CONST)?
   
@@ -524,7 +288,7 @@ typestate_restore_invars(verifier_state *state)
 *******************************************************************************/
 
 static bool
-verify_fieldaccess(verifier_state *state, 
+handle_fieldaccess(verifier_state *state,
                                   varinfo *instance,
                                   varinfo *value)
 {
@@ -544,7 +308,7 @@ verify_fieldaccess(verifier_state *state,
 }
 
 
-/* verify_invocation ***********************************************************
+/* handle_invocation ***********************************************************
  
    Verify an ICMD_INVOKE* instruction.
   
@@ -558,7 +322,7 @@ verify_fieldaccess(verifier_state *state,
 *******************************************************************************/
 
 static bool
-verify_invocation(verifier_state *state)
+handle_invocation(verifier_state *state)
 {
        jitdata *jd;
     varinfo *dv;               /* output variable of current instruction */
@@ -576,7 +340,7 @@ verify_invocation(verifier_state *state)
 }
 
 
-/* verify_builtin **************************************************************
+/* handle_builtin **************************************************************
  
    Verify the call of a builtin method.
   
@@ -590,7 +354,7 @@ verify_invocation(verifier_state *state)
 *******************************************************************************/
 
 static bool
-verify_builtin(verifier_state *state)
+handle_builtin(verifier_state *state)
 {
        jitdata *jd;
     varinfo *dv;               /* output variable of current instruction */
@@ -607,7 +371,7 @@ verify_builtin(verifier_state *state)
        return true;
 }
 
-/* verify_multianewarray *******************************************************
+/* handle_multianewarray *******************************************************
  
    Verify a MULTIANEWARRAY instruction.
   
@@ -621,67 +385,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.
@@ -780,7 +500,7 @@ static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool tw
 #define REACH(target)   REACH_BLOCK((target).block)
 
 
-/* verify_basic_block **********************************************************
+/* handle_basic_block **********************************************************
  
    Perform bytecode verification of a basic block.
   
@@ -794,7 +514,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. */
@@ -937,80 +657,6 @@ verify_basic_block(verifier_state *state)
 }
 
 
-/* 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         */
@@ -1123,7 +769,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 */
@@ -1150,7 +796,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 */