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

📄 verify2.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
					     CLASS_CNAME(class));			return(false);		} else if (CLASS_IS_FINAL(class)) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "interfaces cannot be final (in interface \"%s\")",					     CLASS_CNAME(class));			return(false);		}	}#endif /* UNENFORCED_INTERFACE_RESTRICTIONS */	{		Field *fld;		int lpc;				fld = CLASS_FIELDS(class);		for( lpc = 0; lpc < CLASS_NFIELDS(class); lpc++ )		{			if( !checkField(&fld[lpc], einfo) )				return(false);		}	}	        /* java/lang/Object does not have a superclass, is not final, and is not an interface,	 * so we skip all of those checks	 */	if(strcmp(OBJECTCLASS, CLASS_CNAME(class))) {		if (class->superclass == NULL) {			/***********************************************************			 * 1 - every class except java/lang/Object has a superclass			 ***********************************************************/			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "class \"%s\" does not have a superclass",					     CLASS_CNAME(class));			return(false);		} else if (CLASS_IS_FINAL(class->superclass)) {			/*********************************************************			 * 2a: check that final classes are not inherited from			 *********************************************************/					postExceptionMessage(einfo, JAVA_LANG(VerifyError),					     "class \"%s\" cannot inherit from final class \"%s\"",					     CLASS_CNAME(class),					     CLASS_CNAME(class->superclass));			return(false);		} else if (CLASS_IS_INTERFACE(class)) {		        /* we separate this from the rest of the method checking because the only requirement			 * of methods in an interface is that they be public, abstract, and nothing else.			 */			Method* method;			int n;					for (n = CLASS_NMETHODS(class), method = CLASS_METHODS(class);			     n > 0;			     --n, ++method) {							        /* if it's <clinit> (init_name) then it doesn't have to be public.				 * compilers often insert a <clinit> function to initialize an				 * interfaces public static fields, if there are any.				 */				if (strcmp(init_name->data, METHOD_NAMED(method))) {					if (!METHOD_IS_PUBLIC(method)) {						postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),								     "interface methods must be declared public (method \"%s\" in interface \"%s\")",								     METHOD_NAMED(method),								     CLASS_CNAME(class));						return(false);					} else if (!METHOD_IS_ABSTRACT(method)) {						postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),								     "interface methods must be declared abstract (method \"%s\" in interface \"%s\")",								     METHOD_NAMED(method),								     CLASS_CNAME(class));						return(false);					}				}								if (checkMethodStaticConstraints(method, einfo) == false) {				        /* something else is wrong...exception raised elsewhere */					return(false);				}			}		} else {			/*********************************************************			 * 2b: check that final methods are not overridden			 *********************************************************/						Hjava_lang_Class *superclass;			Method* curMethod;			Method* method;			int n, m;									for (n = CLASS_NMETHODS(class), curMethod = CLASS_METHODS(class);			     n > 0;			     --n, ++curMethod) {						        /* check static constraints on each method */							if (METHOD_IS_CONSTRUCTOR(curMethod) && checkConstructor(curMethod, einfo) == false) {					return(false);				} else if (checkMethodStaticConstraints(curMethod, einfo) == false) {					return(false);				}			}									/* cycle through superclass hiarchy and make sure final methods aren't overriden */			for (superclass = class->superclass; superclass != NULL; superclass = superclass->superclass) {							        /* cycle through methods in current super class */				for (m = CLASS_NMETHODS(superclass), method = CLASS_METHODS(superclass);				     m > 0;				     --m, ++method) {										if (METHOD_IS_FINAL(method) && !METHOD_IS_PRIVATE(method) &&					    					    /* the following exceptions come from testing against Sun's JVM behavior */					    (strcmp(init_name->data, METHOD_NAMED(method)) &&					     strcmp("this", METHOD_NAMED(method)))) {											        /* make sure the method in question was not overriden in the current class */						for (n = CLASS_NMETHODS(class), curMethod = CLASS_METHODS(class);						     n > 0;						     --n, ++curMethod) {													/* TODO: we should really put all the methods of class into a hash table							 *       that we can access through name and signature.  this would make							 *       this check more efficient (is this done in the interpretter?  if so							 *       we may think about setting up the hashes here and just keeping them							 *       around for later).							 */							if (utf8ConstEqual(curMethod->name, method->name)							    && utf8ConstEqual(METHOD_SIG(curMethod), METHOD_SIG(method)))								{									postExceptionMessage(einfo, JAVA_LANG(VerifyError),											     "final method \"%s\" declared in class \"%s\" is overriden in class \"%s\"",											     METHOD_NAMED(method),											     CLASS_CNAME(class->superclass),											     CLASS_CNAME(class));									return(false);								}						}					}				}			}		}	}			/*********************************************************	 * 3 - Check class constant pool is consistent	 *	 * This is the only section of pass 2 that was available	 * under Transvirtual, though even this has been modified.	 *********************************************************/	/* error message for step 3 */			pool = CLASS_CONSTANTS(class);	        /* Constant pool loaded - check it's integrity. */	for (idx = 1; idx < pool->size; idx++) {		switch (pool->tags[idx]) {		case CONSTANT_Fieldref:		case CONSTANT_Methodref:		case CONSTANT_InterfaceMethodref:			tag = CONST_TAG(FIELDREF_CLASS(idx, pool), pool);			if (tag != CONSTANT_Class && tag != CONSTANT_ResolvedClass) {				return poolError(class, einfo);			}			if (CONST_TAG(FIELDREF_NAMEANDTYPE(idx, pool), pool) != CONSTANT_NameAndType) {				return poolError(class, einfo);			}			break;					case CONSTANT_NameAndType:			if (CONST_TAG(NAMEANDTYPE_NAME(idx, pool), pool) != CONSTANT_Utf8) {				return poolError(class, einfo);			}			if (CONST_TAG(NAMEANDTYPE_SIGNATURE(idx, pool), pool) != CONSTANT_Utf8) {				return poolError(class, einfo);			}			break;									/* the following tags are always legal, so no furthur checks need be performed */		case CONSTANT_Long:		case CONSTANT_Double:			idx++;		case CONSTANT_Integer:		case CONSTANT_Float:					case CONSTANT_Utf8:					case CONSTANT_ResolvedString:		case CONSTANT_ResolvedClass:						/* CONSTANT_Class and CONSTANT_String			 * have already been re-written to avoid the			 * extra indirection added by Java.  This is to fit			 * with the precompiled format.  Here we will not			 * get an error.			 */		case CONSTANT_Class:		case CONSTANT_String:			break;								default:		        /* undefined tag */			return poolError(class, einfo);			break;		}	}	DBG(VERIFY2, printConstantPool(class));		/**************************************************************	 * 4 - ensure that all field and method references in	 *     constant pool have valid names, classes, and type	 *     descriptor	 *	 * From the JVM spec pp.141-2:	 *   Note that when it looks at field and method references,	 *   this pass does not check to make sure that the given	 *   field or method actually exists in the given class, nor	 *   does it check that the type descriptors given refer to	 *   real classes.  It checks only that these items are well	 *   formed.	 **************************************************************/		/* Constant pool loaded - check the integrity of the type references */	pool = CLASS_CONSTANTS(class);	for (idx = 1; idx < pool->size; idx++) {		switch (pool->tags[idx]) {		case CONSTANT_Long:		case CONSTANT_Double:			idx++;		case CONSTANT_Integer:		case CONSTANT_Float:					case CONSTANT_Utf8:					case CONSTANT_ResolvedString:		case CONSTANT_ResolvedClass:					case CONSTANT_Class:		case CONSTANT_String:		case CONSTANT_NameAndType:			break;											case CONSTANT_Fieldref:			if (!parseFieldTypeDescriptor(FIELDREF_SIGD(idx, pool))) {				postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),						     "malformed field reference type descriptor, \"%s\", in class \"%s\"",						     CONST_UTF2CHAR(FIELDREF_TYPE(idx, pool), pool),						     CLASS_CNAME(class));				return(false);			}			break;					case CONSTANT_Methodref:			if (!parseMethodTypeDescriptor(METHODREF_SIGD(idx, pool))) {				postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),						     "malformed method reference type descriptor, \"%s\", in class \"%s\"",						     CONST_UTF2CHAR(METHODREF_SIGNATURE(idx, pool), pool),						     CLASS_CNAME(class));				return(false);			}			break;					case CONSTANT_InterfaceMethodref:			if (!parseMethodTypeDescriptor(INTERFACEMETHODREF_SIGD(idx, pool))) {				postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),						     "malformed interface method reference type descriptor, \"%s\", in class \"%s\"",						     CONST_UTF2CHAR(INTERFACEMETHODREF_SIGNATURE(idx, pool), pool),						     CLASS_CNAME(class));				return(false);			}			break;					default:		        /* we'll never get here, because of pass 3 */			postExceptionMessage(einfo, JAVA_LANG(InternalError),					     "step 4 of pass 2 verification has screwed up while processing class \"%s\"",					     CLASS_CNAME(class));			return(false);		}	}		return (true);}

⌨️ 快捷键说明

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