📄 code-analyse.c
字号:
case 'L': STKPUSH(1); STACKOUT(0, TOBJ); break; default: ABORT(); break; } INCPC(3); break; case PUTSTATIC: if (getField(WORD(pc+1), meth->class, true, &finfo, einfo) == 0) { if (!checkNoClassDefFoundError(einfo)) { failed = true; goto done; } } switch (finfo.signature->data[0]){ case 'I': case 'Z': case 'S': case 'B': case 'C': STACKIN(0, TINT); STKPOP(1); break; case 'F': STACKIN(0, TFLOAT); STKPOP(1); break; case 'J': STACKIN(0, TLONG); STACKIN(1, TVOID); STKPOP(2); break; case 'D': STACKIN(0, TDOUBLE); STACKIN(1, TVOID); STKPOP(2); break; case '[': case 'L': STACKIN(0, TOBJ); STKPOP(1); break; default: ABORT(); break; } INCPC(3); break; case GETFIELD: if (getField(WORD(pc+1), meth->class, false, &finfo, einfo) == 0) { failed = true; goto done; } STACKIN(0, TOBJ); if (!FIELD_ISPRIM(finfo.field)) { STACKOUT(0, TOBJ); } else switch (CLASS_PRIM_SIG(FIELD_TYPE(finfo.field))){ case 'I': case 'Z': case 'S': case 'B': case 'C': STACKOUT(0, TINT); break; case 'F': STACKOUT(0, TFLOAT); break; case 'J': STKPUSH(1); STACKOUT(0, TLONG); STACKOUT(1, TVOID); break; case 'D': STKPUSH(1); STACKOUT(0, TDOUBLE); STACKOUT(1, TVOID); break; default: ABORT(); break; } INCPC(3); break; case PUTFIELD: if (getField(WORD(pc+1), meth->class, false, &finfo, einfo) == 0) { failed = true; goto done; } if (!FIELD_ISPRIM(finfo.field)) { STACKIN(0, TOBJ); STACKIN(1, TOBJ); STKPOP(2); } else switch (CLASS_PRIM_SIG(FIELD_TYPE(finfo.field))){ case 'I': case 'Z': case 'S': case 'B': case 'C': STACKIN(0, TINT); STACKIN(1, TOBJ); STKPOP(2); break; case 'F': STACKIN(0, TFLOAT); STACKIN(1, TOBJ); STKPOP(2); break; case 'J': STACKIN(0, TLONG); STACKIN(1, TVOID); STACKIN(2, TOBJ); STKPOP(3); break; case 'D': STACKIN(0, TDOUBLE); STACKIN(1, TVOID); STACKIN(2, TOBJ); STKPOP(3); break; default: ABORT(); break; } INCPC(3); break; case INVOKEVIRTUAL: case INVOKESPECIAL: if (getMethodSignatureClass(WORD(pc+1), meth->class, true, false, &call, einfo) == false) { if (!checkNoClassDefFoundError(einfo) || call.signature == 0) { failed = true; goto done; } } sig = call.signature->data; assert(sig[0] == '('); sig++; idx = call.in; STACKIN(idx, TOBJ); idx -= 1; while (sig[0] != ')') { switch (sig[0]) { case '[': STACKIN(idx, TOBJ); idx -= 1; while (sig[0] == '[') { sig++; } if (sig[0] == 'L') { while (sig[0] != ';') { sig++; } } sig++; break; case 'L': STACKIN(idx, TOBJ); idx -= 1; while (sig[0] != ';') { sig++; } sig++; break; case 'I': case 'Z': case 'S': case 'B': case 'C': STACKIN(idx, TINT); idx -= 1; sig++; break; case 'J': STACKIN(idx-1, TLONG); STACKIN(idx, TVOID); idx -= 2; sig++; break; case 'F': STACKIN(idx, TFLOAT); idx -= 1; sig++; break; case 'D': STACKIN(idx-1, TDOUBLE); STACKIN(idx, TVOID); idx -= 2; sig++; break; default: assert("Signature character unknown" == 0); } } STKPOP(call.in+1); STKPUSH(call.out); switch (call.rettype) { case '[': case 'L': STACKOUT(0, TOBJ); break; case 'I': case 'Z': case 'S': case 'B': case 'C': STACKOUT(0, TINT); break; case 'J': STACKOUT(0, TLONG); STACKOUT(1, TVOID); break; case 'F': STACKOUT(0, TFLOAT); break; case 'D': STACKOUT(0, TDOUBLE); STACKOUT(1, TVOID); break; case 'V': default: break; } INCPC(3); break; case INVOKEINTERFACE: if (getMethodSignatureClass(WORD(pc+1), meth->class, true, false, &call, einfo) == false) { if (!checkNoClassDefFoundError(einfo) || call.signature == 0) { failed = true; goto done; } } sig = call.signature->data; assert(sig[0] == '('); sig++; idx = call.in; STACKIN(idx, TOBJ); idx -= 1; while (sig[0] != ')') { switch (sig[0]) { case '[': STACKIN(idx, TOBJ); idx -= 1; while (sig[0] == '[') { sig++; } if (sig[0] == 'L') { while (sig[0] != ';') { sig++; } } sig++; break; case 'L': STACKIN(idx, TOBJ); idx -= 1; while (sig[0] != ';') { sig++; } sig++; break; case 'I': case 'Z': case 'S': case 'B': case 'C': STACKIN(idx, TINT); idx -= 1; sig++; break; case 'J': STACKIN(idx-1, TLONG); STACKIN(idx, TVOID); idx -= 2; sig++; break; case 'F': STACKIN(idx, TFLOAT); idx -= 1; sig++; break; case 'D': STACKIN(idx-1, TDOUBLE); STACKIN(idx, TVOID); idx -= 2; sig++; break; default: assert("Signature character unknown" == 0); } } STKPOP(call.in+1); STKPUSH(call.out); switch (call.rettype) { case '[': case 'L': STACKOUT(0, TOBJ); break; case 'I': case 'Z': case 'S': case 'B': case 'C': STACKOUT(0, TINT); break; case 'J': STACKOUT(0, TLONG); STACKOUT(1, TVOID); break; case 'F': STACKOUT(0, TFLOAT); break; case 'D': STACKOUT(0, TDOUBLE); STACKOUT(1, TVOID); break; case 'V': default: break; } INCPC(5); break; case INVOKESTATIC: if (getMethodSignatureClass(WORD(pc+1), meth->class, true, false, &call, einfo) == false) { if (!checkNoClassDefFoundError(einfo) || call.signature == 0) { failed = true; goto done; } } sig = call.signature->data; assert(sig[0] == '('); sig++; idx = call.in - 1; while (sig[0] != ')') { switch (sig[0]) { case '[': STACKIN(idx, TOBJ); idx -= 1; while (sig[0] == '[') { sig++; } if (sig[0] == 'L') { while (sig[0] != ';') { sig++; } } sig++; break; case 'L': STACKIN(idx, TOBJ); idx -= 1; while (sig[0] != ';') { sig++; } sig++; break; case 'I': case 'Z': case 'S': case 'B': case 'C': STACKIN(idx, TINT); idx -= 1; sig++; break; case 'J': STACKIN(idx-1, TLONG); STACKIN(idx, TVOID); idx -= 2; sig++; break; case 'F': STACKIN(idx, TFLOAT); idx -= 1; sig++; break; case 'D': STACKIN(idx-1, TDOUBLE); STACKIN(idx, TVOID); idx -= 2; sig++; break; default: assert("Signature character unknown" == 0); } } STKPOP(call.in); STKPUSH(call.out); switch (call.rettype) { case '[': case 'L': STACKOUT(0, TOBJ); break; case 'I': case 'Z': case 'S': case 'B': case 'C': STACKOUT(0, TINT); break; case 'J': STACKOUT(0, TLONG); STACKOUT(1, TVOID); break; case 'F': STACKOUT(0, TFLOAT); break; case 'D': STACKOUT(0, TDOUBLE); STACKOUT(1, TVOID); break; case 'V': default: break; } INCPC(3); break; case NEW: if (getClass(WORD(pc+1), meth->class, einfo) == 0) { if (!checkNoClassDefFoundError(einfo)) { failed = true; goto done; } } STKPUSH(1); STACKOUT(0, TOBJ); INCPC(3); break; case NEWARRAY: STACKIN(0, TINT); STACKOUT(0, TOBJ); INCPC(2); break; case ANEWARRAY: if (getClass(WORD(pc+1), meth->class, einfo) == 0) { if (!checkNoClassDefFoundError(einfo)) { failed = true; goto done; } } STACKIN(0, TINT); STACKOUT(0, TOBJ); INCPC(3); break; case MULTIANEWARRAY: if (getClass(WORD(pc+1), meth->class, einfo) == 0) { if (!checkNoClassDefFoundError(einfo)) { failed = true; goto done; } } 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)) { failed = true; goto done; } } STACKIN(0, TOBJ); STACKOUT(0, TOBJ); INCPC(3); break; case INSTANCEOF: if (getClass(WORD(pc+1), meth->class, einfo) == 0) { if (!checkNoClassDefFoundError(einfo)) { failed = true; goto done; } } 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; } } 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);}/* * Merge the current frame into the beginning of a basic block. */staticvoidmergeFrame(codeinfo* codeInfo, int pc, int sp, frameElement* from, Method* meth){ int m; frameElement* to; to = FRAME(pc); assert(to != 0); /* Merge locals */ for (m = 0; m < meth->localsz; m++) { if (from[m].type != TUNASSIGNED && from[m].type != to[m].type && to[m].type != TUNSTABLE) { SET_NEEDVERIFY(pc); if (to[m].type == TUNASSIGNED) { to[m].type = from[m].type; } else { to[m].type = TUNSTABLE; } } } /* Merge stacks */ for (m = sp; m < meth->localsz + meth->stacksz; m++) { if (from[m].type != TUNASSIGNED && from[m].type != to[m].type && to[m].type != TUNSTABLE) { SET_NEEDVERIFY(pc); if (to[m].type == TUNASSIGNED) { to[m].type = from[m].type; } else { to[m].type = TUNSTABLE; } } }}/* * Tidy up after verfication data has been finished with. */voidtidyAnalyzeMethod(codeinfo** codeInfo){ int pc; /* Free the old data */ if (!*codeInfo) { return; } for (pc = 0; pc < (*codeInfo)->codelen; pc++) { if ((*codeInfo)->perPC[pc].frame != 0) { KFREE((*codeInfo)->perPC[pc].frame); } } KFREE((*codeInfo)->localuse); KFREE(*codeInfo); *codeInfo = 0;DBG(CODEANALYSE, dprintf("%s %p: clearing codeInfo %p\n",__FUNCTION__, THREAD_NATIVE(), codeInfo); )}staticvoidupdateLocals(codeinfo* codeInfo, int32 pc, frameElement* frame){ int i; localUse* l; for (i = 0; i < codeInfo->localsz; i++) { if (frame[i].used == 0) { continue; } l = &codeInfo->localuse[i]; if (pc < l->first) { l->first = pc; } if (pc > l->last) { l->last = pc; } if (frame[i].modified != 0 && pc > l->write) { l->write = pc; } l->use++; if (l->type == TUNASSIGNED) { l->type = frame[i].type; } else if (frame[i].type == TUNASSIGNED || l->type == frame[i].type) { /* Do nothing */ } else { l->type = TUNSTABLE; } }}/* * Verification requires us to resolve the catch type and check that * its actually a Throwable. But, we also do it to ensure that the * classes are ready when we need them and have little room to work * (e.g. a stack overflow). */static boolanalyzeCatchClause(jexceptionEntry* eptr, Hjava_lang_Class* class, errorInfo *einfo){ if( eptr->catch_idx == 0 ) { /* A finally clause... */ } else { eptr->catch_type = getClass(eptr->catch_idx, class, einfo); /* * If we could not resolve the catch class, then we * must record that fact to guard against possible * recursive attempts to load it. Throw whatever * error getClass() generated. */ if (eptr->catch_type == NULL) { eptr->catch_type = UNRESOLVABLE_CATCHTYPE; /* Pass on einfo generated by getClass() */ return false; } /* * Make sure the exception is a subclass of Throwable. */ if( !instanceof(javaLangThrowable, eptr->catch_type) ) { postException(einfo, JAVA_LANG(VerifyError)); return false; } } /* Catch clause is okay. */ return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -