[kaffe] CVS kaffe (robilad): small compiler warning fix
Kaffe CVS
cvs-commits at kaffe.org
Wed Apr 5 20:22:59 PDT 2006
PatchSet 7216
Date: 2006/04/06 03:11:00
Author: robilad
Branch: HEAD
Tag: (none)
Log:
small compiler warning fix
2006-04-06 Dalibor Topic <robilad at kaffe.org>
* kaffe/kaffevm/classMethod.h: Made
methods.c.bcode.codelen an unsigned int.
* kaffe/kaffevm/code-analyse.c (analyzeBasicBlock):
Removed unnecessary casts. Moved function up, so
that the static prototype could be removed. Changed
parameter pc's type to uint32.
(analyzeMethod): Made pc an uint32.
* kaffe/kaffevm/verifier/verify3a.c (verifyMethod3a):
Throw a verifier error if code length is 0.
Members:
ChangeLog:1.4722->1.4723
kaffe/kaffevm/classMethod.h:1.87->1.88
kaffe/kaffevm/code-analyse.c:1.48->1.49
kaffe/kaffevm/verifier/verify3a.c:1.4->1.5
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4722 kaffe/ChangeLog:1.4723
--- kaffe/ChangeLog:1.4722 Thu Apr 6 01:39:06 2006
+++ kaffe/ChangeLog Thu Apr 6 03:11:00 2006
@@ -1,5 +1,19 @@
2006-04-06 Dalibor Topic <robilad at kaffe.org>
+ * kaffe/kaffevm/classMethod.h: Made
+ methods.c.bcode.codelen an unsigned int.
+
+ * kaffe/kaffevm/code-analyse.c (analyzeBasicBlock):
+ Removed unnecessary casts. Moved function up, so
+ that the static prototype could be removed. Changed
+ parameter pc's type to uint32.
+ (analyzeMethod): Made pc an uint32.
+
+ * kaffe/kaffevm/verifier/verify3a.c (verifyMethod3a):
+ Throw a verifier error if code length is 0.
+
+2006-04-06 Dalibor Topic <robilad at kaffe.org>
+
* kaffe/kaffevm/object.c (newArrayChecked): Added assert to check
that count is >= 0. Simplified a bit, and added casts to fix
compiler warnings.
Index: kaffe/kaffe/kaffevm/classMethod.h
diff -u kaffe/kaffe/kaffevm/classMethod.h:1.87 kaffe/kaffe/kaffevm/classMethod.h:1.88
--- kaffe/kaffe/kaffevm/classMethod.h:1.87 Thu Mar 30 17:39:16 2006
+++ kaffe/kaffe/kaffevm/classMethod.h Thu Apr 6 03:11:03 2006
@@ -323,7 +323,7 @@
} ncode;
struct {
unsigned char* code;
- int codelen;
+ unsigned int codelen;
} bcode;
} c;
Hjava_lang_Class* class;
Index: kaffe/kaffe/kaffevm/code-analyse.c
diff -u kaffe/kaffe/kaffevm/code-analyse.c:1.48 kaffe/kaffe/kaffevm/code-analyse.c:1.49
--- kaffe/kaffe/kaffevm/code-analyse.c:1.48 Thu Mar 30 17:39:16 2006
+++ kaffe/kaffe/kaffevm/code-analyse.c Thu Apr 6 03:11:03 2006
@@ -34,456 +34,147 @@
#include "gc.h"
static void mergeFrame(codeinfo*, int, int, frameElement*, Method*);
-static bool analyzeBasicBlock(codeinfo*, Method*, int32, errorInfo*);
static void updateLocals(codeinfo*, int32, frameElement*);
static bool analyzeCatchClause(jexceptionEntry*, Hjava_lang_Class*, errorInfo*);
+static
bool
-analyzeMethod(Method* meth, codeinfo **pcodeinfo, errorInfo *einfo)
+analyzeBasicBlock(codeinfo* codeInfo, Method* meth, uint32 pc, errorInfo *einfo)
{
- int32 pc;
int32 tabpc;
int32 idx;
int32 sp;
- int32 lcl;
- int count;
- perPCInfo* bhead;
- perPCInfo* btail;
- perPCInfo* bcurr;
- bool rerun;
- bool failed;
+ int32 opc;
+ callInfo call;
+ fieldInfo finfo;
+ Hjava_lang_Class* type;
+ const char* sig;
+ frameElement* activeFrame;
bool wide;
- codeinfo *codeInfo;
- localUse* localuse;
-
-DBG(CODEANALYSE,
- dprintf("%s %p: %s.%s\n", __FUNCTION__, THREAD_NATIVE(),
- meth->class->name->data, meth->name->data);
- );
+ bool failed;
+ bool firsttime;
- if( meth->c.bcode.code == 0 )
- {
- postExceptionMessage(einfo, JAVA_LANG(VerifyError),
- "No code attribute for %s.%s.",
- meth->class->name->data,
- meth->name->data);
- return false;
- }
+ opc = pc;
+ assert(pc == 0 || IS_STARTOFBASICBLOCK(pc) || IS_STARTOFEXCEPTION(pc));
+ assert(IS_STACKPOINTERSET(pc));
- codeInfo = gc_malloc(sizeof(codeinfo) + meth->c.bcode.codelen*sizeof(perPCInfo),
- KGC_ALLOC_CODEANALYSE);
- *pcodeinfo = codeInfo;
- if (!codeInfo) {
- postOutOfMemory(einfo);
- return false;
+ /* If this block hasn't been verified before then note this */
+ if (!IS_DONEVERIFY(pc)) {
+ firsttime = true;
}
- /* Allocate space for local register info - we add in an extra one
- * to avoid mallocing 0 bytes.
- */
- localuse = gc_malloc(sizeof(localUse) * (meth->localsz+1), KGC_ALLOC_CODEANALYSE);
- if (!localuse) {
- KFREE(codeInfo);
- postOutOfMemory(einfo);
- return false;
+ else {
+ firsttime = false;
}
- codeInfo->localuse = localuse;
- /* We don't need to do this twice */
- meth->kFlags |= KFLAG_VERIFIED;
+ /* Get stack pointer */
+ sp = STACKPOINTER(pc);
- for (lcl = 0; lcl < meth->localsz; lcl++) {
- localuse = codeInfo->localuse;
- localuse[lcl].use = 0;
- localuse[lcl].first = 0x7FFFFFFF;
- localuse[lcl].last = -1;
- localuse[lcl].write = -1;
- localuse[lcl].type = NULL;
+ /* Allocate frame to hold type data */
+ activeFrame = ALLOCFRAME();
+ if (activeFrame == 0) {
+ postOutOfMemory(einfo);
+ return true;
}
-DBG(CODEANALYSE,
- dprintf("%s %p: codeInfo = %p\n", __FUNCTION__, THREAD_NATIVE(), codeInfo);
- );
-
- /* Allocate code info. block */
- codeInfo->localsz = meth->localsz;
- codeInfo->stacksz = meth->stacksz;
- codeInfo->codelen = meth->c.bcode.codelen;
+ SET_DONEVERIFY(pc);
- /* First basic block becomes head of block chain */
- SET_NEEDVERIFY(0);
- bhead = &codeInfo->perPC[0];
- btail = bhead;
+ FRAMELOAD(pc);
- /* Scan the code and mark the beginning of basic blocks */
+ /* Process basic block until we get to the beginning of a new one */
wide = false;
- for (pc = 0; pc < codeInfo->codelen;) {
- SET_STARTOFINSTRUCTION(pc);
- /* set native pc to -1 so that we can recognize whether
- * a corresponding native PC will be generated.
+ failed = false;
+ do {
+ if (sp < meth->localsz || sp > meth->localsz + meth->stacksz) {
+ failed = true;
+ postExceptionMessage(einfo, JAVA_LANG(VerifyError),
+ "In class %s in method %s with signature %s at pc %d: sp %d not in range [%d, %d]",
+ meth->class->name->data, meth->name->data, METHOD_SIGD(meth),
+ pc, sp, meth->localsz,
+ meth->localsz + meth->stacksz);
+ break;
+ }
+
+ /* If we're in an exception block, merge locals into
+ * the handler.
*/
- SET_INSNPC(pc, -1);
+ if (meth->exception_table != 0) {
+ for (idx = 0; idx < (int32)meth->exception_table->length; idx++) {
+ if (pc >= meth->exception_table->entry[idx].start_pc
+ && pc < meth->exception_table->entry[idx].end_pc) {
+ FRAMEMERGE_LOCALS((int32)(meth->exception_table->entry[idx].handler_pc));
+ }
+ }
+ }
+
+IDBG( dprintf("%d: %d\n", pc, INSN(pc)); )
+
switch (INSN(pc)) {
- case IFEQ: case IFNE: case IFLT:
- case IFGE: case IFGT: case IFLE:
- case IF_ICMPEQ: case IF_ICMPNE:
- case IF_ICMPLT: case IF_ICMPGE:
- case IF_ICMPGT: case IF_ICMPLE:
- case IF_ACMPEQ: case IF_ACMPNE:
- case IFNULL: case IFNONNULL:
- tabpc = pc + WORD(pc+1);
- SET_STARTOFBASICBLOCK(tabpc);
- SET_JUMPFLOW(pc, tabpc);
- pc = pc + INSNLEN(pc);
- SET_STARTOFBASICBLOCK(pc);
- SET_NORMALFLOW(pc);
+ int32 lcl;
+
+ case NOP:
+ INCPC(1);
break;
- case GOTO:
- tabpc = pc + WORD(pc+1);
- SET_STARTOFBASICBLOCK(tabpc);
- SET_JUMPFLOW(pc, tabpc);
- pc = pc + INSNLEN(pc);
- if (pc < codeInfo->codelen) {
- SET_STARTOFBASICBLOCK(pc);
- }
+
+ case ACONST_NULL:
+ STKPUSH(1);
+ STACKOUT(0, TOBJ);
+ INCPC(1);
break;
- case GOTO_W:
- tabpc = pc + DWORD(pc+1);
- SET_STARTOFBASICBLOCK(tabpc);
- SET_JUMPFLOW(pc, tabpc);
- pc = pc + INSNLEN(pc);
- if (pc < codeInfo->codelen) {
- SET_STARTOFBASICBLOCK(pc);
- }
+
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ STKPUSH(1);
+ STACKOUT_CONST(0, TINT, INSN(pc) - ICONST_0);
+ INCPC(1);
break;
- case JSR:
- tabpc = pc + WORD(pc+1);
- SET_STARTOFBASICBLOCK(tabpc);
- SET_JUMPFLOW(pc, tabpc);
- pc = pc + INSNLEN(pc);
- SET_STARTOFBASICBLOCK(pc);
- SET_NORMALFLOW(pc);
+
+ case BIPUSH:
+ STKPUSH(1);
+ STACKOUT_CONST(0, TINT, BYTE(pc+1));
+ INCPC(2);
break;
- case JSR_W:
- tabpc = pc + DWORD(pc+1);
- SET_STARTOFBASICBLOCK(tabpc);
- SET_JUMPFLOW(pc, tabpc);
- pc = pc + INSNLEN(pc);
- SET_STARTOFBASICBLOCK(pc);
- SET_NORMALFLOW(pc);
+
+ case SIPUSH:
+ STKPUSH(1);
+ STACKOUT_CONST(0, TINT, WORD(pc+1));
+ INCPC(3);
break;
- case TABLESWITCH:
- tabpc = (pc + 4) & -4;
- idx = DWORD(tabpc+8)-DWORD(tabpc+4)+1;
- for (; idx > 0; idx--) {
- SET_STARTOFBASICBLOCK(pc+DWORD(tabpc+idx*4+8));
- SET_JUMPFLOW(pc, pc+DWORD(tabpc+idx*4+8));
- }
- SET_STARTOFBASICBLOCK(pc+DWORD(tabpc));
- SET_JUMPFLOW(pc, pc+DWORD(tabpc));
- pc = tabpc + (DWORD(tabpc+8)-DWORD(tabpc+4)+1+3) * 4;
- if (pc < codeInfo->codelen) {
- SET_STARTOFBASICBLOCK(pc);
- }
+
+ case LCONST_0:
+ case LCONST_1:
+ STKPUSH(2);
+ STACKOUT(0, TLONG);
+ STACKOUT(1, TVOID);
+ INCPC(1);
break;
- case LOOKUPSWITCH:
- tabpc = (pc + 4) & -4;
- idx = DWORD(tabpc+4);
- for (; idx > 0; idx--) {
- SET_STARTOFBASICBLOCK(pc+DWORD(tabpc+idx*8+4));
- SET_JUMPFLOW(pc, pc+DWORD(tabpc+idx*8+4));
- }
- SET_STARTOFBASICBLOCK(pc+DWORD(tabpc));
- SET_JUMPFLOW(pc, pc+DWORD(tabpc));
- pc = tabpc + (DWORD(tabpc+4)+1) * 8;
- if (pc < codeInfo->codelen) {
- SET_STARTOFBASICBLOCK(pc);
- }
+
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ STKPUSH(1);
+ STACKOUT(0, TFLOAT);
+ INCPC(1);
break;
- case IRETURN: case LRETURN: case ARETURN:
- case FRETURN: case DRETURN: case RETURN:
- case ATHROW: case RET:
- pc = pc + INSNLEN(pc);
- if (pc < codeInfo->codelen) {
- SET_STARTOFBASICBLOCK(pc);
- }
+
+ case DCONST_0:
+ case DCONST_1:
+ STKPUSH(2);
+ STACKOUT(0, TDOUBLE);
+ STACKOUT(1, TVOID);
+ INCPC(1);
break;
- case WIDE:
- wide = true;
- pc = pc + INSNLEN(pc);
- SET_NORMALFLOW(pc);
- break;
- case ILOAD: case LLOAD: case FLOAD:
- case DLOAD: case ALOAD:
- case ISTORE: case LSTORE: case FSTORE:
- case DSTORE: case ASTORE:
- pc = pc + INSNLEN(pc);
- if (wide == true) {
- wide = false;
- pc += 1;
- }
- SET_NORMALFLOW(pc);
- break;
- case IINC:
- pc = pc + INSNLEN(pc);
- if (wide == true) {
- wide = false;
- pc += 2;
- }
- SET_NORMALFLOW(pc);
- break;
- default:
- /* The default */
- pc = pc + INSNLEN(pc);
- SET_NORMALFLOW(pc);
- break;
- }
- }
-
- /* Setup exception info. */
- sp = meth->localsz + meth->stacksz - 1;
- if (meth->exception_table != 0) {
- for (lcl = 0; lcl < (int32)meth->exception_table->length; lcl++) {
- bool succ;
- jexceptionEntry *entry;
-
- entry = &(meth->exception_table->entry[lcl]);
-
- /* Verify catch clause exception has valid type. */
- succ = analyzeCatchClause(entry, meth->class, einfo);
- if (succ == false) {
- return false;
- }
-
- pc = entry->handler_pc;
- ATTACH_NEW_BASICBLOCK(pc);
- SET_STARTOFEXCEPTION(pc);
- SET_STACKPOINTER(pc, sp);
- SET_NEWFRAME(pc);
- STACKINIT(0, TOBJ);
- }
- }
-
- /* Mark the various starting states. These include the main
- * entry point plus all the exception entry points, their arguments
- * and stack values.
- */
- pc = 0;
- SET_STACKPOINTER(pc, meth->localsz + meth->stacksz);
- SET_NEWFRAME(pc);
-
- /* Parse the method signature to setup the inital locals
- */
- idx = 0;
- if ((meth->accflags & ACC_STATIC) == 0) {
- LOCALINIT(0, TOBJ);
- idx++;
- }
-
- for (count = 0; count < METHOD_NARGS(meth); ++count) {
- switch (*METHOD_ARG_TYPE(meth, count)) {
- case 'L':
- case '[':
- LOCALINIT(idx, TOBJ);
- idx += 1;
- break;
- case 'I':
- case 'Z':
- case 'S':
- case 'B':
- case 'C':
- LOCALINIT(idx, TINT);
- idx += 1;
- break;
- case 'J':
- LOCALINIT(idx, TLONG);
- LOCALINIT(idx+1, TVOID);
- idx += 2;
- break;
- case 'F':
- LOCALINIT(idx, TFLOAT);
- idx += 1;
- break;
- case 'D':
- LOCALINIT(idx, TDOUBLE);
- LOCALINIT(idx+1, TVOID);
- idx += 2;
- break;
- default:
- assert("Signature character unknown" == 0);
- }
- }
-
- /* Scan out list of basic blocks. Unfortunately they're not in
- * precise order so we have to do this until they're all done.
- */
- do {
- rerun = false;
- for (bcurr = bhead; bcurr != NULL; bcurr = bcurr->nextBB) {
- pc = bcurr - codeInfo->perPC;
- if (IS_NEEDVERIFY(pc)) {
- failed = analyzeBasicBlock(codeInfo, meth,
- pc, einfo);
-
- if (failed) {
- tidyAnalyzeMethod(pcodeinfo);
- return (false);
- }
- rerun = true;
- }
- }
- } while (rerun == true);
-
- /* Check we've processed each block at least once */
- /* Note that it is perfectly legal for code to contain unreachable
- * basic blocks; There's no need to complain.
- */
-#if VDBG(1) - 1 == 0
- for (bcurr = bhead; bcurr != NULL; bcurr = bcurr->nextBB) {
- if ((bcurr->flags & FLAG_DONEVERIFY) == 0) {
- VDBG(dprintf("%s.%s%s pc %d bcurr->flags 0x%04x\n", meth->class->name->data, meth->name->data, METHOD_SIGD(meth), bcurr - codeInfo->perPC, bcurr->flags);)
- }
- }
-#endif
- return (true);
-}
-
-static
-bool
-analyzeBasicBlock(codeinfo* codeInfo, Method* meth, int32 pc, errorInfo *einfo)
-{
- int32 tabpc;
- int32 idx;
- int32 sp;
- int32 opc;
- callInfo call;
- fieldInfo finfo;
- Hjava_lang_Class* type;
- const char* sig;
- frameElement* activeFrame;
- bool wide;
- bool failed;
- bool firsttime;
-
- opc = pc;
- assert(pc == 0 || IS_STARTOFBASICBLOCK(pc) || IS_STARTOFEXCEPTION(pc));
- assert(IS_STACKPOINTERSET(pc));
-
- /* If this block hasn't been verified before then note this */
- if (!IS_DONEVERIFY(pc)) {
- firsttime = true;
- }
- else {
- firsttime = false;
- }
-
- /* Get stack pointer */
- sp = STACKPOINTER(pc);
-
- /* Allocate frame to hold type data */
- activeFrame = ALLOCFRAME();
- if (activeFrame == 0) {
- postOutOfMemory(einfo);
- return true;
- }
-
- SET_DONEVERIFY(pc);
-
- FRAMELOAD(pc);
-
- /* Process basic block until we get to the beginning of a new one */
- wide = false;
- failed = false;
- do {
- if (sp < meth->localsz || sp > meth->localsz + meth->stacksz) {
- failed = true;
- postExceptionMessage(einfo, JAVA_LANG(VerifyError),
- "In class %s in method %s with signature %s at pc %d: sp %d not in range [%d, %d]",
- meth->class->name->data, meth->name->data, METHOD_SIGD(meth),
- pc, sp, meth->localsz,
- meth->localsz + meth->stacksz);
- break;
- }
-
- /* If we're in an exception block, merge locals into
- * the handler.
- */
- if (meth->exception_table != 0) {
- for (idx = 0; idx < (int32)meth->exception_table->length; idx++) {
- if (pc >= (int32)meth->exception_table->entry[idx].start_pc && pc < (int32)meth->exception_table->entry[idx].end_pc) {
- FRAMEMERGE_LOCALS((int32)(meth->exception_table->entry[idx].handler_pc));
- }
- }
- }
-
-IDBG( dprintf("%d: %d\n", pc, INSN(pc)); )
-
- switch (INSN(pc)) {
- int32 lcl;
-
- case NOP:
- INCPC(1);
- break;
-
- case ACONST_NULL:
- STKPUSH(1);
- STACKOUT(0, TOBJ);
- INCPC(1);
- break;
-
- case ICONST_M1:
- case ICONST_0:
- case ICONST_1:
- case ICONST_2:
- case ICONST_3:
- case ICONST_4:
- case ICONST_5:
- STKPUSH(1);
- STACKOUT_CONST(0, TINT, INSN(pc) - ICONST_0);
- INCPC(1);
- break;
-
- case BIPUSH:
- STKPUSH(1);
- STACKOUT_CONST(0, TINT, BYTE(pc+1));
- INCPC(2);
- break;
-
- case SIPUSH:
- STKPUSH(1);
- STACKOUT_CONST(0, TINT, WORD(pc+1));
- INCPC(3);
- break;
-
- case LCONST_0:
- case LCONST_1:
- STKPUSH(2);
- STACKOUT(0, TLONG);
- STACKOUT(1, TVOID);
- INCPC(1);
- break;
-
- case FCONST_0:
- case FCONST_1:
- case FCONST_2:
- STKPUSH(1);
- STACKOUT(0, TFLOAT);
- INCPC(1);
- break;
-
- case DCONST_0:
- case DCONST_1:
- STKPUSH(2);
- STACKOUT(0, TDOUBLE);
- STACKOUT(1, TVOID);
- INCPC(1);
- break;
-
- case LDC1:
- STKPUSH(1);
- lcl = (uint8)BYTE(pc + 1);
- CONSTANTTYPE(type, lcl);
- STACKOUT(0, type);
- INCPC(2);
+
+ case LDC1:
+ STKPUSH(1);
+ lcl = (uint8)BYTE(pc + 1);
+ CONSTANTTYPE(type, lcl);
+ STACKOUT(0, type);
+ INCPC(2);
break;
case LDC2:
@@ -1874,130 +1565,439 @@
STACKOUT(0, TOBJ);
INCPC(2);
break;
-
- case ANEWARRAY:
- if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
- if (!checkNoClassDefFoundError(einfo)) {
- goto done_fail;
- }
+
+ case ANEWARRAY:
+ if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
+ if (!checkNoClassDefFoundError(einfo)) {
+ goto done_fail;
+ }
+ }
+ if (METHOD_TRANSLATED(meth))
+ goto done_fail;
+ STACKIN(0, TINT);
+ STACKOUT(0, TOBJ);
+ INCPC(3);
+ break;
+
+ case MULTIANEWARRAY:
+ if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
+ if (!checkNoClassDefFoundError(einfo)) {
+ goto done_fail;
+ }
+ }
+ if (METHOD_TRANSLATED(meth))
+ goto done_fail;
+ for (idx = INSN(pc+3) - 1; idx >= 0; idx--) {
+ STACKIN(idx, TINT);
+ }
+ STKPOP(INSN(pc+3) - 1);
+ STACKOUT(0, TOBJ);
+ INCPC(4);
+ break;
+
+ case ARRAYLENGTH:
+ STACKIN(0, TOBJ);
+ STACKOUT(0, TINT);
+ INCPC(1);
+ break;
+
+ case ATHROW:
+ STACKIN(0, TOBJ);
+ STKPOP(1);
+ INCPC(1);
+ break;
+
+ case CHECKCAST:
+ if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
+ if (!checkNoClassDefFoundError(einfo)) {
+ goto done_fail;
+ }
+ }
+ if (METHOD_TRANSLATED(meth))
+ goto done_fail;
+ STACKIN(0, TOBJ);
+ STACKOUT(0, TOBJ);
+ INCPC(3);
+ break;
+
+ case INSTANCEOF:
+ if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
+ if (!checkNoClassDefFoundError(einfo)) {
+ }
+ }
+ if (METHOD_TRANSLATED(meth))
+ goto done_fail;
+ STACKIN(0, TOBJ);
+ STACKOUT(0, TINT);
+ INCPC(3);
+ break;
+
+ case MONITORENTER:
+ case MONITOREXIT:
+ STACKIN(0, TOBJ);
+ STKPOP(1);
+ INCPC(1);
+ break;
+
+ case IFNULL:
+ case IFNONNULL:
+ STACKIN(0, TOBJ);
+ STKPOP(1);
+ FRAMEMERGE(pc + WORD(pc+1), sp);
+ FRAMEMERGE(pc + 3, sp);
+ INCPC(3);
+ break;
+
+ case WIDE:
+ wide = true;
+ INCPC(1);
+ break;
+
+ case BREAKPOINT:
+ INCPC(1);
+ break;
+ default:
+ postExceptionMessage(einfo,
+ JAVA_LANG(VerifyError),
+ "(class: %s, method: %s signature: %s) "
+ "invalid opcode",
+ meth->class->name->data,
+ meth->name->data,
+ meth->parsed_sig->signature->data);
+ goto done_fail;
+ }
+ } while (pc < meth->c.bcode.codelen && !IS_STARTOFBASICBLOCK(pc) && !IS_STARTOFEXCEPTION(pc));
+
+ /* If we flow into the next basic block, set the stack pointer
+ * and merge in the frame.
+ */
+ if (!failed && pc < meth->c.bcode.codelen && IS_NORMALFLOW(pc)) {
+ assert(IS_STARTOFBASICBLOCK(pc) || IS_STARTOFEXCEPTION(pc));
+ FRAMEMERGE(pc, sp);
+ }
+
+ if (firsttime) {
+ updateLocals(codeInfo, opc, activeFrame);
+ }
+
+done:
+ /* Discard active frame */
+ KFREE(activeFrame);
+
+ return (failed);
+
+done_fail:
+ failed = true;
+ goto done;
+}
+
+bool
+analyzeMethod(Method* meth, codeinfo **pcodeinfo, errorInfo *einfo)
+{
+ uint32 pc;
+ int32 tabpc;
+ int32 idx;
+ int32 sp;
+ int32 lcl;
+ int count;
+ perPCInfo* bhead;
+ perPCInfo* btail;
+ perPCInfo* bcurr;
+ bool rerun;
+ bool failed;
+ bool wide;
+ codeinfo *codeInfo;
+ localUse* localuse;
+
+DBG(CODEANALYSE,
+ dprintf("%s %p: %s.%s\n", __FUNCTION__, THREAD_NATIVE(),
+ meth->class->name->data, meth->name->data);
+ );
+
+ if( meth->c.bcode.code == 0 )
+ {
+ postExceptionMessage(einfo, JAVA_LANG(VerifyError),
+ "No code attribute for %s.%s.",
+ meth->class->name->data,
+ meth->name->data);
+ return false;
+ }
+
+ codeInfo = gc_malloc(sizeof(codeinfo) + meth->c.bcode.codelen*sizeof(perPCInfo),
+ KGC_ALLOC_CODEANALYSE);
+ *pcodeinfo = codeInfo;
+ if (!codeInfo) {
+ postOutOfMemory(einfo);
+ return false;
+ }
+ /* Allocate space for local register info - we add in an extra one
+ * to avoid mallocing 0 bytes.
+ */
+ localuse = gc_malloc(sizeof(localUse) * (meth->localsz+1), KGC_ALLOC_CODEANALYSE);
+ if (!localuse) {
+ KFREE(codeInfo);
+ postOutOfMemory(einfo);
+ return false;
+ }
+ codeInfo->localuse = localuse;
+
+ /* We don't need to do this twice */
+ meth->kFlags |= KFLAG_VERIFIED;
+
+ for (lcl = 0; lcl < meth->localsz; lcl++) {
+ localuse = codeInfo->localuse;
+ localuse[lcl].use = 0;
+ localuse[lcl].first = 0x7FFFFFFF;
+ localuse[lcl].last = -1;
+ localuse[lcl].write = -1;
+ localuse[lcl].type = NULL;
+ }
+
+DBG(CODEANALYSE,
+ dprintf("%s %p: codeInfo = %p\n", __FUNCTION__, THREAD_NATIVE(), codeInfo);
+ );
+
+ /* Allocate code info. block */
+ codeInfo->localsz = meth->localsz;
+ codeInfo->stacksz = meth->stacksz;
+ codeInfo->codelen = meth->c.bcode.codelen;
+
+ /* First basic block becomes head of block chain */
+ SET_NEEDVERIFY(0);
+ bhead = &codeInfo->perPC[0];
+ btail = bhead;
+
+ /* Scan the code and mark the beginning of basic blocks */
+ wide = false;
+ for (pc = 0; pc < codeInfo->codelen;) {
+ SET_STARTOFINSTRUCTION(pc);
+ /* set native pc to -1 so that we can recognize whether
+ * a corresponding native PC will be generated.
+ */
+ SET_INSNPC(pc, -1);
+ switch (INSN(pc)) {
+ case IFEQ: case IFNE: case IFLT:
+ case IFGE: case IFGT: case IFLE:
+ case IF_ICMPEQ: case IF_ICMPNE:
+ case IF_ICMPLT: case IF_ICMPGE:
+ case IF_ICMPGT: case IF_ICMPLE:
+ case IF_ACMPEQ: case IF_ACMPNE:
+ case IFNULL: case IFNONNULL:
+ tabpc = pc + WORD(pc+1);
+ SET_STARTOFBASICBLOCK(tabpc);
+ SET_JUMPFLOW(pc, tabpc);
+ pc = pc + INSNLEN(pc);
+ SET_STARTOFBASICBLOCK(pc);
+ SET_NORMALFLOW(pc);
+ break;
+ case GOTO:
+ tabpc = pc + WORD(pc+1);
+ SET_STARTOFBASICBLOCK(tabpc);
+ SET_JUMPFLOW(pc, tabpc);
+ pc = pc + INSNLEN(pc);
+ if (pc < codeInfo->codelen) {
+ SET_STARTOFBASICBLOCK(pc);
+ }
+ break;
+ case GOTO_W:
+ tabpc = pc + DWORD(pc+1);
+ SET_STARTOFBASICBLOCK(tabpc);
+ SET_JUMPFLOW(pc, tabpc);
+ pc = pc + INSNLEN(pc);
+ if (pc < codeInfo->codelen) {
+ SET_STARTOFBASICBLOCK(pc);
+ }
+ break;
+ case JSR:
+ tabpc = pc + WORD(pc+1);
+ SET_STARTOFBASICBLOCK(tabpc);
+ SET_JUMPFLOW(pc, tabpc);
+ pc = pc + INSNLEN(pc);
+ SET_STARTOFBASICBLOCK(pc);
+ SET_NORMALFLOW(pc);
+ break;
+ case JSR_W:
+ tabpc = pc + DWORD(pc+1);
+ SET_STARTOFBASICBLOCK(tabpc);
+ SET_JUMPFLOW(pc, tabpc);
+ pc = pc + INSNLEN(pc);
+ SET_STARTOFBASICBLOCK(pc);
+ SET_NORMALFLOW(pc);
+ break;
+ case TABLESWITCH:
+ tabpc = (pc + 4) & -4;
+ idx = DWORD(tabpc+8)-DWORD(tabpc+4)+1;
+ for (; idx > 0; idx--) {
+ SET_STARTOFBASICBLOCK(pc+DWORD(tabpc+idx*4+8));
+ SET_JUMPFLOW(pc, pc+DWORD(tabpc+idx*4+8));
+ }
+ SET_STARTOFBASICBLOCK(pc+DWORD(tabpc));
+ SET_JUMPFLOW(pc, pc+DWORD(tabpc));
+ pc = tabpc + (DWORD(tabpc+8)-DWORD(tabpc+4)+1+3) * 4;
+ if (pc < codeInfo->codelen) {
+ SET_STARTOFBASICBLOCK(pc);
}
- if (METHOD_TRANSLATED(meth))
- goto done_fail;
- STACKIN(0, TINT);
- STACKOUT(0, TOBJ);
- INCPC(3);
break;
-
- case MULTIANEWARRAY:
- if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
- if (!checkNoClassDefFoundError(einfo)) {
- goto done_fail;
- }
+ case LOOKUPSWITCH:
+ tabpc = (pc + 4) & -4;
+ idx = DWORD(tabpc+4);
+ for (; idx > 0; idx--) {
+ SET_STARTOFBASICBLOCK(pc+DWORD(tabpc+idx*8+4));
+ SET_JUMPFLOW(pc, pc+DWORD(tabpc+idx*8+4));
}
- if (METHOD_TRANSLATED(meth))
- goto done_fail;
- for (idx = INSN(pc+3) - 1; idx >= 0; idx--) {
- STACKIN(idx, TINT);
+ SET_STARTOFBASICBLOCK(pc+DWORD(tabpc));
+ SET_JUMPFLOW(pc, pc+DWORD(tabpc));
+ pc = tabpc + (DWORD(tabpc+4)+1) * 8;
+ if (pc < codeInfo->codelen) {
+ SET_STARTOFBASICBLOCK(pc);
}
- STKPOP(INSN(pc+3) - 1);
- STACKOUT(0, TOBJ);
- INCPC(4);
break;
-
- case ARRAYLENGTH:
- STACKIN(0, TOBJ);
- STACKOUT(0, TINT);
- INCPC(1);
+ case IRETURN: case LRETURN: case ARETURN:
+ case FRETURN: case DRETURN: case RETURN:
+ case ATHROW: case RET:
+ pc = pc + INSNLEN(pc);
+ if (pc < codeInfo->codelen) {
+ SET_STARTOFBASICBLOCK(pc);
+ }
break;
-
- case ATHROW:
- STACKIN(0, TOBJ);
- STKPOP(1);
- INCPC(1);
+ case WIDE:
+ wide = true;
+ pc = pc + INSNLEN(pc);
+ SET_NORMALFLOW(pc);
break;
-
- case CHECKCAST:
- if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
- if (!checkNoClassDefFoundError(einfo)) {
- goto done_fail;
- }
+ case ILOAD: case LLOAD: case FLOAD:
+ case DLOAD: case ALOAD:
+ case ISTORE: case LSTORE: case FSTORE:
+ case DSTORE: case ASTORE:
+ pc = pc + INSNLEN(pc);
+ if (wide == true) {
+ wide = false;
+ pc += 1;
}
- if (METHOD_TRANSLATED(meth))
- goto done_fail;
- STACKIN(0, TOBJ);
- STACKOUT(0, TOBJ);
- INCPC(3);
+ SET_NORMALFLOW(pc);
break;
-
- case INSTANCEOF:
- if (getClass(WORD(pc+1), meth->class, einfo) == 0) {
*** Patch too long, truncated ***
More information about the kaffe
mailing list