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

📄 check_code.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (extra == 0) {                panic("unexpected");            } else {                char *name = ID2Str_Local(context, context->classHash,                                          extra, 0);                strcpy(buf, name);                if (indirection) strcat(buf, ";");            }            return;         }        default:             panic("bad type");    }    *buf = '\0';}/*========================================================================= * FUNCTION:      check_class_constant  * OVERVIEW:      Checks and returns the index corresponding to the given *                UTF8 constant entry within the constant pool. *                Returns -1 if none was found. *                Invoked by get_type_code().  * INTERFACE: *   parameters:  pointer to the ClassClass structure.  *                char *: utf8 *                 *   returns:     long type *=======================================================================*/long check_class_constant(ClassClass *cb, char *utf8){    int i;    cp_item_type *constant_pool = cbConstantPool(cb);    unsigned char *type_table =         constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type;    for (i = 0; i < cbConstantPoolCount(cb); i++) {	if (type_table[i] == (CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED) &&	    strcmp(utf8, cbName(constant_pool[i].clazz)) == 0) {	    return i;	}	if (type_table[i] == CONSTANT_Class &&	    strcmp(utf8, constant_pool[constant_pool[i].i].cp) == 0) {	    return i;	}    }    return -1;}/*========================================================================= * FUNCTION:      get_type_code * OVERVIEW:      Retrieves the type code entry given the item type.  *                Invoked by verify_method() to retrieve the type code  *                for the stack map entries.  * INTERFACE: *   parameters:  pointer to the context_type structure.  *                fullinfo_type: type *                 *   returns:     struct map_entry  *=======================================================================*/struct map_entry get_type_code(context_type *context, fullinfo_type type){    struct map_entry result = {0,0};    switch (type) {        case ITEM_Double_2:        case ITEM_Long_2:        case ITEM_Bogus:	    result.type = CF_ITEM_Bogus;	    return result;	case ITEM_Integer:	    result.type = CF_ITEM_Integer;	    return result;	case ITEM_Float:	    result.type = CF_ITEM_Float;	    return result;	case ITEM_Double:	    result.type = CF_ITEM_Double;	    return result;	case ITEM_Long:	    result.type = CF_ITEM_Long;	    return result;	case ITEM_InitObject:	    result.type = CF_ITEM_InitObject;	    return result;	default:	if (GET_ITEM_TYPE(type) == ITEM_NewObject) {	    int inum = GET_EXTRA_INFO(type);	    result.type = CF_ITEM_NewObject;	    result.info = context->instruction_data[inum].offset;	    return result;	} else if (GET_ITEM_TYPE(type) == ITEM_Object && GET_EXTRA_INFO(type) == 0) {	    result.type = CF_ITEM_Null;	    return result;        } else if (GET_ITEM_TYPE(type) == ITEM_Object || GET_INDIRECTION(type) > 0) {	    char type_name[1024];	    int i;    	    result.type = CF_ITEM_Object;	    get_type_name(context, type, type_name);	    i = check_class_constant(context->class, type_name);	    if (i >= 0) {		result.info = i;		return result;	    }	    for (i = 0; i < unhand(context->class)->n_new_class_entries; i++) {		if (strcmp(type_name, unhand(context->class)->new_class_entries[i]) == 0) {		    result.info = ~i;		    return result;		}	    }	    { 		int entries = unhand(context->class)->n_new_class_entries;		unhand(context->class)->new_class_entries[entries] = strdup(type_name);		result.info = ~entries;		unhand(context->class)->n_new_class_entries = entries + 1;		return result;	    }	} else {	    panic("bad type code");		return result; /* not reached */	}    }}/*========================================================================= * FUNCTION:      verify_method * OVERVIEW:      Verifies the code for one method within a class file. *                Invoked by verify_class_codes().  * INTERFACE: *   parameters:  pointer to the context_type structure.  *                struct methodblock*: mb *                 *   returns:     nothing  *=======================================================================*/static voidverify_method(context_type *context, struct methodblock *mb){    int access_bits = mb->fb.access;    unsigned char *code;    int code_length;    short *code_data;    instruction_data_type *idata = 0;    int instruction_count;    int i, offset, inumber;    int exception_count;    int n_stack_maps, dead_count, jsr_count; again:    code = mb->code;    code_length = mb->code_length;    /* CCerror can give method-specific info once this is set */    context->mb = mb;    CCreinit(context);		/* initial heap */    code_data = NEW(short, code_length);#ifdef DEBUG_VERIFIER    if (verify_verbose) {	jio_fprintf(stdout, "Looking at %s.%s%s 0x%x\n", 	       cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature, 	       (long)mb);    }#endif    if (((access_bits & ACC_PUBLIC) != 0) && 	((access_bits & (ACC_PRIVATE | ACC_PROTECTED)) != 0)) {	CCerror(context, "Inconsistent access bits.");    }     if ((access_bits & (ACC_ABSTRACT | ACC_NATIVE)) != 0) { 	/* not much to do for abstract or native methods */        return;    }     if (code_length >= 65535) {	CCerror(context, "Code of a method longer than 65535 bytes");    }    /* Run through the code.  Mark the start of each instruction, and give     * the instruction a number */    for (i = 0, offset = 0; offset < code_length; i++) {	int length = instruction_length(&code[offset]);	int next_offset = offset + length;	if (length <= 0) 	    CCerror(context, "Illegal instruction found at offset %d", offset);	if (next_offset > code_length) 	    CCerror(context, "Code stops in the middle of instruction "		    " starting at offset %d", offset);	code_data[offset] = i;	while (++offset < next_offset)	    code_data[offset] = -1; /* illegal location */    }    instruction_count = i;	/* number of instructions in code */        /* Allocate a structure to hold info about each instruction. */    idata = NEW(instruction_data_type, instruction_count);    /* Initialize the heap, and other info in the context structure. */    context->code = code;    context->instruction_data = idata;    context->code_data = code_data;    context->instruction_count = instruction_count;    context->handler_info = NEW(struct handler_info_type, 				mb->exception_table_length);    context->bitmask_size = (mb->nlocals + (BITS_PER_INT - 1))/BITS_PER_INT;        if (instruction_count == 0) 	CCerror(context, "Empty code");	    for (inumber = 0, offset = 0; offset < code_length; inumber++) {	int length = instruction_length(&code[offset]);	instruction_data_type *this_idata = &idata[inumber];	this_idata->opcode = code[offset];	this_idata->offset = offset;	this_idata->length = length;	this_idata->stack_info.stack = NULL;	this_idata->stack_info.stack_size  = UNKNOWN_STACK_SIZE;	this_idata->register_info.register_count = UNKNOWN_REGISTER_COUNT;	this_idata->changed = FALSE;  /* no need to look at it yet. */	this_idata->protected = FALSE;  /* no need to look at it yet. */        /* Added for inlinejsr */ 	   this_idata->is_target = FALSE;  /* no need to look at it yet. */	this_idata->and_flags = (flag_type) -1;	/* "bottom" and value */	this_idata->or_flags = 0; /* "bottom" or value*/	/* This also sets up this_data->operand.  It also makes the 	 * xload_x and xstore_x instructions look like the generic form. */	verify_opcode_operands(context, inumber, offset);	offset += length;    }            /* make sure exception table is reasonable. */    initialize_exception_table(context);    /* Set up first instruction, and start of exception handlers. */    initialize_dataflow(context);    /* Run data flow analysis on the instructions. */    context->redoJsr = FALSE;    run_dataflow(context);    for (inumber = 0; inumber < instruction_count; inumber++) {        instruction_data_type *this_idata = &idata[inumber];        if (  (this_idata->or_flags & FLAG_REACHED) &&               ((this_idata->opcode == opc_jsr) ||                (this_idata->opcode == opc_jsr_w)) &&               (this_idata->operand2.i == UNKNOWN_RET_INSTRUCTION)) {             this_idata->changed = TRUE;            context->redoJsr = TRUE;        }    }    if (context->redoJsr) {         run_dataflow(context);    }    /* verify checked exceptions, if any */    if ((exception_count = mb->nexceptions) > 0) {	unsigned short *exceptions = mb->exceptions;	for (i = 0; i < (int)exception_count; i++) {	    /* Make sure the constant pool item is CONSTANT_Class */	    verify_constant_pool_type(context, (int)exceptions[i],		1 << CONSTANT_Class);	}    }        dead_count = jsr_count = 0;    for (inumber = 0; inumber < instruction_count; inumber++) {        instruction_data_type *this_idata = &idata[inumber];        if ((this_idata->or_flags & FLAG_REACHED) == 0) {             dead_count++;        } else if (this_idata->opcode == opc_jsr ||                   this_idata->opcode == opc_jsr_w) {             jsr_count++;        }    }    if (dead_count > 0 || jsr_count > 0) {         rewriteCode(context, mb);        goto again;    }    n_stack_maps = 0;    for (inumber = 0; inumber < instruction_count; inumber++) {        instruction_data_type *this_idata = &idata[inumber];        if (this_idata->is_target) {             n_stack_maps++;        }    }    mb->n_stack_maps = n_stack_maps;    mb->stack_maps =         (struct stack_map *)malloc(n_stack_maps * sizeof(struct stack_map));    n_stack_maps = 0;    for (inumber = 0; inumber < instruction_count; inumber++) {	instruction_data_type *this_idata = &idata[inumber];	if (this_idata->is_target) {            struct stack_info_type *stack_info = &this_idata->stack_info;            struct register_info_type *register_info = &this_idata->register_info;            int register_count = register_info->register_count;  	    struct stack_item_type *stack;	    struct map_entry *new_entries;	    int index, index2;            /* We may be allocating too big a structure if there are longs              * or doubles on the stack, but that's okay */	    new_entries = (struct map_entry *)malloc(register_count * sizeof(struct map_entry));	    for (index2 = 0, index = 0; index < register_count; index++) {                fullinfo_type info = register_info->registers[index];                if (info == ITEM_Double || info == ITEM_Long) {                     if (index + 1 < register_count &&                            register_info->registers[index + 1] == info+1) {                        new_entries[index2++] = get_type_code(context, info);                        index++;                    } else {                        new_entries[index2++] = get_type_code(context, ITEM_Bogus);                    }                } else {                     new_entries[index2++] = get_type_code(context, info);                }            }            mb->stack_maps[n_stack_maps].offset = this_idata->offset;	    mb->stack_maps[n_stack_maps].locals = new_entries;	    mb->stack_maps[n_stack_maps].nlocals = index2;	    mb->stack_maps[n_stack_maps].nstacks = 0;	    for (stack = stack_info->stack; stack; stack = stack->next) {		mb->stack_maps[n_stack_maps].nstacks++;	    }	    new_entries = (struct map_entry *)malloc(mb->stack_maps[n_stack_maps].nstacks * sizeof(struct map_entry));	    index = 0;    	    for (stack = stack_info->stack; stack; stack = stack->next) {		new_entries[mb->stack_maps[n_stack_maps].nstacks - (++index)] = 		    get_type_code(context, stack->item);	    }    	    mb->stack_maps[n_stack_maps].stacks = new_entries;	    unhand(context->class)->has_stack_maps = 1;	    n_stack_maps++;	}    }}/*========================================================================= * FUNCTION:      verify_opcode_operands * OVERVIEW:      Verifies the operands of a single instruction given an *                instruction number and an offset. *                Also, for simplicity, move the operand into the ->operand *                field.  *                Make sure that branches do not go into the middle *                of nowhere. *                Invoked by verify_method().  * INTERFACE: *   parameters:  context_type *: context *                int: inumber *                int: offset *                 *   returns:     nothing  *=======================================================================*/static void

⌨️ 快捷键说明

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