⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code-analyse.c

📁 基于LWVCL开发的库
💻 C
📖 第 1 页 / 共 3 页
字号:
				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) {					goto done_fail;				}			}			if (METHOD_TRANSLATED(meth))				goto done_fail;			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)) {					goto done_fail;				}			}			if (METHOD_TRANSLATED(meth))				goto done_fail;			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)) {					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;}boolanalyzeMethod(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);			}			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);			}			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);			}			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);}/* * 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 = NULL;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 + -