-/* 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 1067 2004-05-18 10:25:51Z stefan $
+ $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 "jit.h"
-#include "builtin.h"
-#include "tables.h"
-#include "loader.h"
#include "types.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 */
int k;
for (;dst; dst=dst->prev, y=y->prev) {
- if (!y) panic("Stack depth mismatch");
+ if (!y) panic("Stack depth mismatch 1");
if (dst->type != y->type)
- panic("Stack type mismatch");
+ panic("Stack type mismatch 1");
LOG3("copy %p -> %p (type %d)",y,dst,dst->type);
if (dst->type == TYPE_ADDRESS) {
if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
}
}
}
- if (y) panic("Stack depth mismatch");
+ if (y) panic("Stack depth mismatch 2");
}
static void
{
bool changed = false;
for (; dst; dst = dst->prev, y=y->prev) {
- if (!y) panic("Stack depth mismatch");
- if (dst->type != y->type) panic("Stack type mismatch");
+ if (!y)
+ panic("Stack depth mismatch 3");
+ if (dst->type != y->type) panic("Stack type mismatch 2");
if (dst->type == TYPE_ADDRESS) {
if (TYPEINFO_IS_PRIMITIVE(dst->typeinfo)) {
/* dst has returnAddress type */
}
}
}
- if (y) panic("Stack depth mismatch");
+ if (y) panic("Stack depth mismatch 4");
return changed;
}
return changed;
}
-/* Globals used:
- * block
- */
+
static bool
-typestate_reach(void *localbuf,
+typestate_reach(codegendata *cd, registerdata *rd,void *localbuf,
basicblock *current,
basicblock *destblock,
stackptr ystack,typevector *yloc,
LOG1("reaching block L%03d",destblock->debug_nr);
TYPECHECK_COUNT(stat_reached);
- destidx = destblock - block;
+ destidx = destblock - cd->method->basicblocks;
destloc = MGET_TYPEVECTOR(localbuf,destidx,locsize);
/* When branching backwards we have to check for uninitialized objects */
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 */
return false;
}
-/* Globals used:
- * see typestate_reach
- */
+
static bool
-typestate_ret(void *localbuf,
+typestate_ret(codegendata *cd,registerdata *rd, void *localbuf,
basicblock *current,
stackptr ystack,typevector *yloc,
int retindex,int locsize)
selected = typevectorset_select(&yvec,retindex,destblock);
- repeat |= typestate_reach(localbuf,current,destblock,
+ repeat |= typestate_reach(cd, rd, localbuf,current,destblock,
ystack,selected,locsize,true);
}
return repeat;
#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 */
{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
*/
#define TYPECHECK_REACH \
do { \
- repeat |= typestate_reach(localbuf,bptr,tbptr,dst, \
+ repeat |= typestate_reach(cd,rd, localbuf,bptr,tbptr,dst, \
localset,numlocals,jsrencountered); \
LOG("done."); \
} while (0)
*/
#define TYPECHECK_LEAVE \
do { \
- if (initmethod && class != class_java_lang_Object) { \
+ if (initmethod && m->class != class_java_lang_Object) { \
/* check the marker variable */ \
LOG("Checking <init> marker"); \
if (!typevectorset_checktype(localset,numlocals-1,TYPE_INT))\
#define MAXPARAMS 255
/* typecheck is called directly after analyse_stack */
-void
-typecheck()
+
+methodinfo *typecheck(methodinfo *m, codegendata *cd, registerdata *rd)
{
int b_count, b_index;
stackptr curstack; /* input stack top for current instruction */
stackptr dst; /* output stack of current instruction */
basicblock **tptr; /* pointer into target list of switch instr. */
- xtable **handlers; /* active exception handlers */
+ exceptiontable **handlers; /* active exception handlers */
classinfo *cls; /* temporary */
bool maythrow; /* true if this instruction may throw */
static utf *name_init; /* "<init>" */
classinfo *myclass;
- if (compileverbose) {
- char logtext[MAXLOGTEXT];
- sprintf(logtext, "Typechecking: ");
- utf_sprint_classname(logtext + strlen(logtext), method->class->name);
- sprintf(logtext + strlen(logtext), ".");
- utf_sprint(logtext + strlen(logtext), method->name);
- utf_sprint_classname(logtext + strlen(logtext), method->descriptor);
- log_text(logtext);
- }
-
#ifdef TYPECHECK_STATISTICS
int count_iterations = 0;
TYPECHECK_COUNT(stat_typechecked);
- TYPECHECK_COUNT_FREQ(stat_locals,maxlocals,STAT_LOCALS);
- TYPECHECK_COUNT_FREQ(stat_blocks,block_count/10,STAT_BLOCKS);
+ TYPECHECK_COUNT_FREQ(stat_locals,m->codegendata->maxlocals,STAT_LOCALS);
+ TYPECHECK_COUNT_FREQ(stat_blocks,m->basicblockcount/10,STAT_BLOCKS);
#endif
LOGSTR("\n==============================================================================\n");
if (!name_init)
name_init = utf_new_char("<init>");
- initmethod = (method->name == name_init);
+ initmethod = (m->name == name_init);
/* Allocate buffer for method arguments */
LOG("Buffer allocated.\n");
/* reset all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
- b_count = block_count;
- bptr = block;
+ b_count = m->basicblockcount;
+ bptr = m->basicblocks;
while (--b_count >= 0) {
#ifdef TYPECHECK_DEBUG
if (bptr->flags != BBFINISHED && bptr->flags != BBDELETED
}
/* The first block is always reached */
- if (block_count && block[0].flags == BBTYPECHECK_UNDEF)
- block[0].flags = BBTYPECHECK_REACHED;
+ if (m->basicblockcount && m->basicblocks[0].flags == BBTYPECHECK_UNDEF)
+ m->basicblocks[0].flags = BBTYPECHECK_REACHED;
LOG("Blocks reset.\n");
/* In <init> methods we use an extra local variable to signal if
* the 'this' reference has been initialized. */
- numlocals = maxlocals;
+ numlocals = cd->maxlocals;
validlocals = numlocals;
if (initmethod) numlocals++;
/* allocate the buffers for local variables */
- localbuf = DMNEW_TYPEVECTOR(block_count+1, numlocals);
- localset = MGET_TYPEVECTOR(localbuf,block_count,numlocals);
+ localbuf = DMNEW_TYPEVECTOR(m->basicblockcount+1, numlocals);
+ localset = MGET_TYPEVECTOR(localbuf,m->basicblockcount,numlocals);
LOG("Variable buffer allocated.\n");
/* allocate the buffer of active exception handlers */
- handlers = DMNEW(xtable*,method->exceptiontablelength + 1);
+ handlers = DMNEW(exceptiontable*, cd->exceptiontablelength + 1);
/* initialize the variable types of the first block */
/* to the types of the arguments */
i = validlocals;
/* if this is an instance method initialize the "this" ref type */
- if (!(method->flags & ACC_STATIC)) {
+ if (!(m->flags & ACC_STATIC)) {
if (!i)
panic("Not enough local variables for method arguments");
td->type = TYPE_ADDRESS;
if (initmethod)
TYPEINFO_INIT_NEWOBJECT(td->info,NULL);
else
- TYPEINFO_INIT_CLASSINFO(td->info,class);
+ TYPEINFO_INIT_CLASSINFO(td->info, m->class);
td++;
i--;
}
LOG("'this' argument set.\n");
/* the rest of the arguments and the return type */
- i = typedescriptors_init_from_method_args(td,method->descriptor,
+ i = typedescriptors_init_from_method_args(td, m->descriptor,
i,
true, /* two word types use two slots */
&returntype);
repeat = false;
- b_count = block_count;
- bptr = block;
+ b_count = m->basicblockcount;
+ bptr = m->basicblocks;
while (--b_count >= 0) {
LOGSTR1("---- BLOCK %04d, ",bptr-block);
superblockend = false;
bptr->flags = BBFINISHED;
- b_index = bptr - block;
+ b_index = bptr - m->basicblocks;
/* init stack at the start of this block */
curstack = bptr->instack;
/* XXX could use a faster algorithm with sorted lists or
* something? */
len = 0;
- for (i=0; i<method->exceptiontablelength; ++i) {
- if ((extable[i].start <= bptr) && (extable[i].end > bptr)) {
- LOG1("active handler L%03d",extable[i].handler->debug_nr);
- handlers[len++] = extable + 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;
/* 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;
DOLOG(show_icmd(iptr,false)); LOGNL; LOGFLUSH;
opcode = iptr->opc;
- myclass = iptr->clazz;
+ myclass = iptr->method->class;
dst = iptr->dst;
maythrow = false;
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;
&& !TYPEINFO_NEWOBJECT_INSTRUCTION(curstack->prev->typeinfo))
{
/* uninitialized "this" instance */
- if (fi->class != class || (fi->flags & ACC_STATIC) != 0)
+ if (fi->class != m->class || (fi->flags & ACC_STATIC) != 0)
panic("Setting unaccessible field in uninitialized object");
}
else {
maythrow = true;
break;
+ case ICMD_IASTORECONST:
+ if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_INT))
+ panic("Array type mismatch");
+ maythrow = true;
+ break;
+
+ case ICMD_LASTORECONST:
+ if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_LONG))
+ panic("Array type mismatch");
+ maythrow = true;
+ break;
+
+ case ICMD_BASTORECONST:
+ if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_BOOLEAN)
+ && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_BYTE))
+ panic("Array type mismatch");
+ maythrow = true;
+ break;
+
+ case ICMD_CASTORECONST:
+ if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_CHAR))
+ panic("Array type mismatch");
+ maythrow = true;
+ break;
+
+ case ICMD_SASTORECONST:
+ if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(curstack->prev->typeinfo, ARRAYTYPE_SHORT))
+ panic("Array type mismatch");
+ maythrow = true;
+ break;
+
+
/****************************************/
/* ADDRESS CONSTANTS */
dst = (stackptr) iptr->val.a;
tbptr = (basicblock *) iptr->target;
- if (bptr+1 == last_block)
+ 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(localbuf,bptr,tbptr,dst,
+ repeat |= typestate_reach(cd, rd,localbuf,bptr,tbptr,dst,
localset,numlocals,true);
superblockend = true;
if (!typevectorset_checkretaddr(localset,iptr->op1))
panic("illegal instruction: RET using non-returnAddress variable");
- repeat |= typestate_ret(localbuf,bptr,curstack,
+ repeat |= typestate_ret(cd,rd, localbuf,bptr,curstack,
localset,iptr->op1,numlocals);
superblockend = true;
/* (If callinginit the class is checked later.) */
if (!callinginit) {
- if (!builtin_isanysubclass(class,mi->class))
+ if (!builtin_isanysubclass(myclass,mi->class))
panic("Illegal instruction: INVOKESPECIAL calling non-superclass method");
}
}
/* get the address of the NEW instruction */
LOGINFO(&(srcstack->typeinfo));
ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(srcstack->typeinfo);
- initclass = (ins) ? (classinfo*)ins[-1].val.a : method->class;
+ initclass = (ins) ? (classinfo*)ins[-1].val.a : m->class;
LOGSTR("class: "); LOGSTRu(initclass->name); LOGNL;
/* check type */
LOG("saving input stack types");
if (!savedstackbuf) {
LOG("allocating savedstack buffer");
- savedstackbuf = DMNEW(stackelement,maxstack);
+ savedstackbuf = DMNEW(stackelement, cd->maxstack);
savedstackbuf->prev = NULL;
- for (i=1; i<maxstack; ++i)
+ for (i = 1; i < cd->maxstack; ++i)
savedstackbuf[i].prev = savedstackbuf+(i-1);
}
sp = savedstack = bptr->instack;
panic("Internal error: calling <init> on this in non-<init> method.");
#endif
/* must be <init> of current class or direct superclass */
- if (mi->class != class && mi->class != class->super)
+ if (mi->class != m->class && mi->class != m->class->super)
panic("<init> calling <init> of the wrong class");
/* set our marker variable to type int */
case ICMD_MULTIANEWARRAY:
{
- vftbl *arrayvftbl;
+ vftbl_t *arrayvftbl;
arraydescriptor *desc;
/* check the array lengths on the stack */
}
/* check array descriptor */
- arrayvftbl = (vftbl*) iptr[0].val.a;
+ arrayvftbl = (vftbl_t*) iptr[0].val.a;
if (!arrayvftbl)
panic("MULTIANEWARRAY with unlinked class");
if ((desc = arrayvftbl->arraydesc) == NULL)
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);
TYPECHECK_COUNT(stat_ins_builtin);
if (ISBUILTIN(BUILTIN_newarray))
{
- vftbl *vft;
+ vftbl_t *vft;
TYPECHECK_INT(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: builtin_newarray without classinfo");
- vft = (vftbl *)iptr[-1].val.a;
+ vft = (vftbl_t *)iptr[-1].val.a;
if (!vft)
panic("ANEWARRAY with unlinked class");
if (!vft->arraydesc)
}
else if (ISBUILTIN(BUILTIN_arrayinstanceof))
{
- vftbl *vft;
+ vftbl_t *vft;
TYPECHECK_ADR(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: builtin_arrayinstanceof without classinfo");
- vft = (vftbl *)iptr[-1].val.a;
+ vft = (vftbl_t *)iptr[-1].val.a;
if (!vft)
panic("INSTANCEOF with unlinked class");
if (!vft->arraydesc)
panic("internal error: builtin_arrayinstanceof with non-array class");
}
else if (ISBUILTIN(BUILTIN_checkarraycast)) {
- vftbl *vft;
+ vftbl_t *vft;
TYPECHECK_ADR(curstack->prev);
if (iptr[-1].opc != ICMD_ACONST)
panic("illegal instruction: BUILTIN_checkarraycast without classinfo");
- vft = (vftbl *)iptr[-1].val.a;
+ vft = (vftbl_t *)iptr[-1].val.a;
if (!vft)
panic("CHECKCAST with unlinked class");
if (!vft->arraydesc)
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);
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);
cls = handlers[i]->catchtype;
excstack.typeinfo.typeclass = (cls) ? cls
: class_java_lang_Throwable;
- repeat |= typestate_reach(localbuf,bptr,
+ repeat |= typestate_reach(cd,rd, localbuf,bptr,
handlers[i]->handler,
&excstack,localset,
numlocals,
while (tbptr->flags == BBDELETED) {
tbptr++;
#ifdef TYPECHECK_DEBUG
- if ((tbptr-block) >= block_count)
+ if ((tbptr-block) >= m->basicblockcount)
panic("Control flow falls off the last block");
#endif
}
#endif
#ifdef TYPECHECK_DEBUG
- for (i=0; i<block_count; ++i) {
- if (block[i].flags != BBDELETED
- && block[i].flags != BBUNDEF
- && block[i].flags != BBFINISHED
- && block[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
+ for (i=0; i<m->basicblockcount; ++i) {
+ if (m->basicblocks[i].flags != BBDELETED
+ && m->basicblocks[i].flags != BBUNDEF
+ && m->basicblocks[i].flags != BBFINISHED
+ && m->basicblocks[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
* some exception handlers,
* that's ok. */
{
LOG2("block L%03d has invalid flags after typecheck: %d",
- block[i].debug_nr,block[i].flags);
+ m->basicblocks[i].debug_nr,m->basicblocks[i].flags);
panic("Invalid block flags after typecheck");
}
}
#endif
/* Reset blocks we never reached */
- for (i=0; i<block_count; ++i) {
- if (block[i].flags == BBTYPECHECK_UNDEF)
- block[i].flags = BBFINISHED;
+ for (i=0; i<m->basicblockcount; ++i) {
+ if (m->basicblocks[i].flags == BBTYPECHECK_UNDEF)
+ m->basicblocks[i].flags = BBFINISHED;
}
LOGimp("exiting typecheck");
- if (compileverbose) {
- char logtext[MAXLOGTEXT];
- sprintf(logtext, "Typechecking done: ");
- utf_sprint_classname(logtext + strlen(logtext), method->class->name);
- sprintf(logtext + strlen(logtext), ".");
- utf_sprint(logtext + strlen(logtext), method->name);
- utf_sprint_classname(logtext + strlen(logtext), method->descriptor);
- log_text(logtext);
- }
+ /* just return methodinfo* to signal everything was ok */
+
+ return m;
}
#undef COPYTYPE