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

📄 verify3b.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
				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:				newpc     = pc + 1;				newpc     = pc + getWord(code, newpc);				nextBlock = inWhichBlock(newpc, blocks, v->numBlocks);								if (!mergeBasicBlocks(v, curBlock, nextBlock)) {					return verifyErrorInVerifyMethod3b(v, curBlock, "error merging operand stacks");				}								/* if the condition is false, then the next block is the one that will be executed */				curIndex++;				if (curIndex >= v->numBlocks) {					return verifyErrorInVerifyMethod3b(v, curBlock, "execution falls off the end of a basic block");				}				else if (!mergeBasicBlocks(v, curBlock, blocks[curIndex])) {					return verifyErrorInVerifyMethod3b(v, curBlock, "error merging operand stacks");				}				break;											case LOOKUPSWITCH:			        /* 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);				nextBlock = inWhichBlock(newpc, blocks, v->numBlocks);				if (!mergeBasicBlocks(v, curBlock, nextBlock)) {					return verifyErrorInVerifyMethod3b(v, curBlock, "error merging into the default branch of a lookupswitch instruction");				}								/* get number of key/target pairs */				n += 4;				low = getDWord(code, n);								/* branch into all targets */				/* NOTE: the cast is there only to keep gcc happy */				for (n += 4, high = n + 8*low; n < (uint32)high; n += 8) {					newpc = pc + getDWord(code, n+4);					nextBlock = inWhichBlock(newpc, blocks, v->numBlocks);					if (!mergeBasicBlocks(v, curBlock, nextBlock)) {						return verifyErrorInVerifyMethod3b(v, curBlock, "error merging into a branch of a lookupswitch instruction");					}				}								break;							case TABLESWITCH:			        /* 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);								/* get the high and low values of the table */				low  = getDWord(code, n + 4);				high = getDWord(code, n + 8);								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 there only to keep gcc happy */				for (high = n + 4*(high - low + 1); n < (uint32)high; n += 4) {					newpc = pc + getDWord(code, n);					nextBlock = inWhichBlock(newpc, blocks, v->numBlocks);					if (!mergeBasicBlocks(v, curBlock, nextBlock)) {						return verifyErrorInVerifyMethod3b(v, curBlock, "error merging into a branch of a tableswitch instruction");					}				}				break;												/* the rest of the ways to end a block */			case RETURN:			case ARETURN:			case IRETURN:			case FRETURN:			case LRETURN:			case DRETURN:			case ATHROW:				curIndex++;				continue;							default:				for (n = pc + 1; n < codelen; n++) {					if (v->status[n] & IS_INSTRUCTION) break;				}				if (n == codelen) {					return verifyErrorInVerifyMethod3b(v, curBlock, "execution falls off the end of a code block");				}				else if (!mergeBasicBlocks(v, curBlock, blocks[curIndex+1])) {					return verifyErrorInVerifyMethod3b(v, curBlock, "error merging operand stacks");				}			}						for (curIndex = 0; curIndex < v->numBlocks; curIndex++) {			if (blocks[curIndex]->status & CHANGED)				break;		}	}			DBG(VERIFY3, dprintf("    Verifier Pass 3b: Complete\n"); );	gc_free(curBlock);	return(true);}/* * merges two operand stacks.  just to repeat what the JVML 2 spec says about this: *   Merge the state of the operand stack and local variable array at the end of the *   execution of the current instruction into each of the successor instructions.  In *   the special case of control transfer to an exception handler, the operand stack is *   set to contain a single object of the exception type indicated by the exception *   handler information. *     - if this if the first time the successor instruction has been visited, record *       that the operand stack and local variable values calculated in steps 2 and 3 *       are the state of the operand stack and local variable array prior to executing *       the successor instruction.  Set the "changed" bit for the successor instruction. *     - if the successor instruction has been seen before, merge the operand stack and *       local variable values calculated in steps 2 and 3 into the values already there. *       set the "changed" bit if there is any modification to the values. * *   to merge two operand stacks, the number of values on each stack must be identical. *   the types of values on the stacks must also be identical, except that differently *   typed reference values may appear at corresponding places on the two stacks.  in this *   case, the merged operand stack contains a reference to an instance of the first common *   superclass of the two types.  such a reference type always exists because the type Object *   is a superclass of all class and interface types.  if the operand stacks cannot be merged, *   verification of the method fails. * *   to merge two local variable array states, corresponding pairs of local variables are *   compared.  if the two types are not identical, then unless both contain reference values, *   the verification records that the local variable contains an unusable value.  if both of *   the pair of local variables contain reference values, the merged state contains a reference *   to an instance of the first common superclass of the two types. */staticboolmergeBasicBlocks(Verifier* v,		 BlockInfo* fromBlock,		 BlockInfo* toBlock){	uint32 n;			/* Ensure that no uninitiazed object instances are in the local variable array	 * or on the operand stack during a backwards branch	 */	if (toBlock->startAddr < fromBlock->startAddr) {		for (n = 0; n < v->method->localsz; n++) {			if (fromBlock->locals[n].tinfo & TINFO_UNINIT) {				return verifyError(v, "uninitialized object reference in a local variable during a backwards branch");			}		}		for (n = 0; n < fromBlock->stacksz; n++) {			if (fromBlock->opstack[n].tinfo & TINFO_UNINIT) {				return verifyError(v, "uninitialized object reference on operand stack during a backwards branch");			}		}	}		if (!(toBlock->status & VISITED)) {		DBG(VERIFY3, dprintf("          visiting block starting at %d for the first time\n",				     toBlock->startAddr); );				copyBlockState(v->method, fromBlock, toBlock);		toBlock->status |= CHANGED;		return(true);	}		DBG(VERIFY3,	    dprintf("%snot a first time merge\n", indent);	    dprintf("%s  from block (%d - %d):\n", indent, fromBlock->startAddr, fromBlock->lastAddr);	    printBlock(v->method, fromBlock, indent2);	    dprintf("%s  to block (%d - %d):\n", indent, toBlock->startAddr, toBlock->lastAddr);	    printBlock(v->method, toBlock, indent2);	    dprintf("\n");	    );			if (fromBlock->stacksz != toBlock->stacksz) {		return verifyError(v, "merging two operand stacks of unequal size");	}			/* merge the local variable arrays */	for (n = 0; n < v->method->localsz; n++) {		if (mergeTypes(v, &fromBlock->locals[n], &toBlock->locals[n])) {			toBlock->status |= CHANGED;		}	}		/* merge the operand stacks */	for (n = 0; n < fromBlock->stacksz; n++) {	        /* if we get unstable here, not really a big deal until we try to use it.		 * i mean, we could get an unstable value and then immediately pop it off the stack,		 * for instance.		 */		if (mergeTypes(v, &fromBlock->opstack[n], &toBlock->opstack[n])) {			toBlock->status |= CHANGED;		}	}			DBG(VERIFY3,	    dprintf("%s  result block:\n", indent);	    printBlock(v->method, toBlock, indent2);	    );			return(true);}

⌨️ 快捷键说明

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