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

📄 check_class.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * @(#)check_class.c	1.6 02/09/27 * * Copyright 1995-1998 by Sun Microsystems, Inc., * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. * All rights reserved. *  * This software is the confidential and proprietary information * of Sun Microsystems, Inc. ("Confidential Information").  You * shall not disclose such Confidential Information and shall use * it only in accordance with the terms of the license agreement * you entered into with Sun. * Use is subject to license terms. *//*========================================================================= * SYSTEM:    Verifier * SUBSYSTEM: Verifies ClassClass structure. * FILE:      check_class.c * OVERVIEW:  Code for verifying the ClassClass structure for internal *            consistency. * AUTHOR:    Sheng Liang, Consumer & Embedded  *            Initial implementation based on the Classic VM Verifier. *            Edited by Tasneem Sayeed, Java Consumer Technologies *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include <ctype.h>#include <oobj.h>#include <utf.h>#include <tree.h>#include <sys_api.h>/*========================================================================= * Globals and extern declarations *=======================================================================*/extern bool_t verify_class_codes(ClassClass *cb);static bool_t verify_constant_pool(ClassClass *cb);static bool_t is_legal_fieldname(ClassClass *cb, char *name, int type);static bool_t is_legal_method_signature(ClassClass *cb, char *name, char *signature);static bool_t is_legal_field_signature(ClassClass *cb, char *name, char *signature);static char *skip_over_fieldname(char *name, bool_t slash_okay);static char *skip_over_field_signature(char *name, bool_t void_okay);static void CCerror (ClassClass *cb, char *format, ...);/* Argument for is_legal_fieldname */enum { LegalClass, LegalField, LegalMethod };/*========================================================================= * FUNCTION:      VerifyClass * OVERVIEW:      Verifies a class given a pointer to the ClassClass struct.  *                Returns true if the class is ok.  * INTERFACE: *   parameters:  pointer to the ClassClass structure.  *                 *   returns:     boolean type *=======================================================================*/bool_tVerifyClass(ClassClass *cb){    bool_t result = TRUE;    struct methodblock *mb;    struct fieldblock *fb;    int i;    if (!verify_constant_pool(cb))         return FALSE;    /* Make sure all the method names and signatures are okay */    for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {	char *name = mb->fb.name;	char *signature = mb->fb.signature;	if (! (is_legal_fieldname(cb, name, LegalMethod)  &&	       is_legal_method_signature(cb, name, signature)))	    result = FALSE;    }    /* Make sure all the field names and signatures are okay */    for (i = cbFieldsCount(cb), fb = cbFields(cb); --i >= 0; fb++) {	if (!  (is_legal_fieldname(cb, fb->name, LegalField) &&		is_legal_field_signature(cb, fb->name, fb->signature))) 	    result = FALSE;    }    /* Make sure we are not overriding any final methods or classes*/    if (cbIsInterface(cb)) { 	struct methodblock *mb;	if ((cbSuperclass(cb) == NULL) ||	    (cbSuperclass(cb) != classJavaLangObject)) { 	    CCerror(cb, "Interface %s has bad superclass", cbName(cb));	    result = FALSE;	}	for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {	    if (mb->fb.access & ACC_STATIC) {		if (mb->fb.name[0] != '<') { 		    /* Only internal methods can be static */		    CCerror(cb, "Illegal static method %s in interface %s",			    mb->fb.name, cbName(cb));		    result = FALSE;		}	    }	}    } else if (cbSuperclass(cb)) { 	ClassClass *super_cb;	unsigned bitvector_size = (unsigned)(cbMethodTableSize(cb) + 31) >> 5;	long *bitvector = sysCalloc(bitvector_size, sizeof(long));	for (super_cb = cbSuperclass(cb); ; super_cb = cbSuperclass(super_cb)) {	    if (cbAccess(super_cb) & ACC_FINAL) {		CCerror(cb, "Class %s is subclass of final class %s",			cbName(cb), cbName(super_cb));		result = FALSE;	    }	    mb = cbMethods(super_cb);	    for (i = cbMethodsCount(super_cb); --i >= 0; mb++) {		if (mb->fb.access & ACC_FINAL) {		    unsigned offset = mb->fb.u.offset;		    bitvector[offset >> 5] |= (1 << (offset & 0x1F));		}	    }	    if (cbSuperclass(super_cb) == NULL) break;	}	for (i = cbMethodsCount(cb), mb = cbMethods(cb); --i >= 0; mb++) {	    unsigned offset = mb->fb.u.offset;	    if ((offset > 0) 		   && bitvector[offset >> 5] & (1 << (offset & 0x1F))) {		CCerror(cb, "Class %s overrides final method %s.%s",			cbName(cb), mb->fb.name, mb->fb.signature);		result = FALSE;	    }	}	sysFree(bitvector);    } else if (cb != classJavaLangObject) {	CCerror(cb, "Class %s does not have superclass", cbName(cb));	result = FALSE;    }	    if (result)	result = verify_class_codes(cb);    return result;}/*========================================================================= * FUNCTION:      verify_constant_pool  * OVERVIEW:      Verifies the constant pool given a pointer to the  *                ClassClass structure.  *                Makes two quick passes over the constant pool. The first *                pass ensures that everything is of the right type. *                Returns true if the constant pool is ok.  * INTERFACE: *   parameters:  pointer to the ClassClass structure.  *                 *   returns:     boolean type *=======================================================================*/static bool_tverify_constant_pool(ClassClass *cb){    union cp_item_type *cp = cbConstantPool(cb);    long cp_count = cbConstantPoolCount(cb);    unsigned char *type_table;    int i, type;        const int utf8_resolved = (CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED);    if (cp_count == 0) /* Primitive classes */        return TRUE;    type_table = cp[CONSTANT_POOL_TYPE_TABLE_INDEX].type;    /* Let's make two quick passes over the constant pool. The first one      * checks that everything is of the right type.            */    for (i = 1; i < cp_count; i++) {	switch(type = type_table[i]) {	    case CONSTANT_String:	    case CONSTANT_Class: {		int index = cp[i].i;		if (   (index < 1) 		       || (index >= cp_count)		       || (type_table[index] != utf8_resolved)) {		    CCerror(cb, "Bad index in constant pool #%d", i);		    return FALSE;		}		break;	    }			    case CONSTANT_String | CONSTANT_POOL_ENTRY_RESOLVED:		/* This can only happen if a string is the "initial" value of		 * some final static String.  We assume that the checking has		 * already been done.		 */		break;	    case CONSTANT_Fieldref:	    case CONSTANT_Methodref:	    case CONSTANT_InterfaceMethodref: 	    case CONSTANT_NameAndType: {		unsigned index = (unsigned)(cp[i].i);		int key1 = index >> 16;		int key2 = index & 0xFFFF;		if (key1 < 1 || key1 >= cp_count 		      || key2 < 1 || key2 >= cp_count) {		    CCerror(cb, "Bad index in constant pool #%d", i);		    return FALSE;		}		if (type == CONSTANT_NameAndType) {		    if (   (type_table[key1] != utf8_resolved) 			|| (type_table[key2] != utf8_resolved)) {			CCerror(cb, "Bad index in constant pool.");			return FALSE;		    }		} else {		    if (     ((type_table[key1] & CONSTANT_POOL_ENTRY_TYPEMASK) 			        != CONSTANT_Class)			  || ((type_table[key2] != CONSTANT_NameAndType))) {			CCerror(cb, "Bad index in constant pool #%d", i);			return FALSE;		    }		}		break;	    }			    case CONSTANT_Fieldref | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_Methodref | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_InterfaceMethodref | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_NameAndType | CONSTANT_POOL_ENTRY_RESOLVED:	        CCerror(cb, "Improperly resolved constant pool #%d", i);	        return FALSE;	    case CONSTANT_Class | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_Utf8 | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_Integer | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_Float | CONSTANT_POOL_ENTRY_RESOLVED:		break;	    case CONSTANT_Long | CONSTANT_POOL_ENTRY_RESOLVED:	    case CONSTANT_Double | CONSTANT_POOL_ENTRY_RESOLVED:		if ((i + 1 >= cp_count) || 		    (type_table[i + 1] != CONSTANT_POOL_ENTRY_RESOLVED)) {		    CCerror(cb, "Improper constant pool long/double #%d", i);		    return FALSE;		} else {		    i++;			    break;	    		}	    case CONSTANT_Integer:	    case CONSTANT_Float:	    case CONSTANT_Long:	    case CONSTANT_Double:	    case CONSTANT_Utf8:	        CCerror(cb, "Improperly unresolved constant pool #%d", i);	        return FALSE;	    default:	        CCerror(cb, "Illegal constant pool type at #%d", i);	        return FALSE;	}    }    for (i = 1; i < cp_count; i++) {	switch(type = type_table[i]) {	    case CONSTANT_Class: {		int index = cp[i].i;		if (!is_legal_fieldname(cb, cp[index].cp, LegalClass)) 		    return FALSE;		break;	    }	      	    case CONSTANT_Fieldref:	    case CONSTANT_Methodref:	    case CONSTANT_InterfaceMethodref: {		unsigned index = (unsigned)(cp[i].i);		int name_type_index = index & 0xFFFF;		int name_type_key = cp[name_type_index].i;		int name_index = name_type_key >> 16;		int signature_index = name_type_key & 0xFFFF;		char *name = cp[name_index].cp;		char *signature = cp[signature_index].cp;		if (type == CONSTANT_Fieldref) {		    if (! (is_legal_fieldname(cb, name, LegalField) &&			   is_legal_field_signature(cb, name, signature)))		        return FALSE;		} else {		    if (! (is_legal_fieldname(cb, name, LegalMethod) &&			   is_legal_method_signature(cb, name, signature)))		        return FALSE;		}		break;	    }	}    }    return TRUE;}	    /*========================================================================= * FUNCTION:      is_legal_fieldname  * OVERVIEW:      Returns true if the given name within the given ClassClass  *                structure consists of a legal fieldname or a classname  *                if the third argument is LegalClass. * INTERFACE: *   parameters:  pointer to the ClassClass structure.  *                char*: legal field name or a classname *                int: type of name (class or field name)  *                 *   returns:     boolean type *=======================================================================*/static bool_t is_legal_fieldname(ClassClass *cb, char *name, int type){    bool_t result;    if (name[0] == '<') {	result = (type == LegalMethod) && 	         ((strcmp(name, "<init>") == 0) || 		  (strcmp(name, "<clinit>") == 0));    } else {	char *p;	if (type == LegalClass && name[0] == SIGNATURE_ARRAY) {	    p = skip_over_field_signature(name, FALSE);	} else {	    p = skip_over_fieldname(name, type == LegalClass);	}	result = (p != 0 && p[0] == '\0');    }    if (!result) {	char *thing =    (type == LegalField) ? "Field" 	               : (type == LegalMethod) ? "Method" : "Class";			 	CCerror(cb, "Illegal %s name \"%s\"", thing, name);	return FALSE;    } else {        return TRUE;        }}/*========================================================================= * FUNCTION:      is_legal_field_signature * OVERVIEW:      Returns true if the entire given string within the given  *                ClassClass structure consists of a legal field signature. * INTERFACE: *   parameters:  pointer to the ClassClass structure.  *                char*: field name  *                char*: field signature  *                 *   returns:     boolean type *=======================================================================*/static bool_t is_legal_field_signature(ClassClass *cb, char *fieldname, char *signature) {    char *p = skip_over_field_signature(signature, FALSE);    if (p != 0 && p[0] == '\0') {	return TRUE;    } else {	CCerror(cb, "Field \"%s\" has illegal signature \"%s\"", 	       fieldname, signature);	return FALSE;    }}/*========================================================================= * FUNCTION:      is_legal_method_signature * OVERVIEW:      Returns true if the entire given string within the given  *                ClassClass structure consists of a legal method signature. * INTERFACE: *   parameters:  pointer to the ClassClass structure.  *                char*: method name  *                char*: method signature   *                 *   returns:     boolean type *=======================================================================*/static bool_t is_legal_method_signature(ClassClass *cb, char *methodname, char *signature){    char *p = signature;    char *next_p;    /* The first character must be a '(' */    if (*p++ == SIGNATURE_FUNC) {	/* Skip over however many legal field signatures there are */	while ((next_p = skip_over_field_signature(p, FALSE)) != 0) 	    p = next_p;	/* The first non-signature thing better be a ')' */	if (*p++ == SIGNATURE_ENDFUNC) {	    if (methodname[0] == '<') {		/* All internal methods must return void */		if ((p[0] == SIGNATURE_VOID) && (p[1] == '\0'))		    return TRUE;	    } else {		/* Now, we better just have a return value. */		next_p =  skip_over_field_signature(p, TRUE);		if (next_p && next_p[0] == '\0')		    return TRUE;	    }	}    }    CCerror(cb, "Method \"%s\" has illegal signature \"%s\"", 	   methodname, signature);    return FALSE;}	/*========================================================================= * Automatic code generation tables  *=======================================================================*/  /* The following tables and code generated using: */  /* java GenerateCharacter -verbose -c -identifiers -spec UnicodeData-2.1.2.txt -template check_class.c.template -o check_class.c 8 4 4 */  /* The X table has 256 entries for a total of 256 bytes. */

⌨️ 快捷键说明

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