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

📄 classresolver.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 3 页
字号:
    if ((ret = ResolveInterfaces(cb, detail))) { /* All sorts of errors */	CCSet(cb, Error);	return ret;    }    InitializeInvoker(cb);    if ((verifyclasses == VERIFY_ALL) ||        ((verifyclasses == VERIFY_REMOTE) && (cbLoader(cb) != NULL))) {        if (!VerifyClass(cb)) {            *detail = "";            return JAVAPKG "VerifyError";        }    }    CCSet(cb, Linked);    /* We need this for bootstrapping.  We can't set the Handle's class block     * pointer in Object or Class until Class has been resolved.     */    if (cb == classJavaLangClass) {	int         j;	ClassClass **pcb;	BINCLASS_LOCK();	for (j = nbinclasses, pcb = binclasses; --j >= 0; pcb++) {	    cbHandle(*pcb)->methods = cbMethodTable(cb);	}	BINCLASS_UNLOCK();	InitPrimitiveClasses();    }    return NULL;}static bool_tRunClinit(ClassClass * cb){    if (CCIs(cb, Resolved))        return TRUE;    if ((cbName(cb)[0] != SIGNATURE_ARRAY) && !cbIsPrimitive(cb)) {	/* Don't need to initialize or verify array or primitive classes */        return RunStaticInitializers(cb);    } else if (cbName(cb)[0] == SIGNATURE_ARRAY) {	ClassClass *inner_cb = 	    cbConstantPool(cb)[CONSTANT_POOL_ARRAY_CLASS_INDEX].clazz;	if (inner_cb) {	    char *detail = 0;	    char *ret = ResolveClass(inner_cb, &detail);	    if (ret != NULL) {	        if (!exceptionOccurred(EE())) { 		    SignalError(0, ret, detail);		}		CCSet(cb, Error);		return FALSE;	    } else {	        CCSet(cb, Resolved);	    }	} else {	    CCSet(cb, Resolved);	}    } else {        CCSet(cb, Resolved);    }    return TRUE;}/* Find an already loaded class with the given name.  If no such class exists * then return 0. */#ifdef DEBUGvoidPrintLoadedClasses(){    int         j;    ClassClass **pcb, *cb;    BINCLASS_LOCK();    pcb = binclasses;    for (j = nbinclasses; --j >= 0; pcb++) {	cb = *pcb;	jio_fprintf(stdout, "class=%s, 0x%x\n", cbName(cb), cbLoader(cb));    }    BINCLASS_UNLOCK();}#endifstatic ClassClass *FindLoadedClass(char *name, struct Hjava_lang_ClassLoader *loader){    int left, right, middle, result;    ClassClass *cb = NULL;    BINCLASS_LOCK();    left = 0;    right = nbinclasses - 1;    result = 1;    while (left <= right) {        middle = (left + right)/2;	cb = binclasses[middle];	result = strcmp(name, cbName(cb));	if (result == 0) {	    if (loader < cbLoader(cb)) {	        result = -1;	    } else if (loader > cbLoader(cb)) {	        result = 1;	    } else {	        result = 0;	    }	}	if (result < 0) {	    right = middle - 1;	} else if (result > 0) {	    left = middle + 1;	} else {	    break;	}    }    BINCLASS_UNLOCK();    if (result == 0) {        return cb;    }    return NULL;}/* We attempt to resolve it, also, if the "resolve" argument is true. * Otherwise, we only perform a minimal initialization on it, such that * it points to its superclass, which points to its superclass. . . . */static ClassClass *InitializeAndResolveClass(ClassClass *cb, bool_t resolve){    char *err, *detail = NULL;    if ((err = InitializeClass(cb, &detail))) {        /* Check for underlying error already posted */	if (!exceptionOccurred(EE()))	    SignalError(0, err, detail);	return 0;    }    if (resolve) {        err = ResolveClass(cb, &detail);	if (err) {	    /* Check for underlying error already posted */ 	    if (!exceptionOccurred(EE())) 	        SignalError(0, err, detail);	    return 0;	}    }    return cb;}/* Find the class with the given name.   * If "resolve" is true, then we completely resolve the class.  Otherwise, * we only make sure that it points to its superclass, which points to its * superclass, . . . . */ClassClass *(*class_loader_func)(HObject *loader, char *name, long resolve) = 0;ClassClass *FindClass(struct execenv *ee, char *name, bool_t resolve){    return FindClassFromClass(ee, name, resolve, 0);}/* * lock_classes and unlock_classes are exported by the JIT interface, * but no longer used anywhere else. It grabs both locks to ensure  * backward compatibility with 1.0.2. */voidlock_classes(){    LOADCLASS_LOCK();    BINCLASS_LOCK();}voidunlock_classes(){    BINCLASS_UNLOCK();    LOADCLASS_UNLOCK();}ClassClass *FindClassFromClass(struct execenv *ee, char *name, bool_t resolve,		   ClassClass *from){    ClassClass *cb = 0;    if (name[0] == SIGNATURE_ARRAY) {	cb = Locked_FindArrayClassFromClass(ee, name, from) ;	if (cb && !exceptionOccurred(ee ? ee : EE()))	    return InitializeAndResolveClass(cb, resolve);        return NULL;    } else if (from != NULL && cbLoader(from)) {	/* unlock the classes while the class is located by	 * the class loader. The class loader should do this	 * in a synchronized method	 */	return ClassLoaderFindClass(ee, cbLoader(from), name, resolve);    } else {        extern char *current_class_name;        ClassClass *result = NULL;        char *old_class_name = current_class_name;        current_class_name = name;        LOADCLASS_LOCK();	cb = FindLoadedClass(name, 0);	if (cb == 0) {	    /* Check if there was an error; bail if so */	    if (ee == NULL)		ee = EE();	    if (!exceptionOccurred(ee))		cb = LoadClassLocally(name);	}	LOADCLASS_UNLOCK();	if (cb && !exceptionOccurred(ee ? ee : EE())) { 	    result = InitializeAndResolveClass(cb, resolve);        }        current_class_name = old_class_name;        return result;    }}/* * FindStickySystemClass is a variant of FindClassFromClass that makes the  * class sticky (immune to class GC) if the class can be found.  It is only * used on system classes, i.e. classes with no class loader, so it's  * equivalent to FindClassFromClass with "from" argument 0.  It returns 0 * if the class can't be found, and like FindClass assumes that the caller * will deal with that.  Note that until the class has been made sticky it * must be kept somewhere where GC will find it. */ClassClass *FindStickySystemClass(struct execenv *ee, char *name, bool_t resolve){    ClassClass *cb;    if ((cb = FindClassFromClass(ee, name, resolve, 0)) != NULL) {	MakeClassSticky(cb);    }    return cb;}/* Find the array class with the specified name.  */static ClassClass *Locked_FindArrayClassFromClass(struct execenv *ee, char *name, 			       ClassClass *from) {     struct Hjava_lang_ClassLoader *fromLoader = 	        (from  == NULL) ? NULL : cbLoader(from);    char *name_p;    int depth, base_type;    ClassClass *cb;    struct Hjava_lang_ClassLoader *loader;    ClassClass *inner_cb;    sysAssert(name[0] == SIGNATURE_ARRAY);    if (fromLoader == NULL) { 	/* quick optimization if we know that we don't need a class loader */	cb = FindLoadedClass(name, NULL);	if (cb != NULL) 	    return cb;    }	        /* Strip off all the initial SIGNATURE_ARRAY's to determine the depth,     * and also what's left.  When we're done, name_p points at the first     * non-character, and depth is the count of the array depth     */    for (name_p = name, depth = 0; *name_p == SIGNATURE_ARRAY; 	 name_p++, depth++);    /* Look at the character to determine what type of array we have. */    switch(*name_p++) {        case SIGNATURE_INT:    base_type = T_INT; break;	case SIGNATURE_LONG:   base_type = T_LONG; break;	case SIGNATURE_FLOAT:  base_type = T_FLOAT; break;	case SIGNATURE_DOUBLE: base_type = T_DOUBLE; break;	case SIGNATURE_BOOLEAN:base_type = T_BOOLEAN; break; 	case SIGNATURE_BYTE:   base_type = T_BYTE; break;	case SIGNATURE_CHAR:   base_type = T_CHAR; break;	case SIGNATURE_SHORT:  base_type = T_SHORT; break;	case SIGNATURE_CLASS:  base_type = T_CLASS; break;        default:	       return NULL;	/* bad signature */    }    if (base_type == T_CLASS) { 	char buffer_space[50];	char *buffer = buffer_space;	char *endChar = strchr(name_p, SIGNATURE_ENDCLASS);	int nameLength = endChar - name_p;	if (endChar == NULL || endChar[1] != '\0')	    return NULL;	if (nameLength >= sizeof(buffer_space)) /* need bigger buffer */	    buffer = sysMalloc(nameLength + 1);	memcpy(buffer, name_p, nameLength);	buffer[nameLength] = '\0';	inner_cb = FindClassFromClass(ee, buffer, FALSE, from);	if (buffer != buffer_space) /* free buffer, if we malloc'ed it */	    sysFree(buffer);	if (inner_cb == NULL) 	    return NULL;	/* loader should either be fromLoader or NULL. */	loader = cbLoader(inner_cb);    } else { 	if (*name_p != '\0')			/* bad signature */	    return NULL;	inner_cb = NULL;	loader = NULL;    }    LOADCLASS_LOCK();    cb = FindLoadedClass(name, loader);    if (cb == NULL) { 	/* Create the fake array class corresponding to this.	 */	cb = createFakeArrayClass(name, base_type, depth, inner_cb, loader);    }     LOADCLASS_UNLOCK();    return cb;}/* * Convert a name and type to a hash code * * We make copies of all strings that go into the hash table * in case the class that is the source of the strings being * inserted is eventually unloaded. */unsigned NameAndTypeToHash(char *name, char *type){    extern struct StrIDhash *nameTypeHash;    unsigned name_key;    unsigned type_key;    unsigned ret;    NAMETYPEHASH_LOCK();    if (((name_key = Str2ID(&nameTypeHash, name, 0, TRUE)) == 0) ||	((type_key = Str2ID(&nameTypeHash, type, 0, TRUE)) == 0)) {	SignalError(0, JAVAPKG "OutOfMemoryError", 0);	ret = 0;    } else {	ret = (name_key << 16) + type_key;    }    NAMETYPEHASH_UNLOCK();    return ret;}/* * Pseudo-classes to represent primitive Java types. */ClassClass *class_void;ClassClass *class_boolean;ClassClass *class_byte;ClassClass *class_char;ClassClass *class_short;ClassClass *class_int;ClassClass *class_long;ClassClass *class_float;ClassClass *class_double;struct primtype {    char		*name;    char		typesig;    unsigned char	typecode;    unsigned char	slotsize;    unsigned char	elementsize;    ClassClass		**cellp;} const primitive_types[] = {    { "void",	SIGNATURE_VOID,	   T_VOID,	0, 0,	&class_void },    { "boolean",SIGNATURE_BOOLEAN, T_BOOLEAN,	4, 1,	&class_boolean },    { "byte",	SIGNATURE_BYTE,	   T_BYTE,	4, 1,	&class_byte },    { "char",	SIGNATURE_CHAR,	   T_CHAR,	4, 2,	&class_char },    { "short",	SIGNATURE_SHORT,   T_SHORT,	4, 2,	&class_short },    { "int",	SIGNATURE_INT,	   T_INT,	4, 4,	&class_int },    { "long",	SIGNATURE_LONG,	   T_LONG,	8, 8,	&class_long },    { "float",	SIGNATURE_FLOAT,   T_FLOAT,	4, 4,	&class_float },    { "double",	SIGNATURE_DOUBLE,  T_DOUBLE,	8, 8,	&class_double }};#define	PRIMITIVE_TYPE_COUNT	\	(sizeof (primitive_types) / sizeof (primitive_types[0]))#define	GET_PRIMITIVE_CLASS(nm) \	(class_##nm ? class_##nm : FindPrimitiveClass(#nm))ClassClass *FindPrimitiveClass(char *name){    int i;    ClassClass *cb;    const struct primtype *p;        for (i = 0; i < PRIMITIVE_TYPE_COUNT; i++) {	p = &primitive_types[i];	if (strcmp(name, p->name) == 0) {	    cb = *p->cellp;	    if (cb == NULL) {		char *err, *detail = NULL;		cb = createPrimitiveClass(p->name, p->typesig, p->typecode,		    p->slotsize, p->elementsize);		sysAssert(cb != NULL);		if ((err = InitializeClass(cb, &detail)) != NULL)		    return NULL; /* XXX */		if ((err = ResolveClass(cb, &detail)) != NULL)		    return NULL; /* XXX*/		*p->cellp = cb;	    }	    return cb;	}    }    return NULL;}static voidInitPrimitiveClasses(){    int i;    for (i = 0; i < PRIMITIVE_TYPE_COUNT; i++)	FindPrimitiveClass(primitive_types[i].name);}

⌨️ 快捷键说明

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