* src/vm/jit/verify/typecheck.c (verify_invocation): Moved body to a
authoredwin <none@none>
Wed, 11 Oct 2006 23:00:01 +0000 (23:00 +0000)
committeredwin <none@none>
Wed, 11 Oct 2006 23:00:01 +0000 (23:00 +0000)
separate file in order to prepare comitting the stackbased verifier.
(verify_builtin): Likewise.
(verify_generic_builtin): Likewise, no integrated in verify_builtin.
(verify_basic_block): Moved field instruction verification to a
separate file.

* src/vm/jit/verify/typecheck-invoke.inc: New file.
* src/vm/jit/verify/typecheck-fields.inc: New file.
* src/vm/jit/verify/typecheck-builtins.inc: New file.

* src/vm/jit/verify/Makefile.am: Added new source files.

src/vm/jit/verify/Makefile.am
src/vm/jit/verify/typecheck-builtins.inc [new file with mode: 0644]
src/vm/jit/verify/typecheck-fields.inc [new file with mode: 0644]
src/vm/jit/verify/typecheck-invoke.inc [new file with mode: 0644]
src/vm/jit/verify/typecheck.c

index 0536f0d860696f0821d11431782ef5a6c2bb9e5b..b68170b5c7981af8d6b9317962be5ec5cfb581c3 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes:
 ##
-## $Id: Makefile.am 4627 2006-03-16 12:53:32Z twisti $
+## $Id: Makefile.am 5740 2006-10-11 23:00:01Z edwin $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -41,6 +41,9 @@ noinst_LTLIBRARIES = libverify.la
 libverify_la_SOURCES = \
        typecheck.c \
        typecheck.h \
+       typecheck-builtins.inc \
+       typecheck-fields.inc \
+       typecheck-invoke.inc \
        typeinfo.c \
        typeinfo.h
 
diff --git a/src/vm/jit/verify/typecheck-builtins.inc b/src/vm/jit/verify/typecheck-builtins.inc
new file mode 100644 (file)
index 0000000..cb69b4a
--- /dev/null
@@ -0,0 +1,136 @@
+{
+       builtintable_entry *bte;
+    classref_or_classinfo cls;
+    varinfo *dv;               /* output variable of current instruction */
+       jitdata *jd = state->jd;
+
+       bte = state->iptr->sx.s23.s3.bte;
+       dv = VAROP(state->iptr->dst);
+
+       /* XXX this is an ugly if-chain but twisti did not want a function */
+       /* pointer in builtintable_entry for this, so here you go.. ;)     */
+
+       if (ISBUILTIN(BUILTIN_new)) {
+               if (state->iptr[-1].opc != ICMD_ACONST)
+                       TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
+               cls = state->iptr[-1].sx.val.c;
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_NEWOBJECT(dv->typeinfo,state->iptr);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BOOLEAN);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_char)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_CHAR);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_float)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_FLOAT);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_double)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_DOUBLE);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_byte)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BYTE);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_short)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_SHORT);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_int)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_INT);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray_long)) {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               dv->type = TYPE_ADR;
+               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_LONG);
+       }
+       else if (ISBUILTIN(BUILTIN_newarray))
+       {
+               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
+               if (state->iptr[-1].opc != ICMD_ACONST)
+                       TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
+               /* XXX check that it is an array class(ref) */
+               dv->type = TYPE_ADR;
+               typeinfo_init_class(&(dv->typeinfo),state->iptr[-1].sx.val.c);
+       }
+       else if (ISBUILTIN(BUILTIN_arrayinstanceof))
+       {
+               TYPECHECK_ADR(state->iptr->sx.s23.s2.args[0]);
+               if (state->iptr[-1].opc != ICMD_ACONST)
+                       TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
+               dv->type = TYPE_INT;
+               /* XXX check that it is an array class(ref) */
+       }
+       else {
+               methoddesc *md;
+               s4 i;
+               u1 rtype;
+               varinfo *av;
+
+               /* verify a generic builtin call */
+
+               TYPECHECK_COUNT(stat_ins_builtin_gen);
+
+               md = bte->md;
+               i = md->paramcount;
+
+               /* check the types of the arguments on the stack */
+
+               for (i--; i >= 0; i--) {
+                       av = VAR(state->iptr->sx.s23.s2.args[i]);
+
+                       if (av->type != md->paramtypes[i].type) {
+                               TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
+                       }
+
+#ifdef TYPECHECK_DEBUG
+                       /* generic builtins may only take primitive types and java.lang.Object references */
+                       if (av->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
+                               *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
+                               return false;
+                       }
+#endif
+               }
+
+               /* set the return type */
+
+               rtype = md->returntype.type;
+               if (rtype != TYPE_VOID) {
+                       varinfo *dv;
+
+                       dv = VAROP(state->iptr->dst);
+                       dv->type = rtype;
+                       if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
+                               return false;
+               }
+
+               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:filetype=c:
+ */
diff --git a/src/vm/jit/verify/typecheck-fields.inc b/src/vm/jit/verify/typecheck-fields.inc
new file mode 100644 (file)
index 0000000..9c6c77f
--- /dev/null
@@ -0,0 +1,144 @@
+{
+       varinfo *valueslot = NULL;
+       typeinfo *instanceti = NULL;
+       typeinfo *valueti = NULL;
+       bool isstatic = false;
+       bool isput = false;
+       typeinfo constti;
+
+       TYPECHECK_COUNT(stat_ins_field);
+
+       if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
+               uf = state->iptr->sx.s23.s3.uf;
+               fieldref = uf->fieldref;
+       }
+       else {
+               uf = NULL;
+               fieldref = state->iptr->sx.s23.s3.fmiref;
+       }
+
+       /* get opcode dependent values */
+
+       switch (state->iptr->opc) {
+               case ICMD_PUTFIELD:
+                       isput = true;
+                       valueslot = VAROP(state->iptr->sx.s23.s2);
+                       instanceti = &(VAROP(state->iptr->s1)->typeinfo);
+                       break;
+
+               case ICMD_PUTFIELDCONST:
+                       isput = true;
+                       instanceti = &(VAROP(state->iptr->s1)->typeinfo);
+putfield_const_tail:
+                       if (IS_ADR_TYPE(fieldref->parseddesc.fd->type)) {
+                               /* XXX check for java.lang.Class constant values? */
+                               if (state->iptr->sx.val.anyptr) {
+                                       assert(class_java_lang_String);
+                                       assert(class_java_lang_String->state & CLASS_LOADED);
+                                       assert(class_java_lang_String->state & CLASS_LINKED);
+                                       typeinfo_init_classinfo(&constti, class_java_lang_String);
+                               }
+                               else {
+                                       TYPEINFO_INIT_NULLTYPE(constti);
+                               }
+                               valueti = &constti;
+                       }
+                       break;
+
+               case ICMD_PUTSTATIC:
+                       isput = true;
+                       isstatic = true;
+                       valueslot = VAROP(state->iptr->s1);
+                       break;
+
+               case ICMD_PUTSTATICCONST:
+                       isput = true;
+                       isstatic = true;
+                       goto putfield_const_tail;
+
+               case ICMD_GETFIELD:
+                       instanceti = &(VAROP(state->iptr->s1)->typeinfo);
+                       break;
+
+               case ICMD_GETSTATIC:
+                       isstatic = true;
+                       break;
+
+               default:
+                       assert(false);
+       }
+
+       if (valueslot && IS_ADR_TYPE(valueslot->type)) {
+               valueti = &(valueslot->typeinfo);
+       }
+
+       /* try to resolve the field reference lazily */
+
+       result = resolve_field_lazy(state->m, fieldref);
+
+       if (result == resolveSucceeded) {
+               fieldinfo *fi;
+
+               /* perform verification checks now */
+
+               fi  = fieldref->p.field;
+
+               result = resolve_field_verifier_checks(
+                               state->m, fieldref, fi->class, fi,
+                               instanceti, valueti, isstatic, isput);
+       }
+
+       if (result == resolveFailed)
+               return false;
+
+       /* if not resolved, yet, create an unresolved field */
+
+       if (result != resolveSucceeded) {
+               if (!uf) {
+                       uf = resolve_create_unresolved_field(state->m->class, 
+                                       state->m, state->iptr);
+                       if (!uf)
+                               return false;
+
+                       state->iptr->sx.s23.s3.uf = uf;
+                       state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
+               }
+
+               /* record the subtype constraints for this field access */
+
+               if (!resolve_constrain_unresolved_field(
+                                       uf, state->m->class, state->m,
+                                       instanceti, valueti))
+                       return false; /* XXX maybe wrap exception? */
+
+               TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
+               TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && 
+                               !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,
+                               stat_ins_field_uninitialized);
+       }
+               
+       /* write the result type */
+
+       if (iptr->opc == ICMD_GETFIELD || iptr->opc == ICMD_GETSTATIC) {
+               dv->type = fieldref->parseddesc.fd->type;
+               if (dv->type == TYPE_ADR) {
+                       if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd, 
+                                               NULL, &(dv->typeinfo)))
+                               return false;
+               }
+       }
+}
+
+/*
+ * 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:
+ */
diff --git a/src/vm/jit/verify/typecheck-invoke.inc b/src/vm/jit/verify/typecheck-invoke.inc
new file mode 100644 (file)
index 0000000..715fb4e
--- /dev/null
@@ -0,0 +1,294 @@
+{
+       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 */
+       utf *mclassname;                     /* name of the method's class */
+       bool specialmethod;            /* true if a <...> method is called */
+       int opcode;                                   /* invocation opcode */
+       bool callinginit;                      /* true if <init> is called */
+       instruction *ins;
+       classref_or_classinfo initclass;
+       typedesc *td;
+       s4 argindex;                            /* argument variable index */
+       varinfo *av;                                  /* argument variable */
+       varinfo *dv;                  /* result variable of the invocation */
+       int i;                                                  /* counter */
+    u1 rtype;                          /* return type of called method */
+       resolve_result_t result;
+       jitdata *jd;
+       bool invokestatic;
+       bool invokespecial;
+
+       jd = state->jd;
+
+       /* get the FMIref and the unresolved_method struct (if any) */
+       /* from the instruction                                     */
+
+       if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
+               /* unresolved method */
+               um = state->iptr->sx.s23.s3.um;
+               mref = um->methodref;
+       }
+       else {
+               /* resolved method */
+               um = NULL;
+               mref = state->iptr->sx.s23.s3.fmiref;
+       }
+
+       /* get method descriptor and name */
+
+       md = mref->parseddesc.md;
+       mname = mref->name;
+
+       /* get method info (if resolved) and classname */
+
+       if (IS_FMIREF_RESOLVED(mref)) {
+               mi = mref->p.method;
+               mclassname = mi->class->name;
+       }
+       else {
+               mi = NULL;
+               mclassname = mref->p.classref->name;
+       }
+
+       opcode = state->iptr[0].opc;
+       invokestatic = (opcode == ICMD_INVOKESTATIC);
+       invokespecial = (opcode == ICMD_INVOKESPECIAL);
+       specialmethod = (mname->text[0] == '<');
+       dv = VAROP(state->iptr->dst);
+
+       /* prevent compiler warnings */
+
+       ins = NULL;
+
+       /* check whether we are calling <init> */
+       
+       callinginit = (invokespecial && mname == utf_init);
+       if (specialmethod && !callinginit)
+               TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
+
+       /* allocate parameters if necessary */
+       
+       if (!md->params)
+               if (!descriptor_params_from_paramtypes(md,
+                                       (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
+                       return false;
+
+       /* check parameter types */
+
+       i = md->paramcount; /* number of parameters including 'this'*/
+       while (--i >= 0) {
+               LOG1("param %d",i);
+               argindex = state->iptr->sx.s23.s2.args[i];
+               av = VAR(argindex);
+               td = md->paramtypes + i;
+
+               if (av->type != td->type)
+                       TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
+
+               if (av->type == TYPE_ADR) {
+                       LOGINFO(&(av->typeinfo));
+                       if (i==0 && callinginit)
+                       {
+                               /* first argument to <init> method */
+                               if (!TYPEINFO_IS_NEWOBJECT(av->typeinfo))
+                                       TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
+
+                               /* get the address of the NEW instruction */
+                               LOGINFO(&(av->typeinfo));
+                               ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo);
+                               if (ins)
+                                       initclass = ins[-1].sx.val.c;
+                               else
+                                       initclass.cls = state->m->class;
+                               LOGSTR("class: "); LOGNAME(initclass); LOGNL;
+                       }
+               }
+               else {
+                       /* non-adress argument. if this is the first argument and we are */
+                       /* invoking an instance method, this is an error.                */
+                       if (i==0 && opcode != ICMD_INVOKESTATIC) {
+                               TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
+                       }
+               }
+               LOG("ok");
+       }
+
+       if (callinginit) {
+               LOG("replacing uninitialized object");
+               /* replace uninitialized object type on stack */
+
+               /* for all live-in and live-through variables */ 
+               for (i=0; i<state->iptr->s1.argcount; ++i) {
+                       argindex = state->iptr->sx.s23.s2.args[i];
+                       av = VAR(argindex);
+                       if (av->type == TYPE_ADR
+                                       && TYPEINFO_IS_NEWOBJECT(av->typeinfo)
+                                       && TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo) == ins)
+                       {
+                               LOG("replacing uninitialized type");
+
+                               /* If this stackslot is in the instack of
+                                * this basic block we must save the type(s)
+                                * we are going to replace.
+                                */
+                               /* XXX this needs a new check */
+                               if (state->bptr->invars
+                                               && argindex >= state->bptr->invars[0] 
+                                               && argindex < state->bptr->varstart 
+                                               && !state->savedinvars)
+                               {
+                                       typestate_save_invars(state);
+                               }
+
+                               if (!typeinfo_init_class(&(av->typeinfo),initclass))
+                                       return false;
+                       }
+               }
+
+               /* replace uninitialized object type in locals */
+               if (!typevector_init_object(state->jd->var, ins, initclass,
+                                       state->numlocals))
+                       return false;
+
+               /* initializing the 'this' reference? */
+               if (!ins) {
+                       classinfo *cls;
+                       TYPECHECK_ASSERT(state->initmethod);
+                       /* { we are initializing the 'this' reference }                           */
+                       /* must be <init> of current class or direct superclass                   */
+                       /* the current class is linked, so must be its superclass. thus we can be */
+                       /* sure that resolving will be trivial.                                   */
+                       if (mi) {
+                               cls = mi->class;
+                       }
+                       else {
+                               if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
+                                       return false; /* exception */
+                       }
+
+                       /* if lazy resolving did not succeed, it's not one of the allowed classes */
+                       /* otherwise we check it directly                                         */
+                       if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
+                               TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
+                       }
+
+                       /* set our marker variable to type int */
+                       LOG("setting <init> marker");
+                       typevector_store(jd->var, state->numlocals-1, TYPE_INT, NULL);
+               }
+               else {
+                       /* { we are initializing an instance created with NEW } */
+                       if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mclassname) {
+                               TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
+                       }
+               }
+       }
+
+       /* try to resolve the method lazily */
+
+       result = resolve_method_lazy(state->m, mref, invokespecial);
+
+       /* perform verification checks */
+
+       if (result == resolveSucceeded) {
+
+               assert(IS_FMIREF_RESOLVED(mref));
+
+               mi = mref->p.method;
+
+               result = resolve_method_verifier_checks(state->m, 
+                                                                                               mref,
+                                                                                               mi,
+                                                                                               invokestatic);
+       }
+
+       /* check types of parameters */
+
+       if (result == resolveSucceeded && !invokestatic)
+               result = resolve_method_instance_type_checks(
+                               state->m, mi, 
+                               &(VAR(state->iptr->sx.s23.s2.args[0])->typeinfo), 
+                               invokespecial);
+
+       if (result == resolveSucceeded)
+               result = resolve_method_param_type_checks(
+                               jd, state->m, state->iptr,
+                               mi, invokestatic);
+
+       /* impose loading constraints */
+
+       if (result == resolveSucceeded) {
+               /* XXX state->m->class may have to be wrong when inlining */
+               if (!resolve_method_loading_constraints(state->m->class, mi))
+                       return false;
+       }
+
+       if (result == resolveFailed)
+               return false;
+
+       if (result == resolveSucceeded) {
+               /* if this call is monomorphic, turn it into an INVOKESPECIAL */
+
+               if ((state->iptr->opc == ICMD_INVOKEVIRTUAL)
+                       && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
+               {
+                       state->iptr->opc = ICMD_INVOKESPECIAL;
+               }
+       }
+       else {
+               /* resolution must be deferred */
+
+               if (!um) {
+                       um = resolve_create_unresolved_method(state->m->class, state->m,
+                                       mref, 
+                                       state->iptr->opc == ICMD_INVOKESTATIC,
+                                       invokespecial);
+
+                       if (!um)
+                               return false;
+               }
+
+               /* record subtype constraints for parameters */
+
+               if (!invokestatic && !resolve_constrain_unresolved_method_instance(
+                                       um, state->m, 
+                                       &(VAR(state->iptr->sx.s23.s2.args[0])->typeinfo),
+                                       invokespecial))
+                       return false; /* XXX maybe wrap exception */
+
+               if (!resolve_constrain_unresolved_method_params(
+                                       jd, um, state->m, state->iptr))
+                       return false; /* XXX maybe wrap exception */
+
+               /* store the unresolved_method pointer */
+
+               state->iptr->sx.s23.s3.um = um;
+               state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
+       }
+
+       /* set the return type */
+
+       rtype = md->returntype.type;
+       if (rtype != TYPE_VOID) {
+               dv->type = rtype;
+               if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
+                       return false;
+       }
+}
+
+/*
+ * 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 7f5a8dc7ce0bf34ee3158cb2300a759ca8de3b50..a0673133d4775582a4f27e1926ff1fead588beee 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: typecheck.c 5730 2006-10-10 00:29:26Z edwin $
+   $Id: typecheck.c 5740 2006-10-11 23:00:01Z edwin $
 
 */
 
@@ -778,345 +778,8 @@ typestate_restore_invars(verifier_state *state)
 static bool
 verify_invocation(verifier_state *state)
 {
-       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 */
-       utf *mclassname;                     /* name of the method's class */
-       bool specialmethod;            /* true if a <...> method is called */
-       int opcode;                                   /* invocation opcode */
-       bool callinginit;                      /* true if <init> is called */
-       instruction *ins;
-       classref_or_classinfo initclass;
-       typedesc *td;
-       s4 argindex;                            /* argument variable index */
-       varinfo *av;                                  /* argument variable */
-       varinfo *dv;                  /* result variable of the invocation */
-       int i;                                                  /* counter */
-    u1 rtype;                          /* return type of called method */
-       resolve_result_t result;
-       jitdata *jd;
-       bool invokestatic;
-       bool invokespecial;
-
-       jd = state->jd;
-
-       /* get the FMIref and the unresolved_method struct (if any) */
-       /* from the instruction                                     */
-
-       if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
-               /* unresolved method */
-               um = state->iptr->sx.s23.s3.um;
-               mref = um->methodref;
-       }
-       else {
-               /* resolved method */
-               um = NULL;
-               mref = state->iptr->sx.s23.s3.fmiref;
-       }
-
-       /* get method descriptor and name */
-
-       md = mref->parseddesc.md;
-       mname = mref->name;
-
-       /* get method info (if resolved) and classname */
-
-       if (IS_FMIREF_RESOLVED(mref)) {
-               mi = mref->p.method;
-               mclassname = mi->class->name;
-       }
-       else {
-               mi = NULL;
-               mclassname = mref->p.classref->name;
-       }
-
-       opcode = state->iptr[0].opc;
-       invokestatic = (opcode == ICMD_INVOKESTATIC);
-       invokespecial = (opcode == ICMD_INVOKESPECIAL);
-       specialmethod = (mname->text[0] == '<');
-       dv = VAROP(state->iptr->dst);
-
-       /* prevent compiler warnings */
-
-       ins = NULL;
-
-       /* check whether we are calling <init> */
-       
-       callinginit = (invokespecial && mname == utf_init);
-       if (specialmethod && !callinginit)
-               TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
-
-       /* allocate parameters if necessary */
-       
-       if (!md->params)
-               if (!descriptor_params_from_paramtypes(md,
-                                       (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
-                       return false;
-
-       /* check parameter types */
-
-       i = md->paramcount; /* number of parameters including 'this'*/
-       while (--i >= 0) {
-               LOG1("param %d",i);
-               argindex = state->iptr->sx.s23.s2.args[i];
-               av = VAR(argindex);
-               td = md->paramtypes + i;
-
-               if (av->type != td->type)
-                       TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
-
-               if (av->type == TYPE_ADR) {
-                       LOGINFO(&(av->typeinfo));
-                       if (i==0 && callinginit)
-                       {
-                               /* first argument to <init> method */
-                               if (!TYPEINFO_IS_NEWOBJECT(av->typeinfo))
-                                       TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
-
-                               /* get the address of the NEW instruction */
-                               LOGINFO(&(av->typeinfo));
-                               ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo);
-                               if (ins)
-                                       initclass = ins[-1].sx.val.c;
-                               else
-                                       initclass.cls = state->m->class;
-                               LOGSTR("class: "); LOGNAME(initclass); LOGNL;
-                       }
-               }
-               else {
-                       /* non-adress argument. if this is the first argument and we are */
-                       /* invoking an instance method, this is an error.                */
-                       if (i==0 && opcode != ICMD_INVOKESTATIC) {
-                               TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
-                       }
-               }
-               LOG("ok");
-       }
-
-       if (callinginit) {
-               LOG("replacing uninitialized object");
-               /* replace uninitialized object type on stack */
-
-               /* for all live-in and live-through variables */ 
-               for (i=0; i<state->iptr->s1.argcount; ++i) {
-                       argindex = state->iptr->sx.s23.s2.args[i];
-                       av = VAR(argindex);
-                       if (av->type == TYPE_ADR
-                                       && TYPEINFO_IS_NEWOBJECT(av->typeinfo)
-                                       && TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo) == ins)
-                       {
-                               LOG("replacing uninitialized type");
-
-                               /* If this stackslot is in the instack of
-                                * this basic block we must save the type(s)
-                                * we are going to replace.
-                                */
-                               /* XXX this needs a new check */
-                               if (state->bptr->invars
-                                               && argindex >= state->bptr->invars[0] 
-                                               && argindex < state->bptr->varstart 
-                                               && !state->savedinvars)
-                               {
-                                       typestate_save_invars(state);
-                               }
-
-                               if (!typeinfo_init_class(&(av->typeinfo),initclass))
-                                       return false;
-                       }
-               }
-
-               /* replace uninitialized object type in locals */
-               if (!typevector_init_object(state->jd->var, ins, initclass,
-                                       state->numlocals))
-                       return false;
-
-               /* initializing the 'this' reference? */
-               if (!ins) {
-                       classinfo *cls;
-                       TYPECHECK_ASSERT(state->initmethod);
-                       /* { we are initializing the 'this' reference }                           */
-                       /* must be <init> of current class or direct superclass                   */
-                       /* the current class is linked, so must be its superclass. thus we can be */
-                       /* sure that resolving will be trivial.                                   */
-                       if (mi) {
-                               cls = mi->class;
-                       }
-                       else {
-                               if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
-                                       return false; /* exception */
-                       }
-
-                       /* if lazy resolving did not succeed, it's not one of the allowed classes */
-                       /* otherwise we check it directly                                         */
-                       if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
-                               TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
-                       }
-
-                       /* set our marker variable to type int */
-                       LOG("setting <init> marker");
-                       typevector_store(jd->var, state->numlocals-1, TYPE_INT, NULL);
-               }
-               else {
-                       /* { we are initializing an instance created with NEW } */
-                       if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mclassname) {
-                               TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
-                       }
-               }
-       }
-
-       /* try to resolve the method lazily */
-
-       result = resolve_method_lazy(state->m, mref, invokespecial);
-
-       /* perform verification checks */
-
-       if (result == resolveSucceeded) {
-
-               assert(IS_FMIREF_RESOLVED(mref));
-
-               mi = mref->p.method;
-
-               result = resolve_method_verifier_checks(state->m, 
-                                                                                               mref,
-                                                                                               mi,
-                                                                                               invokestatic);
-       }
-
-       /* check types of parameters */
-
-       if (result == resolveSucceeded && !invokestatic)
-               result = resolve_method_instance_type_checks(
-                               state->m, mi, 
-                               &(VAR(state->iptr->sx.s23.s2.args[0])->typeinfo), 
-                               invokespecial);
-
-       if (result == resolveSucceeded)
-               result = resolve_method_param_type_checks(
-                               jd, state->m, state->iptr,
-                               mi, invokestatic);
-
-       /* impose loading constraints */
-
-       if (result == resolveSucceeded) {
-               /* XXX state->m->class may have to be wrong when inlining */
-               if (!resolve_method_loading_constraints(state->m->class, mi))
-                       return false;
-       }
-
-       if (result == resolveFailed)
-               return false;
-
-       if (result == resolveSucceeded) {
-               /* if this call is monomorphic, turn it into an INVOKESPECIAL */
-
-               if ((state->iptr->opc == ICMD_INVOKEVIRTUAL)
-                       && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
-               {
-                       state->iptr->opc = ICMD_INVOKESPECIAL;
-               }
-       }
-       else {
-               /* resolution must be deferred */
-
-               if (!um) {
-                       um = resolve_create_unresolved_method(state->m->class, state->m,
-                                       mref, 
-                                       state->iptr->opc == ICMD_INVOKESTATIC,
-                                       invokespecial);
-
-                       if (!um)
-                               return false;
-               }
-
-               /* record subtype constraints for parameters */
-
-               if (!invokestatic && !resolve_constrain_unresolved_method_instance(
-                                       um, state->m, 
-                                       &(VAR(state->iptr->sx.s23.s2.args[0])->typeinfo),
-                                       invokespecial))
-                       return false; /* XXX maybe wrap exception */
-
-               if (!resolve_constrain_unresolved_method_params(
-                                       jd, um, state->m, state->iptr))
-                       return false; /* XXX maybe wrap exception */
-
-               /* store the unresolved_method pointer */
-
-               state->iptr->sx.s23.s3.um = um;
-               state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
-       }
-
-       rtype = md->returntype.type;
-       if (rtype != TYPE_VOID) {
-               dv->type = rtype;
-               if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
-                       return false;
-       }
-
-       return true;
-}
-
-
-/* verify_generic_builtin ******************************************************
-   Verify the call of a generic builtin method.
-  
-   IN:
-       state............the current state of the verifier
-
-   RETURN VALUE:
-       true.............successful verification,
-          false............an exception has been thrown.
-
-*******************************************************************************/
-
-static bool
-verify_generic_builtin(verifier_state *state)
-{
-       builtintable_entry *bte;
-       s4 i;
-       u1 rtype;
-       methoddesc *md;
-    varinfo *av;
-       jitdata *jd = state->jd;
-
-       TYPECHECK_COUNT(stat_ins_builtin_gen);
-
-       bte = state->iptr->sx.s23.s3.bte;
-       md = bte->md;
-       i = md->paramcount;
-       
-       /* check the types of the arguments on the stack */
-
-       for (i--; i >= 0; i--) {
-               av = VAR(state->iptr->sx.s23.s2.args[i]);
-
-               if (av->type != md->paramtypes[i].type) {
-                       TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
-               }
-               
-#ifdef TYPECHECK_DEBUG
-               /* generic builtins may only take primitive types and java.lang.Object references */
-               if (av->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
-                       *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
-                       return false;
-               }
-#endif
-       }
-
-       /* set the return type */
-
-       rtype = md->returntype.type;
-       if (rtype != TYPE_VOID) {
-               varinfo *dv;
 
-               dv = VAROP(state->iptr->dst);
-               dv->type = rtype;
-               if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
-                       return false;
-       }
+#include <typecheck-invoke.inc>
 
        return true;
 }
@@ -1138,84 +801,9 @@ verify_generic_builtin(verifier_state *state)
 static bool
 verify_builtin(verifier_state *state)
 {
-       builtintable_entry *bte;
-    classref_or_classinfo cls;
-    varinfo *dv;               /* output variable of current instruction */
-       jitdata *jd = state->jd;
-
-       bte = state->iptr->sx.s23.s3.bte;
-       dv = VAROP(state->iptr->dst);
 
-       /* XXX this is an ugly if-chain but twisti did not want a function */
-       /* pointer in builtintable_entry for this, so here you go.. ;)     */
+#include <typecheck-builtins.inc>
 
-       if (ISBUILTIN(BUILTIN_new)) {
-               if (state->iptr[-1].opc != ICMD_ACONST)
-                       TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
-               cls = state->iptr[-1].sx.val.c;
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_NEWOBJECT(dv->typeinfo,state->iptr);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BOOLEAN);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_char)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_CHAR);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_float)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_FLOAT);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_double)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_DOUBLE);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_byte)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BYTE);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_short)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_SHORT);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_int)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_INT);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray_long)) {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               dv->type = TYPE_ADR;
-               TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_LONG);
-       }
-       else if (ISBUILTIN(BUILTIN_newarray))
-       {
-               TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
-               if (state->iptr[-1].opc != ICMD_ACONST)
-                       TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
-               /* XXX check that it is an array class(ref) */
-               dv->type = TYPE_ADR;
-               typeinfo_init_class(&(dv->typeinfo),state->iptr[-1].sx.val.c);
-       }
-       else if (ISBUILTIN(BUILTIN_arrayinstanceof))
-       {
-               TYPECHECK_ADR(state->iptr->sx.s23.s2.args[0]);
-               if (state->iptr[-1].opc != ICMD_ACONST)
-                       TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
-               dv->type = TYPE_INT;
-               /* XXX check that it is an array class(ref) */
-       }
-       else {
-               return verify_generic_builtin(state);
-       }
        return true;
 }
 
@@ -1544,138 +1132,10 @@ verify_basic_block(verifier_state *state)
                        case ICMD_PUTSTATICCONST:
                        case ICMD_GETFIELD:
                        case ICMD_GETSTATIC:
-                               {
-                                       varinfo *valueslot = NULL;
-                                       typeinfo *instanceti = NULL;
-                                       typeinfo *valueti = NULL;
-                                       bool isstatic = false;
-                                       bool isput = false;
-                                       typeinfo constti;
-
-                                       TYPECHECK_COUNT(stat_ins_field);
-
-                                       if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
-                                               uf = state->iptr->sx.s23.s3.uf;
-                                               fieldref = uf->fieldref;
-                                       }
-                                       else {
-                                               uf = NULL;
-                                               fieldref = state->iptr->sx.s23.s3.fmiref;
-                                       }
-
-                                       /* get opcode dependent values */
-
-                                       switch (state->iptr->opc) {
-                                               case ICMD_PUTFIELD:
-                                                       isput = true;
-                                                       valueslot = VAROP(state->iptr->sx.s23.s2);
-                                                       instanceti = &(VAROP(state->iptr->s1)->typeinfo);
-                                                       break;
-
-                                               case ICMD_PUTFIELDCONST:
-                                                       isput = true;
-                                                       instanceti = &(VAROP(state->iptr->s1)->typeinfo);
-putfield_const_tail:
-                                                       if (IS_ADR_TYPE(fieldref->parseddesc.fd->type)) {
-                                                               /* XXX check for java.lang.Class constant values? */
-                                                               if (state->iptr->sx.val.anyptr) {
-                                                                       assert(class_java_lang_String);
-                                                                       assert(class_java_lang_String->state & CLASS_LOADED);
-                                                                       assert(class_java_lang_String->state & CLASS_LINKED);
-                                                                       typeinfo_init_classinfo(&constti, class_java_lang_String);
-                                                               }
-                                                               else {
-                                                                       TYPEINFO_INIT_NULLTYPE(constti);
-                                                               }
-                                                               valueti = &constti;
-                                                       }
-                                                       break;
-
-                                               case ICMD_PUTSTATIC:
-                                                       isput = true;
-                                                       isstatic = true;
-                                                       valueslot = VAROP(state->iptr->s1);
-                                                       break;
-
-                                               case ICMD_PUTSTATICCONST:
-                                                       isput = true;
-                                                       isstatic = true;
-                                                       goto putfield_const_tail;
-
-                                               case ICMD_GETFIELD:
-                                                       instanceti = &(VAROP(state->iptr->s1)->typeinfo);
-                                                       break;
-
-                                               case ICMD_GETSTATIC:
-                                                       isstatic = true;
-                                                       break;
-
-                                               default:
-                                                       assert(false);
-                                       }
 
-                                       if (valueslot && IS_ADR_TYPE(valueslot->type)) {
-                                               valueti = &(valueslot->typeinfo);
-                                       }
-
-                                       /* try to resolve the field reference lazily */
-
-                                       result = resolve_field_lazy(state->m, fieldref);
-
-                                       if (result == resolveSucceeded) {
-                                               fieldinfo *fi;
-
-                                               /* perform verification checks now */
-
-                                               fi  = fieldref->p.field;
-
-                                               result = resolve_field_verifier_checks(
-                                                               state->m, fieldref, fi->class, fi,
-                                                               instanceti, valueti, isstatic, isput);
-                                       }
-
-                                       if (result == resolveFailed)
-                                               return false;
+#include <typecheck-fields.inc>
 
-                                       /* if not resolved, yet, create an unresolved field */
-
-                                       if (result != resolveSucceeded) {
-                                               if (!uf) {
-                                                       uf = resolve_create_unresolved_field(state->m->class, 
-                                                                       state->m, state->iptr);
-                                                       if (!uf)
-                                                               return false;
-
-                                                       state->iptr->sx.s23.s3.uf = uf;
-                                                       state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
-                                               }
-
-                                               /* record the subtype constraints for this field access */
-
-                                               if (!resolve_constrain_unresolved_field(
-                                                                       uf, state->m->class, state->m,
-                                                                       instanceti, valueti))
-                                                       return false; /* XXX maybe wrap exception? */
-
-                                               TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
-                                               TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && 
-                                                               !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,
-                                                               stat_ins_field_uninitialized);
-                                       }
-                                               
-                                       /* write the result type */
-
-                                       if (iptr->opc == ICMD_GETFIELD || iptr->opc == ICMD_GETSTATIC) {
-                                               dv->type = fieldref->parseddesc.fd->type;
-                                               if (dv->type == TYPE_ADR) {
-                                                       if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd, 
-                                                                               NULL, &(dv->typeinfo)))
-                                                               return false;
-                                               }
-                                       }
-
-                                       maythrow = true;
-                               }
+                               maythrow = true;
                                break;
 
                                /****************************************/