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

📄 verify2.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * verify2.c * * Copyright 2004, 2005 *   Kaffe.org contributors. See ChangeLog for details. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. * * * verify2() was originally created by someone in Transvirtual Technologies.  however, * it did almost nothing (only a shrivel of the stuff needed by pass 2... * specifically part 3 of of pass 2, which has been modified), * so questions regarding pass 2 should be sent to: *     Rob Gonzalez <rob@kaffe.org> */#include "config.h"#ifdef HAVE_STRING_H#include <string.h>#endif#include "access.h"#include "baseClasses.h"#include "classMethod.h"#include "errors.h"#include "gtypes.h"#include "utf8const.h"#include "verify.h"#include "verify-debug.h"/********************************************************************************* * Pass 2 Verification *********************************************************************************//* Helper function for pool errors */static inlineboolpoolError(Hjava_lang_Class* class, errorInfo *einfo){	postExceptionMessage(einfo, JAVA_LANG(ClassFormatError), "malformed constant pool in class \"%s\"", CLASS_CNAME(class));	return (false);}staticboolcheckField(Field *field, errorInfo *einfo){	const char *reason = checkAccessFlags(CLASS_IS_INTERFACE(field->clazz) ? ACC_TYPE_INTERFACE_FIELD : ACC_TYPE_FIELD,					field->accflags);	if (reason) {		postExceptionMessage(einfo,				     JAVA_LANG(ClassFormatError),				     "(class: %s, field: %s) %s",				     CLASS_CNAME(field->clazz),				     field->name->data,				     reason);		return false;	}	return true;}/* perhaps this should go in classMethod.[ch]... */static bool isMethodVoid(Method* method){	char* sig = (char*)method->parsed_sig->signature->data;	int i = strlen(sig);		return (i > 2) && (sig[i-2] == ')' && sig[i-1] == 'V');}static inlineboolabstractMethodError(Method* method, errorInfo* einfo, const char * msg){	postExceptionMessage(einfo, 			     JAVA_LANG(ClassFormatError),			     "in method \"%s.%s\": abstract methods cannot be %s",			     CLASS_CNAME(method->class),			     METHOD_NAMED(method),			     msg);	return(false);}/* * Given a method with its ACC_ABSTRACT flag set, this checks the the rest of the access flags * are set appropriately.  that is, it cannot be final, native, private, static, strictfp, or synchronized. * * also, we check that an abstract method doesn't have a code attribute. */staticboolcheckAbstractMethod(Method* method, errorInfo* einfo){	#ifdef ABSTRACT_METHOD_VS_ABSTRACT_CLASS		/* This is commented out because Sun's verifier doesn't care if an abstract method	 * is in an abstract class.	 */	 /* ensure that only abstract classes may have abstract methods */	if (!(CLASS_IS_INTERFACE(method->class) || CLASS_IS_ABSTRACT(method->class))) {		postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),				     "in method \"%s.%s\": only abstract classes may have abstract methods",				     CLASS_CNAME(method->class),				     METHOD_NAMED(method));		return(false);	}#endif /* ABSTRACT_METHOD_VS_ABSTRACT_CLASS */			/* constructors cannot be abstract */	if (METHOD_IS_CONSTRUCTOR(method)) {		if (CLASS_IS_INTERFACE(method->class)) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "in method \"%s.%s\": an interface cannot have a constructor <init>",					     CLASS_CNAME(method->class),					     METHOD_NAMED(method));			return(false);		} else {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "in method \"%s.%s\": constructors cannot be abstract",					     CLASS_CNAME(method->class),					     METHOD_NAMED(method));			return(false);		}	}			/* ensure the abstract method has no code */	if (METHOD_BYTECODE_LEN(method) > 0) {		postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),				     "in method \"%s.%s\": abstract methods cannot have a Code attribute",				     CLASS_CNAME(method->class),				     METHOD_NAMED(method));		return(false);	}			/* enforce access flag rules of the JVML spec. for abstract methods */	if (METHOD_IS_PRIVATE(method))           { return abstractMethodError(method, einfo, "private");      }	else if (METHOD_IS_FINAL(method))        { return abstractMethodError(method, einfo, "final");        }	else if (METHOD_IS_NATIVE(method))       { return abstractMethodError(method, einfo, "native");       }	else if (METHOD_IS_STATIC(method))       { return abstractMethodError(method, einfo, "static");       }	else if (METHOD_IS_STRICT(method))       { return abstractMethodError(method, einfo, "strictfp");     }		/* not enforced by Sun's verifier	 *	else if (METHOD_IS_SYNCHRONISED(method)) { return abstractMethodError(method, einfo, "synchronized"); }	*/			return(true);}/* * ensures that all access flags are legal (more specifically, that the combination * of access flags in a method is legal). * * also checks code-length constraints of the method. */staticboolcheckMethodStaticConstraints(Method* method, errorInfo* einfo){	if (METHOD_IS_PUBLIC(method)) {		if (METHOD_IS_PROTECTED(method)) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "%s.%s: method cannot be both public and protected",					     CLASS_CNAME(method->class),					     METHOD_NAMED(method));			return(false);		} else if(METHOD_IS_PRIVATE(method)) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "%s.%s: method cannot be both public and private",					     CLASS_CNAME(method->class),					     METHOD_NAMED(method));			return(false);		}	} else if (METHOD_IS_PROTECTED(method) && METHOD_IS_PRIVATE(method)) {		postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),				     "%s.%s: method cannot be both protected and private",				     CLASS_CNAME(method->class),				     METHOD_NAMED(method));		return(false);	}			if (METHOD_IS_ABSTRACT(method)) {		if (checkAbstractMethod(method, einfo) == false) {			return(false);		}	} else if (!METHOD_IS_NATIVE(method)) {	        /* code length static constraints */				if (METHOD_BYTECODE_LEN(method) == 0) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "%s.%s: method's code length cannot be zero",					     CLASS_CNAME(method->class),					     METHOD_NAMED(method));			return(false);		} else if (METHOD_BYTECODE_LEN(method) >= 65536) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "%s.%s: method's code length must be less than 65536 bytes",					     CLASS_CNAME(method->class),					     METHOD_NAMED(method));			return(false);		}	}			return(true);}/* * makes sure a constructor's flags are valid. */staticboolcheckConstructor(Method* method, errorInfo* einfo){	if (METHOD_IS_STATIC(method)) {		postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),				     "class %s: constructor cannot be static",				     CLASS_CNAME(method->class));		return false;	} else if (METHOD_IS_FINAL(method)) {		postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),				     "class %s: constructor cannot be final",				     CLASS_CNAME(method->class));		return false;	} else if (!isMethodVoid(method)) {		postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),				     "class %s: constructor does not have void return type",				     CLASS_CNAME(method->class));		return false;	} else if (checkMethodStaticConstraints(method, einfo) == false) {		return false;	}		return(true);}/* * Verify pass 2:  Check the internal consistency of the class file *  but do not check the bytecode.  If at any point we find an error in the *  class file format, we abort and throw a ClassFormatError or VerifyError *  (depending on what the Sun Java VM would throw given the specific error). * * According to the JVML spec for Java 2, this should do the following: *  1. ensure that every class (except java/lang/Object) has a direct superclass * *  2. a.  ensure that final classes are not subclassed  *     b.  ensure that final methods are not overriden * *  3. ensure that constant pool satisfies the documented static constraints *     - i.e. each CONSTANT_Class_info structure in constant pool contains in its *       name_index item a valid constant pool index for a CONSTANT_Utf8_info structure, *       etc. * *  4. ensure that all field references and method references in the constant pool have *     (this is basically parsing type signatures for validity): *     - valid names *     - valid classes *     - a valid type desriptor * * However, the JVML spec also specifies a bunch of other rules that make sense to be * checked here (i.e. interfaces must be abstract) */boolverify2(Hjava_lang_Class* class, errorInfo *einfo){	constants* pool;	uint32 idx;	int tag;			if (isTrustedClass(class))		return(true);			DBG(VERIFY2, dprintf("\nPass 2 Verifying class %s\n", CLASS_CNAME(class)); );	#ifdef UNENFORCED_INTERFACE_RESTRICTIONS	/* this is commented out because Sun's Java runtime environment doesn't enforce the restrictions	 * placed upon interfaces by the specification.	 * GJC also doesn't follow this!	 */	if (CLASS_IS_INTERFACE(class)) {	        /* JVML spec p. 96: if a class has ACC_INTERFACE flag set, it must also have		 * ( ACC_ABSTRACT set and may have ACC_PUBLIC set.  it may not have any other flags		 * (in the given table) set.		 */		if (!CLASS_IS_ABSTRACT(class)) {			postExceptionMessage(einfo, JAVA_LANG(ClassFormatError),					     "interfaces must have their abstract flag set (in interface \"%s\")",

⌨️ 快捷键说明

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