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

📄 check_code.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
verify_opcode_operands(context_type *context, int inumber, int offset){    instruction_data_type *idata = context->instruction_data;    instruction_data_type *this_idata = &idata[inumber];    short *code_data = context->code_data;    struct methodblock *mb = context->mb;    unsigned char *code = context->code;    opcode_type opcode = this_idata->opcode;    int var;         this_idata->operand.i = 0;    this_idata->operand2.i = 0;    switch (opcode) {    case opc_jsr:	/* instruction of ret statement */	this_idata->operand2.i = UNKNOWN_RET_INSTRUCTION;	/* FALLTHROUGH */    case opc_ifeq: case opc_ifne: case opc_iflt:     case opc_ifge: case opc_ifgt: case opc_ifle:    case opc_ifnull: case opc_ifnonnull:    case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt:     case opc_if_icmpge: case opc_if_icmpgt: case opc_if_icmple:    case opc_if_acmpeq: case opc_if_acmpne:       case opc_goto: {	/* Set the ->operand to be the instruction number of the target. */	int jump = (((signed char)(code[offset+1])) << 8) + code[offset+2];	int target = offset + jump;	if (!isLegalTarget(context, target))	    CCerror(context, "Illegal target of jump or branch");	this_idata->operand.i = code_data[target];	break;    }	    case opc_jsr_w:	/* instruction of ret statement */	this_idata->operand2.i = UNKNOWN_RET_INSTRUCTION;	/* FALLTHROUGH */    case opc_goto_w: {	/* Set the ->operand to be the instruction number of the target. */	int jump = (((signed char)(code[offset+1])) << 24) + 	             (code[offset+2] << 16) + (code[offset+3] << 8) + 	             (code[offset + 4]);	int target = offset + jump;	if (!isLegalTarget(context, target))	    CCerror(context, "Illegal target of jump or branch");	this_idata->operand.i = code_data[target];	break;    }    case opc_tableswitch:     case opc_lookupswitch: {	/* Set the ->operand to be a table of possible instruction targets. */	long *lpc = (long *) UCALIGN(code + offset + 1);	long *lptr;	int *saved_operand;	int keys;	int k, delta;	if (opcode == opc_tableswitch) {	    keys = ntohl(lpc[2]) -  ntohl(lpc[1]) + 1;	    delta = 1;	} else { 	    keys = ntohl(lpc[1]); /* number of pairs */	    delta = 2;	    /* Make sure that the tableswitch items are sorted */	    for (k = keys - 1, lptr = &lpc[2]; --k >= 0; lptr += 2) {		long this_key = ntohl(lptr[0]);	/* NB: ntohl may be unsigned */		long next_key = ntohl(lptr[2]);		if (this_key >= next_key) { 		    CCerror(context, "Unsorted lookup switch");		}	    }	}        /* This code has been changed for inlining.   We know have the keys         * in the same order that they occur in the code, with the default         * key being the first one.         */	saved_operand = NEW(int, keys + 2);	if (!isLegalTarget(context, offset + ntohl(lpc[0]))) 	    CCerror(context, "Illegal default target in switch");        saved_operand[0] = keys + 1; /* number of successors */	saved_operand[1] = code_data[offset + ntohl(lpc[0])]; /* default */	for (k = 0, lptr = &lpc[3]; k < keys; lptr += delta, k++) {	    int target = offset + ntohl(lptr[0]);	    if (!isLegalTarget(context, target))		CCerror(context, "Illegal branch in opc_tableswitch");	    saved_operand[k + 2] = code_data[target];	}	this_idata->operand.ip = saved_operand;	break;    }	    case opc_ldc: {   	/* Make sure the constant pool item is the right type. */	int key = code[offset + 1];	int types = (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) |	                    (1 << CONSTANT_String);	this_idata->operand.i = key;	verify_constant_pool_type(context, key, types);	break;    }	      case opc_ldc_w: {   	/* Make sure the constant pool item is the right type. */	int key = (code[offset + 1] << 8) + code[offset + 2];	int types = (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) |	    (1 << CONSTANT_String);	this_idata->operand.i = key;	verify_constant_pool_type(context, key, types);	break;    }	      case opc_ldc2_w: { 	/* Make sure the constant pool item is the right type. */	int key = (code[offset + 1] << 8) + code[offset + 2];	int types = (1 << CONSTANT_Double) | (1 << CONSTANT_Long);	this_idata->operand.i = key;	verify_constant_pool_type(context, key, types);	break;    }    case opc_getfield: case opc_putfield:    case opc_getstatic: case opc_putstatic: {	/* Make sure the constant pool item is the right type. */	int key = (code[offset + 1] << 8) + code[offset + 2];	this_idata->operand.i = key;	verify_constant_pool_type(context, key, 1 << CONSTANT_Fieldref);		if (opcode == opc_getfield || opcode == opc_putfield) 	    set_protected(context, inumber, key, opcode);	break;    }    case opc_invokevirtual:    case opc_invokespecial:     case opc_invokestatic:    case opc_invokeinterface: {	/* Make sure the constant pool item is the right type. */	int key = (code[offset + 1] << 8) + code[offset + 2];	char *methodname;	fullinfo_type clazz_info;	int kind = (opcode == opc_invokeinterface 	                    ? 1 << CONSTANT_InterfaceMethodref	                    : 1 << CONSTANT_Methodref);	/* Make sure the constant pool item is the right type. */	verify_constant_pool_type(context, key, kind);	methodname = cp_index_to_fieldname(context, key);	clazz_info = cp_index_to_class_fullinfo(context, key, TRUE);	this_idata->operand.i = key;	this_idata->operand2.fi = clazz_info;	if (strcmp(methodname, "<init>") == 0) {	    if (opcode != opc_invokespecial)		CCerror(context, 			"Must call initializers using invokespecial");	    this_idata->opcode = opc_invokeinit;	} else {	    if (methodname[0] == '<') 		CCerror(context, "Illegal call to internal method");	    if (opcode == opc_invokespecial 		   && clazz_info != context->currentclass_info  		   && clazz_info != context->superclass_info) {		ClassClass *cb = context->class;		for (; ; cb = cbSuperclass(cb)) { 		    if (clazz_info == MAKE_CLASSNAME_INFO_WITH_COPY(context, cbName(cb), 0))			break;		    /* The optimizer make cause this to happen on local code */		    if (cbSuperclass(cb) == 0) {			/* optimizer make cause this to happen on local code */			if (cbLoader(cb) != 0) 			    CCerror(context, 				    "Illegal use of nonvirtual function call");			break;		    }		}	    }	}	if (opcode == opc_invokeinterface) { 	    char *signature = cp_index_to_signature(context, key);	    unsigned int args1 = Signature2ArgsSize(signature) + 1;	    unsigned int args2 = code[offset + 3];	    if (args1 != args2) {		CCerror(context, 			"Inconsistent args_size for opc_invokeinterface");		    }             if (code[offset + 4] != 0) {                CCerror(context,                        "Fourth operand byte of invokeinterface must be zero");            }	} else if (opcode == opc_invokevirtual 		      || opcode == opc_invokespecial) 	    set_protected(context, inumber, key, opcode);	break;    }	    case opc_instanceof:     case opc_checkcast:     case opc_new:    case opc_anewarray:     case opc_multianewarray: {	/* Make sure the constant pool item is a class */	int key = (code[offset + 1] << 8) + code[offset + 2];	fullinfo_type target;	verify_constant_pool_type(context, key, 1 << CONSTANT_Class);	target = cp_index_to_class_fullinfo(context, key, FALSE);	if (GET_ITEM_TYPE(target) == ITEM_Bogus) 	    CCerror(context, "Illegal type");	switch(opcode) {	case opc_anewarray:	    if ((GET_INDIRECTION(target)) >= MAX_ARRAY_DIMENSIONS)		CCerror(context, "Array with too many dimensions");	    this_idata->operand.fi = MAKE_FULLINFO(GET_ITEM_TYPE(target),						   GET_INDIRECTION(target) + 1,						   GET_EXTRA_INFO(target));	    break;	case opc_new:	    if (WITH_ZERO_EXTRA_INFO(target) !=		             MAKE_FULLINFO(ITEM_Object, 0, 0))		CCerror(context, "Illegal creation of multi-dimensional array");	    /* operand gets set to the "unitialized object".  operand2 gets	     * set to what the value will be after it's initialized. */	    this_idata->operand.fi = MAKE_FULLINFO(ITEM_NewObject, 0, inumber);	    this_idata->operand2.fi = target;	    break;	case opc_multianewarray:	    this_idata->operand.fi = target;	    this_idata->operand2.i = code[offset + 3];	    if (    (this_idata->operand2.i > (int)GET_INDIRECTION(target))		 || (this_idata->operand2.i == 0))		CCerror(context, "Illegal dimension argument");	    break;	default:	    this_idata->operand.fi = target;	}	break;    }	    case opc_newarray: {	/* Cache the result of the opc_newarray into the operand slot */	fullinfo_type full_info;	switch (code[offset + 1]) {	    case T_INT:    	        full_info = MAKE_FULLINFO(ITEM_Integer, 1, 0); break;	    case T_LONG:   		full_info = MAKE_FULLINFO(ITEM_Long, 1, 0); break;	    case T_FLOAT:                  full_info = MAKE_FULLINFO(ITEM_Float, 1, 0); break;	    case T_DOUBLE: 		full_info = MAKE_FULLINFO(ITEM_Double, 1, 0); break;	    case T_BYTE:		full_info = MAKE_FULLINFO(ITEM_Byte, 1, 0); break;	    case T_BOOLEAN:		full_info = MAKE_FULLINFO(ITEM_Boolean, 1, 0); break;	    case T_CHAR:   		full_info = MAKE_FULLINFO(ITEM_Char, 1, 0); break;	    case T_SHORT:  		full_info = MAKE_FULLINFO(ITEM_Short, 1, 0); break;	    default:                full_info = 0;  /* make GCC happy */		CCerror(context, "Bad type passed to opc_newarray");	}	this_idata->operand.fi = full_info;	break;    }	      /* Fudge iload_x, aload_x, etc to look like their generic cousin. */    case opc_iload_0: case opc_iload_1: case opc_iload_2: case opc_iload_3:	this_idata->opcode = opc_iload;	var = opcode - opc_iload_0;	goto check_local_variable;	      case opc_fload_0: case opc_fload_1: case opc_fload_2: case opc_fload_3:	this_idata->opcode = opc_fload;	var = opcode - opc_fload_0;	goto check_local_variable;    case opc_aload_0: case opc_aload_1: case opc_aload_2: case opc_aload_3:	this_idata->opcode = opc_aload;	var = opcode - opc_aload_0;	goto check_local_variable;    case opc_lload_0: case opc_lload_1: case opc_lload_2: case opc_lload_3:	this_idata->opcode = opc_lload;	var = opcode - opc_lload_0;	goto check_local_variable2;    case opc_dload_0: case opc_dload_1: case opc_dload_2: case opc_dload_3:	this_idata->opcode = opc_dload;	var = opcode - opc_dload_0;	goto check_local_variable2;    case opc_istore_0: case opc_istore_1: case opc_istore_2: case opc_istore_3:	this_idata->opcode = opc_istore;	var = opcode - opc_istore_0;	goto check_local_variable;	    case opc_fstore_0: case opc_fstore_1: case opc_fstore_2: case opc_fstore_3:	this_idata->opcode = opc_fstore;	var = opcode - opc_fstore_0;	goto check_local_variable;    case opc_astore_0: case opc_astore_1: case opc_astore_2: case opc_astore_3:	this_idata->opcode = opc_astore;	var = opcode - opc_astore_0;	goto check_local_variable;    case opc_lstore_0: case opc_lstore_1: case opc_lstore_2: case opc_lstore_3:	this_idata->opcode = opc_lstore;	var = opcode - opc_lstore_0;	goto check_local_variable2;    case opc_dstore_0: case opc_dstore_1: case opc_dstore_2: case opc_dstore_3:	this_idata->opcode = opc_dstore;	var = opcode - opc_dstore_0;	goto check_local_variable2;    case opc_wide: 	this_idata->opcode = code[offset + 1];	var = (code[offset + 2] << 8) + code[offset + 3];	switch(this_idata->opcode) {	    case opc_lload:  case opc_dload: 	    case opc_lstore: case opc_dstore:	        goto check_local_variable2;	    default:	        goto check_local_variable;	}    case opc_iinc:		/* the increment amount doesn't matter */    case opc_ret:     case opc_aload: case opc_iload: case opc_fload:    case opc_astore: case opc_istore: case opc_fstore:	var = code[offset + 1];    check_local_variable:	/* Make sure that the variable number isn't illegal. */	this_idata->operand.i = var;	if (var >= (int)mb->nlocals) 	    CCerror(context, "Illegal local variable number");	break;	        case opc_lload: case opc_dload: case opc_lstore: case opc_dstore: 	var = code[offset + 1];    check_local_variable2:	/* Make sure that the variable number isn't illegal. */	this_idata->operand.i = var;	if ((var + 1) >= (int)mb->nlocals)	    CCerror(context, "Illegal local variable number");	break;	    default:	if (opcode >= opc_breakpoint) 	    CCerror(context, "Quick instructions shouldn't appear yet.");	break;    } /* of switch */}/*========================================================================= * FUNCTION:      set_protected * OVERVIEW:      Checks the field access to see if the instruction is  *                protected, is private and is in the same class package,  *                then the protected bit for the given instruction is set. *                Invoked by verify_operands_opcodes() to set protected bit *                for instructions of the following opcode types: 

⌨️ 快捷键说明

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