GNU header update.
[cacao.git] / src / vm / jit / verify / typecheck.c
index 0674f0923ab1732ca20f013d250e8c1a056a5d40..900262a3512d3c92cffcbffb930e3ca1dfa70732 100644 (file)
@@ -1,9 +1,9 @@
-/* jit/typecheck.c - typechecking (part of bytecode verification)
+/* vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    Authors: Edwin Steiner
 
-   $Id: typecheck.c 1429 2004-11-02 08:58:26Z jowenn $
+   $Id: typecheck.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
-#include "global.h" /* must be here because of CACAO_TYPECHECK */
+#include <string.h>
+
+#include "vm/global.h" /* must be here because of CACAO_TYPECHECK */
 
 #ifdef CACAO_TYPECHECK
 
-#include <string.h>
-#include "main.h"
-#include "builtin.h"
-#include "tables.h"
-#include "loader.h"
-#include "native.h"
 #include "types.h"
-#include "jit/jit.h"
-#include "jit/stack.h"
+/*  #include "main.h" */
+#include "mm/memory.h"
 #include "toolbox/logging.h"
-#include "toolbox/memory.h"
+#include "native/native.h"
+#include "vm/builtin.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/tables.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/stack.h"
+
 
 /****************************************************************************/
 /* DEBUG HELPERS                                                            */
@@ -496,7 +499,7 @@ typestate_merge(stackptr deststack,typevector *destloc,
 
 
 static bool
-typestate_reach(methodinfo *m, void *localbuf,
+typestate_reach(codegendata *cd, registerdata *rd,void *localbuf,
                                basicblock *current,
                                basicblock *destblock,
                                stackptr ystack,typevector *yloc,
@@ -509,7 +512,7 @@ typestate_reach(methodinfo *m, void *localbuf,
        LOG1("reaching block L%03d",destblock->debug_nr);
        TYPECHECK_COUNT(stat_reached);
        
-       destidx = destblock - m->basicblocks;
+       destidx = destblock - cd->method->basicblocks;
        destloc = MGET_TYPEVECTOR(localbuf,destidx,locsize);
 
        /* When branching backwards we have to check for uninitialized objects */
@@ -517,19 +520,26 @@ typestate_reach(methodinfo *m, void *localbuf,
        if (destblock <= current) {
                stackptr sp;
                int i;
-               
-               TYPECHECK_COUNT(stat_backwards);
-        LOG("BACKWARDS!");
-        for (sp = ystack; sp; sp=sp->prev)
-            if (sp->type == TYPE_ADR &&
-                TYPEINFO_IS_NEWOBJECT(sp->typeinfo))
-                panic("Branching backwards with uninitialized object on stack");
-
-        for (i=0; i<locsize; ++i)
-            if (yloc->td[i].type == TYPE_ADR &&
-                TYPEINFO_IS_NEWOBJECT(yloc->td[i].info))
-                panic("Branching backwards with uninitialized object in local variable");
-    }
+#if defined(__GNUC__)
+#warning FIXME FOR INLINING
+#endif
+               if (!useinlining) {
+                       TYPECHECK_COUNT(stat_backwards);
+                       LOG("BACKWARDS!");
+                       for (sp = ystack; sp; sp=sp->prev)
+                               if (sp->type == TYPE_ADR &&
+                               TYPEINFO_IS_NEWOBJECT(sp->typeinfo)) {
+                                       show_icmd_method(cd->method,cd,rd);
+                               printf("current: %ld, dest: %ld\n",current->debug_nr,destblock->debug_nr);
+                               panic("Branching backwards with uninitialized object on stack");
+                       }
+
+                       for (i=0; i<locsize; ++i)
+                               if (yloc->td[i].type == TYPE_ADR &&
+                               TYPEINFO_IS_NEWOBJECT(yloc->td[i].info))
+                                       panic("Branching backwards with uninitialized object in local variable");
+               }
+       }
        
        if (destblock->flags == BBTYPECHECK_UNDEF) {
                /* The destblock has never been reached before */
@@ -563,7 +573,7 @@ typestate_reach(methodinfo *m, void *localbuf,
 
 
 static bool
-typestate_ret(methodinfo *m, void *localbuf,
+typestate_ret(codegendata *cd,registerdata *rd, void *localbuf,
                          basicblock *current,
                          stackptr ystack,typevector *yloc,
                          int retindex,int locsize)
@@ -581,7 +591,7 @@ typestate_ret(methodinfo *m, void *localbuf,
 
                selected = typevectorset_select(&yvec,retindex,destblock);
                
-               repeat |= typestate_reach(m, localbuf,current,destblock,
+               repeat |= typestate_reach(cd, rd,  localbuf,current,destblock,
                                                                  ystack,selected,locsize,true);
        }
        return repeat;
@@ -681,7 +691,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
 
 #define WORDCHECKFAULT \
        do { \
-               show_icmd_method(m); \
+               show_icmd_method(m, cd, rd); \
                dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n", \
                iptr->op1,iptr->method->class->name->text, \
                        iptr->method->name->text,m->class->name->text,m->name->text); \
@@ -747,7 +757,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
        {if ((source)->type == TYPE_ADR)                                                                \
                        TYPEINFO_COPY((source)->typeinfo,(dest)->typeinfo);}
 
-#define ISBUILTIN(v)   (iptr->val.a == (functionptr)(v))
+#define ISBUILTIN(v)   (iptr->val.fp == (functionptr) (v))
 
 /* TYPECHECK_REACH: executed, when the target block (tbptr) can be reached
  *     from the current block (bptr). The types of local variables and
@@ -766,7 +776,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
  */
 #define TYPECHECK_REACH                                                 \
     do {                                                                \
-    repeat |= typestate_reach(m, localbuf,bptr,tbptr,dst,               \
+    repeat |= typestate_reach(cd,rd, localbuf,bptr,tbptr,dst,               \
                                                          localset,numlocals,jsrencountered);       \
     LOG("done.");                                                       \
     } while (0)
@@ -796,7 +806,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
 
 /* typecheck is called directly after analyse_stack */
 
-methodinfo *typecheck(codegendata *codegendata)
+methodinfo *typecheck(methodinfo *m, codegendata *cd, registerdata *rd)
 {
     int b_count, b_index;
     stackptr curstack;      /* input stack top for current instruction */
@@ -839,7 +849,6 @@ methodinfo *typecheck(codegendata *codegendata)
        bool jsrencountered = false;         /* true if we there was a JSR */
 
     classinfo *myclass;
-    methodinfo *m=codegendata->method;
 
 #ifdef TYPECHECK_STATISTICS
        int count_iterations = 0;
@@ -900,7 +909,7 @@ methodinfo *typecheck(codegendata *codegendata)
     
     /* In <init> methods we use an extra local variable to signal if
      * the 'this' reference has been initialized. */
-    numlocals = m->codegendata->maxlocals;
+    numlocals = cd->maxlocals;
        validlocals = numlocals;
     if (initmethod) numlocals++;
 
@@ -911,7 +920,7 @@ methodinfo *typecheck(codegendata *codegendata)
     LOG("Variable buffer allocated.\n");
 
     /* allocate the buffer of active exception handlers */
-    handlers = DMNEW(exceptiontable*, codegendata->exceptiontablelength + 1);
+    handlers = DMNEW(exceptiontable*, cd->exceptiontablelength + 1);
 
     /* initialize the variable types of the first block */
     /* to the types of the arguments */
@@ -987,10 +996,10 @@ methodinfo *typecheck(codegendata *codegendata)
                 /* XXX could use a faster algorithm with sorted lists or
                  * something? */
                 len = 0;
-                for (i = 0; i < codegendata->exceptiontablelength; ++i) {
-                    if ((codegendata->exceptiontable[i].start <= bptr) && (codegendata->exceptiontable[i].end > bptr)) {
-                        LOG1("active handler L%03d", codegendata->exceptiontable[i].handler->debug_nr);
-                        handlers[len++] = codegendata->exceptiontable + i;
+                for (i = 0; i < cd->exceptiontablelength; ++i) {
+                    if ((cd->exceptiontable[i].start <= bptr) && (cd->exceptiontable[i].end > bptr)) {
+                        LOG1("active handler L%03d", cd->exceptiontable[i].handler->debug_nr);
+                        handlers[len++] = cd->exceptiontable + i;
                     }
                 }
                 handlers[len] = NULL;
@@ -998,12 +1007,19 @@ methodinfo *typecheck(codegendata *codegendata)
                 /* init variable types at the start of this block */
                                COPY_TYPEVECTORSET(MGET_TYPEVECTOR(localbuf,b_index,numlocals),
                                                                   localset,numlocals);
+#if defined(__GNUC__)
+#warning FIXME FOR INLINING
+#endif
+               if(!useinlining) {
                                if (handlers[0])
                                        for (i=0; i<numlocals; ++i)
                                                if (localset->td[i].type == TYPE_ADR
-                                                       && TYPEINFO_IS_NEWOBJECT(localset->td[i].info))
-                                                       panic("Uninitialized object in local variable inside try block");
-
+                                                       && TYPEINFO_IS_NEWOBJECT(localset->td[i].info)) {
+                                                               show_icmd_method(m, cd, rd);
+                                                               printf("Uninitialized variale:%ld, block:%ld\n",i,bptr->debug_nr);
+                                                               panic("Uninitialized object in local variable inside try block");
+                                                       }
+               }
                                DOLOG(typestate_print(get_logfile(),curstack,localset,numlocals));
                                LOGNL; LOGFLUSH;
 
@@ -1115,7 +1131,7 @@ methodinfo *typecheck(codegendata *codegendata)
                                                  }
                                                  else {
                                                          if (!TYPEDESC_IS_REFERENCE(localset->td[iptr->op1])) {
-                                                                 show_icmd_method(m);
+                                                                 show_icmd_method(m, cd, rd);
                                                                  dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n",
                                                                        iptr->op1,iptr->method->class->name->text,
                                                                        iptr->method->name->text,m->class->name->text,m->name->text);
@@ -1542,7 +1558,7 @@ methodinfo *typecheck(codegendata *codegendata)
                                                  if (bptr + 1 == (m->basicblocks + m->basicblockcount + 1))
                                                          panic("Illegal instruction: JSR at end of bytecode");
                                                  typestack_put_retaddr(dst,bptr+1,localset);
-                                                 repeat |= typestate_reach(m, localbuf,bptr,tbptr,dst,
+                                                 repeat |= typestate_reach(cd, rd,localbuf,bptr,tbptr,dst,
                                                                                                        localset,numlocals,true);
 
                                                  superblockend = true;
@@ -1553,7 +1569,7 @@ methodinfo *typecheck(codegendata *codegendata)
                                                  if (!typevectorset_checkretaddr(localset,iptr->op1))
                               panic("illegal instruction: RET using non-returnAddress variable");
 
-                                                 repeat |= typestate_ret(m, localbuf,bptr,curstack,
+                                                 repeat |= typestate_ret(cd,rd, localbuf,bptr,curstack,
                                                                                                  localset,iptr->op1,numlocals);
 
                           superblockend = true;
@@ -1672,9 +1688,9 @@ methodinfo *typecheck(codegendata *codegendata)
                                                                                          LOG("saving input stack types");
                                                                                          if (!savedstackbuf) {
                                                                                                  LOG("allocating savedstack buffer");
-                                                                                                 savedstackbuf = DMNEW(stackelement,m->codegendata->maxstack);
+                                                                                                 savedstackbuf = DMNEW(stackelement, cd->maxstack);
                                                                                                  savedstackbuf->prev = NULL;
-                                                                                                 for (i=1; i<m->codegendata->maxstack; ++i)
+                                                                                                 for (i = 1; i < cd->maxstack; ++i)
                                                                                                          savedstackbuf[i].prev = savedstackbuf+(i-1);
                                                                                          }
                                                                                          sp = savedstack = bptr->instack;
@@ -1760,9 +1776,9 @@ methodinfo *typecheck(codegendata *codegendata)
                                                          TYPECHECK_COUNT(stat_ins_builtin_gen);
                                                          builtindesc = builtin_desc;
                                                          while (builtindesc->opcode && builtindesc->builtin
-                                                                        != (functionptr) iptr->val.a) builtindesc++;
+                                                                        != iptr->val.fp) builtindesc++;
                                                          if (!builtindesc->opcode) {
-                                                                 dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+                                                                 dolog("Builtin not in table: %s",icmd_builtin_name(iptr->val.fp));
                                                                  panic("Internal error: builtin not found in table");
                                                          }
                                                          TYPECHECK_ARGS3(builtindesc->type_s3,builtindesc->type_s2,builtindesc->type_s1);
@@ -1813,9 +1829,9 @@ methodinfo *typecheck(codegendata *codegendata)
                                                          TYPECHECK_COUNT(stat_ins_builtin_gen);
                                                          builtindesc = builtin_desc;
                                                          while (builtindesc->opcode && builtindesc->builtin
-                                                                        != (functionptr) iptr->val.a) builtindesc++;
+                                                                        != iptr->val.fp) builtindesc++;
                                                          if (!builtindesc->opcode) {
-                                                                 dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+                                                                 dolog("Builtin not in table: %s",icmd_builtin_name(iptr->val.fp));
                                                                  panic("Internal error: builtin not found in table");
                                                          }
                                                          TYPECHECK_ARGS2(builtindesc->type_s2,builtindesc->type_s1);
@@ -1873,9 +1889,9 @@ methodinfo *typecheck(codegendata *codegendata)
                                                          TYPECHECK_COUNT(stat_ins_builtin_gen);
                                                          builtindesc = builtin_desc;
                                                          while (builtindesc->opcode && builtindesc->builtin
-                                                                        != (functionptr) iptr->val.a) builtindesc++;
+                                                                        != iptr->val.fp) builtindesc++;
                                                          if (!builtindesc->opcode) {
-                                                                 dolog("Builtin not in table: %s",icmd_builtin_name((functionptr) iptr->val.a));
+                                                                 dolog("Builtin not in table: %s",icmd_builtin_name(iptr->val.fp));
                                                                  panic("Internal error: builtin not found in table");
                                                          }
                                                          TYPECHECK_ARGS1(builtindesc->type_s1);
@@ -2068,7 +2084,7 @@ methodinfo *typecheck(codegendata *codegendata)
                                                        cls = handlers[i]->catchtype;
                                                        excstack.typeinfo.typeclass = (cls) ? cls
                                                                : class_java_lang_Throwable;
-                                                       repeat |= typestate_reach(m, localbuf,bptr,
+                                                       repeat |= typestate_reach(cd,rd, localbuf,bptr,
                                                                                                          handlers[i]->handler,
                                                                                                          &excstack,localset,
                                                                                                          numlocals,