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

📄 check_code.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
		work_to_do = TRUE;#ifdef DEBUG_VERIFIER		if (verify_verbose) {		    int opcode = this_idata->opcode;		    char *opname = (opcode == opc_invokeinit) ? 				    "invokeinit" : opnames[opcode];		    jio_fprintf(stdout, "Instruction %d: ", inumber);		    print_stack(context, &this_idata->stack_info);		    print_registers(context, &this_idata->register_info);		    print_flags(context, 				this_idata->and_flags, this_idata->or_flags);		    jio_fprintf(stdout, "  %s(%d)", opname, this_idata->operand.i);		    fflush(stdout);		}#endif		/* Make sure the registers and flags are appropriate */		check_register_values(context, inumber);		check_flags(context, inumber);		/* Make sure the stack can deal with this instruction */		pop_stack(context, inumber, &new_stack_info);		/* Update the registers  and flags */		update_registers(context, inumber, &new_register_info);		update_flags(context, inumber, &new_and_flags, &new_or_flags);		/* Update the stack. */		push_stack(context, inumber, &new_stack_info);		if (new_stack_info.stack_size > max_stack_size) 		    CCerror(context, "Stack size too large");#ifdef DEBUG_VERIFIER		if (verify_verbose) {		    jio_fprintf(stdout, "  ");		    print_stack(context, &new_stack_info);		    print_registers(context, &new_register_info);		    print_flags(context, new_and_flags, new_or_flags);		    fflush(stdout);		}#endif		/* Add the new stack and register information to any		 * instructions that can follow this instruction.     */		merge_into_successors(context, inumber, 				      &new_register_info, &new_stack_info,				      new_and_flags, new_or_flags);	    }	}    }}/*========================================================================= * FUNCTION:      check_register_values  * OVERVIEW:      Make sure that the registers contain a legitimate value *                for the given instruction.  * INTERFACE: *   parameters:  pointer to the context_type *                int inumber *   returns:     nothing  *=======================================================================*/static voidcheck_register_values(context_type *context, int inumber){    instruction_data_type *idata = context->instruction_data;    instruction_data_type *this_idata = &idata[inumber];    opcode_type opcode = this_idata->opcode;    int operand = this_idata->operand.i;    int register_count = this_idata->register_info.register_count;    fullinfo_type *registers = this_idata->register_info.registers;    bool_t double_word = FALSE;	/* default value */    int type;        switch (opcode) {        default:	    return;        case opc_iload: case opc_iinc:	    type = ITEM_Integer; break;        case opc_fload:	    type = ITEM_Float; break;        case opc_aload:	    type = ITEM_Object; break;        case opc_ret:	    type = ITEM_ReturnAddress; break;        case opc_lload:		    type = ITEM_Long; double_word = TRUE; break;        case opc_dload:	    type = ITEM_Double; double_word = TRUE; break;    }    if (!double_word) {	fullinfo_type reg = registers[operand];	/* Make sure we don't have an illegal register or one with wrong type */	if (operand >= register_count) {	    CCerror(context, 		    "Accessing value from uninitialized register %d", operand);	} else if (WITH_ZERO_EXTRA_INFO(reg) == MAKE_FULLINFO(type, 0, 0)) {	    /* the register is obviously of the given type */	    return;	} else if (GET_INDIRECTION(reg) > 0 && type == ITEM_Object) {	    /* address type stuff be used on all arrays */	    return;	} else if (GET_ITEM_TYPE(reg) == ITEM_ReturnAddress) { 	    CCerror(context, "Cannot load return address from register %d", 		              operand);	    /* alternatively 	              (GET_ITEM_TYPE(reg) == ITEM_ReturnAddress)                   && (opcode == opc_iload) 		   && (type == ITEM_Object || type == ITEM_Integer)	       but this never occurs	    */	} else if (reg == ITEM_InitObject && type == ITEM_Object) {	    return;	} else if (WITH_ZERO_EXTRA_INFO(reg) == 		        MAKE_FULLINFO(ITEM_NewObject, 0, 0) && 		   type == ITEM_Object) {	    return;        } else {	    CCerror(context, "Register %d contains wrong type", operand);	}    } else {	/* Make sure we don't have an illegal register or one with wrong type */	if ((operand + 1) >= register_count) {	    CCerror(context, 		    "Accessing value from uninitialized register pair %d/%d", 		    operand, operand+1);	} else {	    if ((registers[operand] == MAKE_FULLINFO(type, 0, 0)) &&		(registers[operand + 1] == MAKE_FULLINFO(type + 1, 0, 0))) {		return;	    } else {		CCerror(context, "Register pair %d/%d contains wrong type", 		        operand, operand+1);	    }	}    } }/*========================================================================= * FUNCTION:      check_flags  * OVERVIEW:      Make sure that the flags contain legitimate values for this *                instruction.  * INTERFACE: *   parameters:  pointer to the context_type *                int: instruction number *   returns:     nothing  *=======================================================================*/static voidcheck_flags(context_type *context, int inumber){    instruction_data_type *idata = context->instruction_data;    instruction_data_type *this_idata = &idata[inumber];    opcode_type opcode = this_idata->opcode;    if (opcode == opc_return) {	    /* We need a constructor, but we aren't guaranteed it's called */	    if ((this_idata->or_flags & FLAG_NEED_CONSTRUCTOR) && 		   !(this_idata->and_flags & FLAG_CONSTRUCTED))		CCerror(context, "Constructor must call super() or this()");	    /* fall through */    } else if ((opcode == opc_ireturn) || (opcode == opc_lreturn) ||                (opcode == opc_freturn) || (opcode == opc_dreturn) ||               (opcode == opc_areturn)) { 	    if (this_idata->or_flags & FLAG_NO_RETURN)		/* This method cannot exit normally */		CCerror(context, "Cannot return normally");    }}/*========================================================================= * FUNCTION:      pop_stack  * OVERVIEW:      Make sure that the top of the stack contains reasonable  *                values for the given instruction. The post-pop values of *                the stack and its size are returned in *new_stack_info.  * INTERFACE: *   parameters:  pointer to the context_type *                int: instruction number *                stack_info_type: *new_stack_info *   returns:     nothing  *=======================================================================*/static void pop_stack(context_type *context, int inumber, stack_info_type *new_stack_info){    instruction_data_type *idata = context->instruction_data;    instruction_data_type *this_idata = &idata[inumber];    opcode_type opcode = this_idata->opcode;    stack_item_type *stack = this_idata->stack_info.stack;    int stack_size = this_idata->stack_info.stack_size;    char *stack_operands, *p;    char buffer[257];		/* for holding manufactured argument lists */    fullinfo_type stack_extra_info_buffer[256]; /* save info popped off stack */    fullinfo_type *stack_extra_info = &stack_extra_info_buffer[256];    fullinfo_type full_info, put_full_info;        switch(opcode) {        default:	    /* For most instructions, we just use a built-in table */	    stack_operands = opcode_in_out[opcode][0];	    break;        case opc_putstatic: case opc_putfield: {	    /* The top thing on the stack depends on the signature of	     * the object.                         */	    int operand = this_idata->operand.i;	    char *signature = cp_index_to_signature(context, operand);	    char *ip = buffer;#ifdef DEBUG_VERIFIER	    if (verify_verbose) {		print_formatted_fieldname(context, operand);	    }#endif	    if (opcode == opc_putfield)		*ip++ = 'A';	/* object for putfield */	    *ip++ = signature_to_fieldtype(context, &signature, &put_full_info);	    *ip = '\0';	    stack_operands = buffer;	    break;	}	case opc_invokevirtual: case opc_invokespecial:                case opc_invokeinit:	/* invokespecial call to <init> */	case opc_invokestatic: case opc_invokeinterface: {	    /* The top stuff on the stack depends on the method signature */	    int operand = this_idata->operand.i;	    char *signature = cp_index_to_signature(context, operand);	    char *ip = buffer;	    char *p;#ifdef DEBUG_VERIFIER	    if (verify_verbose) {		print_formatted_fieldname(context, operand);	    }#endif	    if (opcode != opc_invokestatic) 		/* First, push the object */		*ip++ = (opcode == opc_invokeinit ? '@' : 'A');	    for (p = signature + 1; *p != SIGNATURE_ENDFUNC; ) {		*ip++ = signature_to_fieldtype(context, &p, &full_info);		if (ip >= buffer + sizeof(buffer) - 1)		    CCerror(context, "Signature %s has too many arguments", 			    signature);	    }	    *ip = 0;	    stack_operands = buffer;	    break;	}	case opc_multianewarray: {	    /* Count can't be larger than 255. So can't overflow buffer */	    int count = this_idata->operand2.i;	/* number of ints on stack */	    memset(buffer, 'I', count);	    buffer[count] = '\0';	    stack_operands = buffer;	    break;	}    } /* of switch */    /* Run through the list of operands >>backwards<< */    for (   p = stack_operands + strlen(stack_operands);	    p > stack_operands; 	    stack = stack->next) {	int type = *--p;	fullinfo_type top_type = stack ? stack->item : 0;	int size = (type == 'D' || type == 'L') ? 2 : 1;	*--stack_extra_info = top_type;	if (stack == NULL) 	    CCerror(context, "Unable to pop operand off an empty stack");	switch (type) {	    case 'I': 	        if (top_type != MAKE_FULLINFO(ITEM_Integer, 0, 0))		    CCerror(context, "Expecting to find integer on stack");		break;			    case 'F': 		if (top_type != MAKE_FULLINFO(ITEM_Float, 0, 0))		    CCerror(context, "Expecting to find float on stack");		break;			    case 'A':		/* object or array */		if (   (GET_ITEM_TYPE(top_type) != ITEM_Object) 		    && (GET_INDIRECTION(top_type) == 0)) { 		    /* The thing isn't an object or an array.  Let's see if it's		     * one of the special cases  */		    if (  (WITH_ZERO_EXTRA_INFO(top_type) == 			        MAKE_FULLINFO(ITEM_ReturnAddress, 0, 0))			&& (opcode == opc_astore)) 			break;		    if (   (GET_ITEM_TYPE(top_type) == ITEM_NewObject 			    || (GET_ITEM_TYPE(top_type) == ITEM_InitObject))			&& ((opcode == opc_astore) || (opcode == opc_aload)))			break;                    /* The 2nd edition VM of the specification allows field                     * initializations before the superclass initializer,                     * if the field is defined within the current class.                     */                     if (   (GET_ITEM_TYPE(top_type) == ITEM_InitObject)                         && (opcode == opc_putfield)) {                                                int num_fields;                        int key = this_idata->operand.i;                        fullinfo_type clazz_info = cp_index_to_class_fullinfo(                                                            context, key, TRUE);                        char *name = cp_index_to_fieldname(context, key);                        char *signature = cp_index_to_signature(context, key);                        unsigned ID = NameAndTypeToHash(name, signature);                        ClassClass *calledClass =                             object_fullinfo_to_classclass(context, clazz_info);                        struct fieldblock *fb;                        if (ID == 0) {                              /* NameAndTypeToHash returns 0                              * if out of memory                              */                            CCerror(context, "Out of memory");                            break;                        }                        num_fields = cbFieldsCount(calledClass);                        fb = cbFields(calledClass);                        for (; --num_fields >= 0; fb++) {                            if (fb->ID == ID) {                                break;                            }                        }                         if (num_fields != -1) {                            top_type = context->currentclass_info;                            *stack_extra_info = top_type;                            break;                        }                    }		    CCerror(context, "Expecting to find object/array on stack");		}		break;	    case '@': {		/* unitialized object, for call to <init> */		int item_type = GET_ITEM_TYPE(top_type);		if (item_type != ITEM_NewObject && item_type != ITEM_InitObject)		    CCerror(context, 			    "Expecting to find unitialized object on stack");		break;	    }	    case 'O':		/* object, not array */		if (WITH_ZERO_EXTRA_INFO(top_type) != 		       MAKE_FULLINFO(ITEM_Object, 0, 0))		    CCerror(context, "Expecting to find object on stack");		break;	    case 'a':		/* integer, object, or array */		if (      (top_type != MAKE_FULLINFO(ITEM_Integer, 0, 0)) 		       && (GET_ITEM_TYPE(top_type) != ITEM_Object)		       && (GET_INDIRECTION(top_type) == 0))		    CCerror(context, 			    "Expecting to find object, array, or int on stack");		break;	    case 'D':		/* double */		if (top_type != MAKE_FULLINFO(ITEM_Double, 0, 0))		    CCerror(context, "Expecting to find double on stack");		break;	    case 

⌨️ 快捷键说明

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