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

📄 check_code.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
 *                opc_getfield, opc_putfield, and opc_invokevirtual.  * INTERFACE: *   parameters:  context_type *: context *                int: instruction number *                int: key *                opcode_type: opcode     *                 *   returns:     nothing  *=======================================================================*/static void set_protected(context_type *context, int inumber, int key, opcode_type opcode) {    fullinfo_type clazz_info = cp_index_to_class_fullinfo(context, key, TRUE);    if (isSuperClass(context, clazz_info)) {	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");            return;        }	if (opcode != opc_invokevirtual && opcode != opc_invokespecial) { 	    int n = cbFieldsCount(calledClass);	    fb = cbFields(calledClass);	    for (; --n >= 0; fb++) {		if (fb->ID == ID) {		    goto haveIt;		}	    }	    return;	} else { 	    struct methodblock *mb = cbMethods(calledClass);	    int n = cbMethodsCount(calledClass);	    for (; --n >= 0; mb++) {		if (mb->fb.ID == ID) {		    fb = &mb->fb;		    goto haveIt;		}	    }	    return;	}    haveIt:	if (IsProtected(fb->access)) {	    if (IsPrivate(fb->access) ||		    !IsSameClassPackage(calledClass, context->class))		context->instruction_data[inumber].protected = TRUE;	}    }}/*========================================================================= * FUNCTION:      isSuperClass * OVERVIEW:      Determines which of the classes are superclasses. *                Returns true if the given clazz_info corresponds to a  *                a superclass. * INTERFACE: *   parameters:  context_type* : context  *                fullinfo_type: clazz_info *                 *   returns:     boolean type *=======================================================================*/static bool_t isSuperClass(context_type *context, fullinfo_type clazz_info) {     fullinfo_type *fptr = context->superClasses;    if (fptr == NULL) { 	ClassClass *cb;	fullinfo_type *gptr;	int i;	/* Count the number of superclasses.  By counting ourselves, and	 * not counting Object, we get the same number.    */	for (i = 0, cb = context->class;	     cb != classJavaLangObject; 	     i++, cb = cbSuperclass(cb));	/* Can't go on context heap since it survives more than one method */	context->superClasses = fptr 	    = sysMalloc(sizeof(fullinfo_type)*(i + 1));	if (fptr == 0) {	    CCerror(context, "Out of memory");	}	for (gptr = fptr, cb = context->class; cb != classJavaLangObject; ) { 	    void **addr;	    cb = cbSuperclass(cb);	    *gptr++ = MAKE_CLASSNAME_INFO_WITH_COPY(context, cbName(cb), &addr); 	    *addr = cb;	}	*gptr = 0;    }     for (; *fptr != 0; fptr++) { 	if (*fptr == clazz_info)	    return TRUE;    }    return FALSE;}/*========================================================================= * FUNCTION:      initialize_exception_table * OVERVIEW:      Initializes the exception table. *                Looks through each item on the exception table and ensures *                that each of the fields refers to a legal instruction. * INTERFACE: *   parameters:  pointer to the context_type structure.  *                 *   returns:     nothing  *=======================================================================*/static voidinitialize_exception_table(context_type *context){    struct methodblock *mb = context->mb;    struct CatchFrame *exception_table = mb->exception_table;    struct handler_info_type *handler_info = context->handler_info;    short *code_data = context->code_data;    unsigned long code_length = mb->code_length;    int i;    for (i = mb->exception_table_length; 	     --i >= 0; exception_table++, handler_info++) {	unsigned long start = exception_table->start_pc;	unsigned long end = exception_table->end_pc;	unsigned long handler = exception_table->handler_pc;	unsigned catchType = exception_table->catchType;	stack_item_type *stack_item = NEW(stack_item_type, 1);	if (!(  start < end && start >= 0 	      && isLegalTarget(context, start) 	      && (end ==  code_length || isLegalTarget(context, end)))) {	    CCerror(context, "Illegal exception table range");	}	if (!((handler > 0) && isLegalTarget(context, handler))) {	    CCerror(context, "Illegal exception table handler");	}	handler_info->start = code_data[start];	/* end may point to one byte beyond the end of bytecodes. */	handler_info->end = (end == context->mb->code_length) ? 	    context->instruction_count : code_data[end];	handler_info->handler = code_data[handler];	handler_info->stack_info.stack = stack_item;	handler_info->stack_info.stack_size = 1;	stack_item->next = NULL;	if (catchType != 0) {	    union cp_item_type *cp = cbConstantPool(context->class);	    char *classname;	    verify_constant_pool_type(context, catchType, 1 << CONSTANT_Class);	    classname = GetClassConstantClassName(cp, catchType);	    stack_item->item = MAKE_CLASSNAME_INFO_WITH_COPY(context, classname, 0);	} else {	    stack_item->item = context->throwable_info;	}    }}/*========================================================================= * FUNCTION:      instruction_length * OVERVIEW:      Given a pointer to an instruction, return its length. *                Use the table opcode_length[] which is automatically built.  * INTERFACE: *   parameters:  pointer to the instruction *                 *   returns:     int type *=======================================================================*/static int instruction_length(unsigned char *iptr){    int instruction = *iptr;    switch (instruction) {        case opc_tableswitch: {	    long *lpc = (long *) UCALIGN(iptr + 1);	    int index = ntohl(lpc[2]) - ntohl(lpc[1]);	    if ((index < 0) || (index > 65535)) {		return -1;	/* illegal */	    } else { 		return (unsigned char *)(&lpc[index + 4]) - iptr;            }	}	    	case opc_lookupswitch: {	    long *lpc = (long *) UCALIGN(iptr + 1);	    int npairs = ntohl(lpc[1]);	    if (npairs < 0 || npairs >= 8192) 		return  -1;	    else 		return (unsigned char *)(&lpc[2 * (npairs + 1)]) - iptr;	}	case opc_wide: 	    switch(iptr[1]) {	        case opc_ret:	        case opc_iload: case opc_istore: 	        case opc_fload: case opc_fstore:	        case opc_aload: case opc_astore:	        case opc_lload: case opc_lstore:	        case opc_dload: case opc_dstore: 		    return 4;		case opc_iinc:		    return 6;		default: 		    return -1;	    }	default: {	    /* A length of 0 indicates an error. */	    int length = opcode_length[instruction];	    return (length <= 0) ? -1 : length;	}    }}/*========================================================================= * FUNCTION:      isLegalTarget * OVERVIEW:      Given the target of a branch, make sure that it is a legal *                target. Returns true if it is a legal target of a branch. * INTERFACE: *   parameters:  pointer to the context_type *                int: offset  *                 *   returns:     boolean type *=======================================================================*/static bool_t isLegalTarget(context_type *context, int offset){    struct methodblock *mb = context->mb;    int code_length = mb->code_length;    short *code_data = context->code_data;    return (offset >= 0 && offset < code_length && code_data[offset] >= 0);}/*========================================================================= * FUNCTION:      verify_constant_pool_type  * OVERVIEW:      Make sure that an element of the constant pool is really *                of the indicated type. * INTERFACE: *   parameters:  pointer to the context_type *                int: index *                unsigned: mask  *   returns:     nothing  *=======================================================================*/static voidverify_constant_pool_type(context_type *context, int index, unsigned mask){    ClassClass *cb = context->class;    union cp_item_type *constant_pool = cbConstantPool(cb);    int nconstants = cbConstantPoolCount(cb);    unsigned char *type_table =	constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;    unsigned type;    if ((index <= 0) || (index >= nconstants))	CCerror(context, "Illegal constant pool index");    type = CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, index);    if ((mask & (1 << type)) == 0) 	CCerror(context, "Illegal type in constant pool");}        /*========================================================================= * Functions for Data Flow Analysis  *=======================================================================*//*========================================================================= * FUNCTION:      initialize_dataflow  * OVERVIEW:      Initialize for data flow analysis. * INTERFACE: *   parameters:  pointer to the context_type *   returns:     nothing  *=======================================================================*/static voidinitialize_dataflow(context_type *context) {    instruction_data_type *idata = context->instruction_data;    struct methodblock *mb = context->mb;    fullinfo_type *reg_ptr;    fullinfo_type full_info;    char *p;    /* Initialize the function entry, since we know everything about it. */    idata[0].stack_info.stack_size = 0;    idata[0].stack_info.stack = NULL;    idata[0].register_info.register_count = mb->args_size;    idata[0].register_info.registers = NEW(fullinfo_type, mb->args_size);    idata[0].register_info.mask_count = 0;    idata[0].register_info.masks = NULL;    idata[0].and_flags = 0;	/* nothing needed */    idata[0].or_flags = FLAG_REACHED; /* instruction reached */    reg_ptr = idata[0].register_info.registers;    if ((mb->fb.access & ACC_STATIC) == 0) {	/* A non static method.  If this is an <init> method, the first	 * argument is an uninitialized object.  Otherwise it is an object of	 * the given class type.  java.lang.Object.<init> is special since	 * we don't call its superclass <init> method.	 */	if (strcmp(mb->fb.name, "<init>") == 0 	        && context->currentclass_info != context->object_info) {	    *reg_ptr++ = MAKE_FULLINFO(ITEM_InitObject, 0, 0);	    idata[0].or_flags |= FLAG_NEED_CONSTRUCTOR;	} else {	    *reg_ptr++ = context->currentclass_info;	}    }    /* Fill in each of the arguments into the registers. */    for (p = mb->fb.signature + 1; *p != SIGNATURE_ENDFUNC; ) {	char fieldchar = signature_to_fieldtype(context, &p, &full_info);        if (no_floating_point && (fieldchar == 'D' || fieldchar == 'F')) {             CCerror(context, "Floating point arguments not allowed");        }	switch (fieldchar) {	    case 'D': case 'L': 	        *reg_ptr++ = full_info;	        *reg_ptr++ = full_info + 1;		break;	    default:	        *reg_ptr++ = full_info;		break;	}    }    p++;			/* skip over right parenthesis */    if (*p == 'V') {	context->return_type = MAKE_FULLINFO(ITEM_Void, 0, 0);    } else {	signature_to_fieldtype(context, &p, &full_info);	context->return_type = full_info;    }    /* Indicate that we need to look at the first instruction. */    idata[0].changed = TRUE;}	/*========================================================================= * FUNCTION:      run_dataflow  * OVERVIEW:      Execute the data flow analysis as long as there are things *                to change. * INTERFACE: *   parameters:  pointer to the context_type *   returns:     nothing  *=======================================================================*/static voidrun_dataflow(context_type *context) {    struct methodblock *mb = context->mb;    int max_stack_size = mb->maxstack;    instruction_data_type *idata = context->instruction_data;    int icount = context->instruction_count;    bool_t work_to_do = TRUE;    int inumber;    /* Run through the loop, until there is nothing left to do. */    while (work_to_do) {	work_to_do = FALSE;	for (inumber = 0; inumber < icount; inumber++) {	    instruction_data_type *this_idata = &idata[inumber];	    if (this_idata->changed) {		register_info_type new_register_info;		stack_info_type new_stack_info;		flag_type new_and_flags, new_or_flags;				this_idata->changed = FALSE;

⌨️ 快捷键说明

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