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

📄 verify3a.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
			}						CHECK_LOCAL_INDEX(n);			break;					case LLOAD: case LSTORE:		case DLOAD: case DSTORE:			if (wide == true) {			        /* the WIDE is considered the beginning of the instruction */				v->status[pc] ^= IS_INSTRUCTION;				v->status[pc] |= WIDE_MODDED;								pc++;				wide = false;								n = getWord(code, pc);			}			else {				GET_IDX(n, pc);			}						/* makes sure the index given for a local variable is within the correct index			 *			 * REM: longs and doubles take two consecutive local spots			 */			CHECK_LOCAL_INDEX(n + 1);			break;								case IINC:			if (wide == true) {			        /* the WIDE is considered the beginning of the instruction */				v->status[pc] ^= IS_INSTRUCTION;				v->status[pc] |= WIDE_MODDED;								pc += 2;				wide = false;			}			break;									/********************************************************************			 * BRANCHING INSTRUCTIONS			 ********************************************************************/		case GOTO:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;						n = pc + 1;			branchoffset = getWord(code, n);			newpc = pc + branchoffset;			BRANCH_IN_BOUNDS(newpc, "goto");			v->status[newpc] |= START_BLOCK;			break;					case GOTO_W:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;						n = pc + 1;			branchoffset = getDWord(code, n);			newpc = pc + branchoffset;			BRANCH_IN_BOUNDS(newpc, "goto_w");			v->status[newpc] |= START_BLOCK;			break;								case IF_ACMPEQ:  case IFNONNULL:		case IF_ACMPNE:  case IFNULL:		case IF_ICMPEQ:  case IFEQ:		case IF_ICMPNE:	 case IFNE:		case IF_ICMPGT:	 case IFGT:		case IF_ICMPGE:	 case IFGE:		case IF_ICMPLT:	 case IFLT:		case IF_ICMPLE:	 case IFLE:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;						newpc = getNextPC(code, pc);			BRANCH_IN_BOUNDS(newpc, "if<condition> = false");			v->status[newpc] |= START_BLOCK;						n            = pc + 1;			branchoffset = getWord(code, n);			newpc        = pc + branchoffset;			BRANCH_IN_BOUNDS(newpc, "if<condition> = true");			v->status[newpc] |= START_BLOCK;			break;								case JSR:			newpc = pc + 1;			newpc = pc + getWord(code, newpc);			goto JSR_common;		case JSR_W:			newpc = pc + 1;			newpc = pc + getDWord(code, newpc);					JSR_common:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;						BRANCH_IN_BOUNDS(newpc, "jsr");			v->status[newpc] |= START_BLOCK;						/* the next instruction is a target for branching via RET */			pc = getNextPC(code, pc);			BRANCH_IN_BOUNDS(pc, "jsr/ret");			v->status[pc] |= START_BLOCK;			continue;					case RET:			v->status[pc] |= END_BLOCK;			if (!wide) {				GET_IDX(idx, pc);			} else {				GET_WIDX(idx, pc);								v->status[pc] ^= IS_INSTRUCTION;				v->status[pc] |= WIDE_MODDED;								wide = false;				pc += 2;			}			CHECK_LOCAL_INDEX(idx);			pc = getNextPC(code, pc);			continue;								case LOOKUPSWITCH:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;						/* default branch...between 0 and 3 bytes of padding are added so that the			 * default branch is at an address that is divisible by 4			 */			n = (pc + 1) % 4;			if (n) n = pc + 5 - n;			else   n = pc + 1;			newpc = pc + getDWord(code, n);			BRANCH_IN_BOUNDS(newpc, "lookupswitch");			v->status[newpc] |= START_BLOCK;			DBG(VERIFY3,			    dprintf("          lookupswitch: pc = %d ... instruction = ", newpc);			    printInstruction(code[newpc]);			    dprintf("\n");			    );						/* get number of key/target pairs */			n += 4;			low = getDWord(code, n);			if (low < 0) {				verifyError(v, "lookupswitch with npairs < 0");				return;			}						/* make sure all targets are in bounds */			/* NOTE: the cast here is only there to keep gcc from complaining */			for (n += 4, high = n + 8*low; n < (uint32)high; n += 8) {				newpc = pc + getDWord(code, n+4);				BRANCH_IN_BOUNDS(newpc, "lookupswitch");				v->status[newpc] |= START_BLOCK;								DBG(VERIFY3,				    dprintf("          lookupswitch: pc = %d ... instruction = ", newpc);				    printInstruction(code[newpc]);				    dprintf("\n");				    );			}						pc = high;			continue;								case TABLESWITCH:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;						/* default branch...between 0 and 3 bytes of padding are added so that the			 * default branch is at an address that is divisible by 4			 */			n = (pc + 1) % 4;			if (n) n = pc + 5 - n;			else   n = pc + 1;			newpc = pc + getDWord(code, n);			BRANCH_IN_BOUNDS(newpc, "tableswitch");			v->status[newpc] |= START_BLOCK;			DBG(VERIFY3,			    dprintf("          tableswitch: pc = %d ... instruction = ", newpc);			    printInstruction(code[newpc]);			    dprintf("\n");			    );						/* get the high and low values of the table */			low  = getDWord(code, n + 4);			high = getDWord(code, n + 8);			if (high < low) {				DBG(VERIFY3, dprintf("ERROR: low = %d, high = %d\n", low, high); );				verifyError(v, "tableswitch high val < low val");				return;			}			n += 12;						/* high and low are used as temps in this loop that checks			 * the validity of all the branches in the table			 */			/* NOTE: the cast is only to keep gcc from complaining */			for (high = n + 4*(high - low + 1); n < (uint32)high; n += 4) {				newpc = pc + getDWord(code, n);				BRANCH_IN_BOUNDS(newpc, "tableswitch");				v->status[newpc] |= START_BLOCK;								DBG(VERIFY3,				    dprintf("          tableswitch: pc = %d ... instruction = ", newpc);				    printInstruction(code[newpc]);				    dprintf("\n");				    );			}						pc = high;			continue;									/* the rest of the ways to end a block */		case RETURN:		case ARETURN:		case IRETURN:		case FRETURN:		case LRETURN:		case DRETURN:		case ATHROW:			ENSURE_NON_WIDE;			v->status[pc] |= END_BLOCK;			break;								default:			if (wide == true) {				verifyError(v, "illegal instruction following wide instruction");				return;			}		}				pc = getNextPC(code, pc);	}			DBG(VERIFY3, dprintf("    Verifier Pass 3a: second pass to locate illegal branches and count blocks...\n"); );		/* newpc is going to stand for the PC of the previous instruction */	for (newpc = 0, pc = 0; pc < codelen; pc++) {		if (v->status[pc] & IS_INSTRUCTION) {			if (v->status[pc] & START_BLOCK) {				blockCount++;								if (newpc < pc) {				        /* make sure that the previous instruction is					 * marked as the end of a block (it would only					 * have been marked so if it were some kind of					 * branch).					 */					v->status[newpc] |= END_BLOCK;				}			}						newpc = pc;		}		else if (v->status[pc] & START_BLOCK) {			verifyError(v, "branch into middle of instruction");			return;		}	}			DBG(VERIFY3, dprintf("        perusing exception table\n"); );	if (v->method->exception_table != 0) {		jexceptionEntry *entry;		for (n = 0; n < v->method->exception_table->length; n++) {			entry = &(v->method->exception_table->entry[n]);			pc = entry->start_pc;			if (pc >= codelen) {				verifyError(v, "try block is beyond bound of method code");				return;			}			else if (!(v->status[pc] & IS_INSTRUCTION)) {				verifyError(v, "try block starts in the middle of an instruction");				return;			}						pc = entry->end_pc;			if (pc <= entry->start_pc) {				verifyError(v, "try block ends before its starts");				return;			}			else if (pc > codelen) {				verifyError(v, "try block ends beyond bound of method code");				return;			}			else if (!(v->status[pc] & IS_INSTRUCTION)) {				verifyError(v, "try block ends in the middle of an instruction");				return;			}						pc = entry->handler_pc;			if (pc >= codelen) {				verifyError(v, "exception handler is beyond bound of method code");				return;			}			else if (!(v->status[pc] & IS_INSTRUCTION)) {				verifyError(v, "exception handler starts in the middle of an instruction");				return;			}						v->status[pc] |= (EXCEPTION_HANDLER & START_BLOCK);									/* verify properties about the clause			 *			 * if entry->catch_type == 0, it's a finally clause			 */			if (entry->catch_type != 0) {				if (entry->catch_type == NULL) {					entry->catch_type = getClass(entry->catch_idx, v->method->class, v->einfo);				}				if (entry->catch_type == NULL) {					DBG(VERIFY3, dprintf("        ERROR: could not resolve catch type...\n"); );					entry->catch_type = UNRESOLVABLE_CATCHTYPE;										verifyError(v, "unresolvable catch type");					return;				}				if (!instanceof(javaLangThrowable, entry->catch_type)) {					verifyError(v, "Exception to be handled by exception handler is not a subclass of Java/Lang/Throwable");					return;				}			}		}	}	if (v->method->lvars != NULL) {		for (n = 0; n < v->method->lvars->length; n++) {			localVariableEntry *lve;			lve = &v->method->lvars->entry[n];			pc = lve->start_pc;			if (pc >= codelen) {				verifyError(v, "local variable is beyond bound of method code");				return;			}			else if (!(v->status[pc] & IS_INSTRUCTION)) {				verifyError(v, "local variable starts in the middle of an instruction");				return;			}						if ((pc + lve->length) > codelen) {				verifyError(v, "local variable is beyond bound of method code");				return;			}		}	}			DBG(VERIFY3, dprintf("        done, %d blocks found.\n", blockCount); );			DBG(VERIFY3, dprintf("    Verifier Pass 3a: third pass to allocate memory for basic blocks...\n"); );		blocks = checkPtr((BlockInfo**)gc_malloc(blockCount * sizeof(BlockInfo*), KGC_ALLOC_VERIFIER));		for (inABlock = true, n = 0, pc = 0; pc < codelen; pc++) {		if (v->status[pc] & START_BLOCK) {			blocks[n] = createBlock(v->method);			blocks[n]->startAddr = pc;			n++;						inABlock = true;									DBG(VERIFY3, dprintf("        setting blocks[%d]->startAddr = %d\n",					     n-1, blocks[n-1]->startAddr); );		}				if (inABlock && (v->status[pc] & END_BLOCK)) {			blocks[n-1]->lastAddr = pc;						inABlock = false;									DBG(VERIFY3, dprintf("        setting blocks[%d]->lastAddr = %d\n",					     n-1, blocks[n-1]->lastAddr); );		}	}			DBG(VERIFY3, dprintf("    Verifier Pass 3a: done\n"); );		v->numBlocks = blockCount;	v->blocks = blocks;		#undef CHECK_LOCAL_INDEX	#undef BRANCH_IN_BOUNDS#undef GET_IDX#undef GET_WIDX#undef CHECK_POOL_IDX#undef ENSURE_NON_WIDE}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -