GNU header update.
[cacao.git] / src / vm / jit / verify / typecheck.c
index be479ec1f0c96093aa7c847fea51b28a5b95c292..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 1348 2004-07-22 09:57:51Z twisti $
+   $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;
@@ -678,23 +688,41 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
 #define STORE_TWOWORD(num,type)                                                                                \
        do {typevectorset_store_twoword(localset,num,type);} while(0)
 
+
+#define WORDCHECKFAULT \
+       do { \
+               show_icmd_method(m, cd, rd); \
+               dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n", \
+               iptr->op1,iptr->method->class->name->text, \
+                       iptr->method->name->text,m->class->name->text,m->name->text); \
+               show_icmd(iptr++, false); \
+               show_icmd(iptr, false); \
+       } while (0)
+
+
 #define CHECK_ONEWORD(num,tp)                                                                                  \
        do {TYPECHECK_COUNT(stat_ins_primload);                                                         \
                if (jsrencountered) {                                                                                   \
-                       if (!typevectorset_checktype(localset,num,tp))                          \
+                       if (!typevectorset_checktype(localset,num,tp)) {                                \
+                               WORDCHECKFAULT; \
                                panic("Variable type mismatch");                                                \
+                       }       \
                }                                                                                                                               \
                else {                                                                                                                  \
-                       if (localset->td[num].type != tp)                                                       \
+                       if (localset->td[num].type != tp) {                                                     \
                                panic("Variable type mismatch");                                                \
+                               WORDCHECKFAULT; \
+                       } \
                }                                                                                                                               \
                } while(0)
 
 #define CHECK_TWOWORD(num,type)                                                                                        \
        do {TYPECHECK_COUNT(stat_ins_primload);                                                         \
-               if (!typevectorset_checktype(localset,num,type))                \
-            panic("Variable type mismatch");                           \
-               } while(0)
+               if (!typevectorset_checktype(localset,num,type)) {                \
+                       WORDCHECKFAULT; \
+                       panic("Variable type mismatch");                                \
+               } \
+       } while(0)
 
 /****************************************************************************/
 /* MACROS FOR STACK TYPE CHECKING                                           */
@@ -729,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
@@ -748,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)
@@ -778,7 +806,7 @@ is_accessible(int flags,classinfo *definingclass,classinfo *implementingclass, c
 
 /* typecheck is called directly after analyse_stack */
 
-methodinfo *typecheck(methodinfo *m)
+methodinfo *typecheck(methodinfo *m, codegendata *cd, registerdata *rd)
 {
     int b_count, b_index;
     stackptr curstack;      /* input stack top for current instruction */
@@ -825,7 +853,7 @@ methodinfo *typecheck(methodinfo *m)
 #ifdef TYPECHECK_STATISTICS
        int count_iterations = 0;
        TYPECHECK_COUNT(stat_typechecked);
-       TYPECHECK_COUNT_FREQ(stat_locals,m->maxlocals,STAT_LOCALS);
+       TYPECHECK_COUNT_FREQ(stat_locals,m->codegendata->maxlocals,STAT_LOCALS);
        TYPECHECK_COUNT_FREQ(stat_blocks,m->basicblockcount/10,STAT_BLOCKS);
 #endif
 
@@ -881,7 +909,7 @@ methodinfo *typecheck(methodinfo *m)
     
     /* In <init> methods we use an extra local variable to signal if
      * the 'this' reference has been initialized. */
-    numlocals = m->maxlocals;
+    numlocals = cd->maxlocals;
        validlocals = numlocals;
     if (initmethod) numlocals++;
 
@@ -892,7 +920,7 @@ methodinfo *typecheck(methodinfo *m)
     LOG("Variable buffer allocated.\n");
 
     /* allocate the buffer of active exception handlers */
-    handlers = DMNEW(exceptiontable*, m->exceptiontablelength + 1);
+    handlers = DMNEW(exceptiontable*, cd->exceptiontablelength + 1);
 
     /* initialize the variable types of the first block */
     /* to the types of the arguments */
@@ -968,10 +996,10 @@ methodinfo *typecheck(methodinfo *m)
                 /* XXX could use a faster algorithm with sorted lists or
                  * something? */
                 len = 0;
-                for (i = 0; i < m->exceptiontablelength; ++i) {
-                    if ((m->exceptiontable[i].start <= bptr) && (m->exceptiontable[i].end > bptr)) {
-                        LOG1("active handler L%03d", m->exceptiontable[i].handler->debug_nr);
-                        handlers[len++] = m->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;
@@ -979,12 +1007,19 @@ methodinfo *typecheck(methodinfo *m)
                 /* 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;
 
@@ -1095,8 +1130,14 @@ methodinfo *typecheck(methodinfo *m)
                                                          typevectorset_copymergedtype(localset,iptr->op1,&(dst->typeinfo));
                                                  }
                                                  else {
-                                                         if (!TYPEDESC_IS_REFERENCE(localset->td[iptr->op1]))
+                                                         if (!TYPEDESC_IS_REFERENCE(localset->td[iptr->op1])) {
+                                                                 show_icmd_method(m, cd, rd);
+                                                                 dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n",
+                                                                       iptr->op1,iptr->method->class->name->text,
+                                                                       iptr->method->name->text,m->class->name->text,m->name->text);
+                                                                 show_icmd(iptr, false);
                                                                  panic("illegal instruction: ALOAD loading non-reference");
+                                                         }
                                                          TYPEINFO_COPY(localset->td[iptr->op1].info,dst->typeinfo);
                                                  }
                           break;
@@ -1517,7 +1558,7 @@ methodinfo *typecheck(methodinfo *m)
                                                  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;
@@ -1528,7 +1569,7 @@ methodinfo *typecheck(methodinfo *m)
                                                  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;
@@ -1647,9 +1688,9 @@ methodinfo *typecheck(methodinfo *m)
                                                                                          LOG("saving input stack types");
                                                                                          if (!savedstackbuf) {
                                                                                                  LOG("allocating savedstack buffer");
-                                                                                                 savedstackbuf = DMNEW(stackelement,m->maxstack);
+                                                                                                 savedstackbuf = DMNEW(stackelement, cd->maxstack);
                                                                                                  savedstackbuf->prev = NULL;
-                                                                                                 for (i=1; i<m->maxstack; ++i)
+                                                                                                 for (i = 1; i < cd->maxstack; ++i)
                                                                                                          savedstackbuf[i].prev = savedstackbuf+(i-1);
                                                                                          }
                                                                                          sp = savedstack = bptr->instack;
@@ -1735,9 +1776,9 @@ methodinfo *typecheck(methodinfo *m)
                                                          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);
@@ -1788,9 +1829,9 @@ methodinfo *typecheck(methodinfo *m)
                                                          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);
@@ -1848,9 +1889,9 @@ methodinfo *typecheck(methodinfo *m)
                                                          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);
@@ -2043,7 +2084,7 @@ methodinfo *typecheck(methodinfo *m)
                                                        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,